From 05639b9f86c948185e1a76d034b202c2545a7781 Mon Sep 17 00:00:00 2001 From: YohDeadfall Date: Tue, 11 Feb 2020 13:48:43 +0300 Subject: [PATCH 001/420] Fixed serialization of hidden base class members --- .../Text/Json/Serialization/JsonClassInfo.cs | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs index 12202e395b67a..a70acc53675db 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs @@ -97,52 +97,52 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) case ClassType.Object: { CreateObject = options.MemberAccessorStrategy.CreateConstructor(type); + Dictionary cache = CreatePropertyCache(); - PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - - Dictionary cache = CreatePropertyCache(properties.Length); - - foreach (PropertyInfo propertyInfo in properties) + for (Type? currentType = runtimeType; currentType != null; currentType = currentType.BaseType) { - // Ignore indexers - if (propertyInfo.GetIndexParameters().Length > 0) + foreach (PropertyInfo propertyInfo in currentType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) { - continue; - } - - if (IsNonPublicProperty(propertyInfo)) - { - if (JsonPropertyInfo.GetAttribute(propertyInfo) != null) + // Ignore indexers + if (propertyInfo.GetIndexParameters().Length > 0) { - ThrowHelper.ThrowInvalidOperationException_JsonIncludeOnNonPublicInvalid(propertyInfo, Type); + continue; } - // Non-public properties should not be included for (de)serialization. - continue; - } + if (IsNonPublicProperty(propertyInfo)) + { + if (JsonPropertyInfo.GetAttribute(propertyInfo) != null) + { + ThrowHelper.ThrowInvalidOperationException_JsonIncludeOnNonPublicInvalid(propertyInfo, Type); + } - // For now we only support public getters\setters - if (propertyInfo.GetMethod?.IsPublic == true || - propertyInfo.SetMethod?.IsPublic == true) - { - JsonPropertyInfo jsonPropertyInfo = AddProperty(propertyInfo, type, options); - Debug.Assert(jsonPropertyInfo != null && jsonPropertyInfo.NameAsString != null); + // Non-public properties should not be included for (de)serialization. + continue; + } - // If the JsonPropertyNameAttribute or naming policy results in collisions, throw an exception. - if (!JsonHelpers.TryAdd(cache, jsonPropertyInfo.NameAsString, jsonPropertyInfo)) + // For now we only support public getters\setters + if (propertyInfo.GetMethod?.IsPublic == true || + propertyInfo.SetMethod?.IsPublic == true) { - JsonPropertyInfo other = cache[jsonPropertyInfo.NameAsString]; + JsonPropertyInfo jsonPropertyInfo = AddProperty(propertyInfo.PropertyType, propertyInfo, type, options); + Debug.Assert(jsonPropertyInfo != null && jsonPropertyInfo.NameAsString != null); - if (other.ShouldDeserialize == false && other.ShouldSerialize == false) - { - // Overwrite the one just added since it has [JsonIgnore]. - cache[jsonPropertyInfo.NameAsString] = jsonPropertyInfo; - } - else if (jsonPropertyInfo.ShouldDeserialize == true || jsonPropertyInfo.ShouldSerialize == true) + // If the JsonPropertyNameAttribute or naming policy results in collisions, throw an exception. + if (!JsonHelpers.TryAdd(cache, jsonPropertyInfo.NameAsString, jsonPropertyInfo)) { - ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameConflict(Type, jsonPropertyInfo); + JsonPropertyInfo other = cache[jsonPropertyInfo.NameAsString]; + + if (other.ShouldDeserialize == false && other.ShouldSerialize == false) + { + // Overwrite the one just added since it has [JsonIgnore]. + cache[jsonPropertyInfo.NameAsString] = jsonPropertyInfo; + } + else if (jsonPropertyInfo.ShouldDeserialize == true || jsonPropertyInfo.ShouldSerialize == true) + { + ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameConflict(Type, jsonPropertyInfo); + } + // else ignore jsonPropertyInfo since it has [JsonIgnore]. } - // else ignore jsonPropertyInfo since it has [JsonIgnore]. } } } From a01bbe8adfe229fe974e92fb9662bb2aaf981221 Mon Sep 17 00:00:00 2001 From: YohDeadfall Date: Mon, 3 Feb 2020 17:43:53 +0300 Subject: [PATCH 002/420] Added tests to check non-public props are ignored --- .../Serialization/PropertyVisibilityTests.cs | 225 ++++++++++++++++++ 1 file changed, 225 insertions(+) diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index 9aa9cd6bb8ba7..b61f8f19e94a6 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -11,6 +11,231 @@ namespace System.Text.Json.Serialization.Tests { public static partial class PropertyVisibilityTests { + [Fact] + public static void Serialize_new_slot_public_property() + { + // Serialize + var obj = new ClassWithNewSlotProperty(); + string json = JsonSerializer.Serialize(obj); + + Assert.Equal(@"{""MyString"":""NewDefaultValue""}", json); + + // Deserialzie + json = @"{""MyString"":""NewValue""}"; + obj = JsonSerializer.Deserialize(json); + + Assert.Equal("NewValue", ((ClassWithNewSlotProperty)obj).MyString); + Assert.Equal("DefaultValue", ((ClassWithPrivateProperty)obj).MyString); + } + + [Fact] + public static void Serialize_base_public_property_on_conflict_with_derived_private() + { + // Serialize + var obj = new ClassWithNewSlotPrivateProperty(); + string json = JsonSerializer.Serialize(obj); + + Assert.Equal(@"{""MyString"":""DefaultValue""}", json); + + // Deserialzie + json = @"{""MyString"":""NewValue""}"; + obj = JsonSerializer.Deserialize(json); + + Assert.Equal("NewValue", ((ClassWithPublicProperty)obj).MyString); + Assert.Equal("NewDefaultValue", ((ClassWithNewSlotPrivateProperty)obj).MyString); + } + + [Fact] + public static void Serialize_public_property_on_conflict_with_private_due_to_attributes() + { + // Serialize + var obj = new ClassWithPropertyNamingConflict(); + string json = JsonSerializer.Serialize(obj); + + Assert.Equal(@"{""MyString"":""DefaultValue""}", json); + + // Deserialzie + json = @"{""MyString"":""NewValue""}"; + obj = JsonSerializer.Deserialize(json); + + Assert.Equal("NewValue", obj.MyString); + Assert.Equal("ConflictingValue", obj.ConflictingString); + } + + [Fact] + public static void Serialize_public_property_on_conflict_with_private_due_to_policy() + { + var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + + // Serialize + var obj = new ClassWithPropertyPolicyConflict(); + string json = JsonSerializer.Serialize(obj, options); + + Assert.Equal(@"{""myString"":""DefaultValue""}", json); + + // Deserialzie + json = @"{""myString"":""NewValue""}"; + obj = JsonSerializer.Deserialize(json, options); + + Assert.Equal("NewValue", obj.MyString); + Assert.Equal("ConflictingValue", obj.myString); + } + + [Fact] + public static void Ignore_non_public_property() + { + // Serialize + var obj = new ClassWithPrivateProperty(); + string json = JsonSerializer.Serialize(obj); + + Assert.Equal(@"{}", json); + + // Deserialzie + json = @"{""MyString"":""NewValue""}"; + obj = JsonSerializer.Deserialize(json); + + Assert.Equal("DefaultValue", obj.MyString); + } + + [Fact] + public static void Ignore_ignored_new_slot_public_property() + { + // Serialize + var obj = new ClassWithIgnoredNewSlotProperty(); + string json = JsonSerializer.Serialize(obj); + + Assert.Equal(@"{}", json); + + // Deserialzie + json = @"{""MyString"":""NewValue""}"; + obj = JsonSerializer.Deserialize(json); + + Assert.Equal("NewDefaultValue", ((ClassWithIgnoredNewSlotProperty)obj).MyString); + Assert.Equal("DefaultValue", ((ClassWithPrivateProperty)obj).MyString); + } + + [Fact] + public static void Ignore_ignored_base_public_property_on_conflict_with_derived_private() + { + // Serialize + var obj = new ClassWithIgnoredPublicPropertyAndNewSlotPrivate(); + string json = JsonSerializer.Serialize(obj); + + Assert.Equal(@"{}", json); + + // Deserialzie + json = @"{""MyString"":""NewValue""}"; + obj = JsonSerializer.Deserialize(json); + + Assert.Equal("DefaultValue", ((ClassWithIgnoredPublicProperty)obj).MyString); + Assert.Equal("NewDefaultValue", ((ClassWithIgnoredPublicPropertyAndNewSlotPrivate)obj).MyString); + } + + [Fact] + public static void Ignore_public_property_on_conflict_with_private_due_to_attributes() + { + // Serialize + var obj = new ClassWithIgnoredPropertyNamingConflict(); + string json = JsonSerializer.Serialize(obj); + + Assert.Equal(@"{}", json); + + // Deserialzie + json = @"{""MyString"":""NewValue""}"; + obj = JsonSerializer.Deserialize(json); + + Assert.Equal("DefaultValue", obj.MyString); + Assert.Equal("ConflictingValue", obj.ConflictingString); + } + + [Fact] + public static void Ignore_public_property_on_conflict_with_private_due_to_policy() + { + var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + + // Serialize + var obj = new ClassWithIgnoredPropertyPolicyConflict(); + string json = JsonSerializer.Serialize(obj, options); + + Assert.Equal(@"{}", json); + + // Deserialzie + json = @"{""myString"":""NewValue""}"; + obj = JsonSerializer.Deserialize(json, options); + + Assert.Equal("DefaultValue", obj.MyString); + Assert.Equal("ConflictingValue", obj.myString); + } + + public class ClassWithPrivateProperty + { + internal string MyString { get; set; } = "DefaultValue"; + } + + public class ClassWithNewSlotProperty : ClassWithPrivateProperty + { + public new string MyString { get; set; } = "NewDefaultValue"; + } + + public class ClassWithPublicProperty + { + public string MyString { get; set; } = "DefaultValue"; + } + + public class ClassWithNewSlotPrivateProperty : ClassWithPublicProperty + { + internal new string MyString { get; set; } = "NewDefaultValue"; + } + + public class ClassWithPropertyNamingConflict + { + public string MyString { get; set; } = "DefaultValue"; + + [JsonPropertyName(nameof(MyString))] + internal string ConflictingString { get; set; } = "ConflictingValue"; + } + + public class ClassWithPropertyPolicyConflict + { + public string MyString { get; set; } = "DefaultValue"; + + internal string myString { get; set; } = "ConflictingValue"; + } + + public class ClassWithIgnoredNewSlotProperty : ClassWithPrivateProperty + { + [JsonIgnore] + public new string MyString { get; set; } = "NewDefaultValue"; + } + + public class ClassWithIgnoredPublicProperty + { + [JsonIgnore] + public string MyString { get; set; } = "DefaultValue"; + } + + public class ClassWithIgnoredPublicPropertyAndNewSlotPrivate : ClassWithIgnoredPublicProperty + { + internal new string MyString { get; set; } = "NewDefaultValue"; + } + + public class ClassWithIgnoredPropertyNamingConflict + { + [JsonIgnore] + public string MyString { get; set; } = "DefaultValue"; + + [JsonPropertyName(nameof(MyString))] + internal string ConflictingString { get; set; } = "ConflictingValue"; + } + + public class ClassWithIgnoredPropertyPolicyConflict + { + [JsonIgnore] + public string MyString { get; set; } = "DefaultValue"; + + internal string myString { get; set; } = "ConflictingValue"; + } + [Fact] public static void NoSetter() { From 827df7e23fb574aa07e83c87d196fd37a335b45e Mon Sep 17 00:00:00 2001 From: YohDeadfall Date: Tue, 11 Feb 2020 14:16:49 +0300 Subject: [PATCH 003/420] Simplified cache construction --- .../src/System/Text/Json/Serialization/JsonClassInfo.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs index a70acc53675db..f4c6368dc5b9a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs @@ -97,7 +97,10 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) case ClassType.Object: { CreateObject = options.MemberAccessorStrategy.CreateConstructor(type); - Dictionary cache = CreatePropertyCache(); + Dictionary cache = new Dictionary( + Options.PropertyNameCaseInsensitive + ? StringComparer.OrdinalIgnoreCase + : StringComparer.Ordinal); for (Type? currentType = runtimeType; currentType != null; currentType = currentType.BaseType) { From ed8ca2b34e51971d22eed70545444aff1f67bf37 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Sun, 23 Feb 2020 12:30:07 +0300 Subject: [PATCH 004/420] Addressed review issues --- .../Text/Json/Serialization/JsonClassInfo.cs | 2 +- .../Serialization/PropertyVisibilityTests.cs | 42 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs index f4c6368dc5b9a..1c34862229f60 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs @@ -102,7 +102,7 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal); - for (Type? currentType = runtimeType; currentType != null; currentType = currentType.BaseType) + for (Type? currentType = type; currentType != null; currentType = currentType.BaseType) { foreach (PropertyInfo propertyInfo in currentType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) { diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index b61f8f19e94a6..9da764065384a 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -12,7 +12,7 @@ namespace System.Text.Json.Serialization.Tests public static partial class PropertyVisibilityTests { [Fact] - public static void Serialize_new_slot_public_property() + public static void SerializeNewSlotPublicProperty() { // Serialize var obj = new ClassWithNewSlotProperty(); @@ -20,29 +20,29 @@ public static void Serialize_new_slot_public_property() Assert.Equal(@"{""MyString"":""NewDefaultValue""}", json); - // Deserialzie + // Deserialize json = @"{""MyString"":""NewValue""}"; obj = JsonSerializer.Deserialize(json); Assert.Equal("NewValue", ((ClassWithNewSlotProperty)obj).MyString); - Assert.Equal("DefaultValue", ((ClassWithPrivateProperty)obj).MyString); + Assert.Equal("DefaultValue", ((ClassWithInternalProperty)obj).MyString); } [Fact] public static void Serialize_base_public_property_on_conflict_with_derived_private() { // Serialize - var obj = new ClassWithNewSlotPrivateProperty(); + var obj = new ClassWithNewSlotInternalProperty(); string json = JsonSerializer.Serialize(obj); Assert.Equal(@"{""MyString"":""DefaultValue""}", json); - // Deserialzie + // Deserialize json = @"{""MyString"":""NewValue""}"; - obj = JsonSerializer.Deserialize(json); + obj = JsonSerializer.Deserialize(json); Assert.Equal("NewValue", ((ClassWithPublicProperty)obj).MyString); - Assert.Equal("NewDefaultValue", ((ClassWithNewSlotPrivateProperty)obj).MyString); + Assert.Equal("NewDefaultValue", ((ClassWithNewSlotInternalProperty)obj).MyString); } [Fact] @@ -54,7 +54,7 @@ public static void Serialize_public_property_on_conflict_with_private_due_to_att Assert.Equal(@"{""MyString"":""DefaultValue""}", json); - // Deserialzie + // Deserialize json = @"{""MyString"":""NewValue""}"; obj = JsonSerializer.Deserialize(json); @@ -73,7 +73,7 @@ public static void Serialize_public_property_on_conflict_with_private_due_to_pol Assert.Equal(@"{""myString"":""DefaultValue""}", json); - // Deserialzie + // Deserialize json = @"{""myString"":""NewValue""}"; obj = JsonSerializer.Deserialize(json, options); @@ -85,14 +85,14 @@ public static void Serialize_public_property_on_conflict_with_private_due_to_pol public static void Ignore_non_public_property() { // Serialize - var obj = new ClassWithPrivateProperty(); + var obj = new ClassWithInternalProperty(); string json = JsonSerializer.Serialize(obj); Assert.Equal(@"{}", json); - // Deserialzie + // Deserialize json = @"{""MyString"":""NewValue""}"; - obj = JsonSerializer.Deserialize(json); + obj = JsonSerializer.Deserialize(json); Assert.Equal("DefaultValue", obj.MyString); } @@ -106,12 +106,12 @@ public static void Ignore_ignored_new_slot_public_property() Assert.Equal(@"{}", json); - // Deserialzie + // Deserialize json = @"{""MyString"":""NewValue""}"; obj = JsonSerializer.Deserialize(json); Assert.Equal("NewDefaultValue", ((ClassWithIgnoredNewSlotProperty)obj).MyString); - Assert.Equal("DefaultValue", ((ClassWithPrivateProperty)obj).MyString); + Assert.Equal("DefaultValue", ((ClassWithInternalProperty)obj).MyString); } [Fact] @@ -123,7 +123,7 @@ public static void Ignore_ignored_base_public_property_on_conflict_with_derived_ Assert.Equal(@"{}", json); - // Deserialzie + // Deserialize json = @"{""MyString"":""NewValue""}"; obj = JsonSerializer.Deserialize(json); @@ -140,7 +140,7 @@ public static void Ignore_public_property_on_conflict_with_private_due_to_attrib Assert.Equal(@"{}", json); - // Deserialzie + // Deserialize json = @"{""MyString"":""NewValue""}"; obj = JsonSerializer.Deserialize(json); @@ -159,7 +159,7 @@ public static void Ignore_public_property_on_conflict_with_private_due_to_policy Assert.Equal(@"{}", json); - // Deserialzie + // Deserialize json = @"{""myString"":""NewValue""}"; obj = JsonSerializer.Deserialize(json, options); @@ -167,12 +167,12 @@ public static void Ignore_public_property_on_conflict_with_private_due_to_policy Assert.Equal("ConflictingValue", obj.myString); } - public class ClassWithPrivateProperty + public class ClassWithInternalProperty { internal string MyString { get; set; } = "DefaultValue"; } - public class ClassWithNewSlotProperty : ClassWithPrivateProperty + public class ClassWithNewSlotProperty : ClassWithInternalProperty { public new string MyString { get; set; } = "NewDefaultValue"; } @@ -182,7 +182,7 @@ public class ClassWithPublicProperty public string MyString { get; set; } = "DefaultValue"; } - public class ClassWithNewSlotPrivateProperty : ClassWithPublicProperty + public class ClassWithNewSlotInternalProperty : ClassWithPublicProperty { internal new string MyString { get; set; } = "NewDefaultValue"; } @@ -202,7 +202,7 @@ public class ClassWithPropertyPolicyConflict internal string myString { get; set; } = "ConflictingValue"; } - public class ClassWithIgnoredNewSlotProperty : ClassWithPrivateProperty + public class ClassWithIgnoredNewSlotProperty : ClassWithInternalProperty { [JsonIgnore] public new string MyString { get; set; } = "NewDefaultValue"; From c3d7228d560f02c99e6da530373348ca692a9845 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Sun, 23 Feb 2020 12:49:49 +0300 Subject: [PATCH 005/420] Added requested tests --- .../Serialization/PropertyVisibilityTests.cs | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index 9da764065384a..8447723dffe29 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -167,6 +167,90 @@ public static void Ignore_public_property_on_conflict_with_private_due_to_policy Assert.Equal("ConflictingValue", obj.myString); } + [Fact] + public static void Throw_when_public_properties_conflict_due_to_attributes() + { + // Serialize + var obj = new ClassWithPropertyNamingConflictWhichThrows(); + Assert.Throws( + () => JsonSerializer.Serialize(obj)); + + // Deserialize + string json = @"{""MyString"":""NewValue""}"; + Assert.Throws( + () => JsonSerializer.Deserialize(json)); + } + + [Fact] + public static void Throw_when_public_properties_conflict_due_to_attributes_and_inheritance() + { + // Serialize + var obj = new ClassInheritedWithPropertyNamingConflictWhichThrows(); + Assert.Throws( + () => JsonSerializer.Serialize(obj)); + + // Deserialize + string json = @"{""MyString"":""NewValue""}"; + Assert.Throws( + () => JsonSerializer.Deserialize(json)); + } + + [Fact] + public static void Throw_when_public_properties_conflict_due_to_attributes_and_double_inheritance() + { + // Serialize + var obj = new ClassTwiceInheritedWithPropertyNamingConflictWhichThrows(); + Assert.Throws( + () => JsonSerializer.Serialize(obj)); + + // Deserialize + string json = @"{""MyString"":""NewValue""}"; + Assert.Throws( + () => JsonSerializer.Deserialize(json)); + } + + [Fact] + public static void Throw_when_public_properties_conflict_due_to_policy() + { + // Serialize + var obj = new ClassWithPropertyPolicyConflictWhichThrows(); + Assert.Throws( + () => JsonSerializer.Serialize(obj)); + + // Deserialize + string json = @"{""MyString"":""NewValue""}"; + Assert.Throws( + () => JsonSerializer.Deserialize(json)); + } + + [Fact] + public static void Throw_when_public_properties_conflict_due_to_policy_and_inheritance() + { + // Serialize + var obj = new ClassInheritedWithPropertyPolicyConflictWhichThrows(); + Assert.Throws( + () => JsonSerializer.Serialize(obj)); + + // Deserialize + string json = @"{""MyString"":""NewValue""}"; + Assert.Throws( + () => JsonSerializer.Deserialize(json)); + } + + [Fact] + public static void Throw_when_public_properties_conflict_due_to_policy_and_double_inheritance() + { + // Serialize + var obj = new ClassTwiceInheritedWithPropertyPolicyConflictWhichThrows(); + Assert.Throws( + () => JsonSerializer.Serialize(obj)); + + // Deserialize + string json = @"{""MyString"":""NewValue""}"; + Assert.Throws( + () => JsonSerializer.Deserialize(json)); + } + public class ClassWithInternalProperty { internal string MyString { get; set; } = "DefaultValue"; @@ -195,6 +279,31 @@ public class ClassWithPropertyNamingConflict internal string ConflictingString { get; set; } = "ConflictingValue"; } + public class ClassWithPropertyNamingConflictWhichThrows + { + public string MyString { get; set; } = "DefaultValue"; + + [JsonPropertyName(nameof(MyString))] + public string ConflictingString { get; set; } = "ConflictingValue"; + } + + public class ClassInheritedWithPropertyNamingConflictWhichThrows : ClassWithPublicProperty + { + [JsonPropertyName(nameof(MyString))] + public string ConflictingString { get; set; } = "ConflictingValue"; + } + + public class ClassTwiceInheritedWithPropertyNamingConflictWhichThrowsDummy : ClassWithPublicProperty + { + + } + + public class ClassTwiceInheritedWithPropertyNamingConflictWhichThrows : ClassTwiceInheritedWithPropertyNamingConflictWhichThrowsDummy + { + [JsonPropertyName(nameof(MyString))] + public string ConflictingString { get; set; } = "ConflictingValue"; + } + public class ClassWithPropertyPolicyConflict { public string MyString { get; set; } = "DefaultValue"; @@ -202,6 +311,27 @@ public class ClassWithPropertyPolicyConflict internal string myString { get; set; } = "ConflictingValue"; } + public class ClassWithPropertyPolicyConflictWhichThrows + { + public string MyString { get; set; } = "DefaultValue"; + + public string myString { get; set; } = "ConflictingValue"; + } + + public class ClassInheritedWithPropertyPolicyConflictWhichThrows : ClassWithPublicProperty + { + public string myString { get; set; } = "ConflictingValue"; + } + + public class ClassInheritedWithPropertyPolicyConflictWhichThrowsDummy : ClassWithPublicProperty + { + } + + public class ClassTwiceInheritedWithPropertyPolicyConflictWhichThrows : ClassInheritedWithPropertyPolicyConflictWhichThrowsDummy + { + public string myString { get; set; } = "ConflictingValue"; + } + public class ClassWithIgnoredNewSlotProperty : ClassWithInternalProperty { [JsonIgnore] From 8f9653b7dc9bba05a46e8a9e7a42a5ca44831801 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Sun, 23 Feb 2020 16:21:14 +0300 Subject: [PATCH 006/420] Fixed tests --- .../Serialization/PropertyVisibilityTests.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index 8447723dffe29..23a37890bb2dd 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -212,43 +212,49 @@ public static void Throw_when_public_properties_conflict_due_to_attributes_and_d [Fact] public static void Throw_when_public_properties_conflict_due_to_policy() { + var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + // Serialize var obj = new ClassWithPropertyPolicyConflictWhichThrows(); Assert.Throws( - () => JsonSerializer.Serialize(obj)); + () => JsonSerializer.Serialize(obj, options)); // Deserialize string json = @"{""MyString"":""NewValue""}"; Assert.Throws( - () => JsonSerializer.Deserialize(json)); + () => JsonSerializer.Deserialize(json, options)); } [Fact] public static void Throw_when_public_properties_conflict_due_to_policy_and_inheritance() { + var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + // Serialize var obj = new ClassInheritedWithPropertyPolicyConflictWhichThrows(); Assert.Throws( - () => JsonSerializer.Serialize(obj)); + () => JsonSerializer.Serialize(obj, options)); // Deserialize string json = @"{""MyString"":""NewValue""}"; Assert.Throws( - () => JsonSerializer.Deserialize(json)); + () => JsonSerializer.Deserialize(json, options)); } [Fact] public static void Throw_when_public_properties_conflict_due_to_policy_and_double_inheritance() { + var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + // Serialize var obj = new ClassTwiceInheritedWithPropertyPolicyConflictWhichThrows(); Assert.Throws( - () => JsonSerializer.Serialize(obj)); + () => JsonSerializer.Serialize(obj, options)); // Deserialize string json = @"{""MyString"":""NewValue""}"; Assert.Throws( - () => JsonSerializer.Deserialize(json)); + () => JsonSerializer.Deserialize(json, options)); } public class ClassWithInternalProperty From 335c9d0b04fe0e9c8fea88cee1afa5a5cd1fd0e4 Mon Sep 17 00:00:00 2001 From: YohDeadfall Date: Tue, 7 Apr 2020 18:37:29 +0300 Subject: [PATCH 007/420] Fixed handling of public hidden prop by new slot --- .../Text/Json/Serialization/JsonClassInfo.cs | 7 ++--- .../Serialization/PropertyVisibilityTests.cs | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs index 1c34862229f60..8b83519949a0f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs @@ -127,7 +127,7 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) if (propertyInfo.GetMethod?.IsPublic == true || propertyInfo.SetMethod?.IsPublic == true) { - JsonPropertyInfo jsonPropertyInfo = AddProperty(propertyInfo.PropertyType, propertyInfo, type, options); + JsonPropertyInfo jsonPropertyInfo = AddProperty(propertyInfo.PropertyType, propertyInfo, currentType, options); Debug.Assert(jsonPropertyInfo != null && jsonPropertyInfo.NameAsString != null); // If the JsonPropertyNameAttribute or naming policy results in collisions, throw an exception. @@ -140,11 +140,12 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) // Overwrite the one just added since it has [JsonIgnore]. cache[jsonPropertyInfo.NameAsString] = jsonPropertyInfo; } - else if (jsonPropertyInfo.ShouldDeserialize == true || jsonPropertyInfo.ShouldSerialize == true) + else if (other.PropertyInfo?.Name != jsonPropertyInfo.PropertyInfo?.Name && + (jsonPropertyInfo.ShouldDeserialize == true || jsonPropertyInfo.ShouldSerialize == true)) { ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameConflict(Type, jsonPropertyInfo); } - // else ignore jsonPropertyInfo since it has [JsonIgnore]. + // else ignore jsonPropertyInfo since it has [JsonIgnore] or it's hidden by a new slot. } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index 23a37890bb2dd..2e08b329b3476 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -81,6 +81,22 @@ public static void Serialize_public_property_on_conflict_with_private_due_to_pol Assert.Equal("ConflictingValue", obj.myString); } + [Fact] + public static void Serealize_new_slot_public_property_without_conflict_with_base_public_property() + { + // Serialize + var obj = new ClassWithNewSlotDecimalProperty(); + string json = JsonSerializer.Serialize(obj); + + Assert.Equal(@"{""MyNumeric"":1.5}", json); + + // Deserialize + json = @"{""MyNumeric"":2.5}"; + obj = JsonSerializer.Deserialize(json); + + Assert.Equal(2.5M, obj.MyNumeric); + } + [Fact] public static void Ignore_non_public_property() { @@ -372,6 +388,16 @@ public class ClassWithIgnoredPropertyPolicyConflict internal string myString { get; set; } = "ConflictingValue"; } + public class ClassWithHiddenByNewSlotIntProperty + { + public int MyNumeric { get; set; } = 1; + } + + public class ClassWithNewSlotDecimalProperty : ClassWithHiddenByNewSlotIntProperty + { + public new decimal MyNumeric { get; set; } = 1.5M; + } + [Fact] public static void NoSetter() { From efd6ab9d031967b8f1b23b25c563c9d8c992778f Mon Sep 17 00:00:00 2001 From: YohDeadfall Date: Mon, 13 Apr 2020 14:54:16 +0300 Subject: [PATCH 008/420] Canged test naming style --- .../Serialization/PropertyVisibilityTests.cs | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index 2e08b329b3476..aceff1f3869d2 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -12,7 +12,7 @@ namespace System.Text.Json.Serialization.Tests public static partial class PropertyVisibilityTests { [Fact] - public static void SerializeNewSlotPublicProperty() + public static void Serialize_NewSlotPublicProperty() { // Serialize var obj = new ClassWithNewSlotProperty(); @@ -29,7 +29,7 @@ public static void SerializeNewSlotPublicProperty() } [Fact] - public static void Serialize_base_public_property_on_conflict_with_derived_private() + public static void Serialize_BasePublicProperty_ConflictWithDerivedPrivate() { // Serialize var obj = new ClassWithNewSlotInternalProperty(); @@ -46,7 +46,7 @@ public static void Serialize_base_public_property_on_conflict_with_derived_priva } [Fact] - public static void Serialize_public_property_on_conflict_with_private_due_to_attributes() + public static void Serialize_PublicProperty_ConflictWithPrivateDueAttributes() { // Serialize var obj = new ClassWithPropertyNamingConflict(); @@ -63,7 +63,7 @@ public static void Serialize_public_property_on_conflict_with_private_due_to_att } [Fact] - public static void Serialize_public_property_on_conflict_with_private_due_to_policy() + public static void Serialize_PublicProperty_ConflictWithPrivateDuePolicy() { var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; @@ -82,7 +82,7 @@ public static void Serialize_public_property_on_conflict_with_private_due_to_pol } [Fact] - public static void Serealize_new_slot_public_property_without_conflict_with_base_public_property() + public static void Serealize_NewSlotPublicProperty_ConflictWithBasePublicProperty() { // Serialize var obj = new ClassWithNewSlotDecimalProperty(); @@ -98,7 +98,7 @@ public static void Serealize_new_slot_public_property_without_conflict_with_base } [Fact] - public static void Ignore_non_public_property() + public static void Ignore_NonPublicProperty() { // Serialize var obj = new ClassWithInternalProperty(); @@ -114,7 +114,7 @@ public static void Ignore_non_public_property() } [Fact] - public static void Ignore_ignored_new_slot_public_property() + public static void Ignore_NewSlotPublicPropertyIgnored() { // Serialize var obj = new ClassWithIgnoredNewSlotProperty(); @@ -131,7 +131,7 @@ public static void Ignore_ignored_new_slot_public_property() } [Fact] - public static void Ignore_ignored_base_public_property_on_conflict_with_derived_private() + public static void Ignore_BasePublicPropertyIgnored_ConflictWithDerivedPrivate() { // Serialize var obj = new ClassWithIgnoredPublicPropertyAndNewSlotPrivate(); @@ -148,7 +148,7 @@ public static void Ignore_ignored_base_public_property_on_conflict_with_derived_ } [Fact] - public static void Ignore_public_property_on_conflict_with_private_due_to_attributes() + public static void Ignore_PublicProperty_ConflictWithPrivateDueAttributes() { // Serialize var obj = new ClassWithIgnoredPropertyNamingConflict(); @@ -165,7 +165,7 @@ public static void Ignore_public_property_on_conflict_with_private_due_to_attrib } [Fact] - public static void Ignore_public_property_on_conflict_with_private_due_to_policy() + public static void Ignore_PublicProperty_ConflictWithPrivateDuePolicy() { var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; @@ -184,7 +184,7 @@ public static void Ignore_public_property_on_conflict_with_private_due_to_policy } [Fact] - public static void Throw_when_public_properties_conflict_due_to_attributes() + public static void Throw_PublicProperty_ConflictDueAttributes() { // Serialize var obj = new ClassWithPropertyNamingConflictWhichThrows(); @@ -198,7 +198,7 @@ public static void Throw_when_public_properties_conflict_due_to_attributes() } [Fact] - public static void Throw_when_public_properties_conflict_due_to_attributes_and_inheritance() + public static void Throw_PublicProperty_ConflictDueAttributes_SingleInheritance() { // Serialize var obj = new ClassInheritedWithPropertyNamingConflictWhichThrows(); @@ -212,7 +212,7 @@ public static void Throw_when_public_properties_conflict_due_to_attributes_and_i } [Fact] - public static void Throw_when_public_properties_conflict_due_to_attributes_and_double_inheritance() + public static void Throw_PublicProperty_ConflictDueAttributes_DoubleInheritance() { // Serialize var obj = new ClassTwiceInheritedWithPropertyNamingConflictWhichThrows(); @@ -226,7 +226,7 @@ public static void Throw_when_public_properties_conflict_due_to_attributes_and_d } [Fact] - public static void Throw_when_public_properties_conflict_due_to_policy() + public static void Throw_PublicProperty_ConflictDuePolicy() { var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; @@ -242,7 +242,7 @@ public static void Throw_when_public_properties_conflict_due_to_policy() } [Fact] - public static void Throw_when_public_properties_conflict_due_to_policy_and_inheritance() + public static void Throw_PublicProperty_ConflictDuePolicy_SingleInheritance() { var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; @@ -258,7 +258,7 @@ public static void Throw_when_public_properties_conflict_due_to_policy_and_inher } [Fact] - public static void Throw_when_public_properties_conflict_due_to_policy_and_double_inheritance() + public static void Throw_PublicProperty_ConflictDuePolicy_DobuleInheritance() { var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; @@ -317,7 +317,6 @@ public class ClassInheritedWithPropertyNamingConflictWhichThrows : ClassWithPubl public class ClassTwiceInheritedWithPropertyNamingConflictWhichThrowsDummy : ClassWithPublicProperty { - } public class ClassTwiceInheritedWithPropertyNamingConflictWhichThrows : ClassTwiceInheritedWithPropertyNamingConflictWhichThrowsDummy From 9e42d7ce77545d55c7a55344ff38d26f10e4d0fc Mon Sep 17 00:00:00 2001 From: YohDeadfall Date: Mon, 13 Apr 2020 15:02:38 +0300 Subject: [PATCH 009/420] Covered by new slot hidden member serialization --- .../Serialization/PropertyVisibilityTests.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index aceff1f3869d2..f9cf6c2a9e8f8 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -97,6 +97,23 @@ public static void Serealize_NewSlotPublicProperty_ConflictWithBasePublicPropert Assert.Equal(2.5M, obj.MyNumeric); } + [Fact] + public static void Serealize_NewSlotPublicProperty_SpecifiedJsonPropertyName() + { + // Serialize + var obj = new ClassWithNewSlotAttributedDecimalProperty(); + string json = JsonSerializer.Serialize(obj); + + Assert.Equal(@"{""MyNumeric"":1,""MyNewNumeric"":1.5}", json); + + // Deserialize + json = @"{""MyNumeric"":4,""MyNewNumeric"":2.5}"; + obj = JsonSerializer.Deserialize(json); + + Assert.Equal(4, ((ClassWithHiddenByNewSlotIntProperty)obj).MyNumeric); + Assert.Equal(2.5M, ((ClassWithNewSlotAttributedDecimalProperty)obj).MyNumeric); + } + [Fact] public static void Ignore_NonPublicProperty() { @@ -397,6 +414,12 @@ public class ClassWithNewSlotDecimalProperty : ClassWithHiddenByNewSlotIntProper public new decimal MyNumeric { get; set; } = 1.5M; } + public class ClassWithNewSlotAttributedDecimalProperty : ClassWithHiddenByNewSlotIntProperty + { + [JsonPropertyName("MyNewNumeric")] + public new decimal MyNumeric { get; set; } = 1.5M; + } + [Fact] public static void NoSetter() { From cd56b451ddb8cab9896f6c84aa54ee8ba88c0d9f Mon Sep 17 00:00:00 2001 From: YohDeadfall Date: Mon, 13 Apr 2020 20:47:37 +0300 Subject: [PATCH 010/420] Fixed failing test --- .../tests/Serialization/PropertyVisibilityTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index f9cf6c2a9e8f8..a2ff19daabb4f 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -104,10 +104,10 @@ public static void Serealize_NewSlotPublicProperty_SpecifiedJsonPropertyName() var obj = new ClassWithNewSlotAttributedDecimalProperty(); string json = JsonSerializer.Serialize(obj); - Assert.Equal(@"{""MyNumeric"":1,""MyNewNumeric"":1.5}", json); + Assert.Equal(@"{""MyNewNumeric"":1.5,""MyNumeric"":1}", json); // Deserialize - json = @"{""MyNumeric"":4,""MyNewNumeric"":2.5}"; + json = @"{""MyNewNumeric"":2.5,""MyNumeric"":4}"; obj = JsonSerializer.Deserialize(json); Assert.Equal(4, ((ClassWithHiddenByNewSlotIntProperty)obj).MyNumeric); From 87b0c43ea73435cca0f9038ac27abc6ea426e4d7 Mon Sep 17 00:00:00 2001 From: YohDeadfall Date: Tue, 14 Apr 2020 23:22:31 +0300 Subject: [PATCH 011/420] Added comment and improved test --- .../src/System/Text/Json/Serialization/JsonClassInfo.cs | 2 ++ .../tests/Serialization/PropertyVisibilityTests.cs | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs index 8b83519949a0f..cd6ff5fc45ce5 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs @@ -143,6 +143,8 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) else if (other.PropertyInfo?.Name != jsonPropertyInfo.PropertyInfo?.Name && (jsonPropertyInfo.ShouldDeserialize == true || jsonPropertyInfo.ShouldSerialize == true)) { + // Check for name equality is required to determine when a new slot is used for the member. + // Therefore, if names are not the same, there is conflict due to the name policy or attributes. ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameConflict(Type, jsonPropertyInfo); } // else ignore jsonPropertyInfo since it has [JsonIgnore] or it's hidden by a new slot. diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index a2ff19daabb4f..c0b8d07fa1eb6 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -104,7 +104,8 @@ public static void Serealize_NewSlotPublicProperty_SpecifiedJsonPropertyName() var obj = new ClassWithNewSlotAttributedDecimalProperty(); string json = JsonSerializer.Serialize(obj); - Assert.Equal(@"{""MyNewNumeric"":1.5,""MyNumeric"":1}", json); + Assert.Contains(@"""MyNewNumeric"":1.5", json); + Assert.Contains(@"""MyNumeric"":1", json); // Deserialize json = @"{""MyNewNumeric"":2.5,""MyNumeric"":4}"; From 33cd6d6e2487c411b18da307180969d23bc4cf80 Mon Sep 17 00:00:00 2001 From: YohDeadfall Date: Mon, 20 Apr 2020 18:09:15 +0300 Subject: [PATCH 012/420] Fixed rebase issues --- .../src/System/Text/Json/Serialization/JsonClassInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs index cd6ff5fc45ce5..1b87ef779a9c9 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs @@ -116,7 +116,7 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) { if (JsonPropertyInfo.GetAttribute(propertyInfo) != null) { - ThrowHelper.ThrowInvalidOperationException_JsonIncludeOnNonPublicInvalid(propertyInfo, Type); + ThrowHelper.ThrowInvalidOperationException_JsonIncludeOnNonPublicInvalid(propertyInfo, currentType); } // Non-public properties should not be included for (de)serialization. @@ -127,7 +127,7 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) if (propertyInfo.GetMethod?.IsPublic == true || propertyInfo.SetMethod?.IsPublic == true) { - JsonPropertyInfo jsonPropertyInfo = AddProperty(propertyInfo.PropertyType, propertyInfo, currentType, options); + JsonPropertyInfo jsonPropertyInfo = AddProperty(propertyInfo, currentType, options); Debug.Assert(jsonPropertyInfo != null && jsonPropertyInfo.NameAsString != null); // If the JsonPropertyNameAttribute or naming policy results in collisions, throw an exception. From 07fd692b36221a75e4007a8149fce0caf4880e8d Mon Sep 17 00:00:00 2001 From: YohDeadfall Date: Mon, 20 Apr 2020 18:17:11 +0300 Subject: [PATCH 013/420] Added more tests --- .../Serialization/PropertyVisibilityTests.cs | 69 ++++++++++++++++--- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index c0b8d07fa1eb6..3ed7b2ed905d2 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -169,14 +169,14 @@ public static void Ignore_BasePublicPropertyIgnored_ConflictWithDerivedPrivate() public static void Ignore_PublicProperty_ConflictWithPrivateDueAttributes() { // Serialize - var obj = new ClassWithIgnoredPropertyNamingConflict(); + var obj = new ClassWithIgnoredPropertyNamingConflictPrivate(); string json = JsonSerializer.Serialize(obj); Assert.Equal(@"{}", json); // Deserialize json = @"{""MyString"":""NewValue""}"; - obj = JsonSerializer.Deserialize(json); + obj = JsonSerializer.Deserialize(json); Assert.Equal("DefaultValue", obj.MyString); Assert.Equal("ConflictingValue", obj.ConflictingString); @@ -188,14 +188,50 @@ public static void Ignore_PublicProperty_ConflictWithPrivateDuePolicy() var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; // Serialize - var obj = new ClassWithIgnoredPropertyPolicyConflict(); + var obj = new ClassWithIgnoredPropertyPolicyConflictPrivate(); string json = JsonSerializer.Serialize(obj, options); Assert.Equal(@"{}", json); // Deserialize json = @"{""myString"":""NewValue""}"; - obj = JsonSerializer.Deserialize(json, options); + obj = JsonSerializer.Deserialize(json, options); + + Assert.Equal("DefaultValue", obj.MyString); + Assert.Equal("ConflictingValue", obj.myString); + } + + [Fact] + public static void Ignore_PublicProperty_ConflictWithPublicDueAttributes() + { + // Serialize + var obj = new ClassWithIgnoredPropertyNamingConflictPublic(); + string json = JsonSerializer.Serialize(obj); + + Assert.Equal(@"{}", json); + + // Deserialize + json = @"{""MyString"":""NewValue""}"; + obj = JsonSerializer.Deserialize(json); + + Assert.Equal("DefaultValue", obj.MyString); + Assert.Equal("ConflictingValue", obj.ConflictingString); + } + + [Fact] + public static void Ignore_PublicProperty_ConflictWithPublicDuePolicy() + { + var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + + // Serialize + var obj = new ClassWithIgnoredPropertyPolicyConflictPublic(); + string json = JsonSerializer.Serialize(obj, options); + + Assert.Equal(@"{}", json); + + // Deserialize + json = @"{""myString"":""NewValue""}"; + obj = JsonSerializer.Deserialize(json, options); Assert.Equal("DefaultValue", obj.MyString); Assert.Equal("ConflictingValue", obj.myString); @@ -206,8 +242,8 @@ public static void Throw_PublicProperty_ConflictDueAttributes() { // Serialize var obj = new ClassWithPropertyNamingConflictWhichThrows(); - Assert.Throws( - () => JsonSerializer.Serialize(obj)); + var ex = Assert.Throws(() => JsonSerializer.Serialize(obj)); + Assert.Contains($"{typeof(ClassWithPublicProperty)}.{nameof(ClassWithPublicProperty.MyString)}", ex.Message); // Deserialize string json = @"{""MyString"":""NewValue""}"; @@ -388,7 +424,7 @@ public class ClassWithIgnoredPublicPropertyAndNewSlotPrivate : ClassWithIgnoredP internal new string MyString { get; set; } = "NewDefaultValue"; } - public class ClassWithIgnoredPropertyNamingConflict + public class ClassWithIgnoredPropertyNamingConflictPrivate { [JsonIgnore] public string MyString { get; set; } = "DefaultValue"; @@ -397,7 +433,7 @@ public class ClassWithIgnoredPropertyNamingConflict internal string ConflictingString { get; set; } = "ConflictingValue"; } - public class ClassWithIgnoredPropertyPolicyConflict + public class ClassWithIgnoredPropertyPolicyConflictPrivate { [JsonIgnore] public string MyString { get; set; } = "DefaultValue"; @@ -405,6 +441,23 @@ public class ClassWithIgnoredPropertyPolicyConflict internal string myString { get; set; } = "ConflictingValue"; } + public class ClassWithIgnoredPropertyNamingConflictPublic + { + [JsonIgnore] + public string MyString { get; set; } = "DefaultValue"; + + [JsonPropertyName(nameof(MyString))] + public string ConflictingString { get; set; } = "ConflictingValue"; + } + + public class ClassWithIgnoredPropertyPolicyConflictPublic + { + [JsonIgnore] + public string MyString { get; set; } = "DefaultValue"; + + public string myString { get; set; } = "ConflictingValue"; + } + public class ClassWithHiddenByNewSlotIntProperty { public int MyNumeric { get; set; } = 1; From 304fb568068338c918f2f8aabfe04149f2c891f9 Mon Sep 17 00:00:00 2001 From: YohDeadfall Date: Tue, 21 Apr 2020 12:19:41 +0300 Subject: [PATCH 014/420] Fixed tests --- .../tests/Serialization/PropertyVisibilityTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index 3ed7b2ed905d2..4e05d8ae9a6b7 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -242,8 +242,8 @@ public static void Throw_PublicProperty_ConflictDueAttributes() { // Serialize var obj = new ClassWithPropertyNamingConflictWhichThrows(); - var ex = Assert.Throws(() => JsonSerializer.Serialize(obj)); - Assert.Contains($"{typeof(ClassWithPublicProperty)}.{nameof(ClassWithPublicProperty.MyString)}", ex.Message); + Assert.Throws( + () => JsonSerializer.Serialize(obj)); // Deserialize string json = @"{""MyString"":""NewValue""}"; From dc20062d7424c0a69959db78c2a5695dbdeeee1c Mon Sep 17 00:00:00 2001 From: YohDeadfall Date: Wed, 29 Apr 2020 13:49:41 +0300 Subject: [PATCH 015/420] Fixed tests --- .../tests/Serialization/PropertyVisibilityTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index 4e05d8ae9a6b7..2cc311764cb8e 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -208,14 +208,14 @@ public static void Ignore_PublicProperty_ConflictWithPublicDueAttributes() var obj = new ClassWithIgnoredPropertyNamingConflictPublic(); string json = JsonSerializer.Serialize(obj); - Assert.Equal(@"{}", json); + Assert.Equal(@"{""MyString"":""ConflictingValue""}", json); // Deserialize json = @"{""MyString"":""NewValue""}"; obj = JsonSerializer.Deserialize(json); Assert.Equal("DefaultValue", obj.MyString); - Assert.Equal("ConflictingValue", obj.ConflictingString); + Assert.Equal("NewValue", obj.ConflictingString); } [Fact] @@ -227,14 +227,14 @@ public static void Ignore_PublicProperty_ConflictWithPublicDuePolicy() var obj = new ClassWithIgnoredPropertyPolicyConflictPublic(); string json = JsonSerializer.Serialize(obj, options); - Assert.Equal(@"{}", json); + Assert.Equal(@"{""myString"":""ConflictingValue""}", json); // Deserialize json = @"{""myString"":""NewValue""}"; obj = JsonSerializer.Deserialize(json, options); Assert.Equal("DefaultValue", obj.MyString); - Assert.Equal("ConflictingValue", obj.myString); + Assert.Equal("NewValue", obj.myString); } [Fact] From 833a7afab9c7d187a099574227b9189bd0a98cf9 Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Thu, 30 Apr 2020 17:06:58 -0700 Subject: [PATCH 016/420] Nullable: System.Xml, part 2 --- .../src/System/Xml/Core/IRemovableWriter.cs | 1 + .../Xml/Core/IValidationEventHandling.cs | 1 + .../Xml/Core/IncrementalReadDecoders.cs | 7 +- .../Xml/Core/LocalAppContextSwitches.cs | 1 + .../src/System/Xml/Core/NamespaceHandling.cs | 1 + .../src/System/Xml/Core/QueryOutputWriter.cs | 33 +- .../System/Xml/Core/QueryOutputWriterV1.cs | 36 +- .../src/System/Xml/Core/XmlRawWriter.cs | 21 +- .../src/System/Xml/Core/XmlRawWriterAsync.cs | 7 +- .../src/System/Xml/Core/XmlReaderSettings.cs | 1 + .../src/System/Xml/Core/XmlTextEncoder.cs | 17 +- .../System/Xml/Core/XmlTextReaderImpl.Unix.cs | 5 +- .../src/System/Xml/Core/XmlTextReaderImpl.cs | 5 +- .../src/System/Xml/Core/XmlTextWriter.cs | 114 +++- .../src/System/Xml/Core/XmlWriter.cs | 9 +- .../System/Xml/Core/XsdValidatingReader.cs | 612 ++++++++++++------ .../Xml/Core/XsdValidatingReaderAsync.cs | 186 ++++-- .../src/System/Xml/Schema/AutoValidator.cs | 3 +- .../src/System/Xml/Schema/BaseValidator.cs | 59 +- .../Inference/XmlSchemaInferenceException.cs | 7 +- .../src/System/Xml/Schema/XmlSchemaType.cs | 49 +- .../src/System/Xml/Schema/XmlSchemaUse.cs | 1 + .../System/Xml/Schema/XmlSchemaValidator.cs | 5 +- .../System/Xml/Schema/XmlSchemaValidity.cs | 1 + .../src/System/Xml/Schema/XmlSeverityType.cs | 1 + .../src/System/Xml/Schema/XmlTokenizedType.cs | 1 + .../src/System/Xml/Schema/XmlTypeCode.cs | 1 + .../src/System/Xml/Schema/XsdDuration.cs | 25 +- 28 files changed, 794 insertions(+), 416 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IRemovableWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IRemovableWriter.cs index affd635ff1e77..00666a5d34482 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IRemovableWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IRemovableWriter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml { /// diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IValidationEventHandling.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IValidationEventHandling.cs index 528cad5a3f02b..2b8f5d247b6e1 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IValidationEventHandling.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IValidationEventHandling.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Xml.Schema; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/IncrementalReadDecoders.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/IncrementalReadDecoders.cs index 912736c508147..4cf58e2b3a930 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/IncrementalReadDecoders.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/IncrementalReadDecoders.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Xml @@ -38,7 +39,7 @@ internal class IncrementalReadDummyDecoder : IncrementalReadDecoder // internal class IncrementalReadCharsDecoder : IncrementalReadDecoder { - private char[] _buffer; + private char[]? _buffer; private int _startIndex; private int _curIndex; private int _endIndex; @@ -61,6 +62,7 @@ internal override bool IsFull internal override int Decode(char[] chars, int startPos, int len) { + Debug.Assert(_buffer != null); Debug.Assert(chars != null); Debug.Assert(len >= 0); Debug.Assert(startPos >= 0); @@ -73,6 +75,7 @@ internal override int Decode(char[] chars, int startPos, int len) { copyCount = len; } + Buffer.BlockCopy(chars, startPos * 2, _buffer, _curIndex * 2, copyCount * 2); _curIndex += copyCount; @@ -81,6 +84,7 @@ internal override int Decode(char[] chars, int startPos, int len) internal override int Decode(string str, int startPos, int len) { + Debug.Assert(_buffer != null); Debug.Assert(str != null); Debug.Assert(len >= 0); Debug.Assert(startPos >= 0); @@ -93,6 +97,7 @@ internal override int Decode(string str, int startPos, int len) { copyCount = len; } + str.CopyTo(startPos, _buffer, _curIndex, copyCount); _curIndex += copyCount; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs index a36958ec93901..f17a495025efb 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; namespace System diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/NamespaceHandling.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/NamespaceHandling.cs index 9fdb5af95a18b..9627334206f0a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/NamespaceHandling.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/NamespaceHandling.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml { // diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs index ea8030fe3f539..cf7b19cd88a44 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml { using System; @@ -24,9 +25,9 @@ internal class QueryOutputWriter : XmlRawWriter { private readonly XmlRawWriter _wrapped; private bool _inCDataSection; - private readonly Dictionary _lookupCDataElems; - private readonly BitStack _bitsCData; - private readonly XmlQualifiedName _qnameCData; + private readonly Dictionary? _lookupCDataElems; + private readonly BitStack? _bitsCData; + private readonly XmlQualifiedName? _qnameCData; private bool _outputDocType; private readonly bool _checkWellFormedDoc; private bool _hasDocElem; @@ -86,7 +87,7 @@ public QueryOutputWriter(XmlRawWriter writer, XmlWriterSettings settings) /// /// Get and set the namespace resolver that's used by this RawWriter to resolve prefixes. /// - internal override IXmlNamespaceResolver NamespaceResolver + internal override IXmlNamespaceResolver? NamespaceResolver { get { @@ -119,7 +120,7 @@ public override XmlWriterSettings Settings { get { - XmlWriterSettings settings = _wrapped.Settings; + XmlWriterSettings settings = _wrapped.Settings!; settings.ReadOnly = false; settings.DocTypeSystem = _systemId; @@ -133,7 +134,7 @@ public override XmlWriterSettings Settings /// /// Suppress this explicit call to WriteDocType if information was provided by XmlWriterSettings. /// - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { if (_publicId == null && _systemId == null) { @@ -146,7 +147,7 @@ public override void WriteDocType(string name, string pubid, string sysid, strin /// Check well-formedness, possibly output doc-type-decl, and determine whether this element is a /// CData section element. /// - public override void WriteStartElement(string prefix, string localName, string ns) + public override void WriteStartElement(string? prefix, string localName, string? ns) { EndCDataSection(); @@ -164,7 +165,7 @@ public override void WriteStartElement(string prefix, string localName, string n if (_outputDocType) { _wrapped.WriteDocType( - prefix.Length != 0 ? prefix + ":" + localName : localName, + string.IsNullOrEmpty(prefix) ? localName : prefix + ":" + localName, _publicId, _systemId, null); @@ -177,8 +178,8 @@ public override void WriteStartElement(string prefix, string localName, string n if (_lookupCDataElems != null) { // Determine whether this element is a CData section element - _qnameCData.Init(localName, ns); - _bitsCData.PushBit(_lookupCDataElems.ContainsKey(_qnameCData)); + _qnameCData!.Init(localName, ns); + _bitsCData!.PushBit(_lookupCDataElems.ContainsKey(_qnameCData)); } } @@ -192,7 +193,7 @@ internal override void WriteEndElement(string prefix, string localName, string n _depth--; if (_lookupCDataElems != null) - _bitsCData.PopBit(); + _bitsCData!.PopBit(); } internal override void WriteFullEndElement(string prefix, string localName, string ns) @@ -205,7 +206,7 @@ internal override void WriteFullEndElement(string prefix, string localName, stri _depth--; if (_lookupCDataElems != null) - _bitsCData.PopBit(); + _bitsCData!.PopBit(); } internal override void StartElementContent() @@ -213,7 +214,7 @@ internal override void StartElementContent() _wrapped.StartElementContent(); } - public override void WriteStartAttribute(string prefix, string localName, string ns) + public override void WriteStartAttribute(string? prefix, string localName, string? ns) { _inAttr = true; _wrapped.WriteStartAttribute(prefix, localName, ns); @@ -248,7 +249,7 @@ internal override void WriteEndNamespaceDeclaration() _wrapped.WriteEndNamespaceDeclaration(); } - public override void WriteCData(string text) + public override void WriteCData(string? text) { _wrapped.WriteCData(text); } @@ -273,7 +274,7 @@ public override void WriteWhitespace(string ws) _wrapped.WriteWhitespace(ws); } - public override void WriteString(string text) + public override void WriteString(string? text) { if (!_inAttr && (_inCDataSection || StartCDataSection())) _wrapped.WriteCData(text); @@ -351,7 +352,7 @@ public override void Flush() private bool StartCDataSection() { Debug.Assert(!_inCDataSection); - if (_lookupCDataElems != null && _bitsCData.PeekBit()) + if (_lookupCDataElems != null && _bitsCData!.PeekBit()) { _inCDataSection = true; return true; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriterV1.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriterV1.cs index 462854bc4c554..4f6ea549c7459 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriterV1.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriterV1.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.IO; using System.Diagnostics; @@ -25,9 +26,9 @@ internal class QueryOutputWriterV1 : XmlWriter { private readonly XmlWriter _wrapped; private bool _inCDataSection; - private readonly Dictionary _lookupCDataElems; - private readonly BitStack _bitsCData; - private readonly XmlQualifiedName _qnameCData; + private readonly Dictionary? _lookupCDataElems; + private readonly BitStack? _bitsCData; + private readonly XmlQualifiedName? _qnameCData; private bool _outputDocType, _inAttr; private readonly string _systemId, _publicId; @@ -71,7 +72,7 @@ public QueryOutputWriterV1(XmlWriter writer, XmlWriterSettings settings) if (settings.CDataSectionElements != null && settings.CDataSectionElements.Count > 0) { _bitsCData = new BitStack(); - _lookupCDataElems = new Dictionary(); + _lookupCDataElems = new Dictionary(); _qnameCData = new XmlQualifiedName(); // Add each element name to the lookup table @@ -122,7 +123,7 @@ public override void WriteEndDocument() /// /// Suppress this explicit call to WriteDocType if information was provided by XmlWriterSettings. /// - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { if (_publicId == null && _systemId == null) { @@ -135,7 +136,7 @@ public override void WriteDocType(string name, string pubid, string sysid, strin /// Output doc-type-decl on the first element, and determine whether this element is a /// CData section element. /// - public override void WriteStartElement(string prefix, string localName, string ns) + public override void WriteStartElement(string? prefix, string localName, string? ns) { EndCDataSection(); @@ -146,11 +147,12 @@ public override void WriteStartElement(string prefix, string localName, string n if (ws == WriteState.Start || ws == WriteState.Prolog) { _wrapped.WriteDocType( - prefix.Length != 0 ? prefix + ":" + localName : localName, + string.IsNullOrEmpty(prefix) ? localName : prefix + ":" + localName, _publicId, _systemId, null); } + _outputDocType = false; } @@ -158,6 +160,9 @@ public override void WriteStartElement(string prefix, string localName, string n if (_lookupCDataElems != null) { + Debug.Assert(_qnameCData != null); + Debug.Assert(_bitsCData != null); + // Determine whether this element is a CData section element _qnameCData.Init(localName, ns); _bitsCData.PushBit(_lookupCDataElems.ContainsKey(_qnameCData)); @@ -171,7 +176,10 @@ public override void WriteEndElement() _wrapped.WriteEndElement(); if (_lookupCDataElems != null) + { + Debug.Assert(_bitsCData != null); _bitsCData.PopBit(); + } } public override void WriteFullEndElement() @@ -181,10 +189,13 @@ public override void WriteFullEndElement() _wrapped.WriteFullEndElement(); if (_lookupCDataElems != null) + { + Debug.Assert(_bitsCData != null); _bitsCData.PopBit(); + } } - public override void WriteStartAttribute(string prefix, string localName, string ns) + public override void WriteStartAttribute(string? prefix, string localName, string? ns) { _inAttr = true; _wrapped.WriteStartAttribute(prefix, localName, ns); @@ -196,7 +207,7 @@ public override void WriteEndAttribute() _wrapped.WriteEndAttribute(); } - public override void WriteCData(string text) + public override void WriteCData(string? text) { _wrapped.WriteCData(text); } @@ -221,7 +232,7 @@ public override void WriteWhitespace(string ws) _wrapped.WriteWhitespace(ws); } - public override void WriteString(string text) + public override void WriteString(string? text) { if (!_inAttr && (_inCDataSection || StartCDataSection())) _wrapped.WriteCData(text); @@ -291,7 +302,7 @@ public override void Flush() _wrapped.Flush(); } - public override string LookupPrefix(string ns) + public override string? LookupPrefix(string ns) { return _wrapped.LookupPrefix(ns); } @@ -308,11 +319,12 @@ public override string LookupPrefix(string ns) private bool StartCDataSection() { Debug.Assert(!_inCDataSection); - if (_lookupCDataElems != null && _bitsCData.PeekBit()) + if (_lookupCDataElems != null && _bitsCData!.PeekBit()) { _inCDataSection = true; return true; } + return false; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs index 952c3d2348e99..81f8a09aad9bc 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.IO; using System.Diagnostics; @@ -43,10 +44,10 @@ internal abstract partial class XmlRawWriter : XmlWriter // Fields // // base64 converter - protected XmlRawWriterBase64Encoder base64Encoder; + protected XmlRawWriterBase64Encoder? base64Encoder; // namespace resolver - protected IXmlNamespaceResolver resolver; + protected IXmlNamespaceResolver? resolver; // // XmlWriter implementation @@ -68,7 +69,7 @@ public override void WriteEndDocument() throw new InvalidOperationException(SR.Xml_InvalidOperation); } - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { } @@ -91,6 +92,7 @@ public override void WriteBase64(byte[] buffer, int index, int count) { base64Encoder = new XmlRawWriterBase64Encoder(this); } + // Encode will call WriteRaw to write out the encoded characters base64Encoder.Encode(buffer, index, count); } @@ -135,13 +137,13 @@ public override void WriteName(string name) } // Raw writers do not have to verify QName values. - public override void WriteQualifiedName(string localName, string ns) + public override void WriteQualifiedName(string localName, string? ns) { throw new InvalidOperationException(SR.Xml_InvalidOperation); } // Forward call to WriteString(string). - public override void WriteCData(string text) + public override void WriteCData(string? text) { WriteString(text); } @@ -184,17 +186,18 @@ public override void WriteRaw(string data) } // Override in order to handle Xml simple typed values and to pass resolver for QName values - public override void WriteValue(object value) + public override void WriteValue(object? value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } + WriteString(XmlUntypedConverter.Untyped.ToString(value, resolver)); } // Override in order to handle Xml simple typed values and to pass resolver for QName values - public override void WriteValue(string value) + public override void WriteValue(string? value) { WriteString(value); } @@ -227,7 +230,7 @@ public override void WriteNode(System.Xml.XPath.XPathNavigator navigator, bool d // // Get and set the namespace resolver that's used by this RawWriter to resolve prefixes. - internal virtual IXmlNamespaceResolver NamespaceResolver + internal virtual IXmlNamespaceResolver? NamespaceResolver { get { @@ -275,6 +278,7 @@ internal virtual void WriteQualifiedName(string prefix, string localName, string WriteString(prefix); WriteString(":"); } + WriteString(localName); } @@ -311,6 +315,7 @@ internal virtual void WriteEndNamespaceDeclaration() internal virtual void WriteEndBase64() { // The Flush will call WriteRaw to write out the rest of the encoded characters + Debug.Assert(base64Encoder != null); base64Encoder.Flush(); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs index 77ebbf5034a94..ccfac57273c56 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.IO; using System.Diagnostics; @@ -60,7 +61,7 @@ public override Task WriteEndDocumentAsync() throw new InvalidOperationException(SR.Xml_InvalidOperation); } - public override Task WriteDocTypeAsync(string name, string pubid, string sysid, string subset) + public override Task WriteDocTypeAsync(string name, string? pubid, string? sysid, string subset) { return Task.CompletedTask; } @@ -101,7 +102,7 @@ public override Task WriteNameAsync(string name) } // Raw writers do not have to verify QName values. - public override Task WriteQualifiedNameAsync(string localName, string ns) + public override Task WriteQualifiedNameAsync(string localName, string? ns) { throw new InvalidOperationException(SR.Xml_InvalidOperation); } @@ -200,6 +201,7 @@ internal virtual async Task WriteQualifiedNameAsync(string prefix, string localN await WriteStringAsync(prefix).ConfigureAwait(false); await WriteStringAsync(":").ConfigureAwait(false); } + await WriteStringAsync(localName).ConfigureAwait(false); } @@ -224,6 +226,7 @@ internal virtual Task WriteEndNamespaceDeclarationAsync() internal virtual Task WriteEndBase64Async() { // The Flush will call WriteRaw to write out the rest of the encoded characters + Debug.Assert(base64Encoder != null); return base64Encoder.FlushAsync(); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderSettings.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderSettings.cs index 93eb9bb60d85e..67d70187bd0a8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderSettings.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlReaderSettings.cs @@ -651,6 +651,7 @@ private XmlReader AddValidationInternal(XmlReader reader, XmlResolver? resolver, { reader = new XsdValidatingReader(reader, GetXmlResolver_CheckConfig(), this); } + return reader; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs index 912615c9a1662..2e69660d785a3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextEncoder.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.IO; using System.Text; @@ -29,7 +30,7 @@ internal class XmlTextEncoder private char _quoteChar; // caching of attribute value - private StringBuilder _attrValue; + private StringBuilder? _attrValue; private bool _cacheAttrValue; // XmlCharType @@ -77,8 +78,10 @@ internal void EndAttribute() { if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Length = 0; } + _inAttribute = false; _cacheAttrValue = false; } @@ -89,6 +92,7 @@ internal string AttributeValue { if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); return _attrValue.ToString(); } else @@ -134,6 +138,7 @@ internal void Write(char[] array, int offset, int count) if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append(array, offset, count); } @@ -241,6 +246,7 @@ internal void WriteSurrogateCharEntity(char lowChar, char highChar) if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append(highChar); _attrValue.Append(lowChar); } @@ -259,6 +265,7 @@ internal void Write(string text) if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append(text); } @@ -395,8 +402,10 @@ internal void WriteRawWithSurrogateChecking(string text) { return; } + if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append(text); } @@ -469,8 +478,10 @@ internal void WriteRaw(char[] array, int offset, int count) if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append(array, offset, count); } + _textWriter.Write(array, offset, count); } @@ -486,10 +497,12 @@ internal void WriteCharEntity(char ch) string strVal = ((int)ch).ToString("X", NumberFormatInfo.InvariantInfo); if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append("&#x"); _attrValue.Append(strVal); _attrValue.Append(';'); } + WriteCharEntityImpl(strVal); } @@ -497,10 +510,12 @@ internal void WriteEntityRef(string name) { if (_cacheAttrValue) { + Debug.Assert(_attrValue != null); _attrValue.Append('&'); _attrValue.Append(name); _attrValue.Append(';'); } + WriteEntityRefImpl(name); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.Unix.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.Unix.cs index 96e32fd9d3a1d..bc856150e1304 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.Unix.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.Unix.cs @@ -2,11 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml { internal partial class XmlTextReaderImpl { - static partial void ConvertAbsoluteUnixPathToAbsoluteUri(ref string url, XmlResolver resolver) + static partial void ConvertAbsoluteUnixPathToAbsoluteUri(ref string url, XmlResolver? resolver) { // new Uri(uri, UriKind.RelativeOrAbsolute) returns a Relative Uri for absolute unix paths (e.g. /tmp). // We convert the native unix path to a 'file://' uri string to make it an Absolute Uri. @@ -27,4 +28,4 @@ internal partial class XmlTextReaderImpl } } } -} \ No newline at end of file +} diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs index ae7235e0f64d4..7b181e4b798bb 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs @@ -8410,6 +8410,7 @@ private int IncrementalRead(Array array, int index, int count) private int IncrementalRead() { Debug.Assert(_incReadDecoder != null); + Debug.Assert(_ps.chars != null); int charsDecoded = 0; OuterContinue: @@ -8505,7 +8506,6 @@ private int IncrementalRead() _incReadState == IncrementalReadState.Attributes || _incReadState == IncrementalReadState.AttributeValue); - Debug.Assert(_ps.chars != null); char[] chars = _ps.chars; startPos = _ps.charPos; pos = startPos; @@ -9633,6 +9633,7 @@ private int ReadContentAsBinary(byte[] buffer, int index, int count) if (_incReadState == IncrementalReadState.ReadContentAsBinary_OnPartialValue) { _curNode.SetValue(string.Empty); + Debug.Assert(_ps.chars != null); // read next chunk of text bool endOfValue = false; @@ -9657,12 +9658,12 @@ private int ReadContentAsBinary(byte[] buffer, int index, int count) } startPos += charsRead; } + _incReadState = endOfValue ? IncrementalReadState.ReadContentAsBinary_OnCachedValue : IncrementalReadState.ReadContentAsBinary_OnPartialValue; _readValueOffset = 0; if (_incReadDecoder.IsFull) { - Debug.Assert(_ps.chars != null); _curNode.SetValue(_ps.chars, startPos, endPos - startPos); // adjust line info for the chunk that has been already decoded AdjustLineInfo(_ps.chars, startPos - charsRead, startPos, _ps.eolNormalized, ref _incReadLineInfo); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs index dc9a77df0696b..7f65f254fa31c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextWriter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections; using System.Collections.Generic; @@ -25,7 +26,7 @@ public enum Formatting // and not Mixed Content (http://www.w3.org/TR/1998/REC-xml-19980210#sec-mixed-content) // according to the XML 1.0 definitions of these terms. Indented, - }; + } // Represents a writer that provides fast non-cached forward-only way of generating XML streams // containing XML documents that conform to the W3CExtensible Markup Language (XML) 1.0 specification @@ -47,12 +48,12 @@ private enum NamespaceState private struct TagInfo { - internal string name; - internal string prefix; + internal string? name; + internal string? prefix; internal string defaultNs; internal NamespaceState defaultNsState; internal XmlSpace xmlSpace; - internal string xmlLang; + internal string? xmlLang; internal int prevNsTop; internal int prefixCount; internal bool mixed; // whether to pretty print the contents of this element. @@ -131,9 +132,9 @@ private enum Token // Fields // // output - private readonly TextWriter _textWriter; - private readonly XmlTextEncoder _xmlEncoder; - private readonly Encoding _encoding; + private readonly TextWriter _textWriter = null!; + private readonly XmlTextEncoder _xmlEncoder = null!; + private readonly Encoding? _encoding; // formatting private Formatting _formatting; @@ -159,20 +160,20 @@ private static char[] CreateDefaultIndentChars() private Token _lastToken; // Base64 content - private XmlTextWriterBase64Encoder _base64Encoder; + private XmlTextWriterBase64Encoder? _base64Encoder; // misc private char _quoteChar; private char _curQuoteChar; private bool _namespaces; private SpecialAttr _specialAttr; - private string _prefixForXmlNs; + private string? _prefixForXmlNs; private bool _flush; // namespaces private Namespace[] _nsStack; private int _nsTop; - private Dictionary _nsHashtable; + private Dictionary? _nsHashtable; private bool _useNsHashtable; // char types @@ -259,7 +260,7 @@ private static char[] CreateDefaultIndentChars() // // Constructors // - internal XmlTextWriter() + private XmlTextWriter() { _namespaces = true; _formatting = Formatting.None; @@ -281,7 +282,7 @@ internal XmlTextWriter() } // Creates an instance of the XmlTextWriter class using the specified stream. - public XmlTextWriter(Stream w, Encoding encoding) : this() + public XmlTextWriter(Stream w, Encoding? encoding) : this() { _encoding = encoding; if (encoding != null) @@ -313,12 +314,18 @@ public XmlTextWriter(TextWriter w) : this() // XmlTextWriter properties // // Gets the XmlTextWriter base stream. - public Stream BaseStream + public Stream? BaseStream { get { - StreamWriter streamWriter = _textWriter as StreamWriter; - return (streamWriter == null ? null : streamWriter.BaseStream); + if (_textWriter is StreamWriter streamWriter) + { + return streamWriter.BaseStream; + } + else + { + return null; + } } } @@ -437,7 +444,7 @@ public override void WriteEndDocument() } // Writes out the DOCTYPE declaration with the specified name and optional attributes. - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { try { @@ -476,7 +483,7 @@ public override void WriteDocType(string name, string pubid, string sysid, strin } // Writes out the specified start tag and associates it with the given namespace and prefix. - public override void WriteStartElement(string prefix, string localName, string ns) + public override void WriteStartElement(string? prefix, string localName, string? ns) { try { @@ -503,7 +510,7 @@ public override void WriteStartElement(string prefix, string localName, string n { if (prefix == null) { - string definedPrefix = FindPrefix(ns); + string? definedPrefix = FindPrefix(ns); if (definedPrefix != null) { prefix = definedPrefix; @@ -523,6 +530,7 @@ public override void WriteStartElement(string prefix, string localName, string n { prefix = null; } + VerifyPrefixXml(prefix, ns); PushNamespace(prefix, ns, false); // define } @@ -565,7 +573,7 @@ public override void WriteFullEndElement() } // Writes the start of an attribute. - public override void WriteStartAttribute(string prefix, string localName, string ns) + public override void WriteStartAttribute(string? prefix, string localName, string? ns) { try { @@ -607,6 +615,7 @@ public override void WriteStartAttribute(string prefix, string localName, string { throw new ArgumentException(SR.Xml_XmlnsBelongsToReservedNs); } + if (localName == null || localName.Length == 0) { localName = prefix; @@ -617,6 +626,7 @@ public override void WriteStartAttribute(string prefix, string localName, string { _prefixForXmlNs = localName; } + _specialAttr = SpecialAttr.XmlNs; } else if (prefix == null && localName == "xmlns") @@ -626,6 +636,7 @@ public override void WriteStartAttribute(string prefix, string localName, string // add the below line back in when DOM is fixed throw new ArgumentException(SR.Xml_XmlnsBelongsToReservedNs); } + _specialAttr = SpecialAttr.XmlNs; _prefixForXmlNs = null; } @@ -651,8 +662,9 @@ public override void WriteStartAttribute(string prefix, string localName, string { prefix = null; } + // Now verify prefix validity - string definedPrefix = FindPrefix(ns); + string? definedPrefix = FindPrefix(ns); if (definedPrefix != null && (prefix == null || prefix == definedPrefix)) { prefix = definedPrefix; @@ -667,6 +679,7 @@ public override void WriteStartAttribute(string prefix, string localName, string } } } + if (prefix != null && prefix.Length != 0) { _textWriter.Write(prefix); @@ -679,15 +692,18 @@ public override void WriteStartAttribute(string prefix, string localName, string { throw new ArgumentException(SR.Xml_NoNamespaces); } + if (localName == "xml:lang") { _specialAttr = SpecialAttr.XmlLang; } + else if (localName == "xml:space") { _specialAttr = SpecialAttr.XmlSpace; } } + _xmlEncoder.StartAttribute(_specialAttr != SpecialAttr.None); _textWriter.Write(localName); @@ -721,7 +737,7 @@ public override void WriteEndAttribute() } // Writes out a <![CDATA[...]]> block containing the specified text. - public override void WriteCData(string text) + public override void WriteCData(string? text) { try { @@ -730,12 +746,14 @@ public override void WriteCData(string text) { throw new ArgumentException(SR.Xml_InvalidCDataChars); } + _textWriter.Write(""); } catch @@ -770,7 +788,7 @@ public override void WriteComment(string text) } // Writes out a processing instruction with a space between the name and text as follows: - public override void WriteProcessingInstruction(string name, string text) + public override void WriteProcessingInstruction(string name, string? text) { try { @@ -778,10 +796,12 @@ public override void WriteProcessingInstruction(string name, string text) { throw new ArgumentException(SR.Xml_InvalidPiChars); } + if (0 == string.Compare(name, "xml", StringComparison.OrdinalIgnoreCase) && _stateTable == s_stateTableDocument) { throw new ArgumentException(SR.Xml_DupXmlDecl); } + AutoComplete(Token.PI); InternalWriteProcessingInstruction(name, text); } @@ -848,7 +868,7 @@ public override void WriteWhitespace(string ws) } // Writes out the specified text content. - public override void WriteString(string text) + public override void WriteString(string? text) { try { @@ -1040,7 +1060,7 @@ public override void WriteName(string name) } // Writes out the specified namespace-qualified name by looking up the prefix that is in scope for the given namespace. - public override void WriteQualifiedName(string localName, string ns) + public override void WriteQualifiedName(string localName, string? ns) { try { @@ -1049,16 +1069,18 @@ public override void WriteQualifiedName(string localName, string ns) { if (ns != null && ns.Length != 0 && ns != _stack[_top].defaultNs) { - string prefix = FindPrefix(ns); + string? prefix = FindPrefix(ns); if (prefix == null) { if (_currentState != State.Attribute) { throw new ArgumentException(SR.Format(SR.Xml_UndefNamespace, ns)); } - prefix = GeneratePrefix(); // need a prefix if + + prefix = GeneratePrefix(); PushNamespace(prefix, ns, false); } + if (prefix.Length != 0) { InternalWriteName(prefix, true); @@ -1070,6 +1092,7 @@ public override void WriteQualifiedName(string localName, string ns) { throw new ArgumentException(SR.Xml_NoNamespaces); } + InternalWriteName(localName, true); } catch @@ -1080,17 +1103,19 @@ public override void WriteQualifiedName(string localName, string ns) } // Returns the closest prefix defined in the current namespace scope for the specified namespace URI. - public override string LookupPrefix(string ns) + public override string? LookupPrefix(string ns) { if (ns == null || ns.Length == 0) { throw new ArgumentException(SR.Xml_EmptyName); } - string s = FindPrefix(ns); + + string? s = FindPrefix(ns); if (s == null && ns == _stack[_top].defaultNs) { s = string.Empty; } + return s; } @@ -1110,16 +1135,18 @@ public override XmlSpace XmlSpace } // Gets the current xml:lang scope. - public override string XmlLang + public override string? XmlLang { get { for (int i = _top; i > 0; i--) { - string xlang = _stack[i].xmlLang; + string? xlang = _stack[i].xmlLang; + if (xlang != null) return xlang; } + return null; } } @@ -1444,7 +1471,7 @@ private void Indent(bool beforeEndElement) // pushes new namespace scope, and returns generated prefix, if one // was needed to resolve conflicts. - private void PushNamespace(string prefix, string ns, bool declared) + private void PushNamespace(string? prefix, string ns, bool declared) { if (XmlReservedNs.NsXmlNs == ns) { @@ -1469,6 +1496,7 @@ private void PushNamespace(string prefix, string ns, bool declared) Debug.Fail("Should have never come here"); return; } + _stack[_top].defaultNsState = (declared ? NamespaceState.DeclaredAndWrittenOut : NamespaceState.DeclaredButNotWrittenOut); } else @@ -1497,6 +1525,7 @@ private void PushNamespace(string prefix, string ns, bool declared) _nsStack[existingNsIndex].declared = true; // old one is silenced now } } + AddNamespace(prefix, ns, declared); } } @@ -1521,28 +1550,36 @@ private void AddNamespace(string prefix, string ns, bool declared) { // add all _nsHashtable = new Dictionary(); + _useNsHashtable = true; + for (int i = 0; i <= nsIndex; i++) { AddToNamespaceHashtable(i); } - _useNsHashtable = true; } } private void AddToNamespaceHashtable(int namespaceIndex) { + Debug.Assert(_useNsHashtable); + Debug.Assert(_nsHashtable != null); + string prefix = _nsStack[namespaceIndex].prefix; int existingNsIndex; + if (_nsHashtable.TryGetValue(prefix, out existingNsIndex)) { _nsStack[namespaceIndex].prevNsIndex = existingNsIndex; } + _nsHashtable[prefix] = namespaceIndex; } private void PopNamespaces(int indexFrom, int indexTo) { Debug.Assert(_useNsHashtable); + Debug.Assert(_nsHashtable != null); + for (int i = indexTo; i >= indexFrom; i--) { Debug.Assert(_nsHashtable.ContainsKey(_nsStack[i].prefix)); @@ -1564,16 +1601,18 @@ private string GeneratePrefix() + "p" + temp.ToString("d", CultureInfo.InvariantCulture); } - private void InternalWriteProcessingInstruction(string name, string text) + private void InternalWriteProcessingInstruction(string name, string? text) { _textWriter.Write(""); } @@ -1581,6 +1620,7 @@ private int LookupNamespace(string prefix) { if (_useNsHashtable) { + Debug.Assert(_nsHashtable != null); int nsIndex; if (_nsHashtable.TryGetValue(prefix, out nsIndex)) { @@ -1597,6 +1637,7 @@ private int LookupNamespace(string prefix) } } } + return -1; } @@ -1604,7 +1645,9 @@ private int LookupNamespaceInCurrentScope(string prefix) { if (_useNsHashtable) { + Debug.Assert(_nsHashtable != null); int nsIndex; + if (_nsHashtable.TryGetValue(prefix, out nsIndex)) { if (nsIndex > _stack[_top].prevNsTop) @@ -1626,7 +1669,7 @@ private int LookupNamespaceInCurrentScope(string prefix) return -1; } - private string FindPrefix(string ns) + private string? FindPrefix(string ns) { for (int i = _nsTop; i >= 0; i--) { @@ -1638,6 +1681,7 @@ private string FindPrefix(string ns) } } } + return null; } @@ -1745,7 +1789,7 @@ private void HandleSpecialAttribute() } - private void VerifyPrefixXml(string prefix, string ns) + private void VerifyPrefixXml(string? prefix, string ns) { if (prefix != null && prefix.Length == 3) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs index d412522dd279c..07960b08492d8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWriter.cs @@ -74,7 +74,7 @@ public abstract partial class XmlWriter : IDisposable // Writes out the DOCTYPE declaration with the specified name and optional attributes. - public abstract void WriteDocType(string name, string? pubid, string? sysid, string subset); + public abstract void WriteDocType(string name, string? pubid, string? sysid, string? subset); // Writes out the specified start tag and associates it with the given namespace. public void WriteStartElement(string localName, string? ns) @@ -146,7 +146,7 @@ public void WriteStartAttribute(string localName) // Writes out a ; block containing the specified text. - public abstract void WriteCData(string text); + public abstract void WriteCData(string? text); // Writes out a comment ; containing the specified text. @@ -170,7 +170,7 @@ public void WriteStartAttribute(string localName) // Writes out the specified text content. - public abstract void WriteString(string text); + public abstract void WriteString(string? text); // Write out the given surrogate pair as an entity reference. @@ -221,7 +221,7 @@ public virtual XmlSpace XmlSpace } // Gets the current xml:lang scope. - public virtual string XmlLang + public virtual string? XmlLang { get { @@ -282,6 +282,7 @@ public virtual void WriteValue(string? value) { return; } + WriteString(value); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs index 7a6b5928b545f..2115a780f0dd9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.IO; using System.Text; using System.Xml.Schema; @@ -11,6 +12,7 @@ using System.Collections; using System.Collections.Generic; using System.Runtime.Versioning; +using System.Diagnostics.CodeAnalysis; namespace System.Xml { @@ -18,9 +20,9 @@ namespace System.Xml internal class AttributePSVIInfo { - internal string localName; - internal string namespaceUri; - internal object typedAttributeValue; + internal string? localName; + internal string? namespaceUri; + internal object? typedAttributeValue; internal XmlSchemaInfo attributeSchemaInfo; internal AttributePSVIInfo() @@ -55,51 +57,52 @@ private enum ValidatingReaderState EOF = 9, Error = 10, } - //Validation + + // Validation private XmlReader _coreReader; - private readonly IXmlNamespaceResolver _coreReaderNSResolver; + private readonly IXmlNamespaceResolver? _coreReaderNSResolver; private readonly IXmlNamespaceResolver _thisNSResolver; - private XmlSchemaValidator _validator; - private readonly XmlResolver _xmlResolver; - private readonly ValidationEventHandler _validationEvent; + private XmlSchemaValidator _validator = null!; + private readonly XmlResolver? _xmlResolver; + private readonly ValidationEventHandler? _validationEvent; private ValidatingReaderState _validationState; private XmlValueGetter _valueGetter; // namespace management - private readonly XmlNamespaceManager _nsManager; + private readonly XmlNamespaceManager? _nsManager; private readonly bool _manageNamespaces; private readonly bool _processInlineSchema; private bool _replayCache; - //Current Node handling - private ValidatingReaderNodeData _cachedNode; //Used to cache current node when looking ahead or default attributes - private AttributePSVIInfo _attributePSVI; + // Current Node handling + private ValidatingReaderNodeData? _cachedNode; // Used to cache current node when looking ahead or default attributes + private AttributePSVIInfo? _attributePSVI; - //Attributes - private int _attributeCount; //Total count of attributes including default + // Attributes + private int _attributeCount; // Total count of attributes including default private int _coreReaderAttributeCount; private int _currentAttrIndex; private AttributePSVIInfo[] _attributePSVINodes; private ArrayList _defaultAttributes; - //Inline Schema - private Parser _inlineSchemaParser = null; + // Inline Schema + private Parser? _inlineSchemaParser = null; - //Typed Value & PSVI - private object _atomicValue; + // Typed Value & PSVI + private object? _atomicValue; private XmlSchemaInfo _xmlSchemaInfo; // original string of the atomic value - private string _originalAtomicValueString; + private string? _originalAtomicValueString; - //cached coreReader information + // cached coreReader information private readonly XmlNameTable _coreReaderNameTable; - private XsdCachingReader _cachingReader; + private XsdCachingReader? _cachingReader; - //ReadAttributeValue TextNode - private ValidatingReaderNodeData _textNode; + // ReadAttributeValue TextNode + private ValidatingReaderNodeData? _textNode; - //To avoid SchemaNames creation + // To avoid SchemaNames creation private string _nsXmlNs; private string _nsXs; private string _nsXsi; @@ -109,20 +112,20 @@ private enum ValidatingReaderState private string _xsiSchemaLocation; private string _xsiNoNamespaceSchemaLocation; - //Underlying reader's IXmlLineInfo - private IXmlLineInfo _lineInfo; + // Underlying reader's IXmlLineInfo + private IXmlLineInfo? _lineInfo; // helpers for Read[Element]ContentAs{Base64,BinHex} methods - private ReadContentAsBinaryHelper _readBinaryHelper; + private ReadContentAsBinaryHelper? _readBinaryHelper; private ValidatingReaderState _savedState; - //Constants + // Constants private const int InitialAttributeCount = 8; - private static volatile Type s_typeOfString; + private static volatile Type s_typeOfString = null!; - //Constructor - internal XsdValidatingReader(XmlReader reader, XmlResolver xmlResolver, XmlReaderSettings readerSettings, XmlSchemaObject partialValidationType) + // Constructor + internal XsdValidatingReader(XmlReader reader, XmlResolver? xmlResolver, XmlReaderSettings readerSettings, XmlSchemaObject? partialValidationType) { _coreReader = reader; _coreReaderNSResolver = reader as IXmlNamespaceResolver; @@ -133,21 +136,11 @@ internal XsdValidatingReader(XmlReader reader, XmlResolver xmlResolver, XmlReade _nsManager = new XmlNamespaceManager(_coreReaderNameTable); _manageNamespaces = true; } + _thisNSResolver = this as IXmlNamespaceResolver; _xmlResolver = xmlResolver; _processInlineSchema = (readerSettings.ValidationFlags & XmlSchemaValidationFlags.ProcessInlineSchema) != 0; - Init(); - SetupValidator(readerSettings, reader, partialValidationType); - _validationEvent = readerSettings.GetEventHandler(); - } - - internal XsdValidatingReader(XmlReader reader, XmlResolver xmlResolver, XmlReaderSettings readerSettings) - : - this(reader, xmlResolver, readerSettings, null) - { } - private void Init() - { _validationState = ValidatingReaderState.Init; _defaultAttributes = new ArrayList(); _currentAttrIndex = -1; @@ -156,7 +149,7 @@ private void Init() s_typeOfString = typeof(string); _xmlSchemaInfo = new XmlSchemaInfo(); - //Add common strings to be compared to NameTable + // Add common strings to be compared to NameTable _nsXmlNs = _coreReaderNameTable.Add(XmlReservedNs.NsXmlNs); _nsXs = _coreReaderNameTable.Add(XmlReservedNs.NsXs); _nsXsi = _coreReaderNameTable.Add(XmlReservedNs.NsXsi); @@ -165,20 +158,30 @@ private void Init() _xsiSchemaLocation = _coreReaderNameTable.Add("schemaLocation"); _xsiNoNamespaceSchemaLocation = _coreReaderNameTable.Add("noNamespaceSchemaLocation"); _xsdSchema = _coreReaderNameTable.Add("schema"); + + SetupValidator(readerSettings, reader, partialValidationType); + _validationEvent = readerSettings.GetEventHandler(); } - private void SetupValidator(XmlReaderSettings readerSettings, XmlReader reader, XmlSchemaObject partialValidationType) + internal XsdValidatingReader(XmlReader reader, XmlResolver? xmlResolver, XmlReaderSettings readerSettings) + : this(reader, xmlResolver, readerSettings, null) + { } + + [MemberNotNull("_validator")] + private void SetupValidator(XmlReaderSettings readerSettings, XmlReader reader, XmlSchemaObject? partialValidationType) { _validator = new XmlSchemaValidator(_coreReaderNameTable, readerSettings.Schemas, _thisNSResolver, readerSettings.ValidationFlags); _validator.XmlResolver = _xmlResolver; - _validator.SourceUri = XmlConvert.ToUri(reader.BaseURI); //Not using XmlResolver.ResolveUri as it checks for relative Uris,reader.BaseURI will be absolute file paths or string.Empty + _validator.SourceUri = XmlConvert.ToUri(reader.BaseURI); // Not using XmlResolver.ResolveUri as it checks for relative Uris,reader.BaseURI will be absolute file paths or string.Empty _validator.ValidationEventSender = this; _validator.ValidationEventHandler += readerSettings.GetEventHandler(); _validator.LineInfoProvider = _lineInfo; + if (_validator.ProcessSchemaHints) { _validator.SchemaSet.ReaderSettings.DtdProcessing = readerSettings.DtdProcessing; } + _validator.SetDtdSchemaInfo(reader.DtdInfo); if (partialValidationType != null) { @@ -195,13 +198,9 @@ public override XmlReaderSettings Settings { get { - XmlReaderSettings settings = _coreReader.Settings; - if (null != settings) - settings = settings.Clone(); - if (settings == null) - { - settings = new XmlReaderSettings(); - } + XmlReaderSettings? settings = _coreReader.Settings; + settings = settings != null ? settings.Clone() : new XmlReaderSettings(); + settings.Schemas = _validator.SchemaSet; settings.ValidationType = ValidationType.Schema; settings.ValidationFlags = _validator.ValidationFlags; @@ -219,16 +218,18 @@ public override XmlNodeType NodeType { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return _cachedNode.NodeType; } else { XmlNodeType nodeType = _coreReader.NodeType; - //Check for significant whitespace + // Check for significant whitespace if (nodeType == XmlNodeType.Whitespace && (_validator.CurrentContentType == XmlSchemaContentType.TextOnly || _validator.CurrentContentType == XmlSchemaContentType.Mixed)) { return XmlNodeType.SignificantWhitespace; } + return nodeType; } } @@ -241,13 +242,16 @@ public override string Name { if (_validationState == ValidatingReaderState.OnDefaultAttribute) { + Debug.Assert(_cachedNode != null); string prefix = _validator.GetDefaultAttributePrefix(_cachedNode.Namespace); if (prefix != null && prefix.Length != 0) { return prefix + ":" + _cachedNode.LocalName; } + return _cachedNode.LocalName; } + return _coreReader.Name; } } @@ -259,8 +263,10 @@ public override string LocalName { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return _cachedNode.LocalName; } + return _coreReader.LocalName; } } @@ -272,8 +278,10 @@ public override string NamespaceURI { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return _cachedNode.Namespace; } + return _coreReader.NamespaceURI; } } @@ -285,8 +293,10 @@ public override string Prefix { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return _cachedNode.Prefix; } + return _coreReader.Prefix; } } @@ -300,6 +310,7 @@ public override bool HasValue { return true; } + return _coreReader.HasValue; } } @@ -311,8 +322,10 @@ public override string Value { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return _cachedNode.RawValue; } + return _coreReader.Value; } } @@ -324,14 +337,16 @@ public override int Depth { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return _cachedNode.Depth; } + return _coreReader.Depth; } } // Gets the base URI of the current node. - public override string BaseURI + public override string? BaseURI { get { @@ -355,10 +370,12 @@ public override bool IsDefault get { if (_validationState == ValidatingReaderState.OnDefaultAttribute) - { //XSD default attributes + { + // XSD default attributes return true; } - return _coreReader.IsDefault; //This is DTD Default attribute + + return _coreReader.IsDefault; // This is DTD Default attribute } } @@ -407,15 +424,19 @@ public override System.Type ValueType case XmlNodeType.EndElement: if (_xmlSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) { + Debug.Assert(_xmlSchemaInfo.SchemaType.Datatype != null); return _xmlSchemaInfo.SchemaType.Datatype.ValueType; } + goto default; case XmlNodeType.Attribute: if (_attributePSVI != null && AttributeSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) { + Debug.Assert(AttributeSchemaInfo.SchemaType.Datatype != null); return AttributeSchemaInfo.SchemaType.Datatype.ValueType; } + goto default; default: @@ -440,8 +461,9 @@ public override bool ReadContentAsBoolean() { throw CreateReadContentAsException(nameof(ReadContentAsBoolean)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -473,8 +495,9 @@ public override DateTime ReadContentAsDateTime() { throw CreateReadContentAsException(nameof(ReadContentAsDateTime)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -506,8 +529,9 @@ public override double ReadContentAsDouble() { throw CreateReadContentAsException(nameof(ReadContentAsDouble)); } - object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + + object? typedValue = InternalReadContentAsObject(); + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -539,8 +563,9 @@ public override float ReadContentAsFloat() { throw CreateReadContentAsException(nameof(ReadContentAsFloat)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -572,8 +597,9 @@ public override decimal ReadContentAsDecimal() { throw CreateReadContentAsException(nameof(ReadContentAsDecimal)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -605,8 +631,9 @@ public override int ReadContentAsInt() { throw CreateReadContentAsException(nameof(ReadContentAsInt)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -638,8 +665,10 @@ public override long ReadContentAsLong() { throw CreateReadContentAsException(nameof(ReadContentAsLong)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + try { if (xmlType != null) @@ -671,8 +700,10 @@ public override string ReadContentAsString() { throw CreateReadContentAsException(nameof(ReadContentAsString)); } + object typedValue = InternalReadContentAsObject(); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + try { if (xmlType != null) @@ -681,7 +712,7 @@ public override string ReadContentAsString() } else { - return typedValue as string; + return (typedValue as string)!; } } catch (InvalidCastException e) @@ -704,11 +735,10 @@ public override object ReadContentAs(Type returnType, IXmlNamespaceResolver name { throw CreateReadContentAsException(nameof(ReadContentAs)); } - string originalStringValue; + string originalStringValue; object typedValue = InternalReadContentAsObject(false, out originalStringValue); - - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -717,8 +747,9 @@ public override object ReadContentAs(Type returnType, IXmlNamespaceResolver name // which cannot preserve time zone, so we need to convert from the original string if (returnType == typeof(DateTimeOffset) && xmlType.Datatype is Datatype_dateTimeBase) { - typedValue = originalStringValue; + typedValue = originalStringValue!; } + return xmlType.ValueConverter.ChangeType(typedValue, returnType); } else @@ -746,9 +777,9 @@ public override object ReadElementContentAsObject() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsObject)); } - XmlSchemaType xmlType; - return InternalReadElementContentAsObject(out xmlType, true); + XmlSchemaType? xmlType; + return InternalReadElementContentAsObject(out xmlType, true)!; } public override bool ReadElementContentAsBoolean() @@ -757,9 +788,9 @@ public override bool ReadElementContentAsBoolean() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsBoolean)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -792,9 +823,9 @@ public override DateTime ReadElementContentAsDateTime() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsDateTime)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -827,9 +858,9 @@ public override double ReadElementContentAsDouble() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsDouble)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -862,9 +893,9 @@ public override float ReadElementContentAsFloat() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsFloat)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -897,9 +928,9 @@ public override decimal ReadElementContentAsDecimal() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsDecimal)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -932,9 +963,9 @@ public override int ReadElementContentAsInt() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsInt)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -967,9 +998,9 @@ public override long ReadElementContentAsLong() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsLong)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -1002,9 +1033,9 @@ public override string ReadElementContentAsString() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsString)); } - XmlSchemaType xmlType; - object typedValue = InternalReadElementContentAsObject(out xmlType); + XmlSchemaType? xmlType; + object? typedValue = InternalReadElementContentAsObject(out xmlType); try { @@ -1037,10 +1068,10 @@ public override object ReadElementContentAs(Type returnType, IXmlNamespaceResolv { throw CreateReadElementContentAsException(nameof(ReadElementContentAs)); } - XmlSchemaType xmlType; - string originalStringValue; - object typedValue = InternalReadElementContentAsObject(out xmlType, false, out originalStringValue); + XmlSchemaType? xmlType; + string? originalStringValue; + object? typedValue = InternalReadElementContentAsObject(out xmlType, false, out originalStringValue); try { @@ -1052,6 +1083,7 @@ public override object ReadElementContentAs(Type returnType, IXmlNamespaceResolv { typedValue = originalStringValue; } + return xmlType.ValueConverter.ChangeType(typedValue, returnType, namespaceResolver); } else @@ -1085,50 +1117,59 @@ public override int AttributeCount } // Gets the value of the attribute with the specified Name. - public override string GetAttribute(string name) + public override string? GetAttribute(string name) { - string attValue = _coreReader.GetAttribute(name); + string? attValue = _coreReader.GetAttribute(name); if (attValue == null && _attributeCount > 0) - { //Could be default attribute - ValidatingReaderNodeData defaultNode = GetDefaultAttribute(name, false); + { + // Could be default attribute + ValidatingReaderNodeData? defaultNode = GetDefaultAttribute(name, false); if (defaultNode != null) - { //Default found + { + // Default found attValue = defaultNode.RawValue; } } + return attValue; } // Gets the value of the attribute with the specified LocalName and NamespaceURI. - public override string GetAttribute(string name, string namespaceURI) + public override string? GetAttribute(string name, string namespaceURI) { - string attValue = _coreReader.GetAttribute(name, namespaceURI); + string? attValue = _coreReader.GetAttribute(name, namespaceURI); if (attValue == null && _attributeCount > 0) - { //Could be default attribute - namespaceURI = (namespaceURI == null) ? string.Empty : _coreReaderNameTable.Get(namespaceURI); - name = _coreReaderNameTable.Get(name); - if (name == null || namespaceURI == null) - { //Attribute not present since we did not see it + { + // Could be default attribute + string? atomizedNamespaceURI = (namespaceURI == null) ? string.Empty : _coreReaderNameTable.Get(namespaceURI); + string? atomizedName = _coreReaderNameTable.Get(name); + + if (atomizedName == null || atomizedNamespaceURI == null) + { + // Attribute not present since we did not see it return null; } - ValidatingReaderNodeData attNode = GetDefaultAttribute(name, namespaceURI, false); + + ValidatingReaderNodeData? attNode = GetDefaultAttribute(atomizedName, atomizedNamespaceURI, false); if (attNode != null) { return attNode.RawValue; } } + return attValue; } // Gets the value of the attribute with the specified index. public override string GetAttribute(int i) { - if (_attributeCount == 0) + if (i < 0 || i >= _attributeCount) { - return null; + throw new ArgumentOutOfRangeException(nameof(i)); } + if (i < _coreReaderAttributeCount) { return _coreReader.GetAttribute(i); @@ -1136,7 +1177,7 @@ public override string GetAttribute(int i) else { int defaultIndex = i - _coreReaderAttributeCount; - ValidatingReaderNodeData attNode = (ValidatingReaderNodeData)_defaultAttributes[defaultIndex]; + ValidatingReaderNodeData attNode = (ValidatingReaderNodeData)_defaultAttributes[defaultIndex]!; Debug.Assert(attNode != null); return attNode.RawValue; } @@ -1152,8 +1193,9 @@ public override bool MoveToAttribute(string name) goto Found; } else if (_attributeCount > 0) - { //Default attribute - ValidatingReaderNodeData defaultNode = GetDefaultAttribute(name, true); + { + // Default attribute + ValidatingReaderNodeData? defaultNode = GetDefaultAttribute(name, true); if (defaultNode != null) { _validationState = ValidatingReaderState.OnDefaultAttribute; @@ -1162,43 +1204,52 @@ public override bool MoveToAttribute(string name) goto Found; } } + return false; Found: if (_validationState == ValidatingReaderState.OnReadBinaryContent) { + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); _validationState = _savedState; } + return true; } // Moves to the attribute with the specified LocalName and NamespaceURI - public override bool MoveToAttribute(string name, string ns) + public override bool MoveToAttribute(string name, string? ns) { - //Check atomized local name and ns - name = _coreReaderNameTable.Get(name); + // Check atomized local name and ns + string? atomizedName = _coreReaderNameTable.Get(name); ns = ns != null ? _coreReaderNameTable.Get(ns) : string.Empty; - if (name == null || ns == null) - { //Name or ns not found in the nameTable, then attribute is not found + + if (atomizedName == null || ns == null) + { + // Name or ns not found in the nameTable, then attribute is not found return false; } - if (_coreReader.MoveToAttribute(name, ns)) + + if (_coreReader.MoveToAttribute(atomizedName, ns)) { _validationState = ValidatingReaderState.OnAttribute; if (_inlineSchemaParser == null) { - _attributePSVI = GetAttributePSVI(name, ns); + _attributePSVI = GetAttributePSVI(atomizedName, ns); Debug.Assert(_attributePSVI != null); } else - { //Parsing inline schema, no PSVI for schema attributes + { + // Parsing inline schema, no PSVI for schema attributes _attributePSVI = null; } + goto Found; } else - { //Default attribute - ValidatingReaderNodeData defaultNode = GetDefaultAttribute(name, ns, true); + { + // Default attribute + ValidatingReaderNodeData? defaultNode = GetDefaultAttribute(atomizedName, ns, true); if (defaultNode != null) { _attributePSVI = defaultNode.AttInfo; @@ -1207,13 +1258,17 @@ public override bool MoveToAttribute(string name, string ns) goto Found; } } + return false; + Found: if (_validationState == ValidatingReaderState.OnReadBinaryContent) { + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); _validationState = _savedState; } + return true; } @@ -1224,9 +1279,11 @@ public override void MoveToAttribute(int i) { throw new ArgumentOutOfRangeException(nameof(i)); } + _currentAttrIndex = i; if (i < _coreReaderAttributeCount) - { //reader attribute + { + // reader attribute _coreReader.MoveToAttribute(i); if (_inlineSchemaParser == null) { @@ -1236,17 +1293,21 @@ public override void MoveToAttribute(int i) { _attributePSVI = null; } + _validationState = ValidatingReaderState.OnAttribute; } else - { //default attribute + { + // default attribute int defaultIndex = i - _coreReaderAttributeCount; - _cachedNode = (ValidatingReaderNodeData)_defaultAttributes[defaultIndex]; + _cachedNode = (ValidatingReaderNodeData)_defaultAttributes[defaultIndex]!; _attributePSVI = _cachedNode.AttInfo; _validationState = ValidatingReaderState.OnDefaultAttribute; } + if (_validationState == ValidatingReaderState.OnReadBinaryContent) { + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); _validationState = _savedState; } @@ -1266,24 +1327,29 @@ public override bool MoveToFirstAttribute() { _attributePSVI = null; } + _validationState = ValidatingReaderState.OnAttribute; goto Found; } else if (_defaultAttributes.Count > 0) - { //check for default - _cachedNode = (ValidatingReaderNodeData)_defaultAttributes[0]; + { + // check for default + _cachedNode = (ValidatingReaderNodeData)_defaultAttributes[0]!; _attributePSVI = _cachedNode.AttInfo; _currentAttrIndex = 0; _validationState = ValidatingReaderState.OnDefaultAttribute; goto Found; } + return false; Found: if (_validationState == ValidatingReaderState.OnReadBinaryContent) { + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); _validationState = _savedState; } + return true; } @@ -1303,24 +1369,29 @@ public override bool MoveToNextAttribute() { _attributePSVI = null; } + _validationState = ValidatingReaderState.OnAttribute; goto Found; } else if (_currentAttrIndex + 1 < _attributeCount) - { //default attribute + { + // default attribute int defaultIndex = ++_currentAttrIndex - _coreReaderAttributeCount; - _cachedNode = (ValidatingReaderNodeData)_defaultAttributes[defaultIndex]; + _cachedNode = (ValidatingReaderNodeData)_defaultAttributes[defaultIndex]!; _attributePSVI = _cachedNode.AttInfo; _validationState = ValidatingReaderState.OnDefaultAttribute; goto Found; } + return false; Found: if (_validationState == ValidatingReaderState.OnReadBinaryContent) { + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); _validationState = _savedState; } + return true; } @@ -1328,11 +1399,13 @@ public override bool MoveToNextAttribute() public override bool MoveToElement() { if (_coreReader.MoveToElement() || (int)_validationState < 0) - { //states OnDefaultAttribute or OnReadAttributeValue + { + // states OnDefaultAttribute or OnReadAttributeValue _currentAttrIndex = -1; _validationState = ValidatingReaderState.ClearAttributes; return true; } + return false; } @@ -1354,6 +1427,7 @@ public override bool Read() { _validationState = ValidatingReaderState.EOF; } + return false; } @@ -1377,7 +1451,7 @@ public override bool Read() goto case ValidatingReaderState.Read; } - case ValidatingReaderState.ReadAhead: //Will enter here on calling Skip() + case ValidatingReaderState.ReadAhead: // Will enter here on calling Skip() ClearAttributesInfo(); ProcessReaderEvent(); _validationState = ValidatingReaderState.Read; @@ -1385,13 +1459,15 @@ public override bool Read() case ValidatingReaderState.OnReadBinaryContent: _validationState = _savedState; + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); return Read(); case ValidatingReaderState.Init: _validationState = ValidatingReaderState.Read; if (_coreReader.ReadState == ReadState.Interactive) - { //If the underlying reader is already positioned on a ndoe, process it + { + // If the underlying reader is already positioned on a ndoe, process it ProcessReaderEvent(); return true; } @@ -1445,26 +1521,29 @@ public override void Skip() { break; } + bool callSkipToEndElem = true; - //If union and unionValue has been parsed till EndElement, then validator.ValidateEndElement has been called - //Hence should not call SkipToEndElement as the current context has already been popped in the validator + // If union and unionValue has been parsed till EndElement, then validator.ValidateEndElement has been called + // Hence should not call SkipToEndElement as the current context has already been popped in the validator if ((_xmlSchemaInfo.IsUnionType || _xmlSchemaInfo.IsDefault) && _coreReader is XsdCachingReader) { callSkipToEndElem = false; } + _coreReader.Skip(); _validationState = ValidatingReaderState.ReadAhead; if (callSkipToEndElem) { _validator.SkipToEndElement(_xmlSchemaInfo); } + break; case XmlNodeType.Attribute: MoveToElement(); goto case XmlNodeType.Element; } - //For all other NodeTypes Skip() same as Read() + // For all other NodeTypes Skip() same as Read() Read(); return; } @@ -1479,7 +1558,7 @@ public override XmlNameTable NameTable } // Resolves a namespace prefix in the current element's scope. - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { return _thisNSResolver.LookupNamespace(prefix); } @@ -1495,19 +1574,24 @@ public override bool ReadAttributeValue() { if (_validationState == ValidatingReaderState.OnReadBinaryContent) { + Debug.Assert(_readBinaryHelper != null); _readBinaryHelper.Finish(); _validationState = _savedState; } + if (NodeType == XmlNodeType.Attribute) { if (_validationState == ValidatingReaderState.OnDefaultAttribute) { + Debug.Assert(_cachedNode != null); _cachedNode = CreateDummyTextNode(_cachedNode.RawValue, _cachedNode.Depth + 1); _validationState = ValidatingReaderState.OnReadAttributeValue; return true; } + return _coreReader.ReadAttributeValue(); } + return false; } @@ -1537,6 +1621,7 @@ public override int ReadContentAsBase64(byte[] buffer, int index, int count) _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = _readBinaryHelper.ReadContentAsBase64(buffer, index, count); // set OnReadBinaryContent state again and return @@ -1563,6 +1648,7 @@ public override int ReadContentAsBinHex(byte[] buffer, int index, int count) _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = _readBinaryHelper.ReadContentAsBinHex(buffer, index, count); // set OnReadBinaryContent state again and return @@ -1589,6 +1675,7 @@ public override int ReadElementContentAsBase64(byte[] buffer, int index, int cou _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = _readBinaryHelper.ReadElementContentAsBase64(buffer, index, count); // set OnReadBinaryContent state again and return @@ -1615,6 +1702,7 @@ public override int ReadElementContentAsBinHex(byte[] buffer, int index, int cou _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = _readBinaryHelper.ReadElementContentAsBinHex(buffer, index, count); // set OnReadBinaryContent state again and return @@ -1637,6 +1725,7 @@ bool IXmlSchemaInfo.IsDefault { GetIsDefault(); } + return _xmlSchemaInfo.IsDefault; case XmlNodeType.EndElement: @@ -1647,11 +1736,13 @@ bool IXmlSchemaInfo.IsDefault { return AttributeSchemaInfo.IsDefault; } + break; default: break; } + return false; } } @@ -1669,6 +1760,7 @@ bool IXmlSchemaInfo.IsNil default: break; } + return false; } } @@ -1684,10 +1776,13 @@ XmlSchemaValidity IXmlSchemaInfo.Validity { return _xmlSchemaInfo.Validity; } + if (_xmlSchemaInfo.Validity == XmlSchemaValidity.Valid) - { //It might be valid for unions since we read ahead, but report notknown for consistency + { + // It might be valid for unions since we read ahead, but report notknown for consistency return XmlSchemaValidity.NotKnown; } + return _xmlSchemaInfo.Validity; case XmlNodeType.EndElement: @@ -1698,13 +1793,15 @@ XmlSchemaValidity IXmlSchemaInfo.Validity { return AttributeSchemaInfo.Validity; } + break; } + return XmlSchemaValidity.NotKnown; } } - XmlSchemaSimpleType IXmlSchemaInfo.MemberType + XmlSchemaSimpleType? IXmlSchemaInfo.MemberType { get { @@ -1715,6 +1812,7 @@ XmlSchemaSimpleType IXmlSchemaInfo.MemberType { GetMemberType(); } + return _xmlSchemaInfo.MemberType; case XmlNodeType.EndElement: @@ -1725,15 +1823,16 @@ XmlSchemaSimpleType IXmlSchemaInfo.MemberType { return AttributeSchemaInfo.MemberType; } + return null; default: - return null; //Text, PI, Comment etc + return null; // Text, PI, Comment etc } } } - XmlSchemaType IXmlSchemaInfo.SchemaType + XmlSchemaType? IXmlSchemaInfo.SchemaType { get { @@ -1748,14 +1847,16 @@ XmlSchemaType IXmlSchemaInfo.SchemaType { return AttributeSchemaInfo.SchemaType; } + return null; default: - return null; //Text, PI, Comment etc + return null; // Text, PI, Comment etc } } } - XmlSchemaElement IXmlSchemaInfo.SchemaElement + + XmlSchemaElement? IXmlSchemaInfo.SchemaElement { get { @@ -1763,11 +1864,12 @@ XmlSchemaElement IXmlSchemaInfo.SchemaElement { return _xmlSchemaInfo.SchemaElement; } + return null; } } - XmlSchemaAttribute IXmlSchemaInfo.SchemaAttribute + XmlSchemaAttribute? IXmlSchemaInfo.SchemaAttribute { get { @@ -1778,6 +1880,7 @@ XmlSchemaAttribute IXmlSchemaInfo.SchemaAttribute return AttributeSchemaInfo.SchemaAttribute; } } + return null; } } @@ -1799,6 +1902,7 @@ public int LineNumber { return _lineInfo.LineNumber; } + return 0; } } @@ -1811,6 +1915,7 @@ public int LinePosition { return _lineInfo.LinePosition; } + return 0; } } @@ -1826,11 +1931,12 @@ public int LinePosition } else { + Debug.Assert(_nsManager != null); return _nsManager.GetNamespacesInScope(scope); } } - string IXmlNamespaceResolver.LookupNamespace(string prefix) + string? IXmlNamespaceResolver.LookupNamespace(string prefix) { if (_coreReaderNSResolver != null) { @@ -1838,11 +1944,12 @@ string IXmlNamespaceResolver.LookupNamespace(string prefix) } else { + Debug.Assert(_nsManager != null); return _nsManager.LookupNamespace(prefix); } } - string IXmlNamespaceResolver.LookupPrefix(string namespaceName) + string? IXmlNamespaceResolver.LookupPrefix(string namespaceName) { if (_coreReaderNSResolver != null) { @@ -1850,11 +1957,12 @@ string IXmlNamespaceResolver.LookupPrefix(string namespaceName) } else { + Debug.Assert(_nsManager != null); return _nsManager.LookupPrefix(namespaceName); } } - //Internal / Private methods + // Internal / Private methods private object GetStringValue() { @@ -1869,7 +1977,7 @@ private XmlSchemaType ElementXmlType } } - private XmlSchemaType AttributeXmlType + private XmlSchemaType? AttributeXmlType { get { @@ -1877,6 +1985,7 @@ private XmlSchemaType AttributeXmlType { return AttributeSchemaInfo.XmlType; } + return null; } } @@ -1893,11 +2002,13 @@ private XmlSchemaInfo AttributeSchemaInfo private void ProcessReaderEvent() { if (_replayCache) - { //if in replay mode, do nothing since nodes have been validated already - //If NodeType == XmlNodeType.EndElement && if manageNamespaces, may need to pop namespace scope, since scope is not popped in ReadAheadForMemberType + { + // if in replay mode, do nothing since nodes have been validated already + // If NodeType == XmlNodeType.EndElement && if manageNamespaces, may need to pop namespace scope, since scope is not popped in ReadAheadForMemberType return; } + switch (_coreReader.NodeType) { case XmlNodeType.Element: @@ -1943,7 +2054,8 @@ private void ProcessElementEvent() _xmlSchemaInfo.Clear(); _attributeCount = _coreReaderAttributeCount = _coreReader.AttributeCount; if (!_coreReader.IsEmptyElement) - { //If its not empty schema, then parse else ignore + { + // If its not empty schema, then parse else ignore _inlineSchemaParser = new Parser(SchemaType.XSD, _coreReaderNameTable, _validator.SchemaSet.GetSchemaNames(_coreReaderNameTable), _validationEvent); _inlineSchemaParser.StartParsing(_coreReader, null); _inlineSchemaParser.ParseReaderNode(); @@ -1955,27 +2067,32 @@ private void ProcessElementEvent() } } else - { //Validate element - //Clear previous data + { + // Validate element + // Clear previous data _atomicValue = null; _originalAtomicValueString = null; _xmlSchemaInfo.Clear(); if (_manageNamespaces) { + Debug.Assert(_nsManager != null); _nsManager.PushScope(); } - //Find Xsi attributes that need to be processed before validating the element - string xsiSchemaLocation = null; - string xsiNoNamespaceSL = null; - string xsiNil = null; - string xsiType = null; + + // Find Xsi attributes that need to be processed before validating the element + string? xsiSchemaLocation = null; + string? xsiNoNamespaceSL = null; + string? xsiNil = null; + string? xsiType = null; + if (_coreReader.MoveToFirstAttribute()) { do { string objectNs = _coreReader.NamespaceURI; string objectName = _coreReader.LocalName; + if (Ref.Equal(objectNs, _nsXsi)) { if (Ref.Equal(objectName, _xsiSchemaLocation)) @@ -1995,13 +2112,16 @@ private void ProcessElementEvent() xsiNil = _coreReader.Value; } } + if (_manageNamespaces && Ref.Equal(_coreReader.NamespaceURI, _nsXmlNs)) { + Debug.Assert(_nsManager != null); _nsManager.AddNamespace(_coreReader.Prefix.Length == 0 ? string.Empty : _coreReader.LocalName, _coreReader.Value); } } while (_coreReader.MoveToNextAttribute()); _coreReader.MoveToElement(); } + _validator.ValidateElement(_coreReader.LocalName, _coreReader.NamespaceURI, _xmlSchemaInfo, xsiType, xsiNil, xsiSchemaLocation, xsiNoNamespaceSL); ValidateAttributes(); _validator.ValidateEndOfAttributes(_xmlSchemaInfo); @@ -2009,6 +2129,7 @@ private void ProcessElementEvent() { ProcessEndElementEvent(); } + _validationState = ValidatingReaderState.ClearAttributes; } } @@ -2018,10 +2139,12 @@ private void ProcessEndElementEvent() _atomicValue = _validator.ValidateEndElement(_xmlSchemaInfo); _originalAtomicValueString = GetOriginalAtomicValueStringOfElement(); if (_xmlSchemaInfo.IsDefault) - { //The atomicValue returned is a default value + { + // The atomicValue returned is a default value Debug.Assert(_atomicValue != null); int depth = _coreReader.Depth; _coreReader = GetCachingReader(); + Debug.Assert(_cachingReader != null); _cachingReader.RecordTextNode(_xmlSchemaInfo.XmlType.ValueConverter.ToString(_atomicValue), _originalAtomicValueString, depth + 1, 0, 0); _cachingReader.RecordEndElementNode(); _cachingReader.SetToReplayMode(); @@ -2029,6 +2152,7 @@ private void ProcessEndElementEvent() } else if (_manageNamespaces) { + Debug.Assert(_nsManager != null); _nsManager.PopScope(); } } @@ -2055,19 +2179,24 @@ private void ValidateAttributes() attIndex++; continue; } + attributePSVI.typedAttributeValue = _validator.ValidateAttribute(localName, ns, _valueGetter, attributePSVI.attributeSchemaInfo); if (!attributeInvalid) { attributeInvalid = attributePSVI.attributeSchemaInfo.Validity == XmlSchemaValidity.Invalid; } + attIndex++; } while (_coreReader.MoveToNextAttribute()); } + _coreReader.MoveToElement(); if (attributeInvalid) - { //If any of the attributes are invalid, Need to report element's validity as invalid + { + // If any of the attributes are invalid, Need to report element's validity as invalid _xmlSchemaInfo.Validity = XmlSchemaValidity.Invalid; } + _validator.GetUnspecifiedDefaultAttributes(_defaultAttributes, true); _attributeCount += _defaultAttributes.Count; } @@ -2081,12 +2210,14 @@ private void ClearAttributesInfo() _attributePSVI = null; } - private AttributePSVIInfo GetAttributePSVI(string name) + private AttributePSVIInfo? GetAttributePSVI(string name) { if (_inlineSchemaParser != null) - { //Parsing inline schema, no PSVI for schema attributes + { + // Parsing inline schema, no PSVI for schema attributes return null; } + string attrLocalName; string attrPrefix; string ns; @@ -2095,27 +2226,30 @@ private AttributePSVIInfo GetAttributePSVI(string name) attrLocalName = _coreReaderNameTable.Add(attrLocalName); if (attrPrefix.Length == 0) - { //empty prefix, not qualified + { + // empty prefix, not qualified ns = string.Empty; } else { - ns = _thisNSResolver.LookupNamespace(attrPrefix); + ns = _thisNSResolver.LookupNamespace(attrPrefix)!; } + return GetAttributePSVI(attrLocalName, ns); } - private AttributePSVIInfo GetAttributePSVI(string localName, string ns) + private AttributePSVIInfo? GetAttributePSVI(string localName, string ns) { Debug.Assert(_coreReaderNameTable.Get(localName) != null); Debug.Assert(_coreReaderNameTable.Get(ns) != null); - AttributePSVIInfo attInfo = null; + AttributePSVIInfo? attInfo = null; for (int i = 0; i < _coreReaderAttributeCount; i++) { attInfo = _attributePSVINodes[i]; if (attInfo != null) - { //Will be null for invalid attributes + { + // Will be null for invalid attributes if (Ref.Equal(localName, attInfo.localName) && Ref.Equal(ns, attInfo.namespaceUri)) { _currentAttrIndex = i; @@ -2123,16 +2257,17 @@ private AttributePSVIInfo GetAttributePSVI(string localName, string ns) } } } + return null; } - private ValidatingReaderNodeData GetDefaultAttribute(string name, bool updatePosition) + private ValidatingReaderNodeData? GetDefaultAttribute(string name, bool updatePosition) { string attrLocalName; string attrPrefix; ValidateNames.SplitQName(name, out attrPrefix, out attrLocalName); - //Atomize + // Atomize attrPrefix = _coreReaderNameTable.Add(attrPrefix); attrLocalName = _coreReaderNameTable.Add(attrLocalName); string ns; @@ -2142,29 +2277,32 @@ private ValidatingReaderNodeData GetDefaultAttribute(string name, bool updatePos } else { - ns = _thisNSResolver.LookupNamespace(attrPrefix); + ns = _thisNSResolver.LookupNamespace(attrPrefix)!; } + return GetDefaultAttribute(attrLocalName, ns, updatePosition); } - private ValidatingReaderNodeData GetDefaultAttribute(string attrLocalName, string ns, bool updatePosition) + private ValidatingReaderNodeData? GetDefaultAttribute(string attrLocalName, string ns, bool updatePosition) { Debug.Assert(_coreReaderNameTable.Get(attrLocalName) != null); Debug.Assert(_coreReaderNameTable.Get(ns) != null); - ValidatingReaderNodeData defaultNode = null; + ValidatingReaderNodeData? defaultNode = null; for (int i = 0; i < _defaultAttributes.Count; i++) { - defaultNode = (ValidatingReaderNodeData)_defaultAttributes[i]; + defaultNode = (ValidatingReaderNodeData)_defaultAttributes[i]!; if (Ref.Equal(defaultNode.LocalName, attrLocalName) && Ref.Equal(defaultNode.Namespace, ns)) { if (updatePosition) { _currentAttrIndex = _coreReader.AttributeCount + i; } + return defaultNode; } } + return null; } @@ -2177,18 +2315,22 @@ private AttributePSVIInfo AddAttributePSVI(int attIndex) attInfo.Reset(); return attInfo; } + if (attIndex >= _attributePSVINodes.Length - 1) - { //reached capacity of PSVIInfo array, Need to increase capacity to twice the initial + { + // reached capacity of PSVIInfo array, Need to increase capacity to twice the initial AttributePSVIInfo[] newPSVINodes = new AttributePSVIInfo[_attributePSVINodes.Length * 2]; Array.Copy(_attributePSVINodes, newPSVINodes, _attributePSVINodes.Length); _attributePSVINodes = newPSVINodes; } + attInfo = _attributePSVINodes[attIndex]; if (attInfo == null) { attInfo = new AttributePSVIInfo(); _attributePSVINodes[attIndex] = attInfo; } + return attInfo; } @@ -2207,9 +2349,11 @@ private void ProcessInlineSchema() _attributeCount = _coreReaderAttributeCount = _coreReader.AttributeCount; } else - { //Clear attributes info if nodeType is not element + { + // Clear attributes info if nodeType is not element ClearAttributesInfo(); } + if (!_inlineSchemaParser.ParseReaderNode()) { _inlineSchemaParser.FinishParsing(); @@ -2228,8 +2372,7 @@ private object InternalReadContentAsObject() private object InternalReadContentAsObject(bool unwrapTypedValue) { - string str; - return InternalReadContentAsObject(unwrapTypedValue, out str); + return InternalReadContentAsObject(unwrapTypedValue, out _); } private object InternalReadContentAsObject(bool unwrapTypedValue, out string originalStringValue) @@ -2246,10 +2389,11 @@ private object InternalReadContentAsObject(bool unwrapTypedValue, out string ori originalStringValue = (schemaAttr.DefaultValue != null) ? schemaAttr.DefaultValue : schemaAttr.FixedValue; } - return ReturnBoxedValue(_attributePSVI.typedAttributeValue, AttributeSchemaInfo.XmlType, unwrapTypedValue); + return ReturnBoxedValue(_attributePSVI.typedAttributeValue, AttributeSchemaInfo.XmlType, unwrapTypedValue)!; } else - { //return string value + { + // return string value return this.Value; } } @@ -2257,7 +2401,7 @@ private object InternalReadContentAsObject(bool unwrapTypedValue, out string ori { if (_atomicValue != null) { - originalStringValue = _originalAtomicValueString; + originalStringValue = _originalAtomicValueString!; return _atomicValue; } @@ -2269,18 +2413,19 @@ private object InternalReadContentAsObject(bool unwrapTypedValue, out string ori } } else - { //Positioned on text, CDATA, PI, Comment etc + { + // Positioned on text, CDATA, PI, Comment etc if (_validator.CurrentContentType == XmlSchemaContentType.TextOnly) - { //if current element is of simple type - object value = ReturnBoxedValue(ReadTillEndElement(), _xmlSchemaInfo.XmlType, unwrapTypedValue); - originalStringValue = _originalAtomicValueString; + { + // if current element is of simple type + object? value = ReturnBoxedValue(ReadTillEndElement(), _xmlSchemaInfo.XmlType, unwrapTypedValue)!; + originalStringValue = _originalAtomicValueString!; return value; } else { - XsdCachingReader cachingReader = _coreReader as XsdCachingReader; - if (cachingReader != null) + if (_coreReader is XsdCachingReader cachingReader) { originalStringValue = cachingReader.ReadOriginalContentAsString(); } @@ -2294,23 +2439,23 @@ private object InternalReadContentAsObject(bool unwrapTypedValue, out string ori } } - private object InternalReadElementContentAsObject(out XmlSchemaType xmlType) + private object? InternalReadElementContentAsObject(out XmlSchemaType? xmlType) { return InternalReadElementContentAsObject(out xmlType, false); } - private object InternalReadElementContentAsObject(out XmlSchemaType xmlType, bool unwrapTypedValue) + private object? InternalReadElementContentAsObject(out XmlSchemaType? xmlType, bool unwrapTypedValue) { - string tmpString; - return InternalReadElementContentAsObject(out xmlType, unwrapTypedValue, out tmpString); + return InternalReadElementContentAsObject(out xmlType, unwrapTypedValue, out _); } - private object InternalReadElementContentAsObject(out XmlSchemaType xmlType, bool unwrapTypedValue, out string originalString) + private object? InternalReadElementContentAsObject(out XmlSchemaType? xmlType, bool unwrapTypedValue, out string? originalString) { Debug.Assert(this.NodeType == XmlNodeType.Element); - object typedValue = null; + object? typedValue = null; xmlType = null; - //If its an empty element, can have default/fixed value + + // If its an empty element, can have default/fixed value if (this.IsEmptyElement) { if (_xmlSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) @@ -2321,17 +2466,20 @@ private object InternalReadElementContentAsObject(out XmlSchemaType xmlType, boo { typedValue = _atomicValue; } + originalString = _originalAtomicValueString; - xmlType = ElementXmlType; //Set this for default values + xmlType = ElementXmlType; // Set this for default values this.Read(); return typedValue; } + // move to content and read typed value this.Read(); if (this.NodeType == XmlNodeType.EndElement) - { //If IsDefault is true, the next node will be EndElement + { + // If IsDefault is true, the next node will be EndElement if (_xmlSchemaInfo.IsDefault) { if (_xmlSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) @@ -2339,19 +2487,23 @@ private object InternalReadElementContentAsObject(out XmlSchemaType xmlType, boo typedValue = ReturnBoxedValue(_atomicValue, _xmlSchemaInfo.XmlType, unwrapTypedValue); } else - { //anyType has default value + { + // anyType has default value typedValue = _atomicValue; } + originalString = _originalAtomicValueString; } else - { //Empty content + { + // Empty content typedValue = string.Empty; originalString = string.Empty; } } else if (this.NodeType == XmlNodeType.Element) - { //the first child is again element node + { + // the first child is again element node throw new XmlException(SR.Xml_MixedReadElementContentAs, string.Empty, this as IXmlLineInfo); } else @@ -2364,7 +2516,8 @@ private object InternalReadElementContentAsObject(out XmlSchemaType xmlType, boo throw new XmlException(SR.Xml_MixedReadElementContentAs, string.Empty, this as IXmlLineInfo); } } - xmlType = ElementXmlType; //Set this as we are moving ahead to the next node + + xmlType = ElementXmlType; // Set this as we are moving ahead to the next node // move to next node this.Read(); @@ -2372,16 +2525,18 @@ private object InternalReadElementContentAsObject(out XmlSchemaType xmlType, boo return typedValue; } - private object ReadTillEndElement() + private object? ReadTillEndElement() { if (_atomicValue == null) { while (_coreReader.Read()) { if (_replayCache) - { //If replaying nodes in the cache, they have already been validated + { + // If replaying nodes in the cache, they have already been validated continue; } + switch (_coreReader.NodeType) { case XmlNodeType.Element: @@ -2407,33 +2562,41 @@ private object ReadTillEndElement() _originalAtomicValueString = GetOriginalAtomicValueStringOfElement(); if (_manageNamespaces) { + Debug.Assert(_nsManager != null); _nsManager.PopScope(); } + goto breakWhile; } + continue; breakWhile: break; } } else - { //atomicValue != null, meaning already read ahead - Switch reader + { + // atomicValue != null, meaning already read ahead - Switch reader if (_atomicValue == this) - { //switch back invalid marker; dont need it since coreReader moved to endElement + { + // switch back invalid marker; dont need it since coreReader moved to endElement _atomicValue = null; } + SwitchReader(); } + return _atomicValue; } private void SwitchReader() { - XsdCachingReader cachingReader = _coreReader as XsdCachingReader; - if (cachingReader != null) - { //Switch back without going over the cached contents again. + if (_coreReader is XsdCachingReader cachingReader) + { + // Switch back without going over the cached contents again. _coreReader = cachingReader.GetCoreReader(); } + Debug.Assert(_coreReader.NodeType == XmlNodeType.EndElement); _replayCache = false; } @@ -2466,15 +2629,20 @@ private void ReadAheadForMemberType() _atomicValue = _validator.ValidateEndElement(_xmlSchemaInfo); //?? pop namespaceManager scope _originalAtomicValueString = GetOriginalAtomicValueStringOfElement(); if (_atomicValue == null) - { //Invalid marker + { + // Invalid marker _atomicValue = this; } else if (_xmlSchemaInfo.IsDefault) - { //The atomicValue returned is a default value + { + // The atomicValue returned is a default value + Debug.Assert(_cachingReader != null); _cachingReader.SwitchTextNodeAndEndElement(_xmlSchemaInfo.XmlType.ValueConverter.ToString(_atomicValue), _originalAtomicValueString); } + goto breakWhile; } + continue; breakWhile: break; @@ -2483,12 +2651,15 @@ private void ReadAheadForMemberType() private void GetIsDefault() { - XsdCachingReader cachedReader = _coreReader as XsdCachingReader; + XsdCachingReader? cachedReader = _coreReader as XsdCachingReader; if (cachedReader == null && _xmlSchemaInfo.HasDefaultValue) - { //Get Isdefault + { + // Get Isdefault _coreReader = GetCachingReader(); + Debug.Assert(_cachingReader != null); if (_xmlSchemaInfo.IsUnionType && !_xmlSchemaInfo.IsNil) - { //If it also union, get the memberType as well + { + // If it also union, get the memberType as well ReadAheadForMemberType(); } else @@ -2519,9 +2690,11 @@ private void GetIsDefault() _atomicValue = _validator.ValidateEndElement(_xmlSchemaInfo); //?? pop namespaceManager scope _originalAtomicValueString = GetOriginalAtomicValueStringOfElement(); if (_xmlSchemaInfo.IsDefault) - { //The atomicValue returned is a default value + { + // The atomicValue returned is a default value _cachingReader.SwitchTextNodeAndEndElement(_xmlSchemaInfo.XmlType.ValueConverter.ToString(_atomicValue), _originalAtomicValueString); } + break; default: @@ -2529,6 +2702,7 @@ private void GetIsDefault() } } } + _cachingReader.SetToReplayMode(); _replayCache = true; } @@ -2540,39 +2714,46 @@ private void GetMemberType() { return; } - XsdCachingReader cachedReader = _coreReader as XsdCachingReader; + + XsdCachingReader? cachedReader = _coreReader as XsdCachingReader; if (cachedReader == null && _xmlSchemaInfo.IsUnionType && !_xmlSchemaInfo.IsNil) { _coreReader = GetCachingReader(); + Debug.Assert(_cachingReader != null); ReadAheadForMemberType(); _cachingReader.SetToReplayMode(); _replayCache = true; } } - private object ReturnBoxedValue(object typedValue, XmlSchemaType xmlType, bool unWrap) + private object? ReturnBoxedValue(object? typedValue, XmlSchemaType xmlType, bool unWrap) { if (typedValue != null) { if (unWrap) - { //convert XmlAtomicValue[] to object[] for list of unions; The other cases return typed value of the valueType anyway + { + // convert XmlAtomicValue[] to object[] for list of unions; The other cases return typed value of the valueType anyway Debug.Assert(xmlType != null && xmlType.Datatype != null); if (xmlType.Datatype.Variety == XmlSchemaDatatypeVariety.List) { - Datatype_List listType = xmlType.Datatype as Datatype_List; + Datatype_List? listType = xmlType.Datatype as Datatype_List; + Debug.Assert(listType != null); if (listType.ItemType.Variety == XmlSchemaDatatypeVariety.Union) { typedValue = xmlType.ValueConverter.ChangeType(typedValue, xmlType.Datatype.ValueType, _thisNSResolver); } } } + return typedValue; } else - { //return the original string value of the element or attribute + { + // return the original string value of the element or attribute Debug.Assert(NodeType != XmlNodeType.Attribute); typedValue = _validator.GetConcatenatedValue(); } + return typedValue; } @@ -2586,6 +2767,7 @@ private XsdCachingReader GetCachingReader() { _cachingReader.Reset(_coreReader); } + _lineInfo = _cachingReader as IXmlLineInfo; return _cachingReader; } @@ -2596,6 +2778,7 @@ internal ValidatingReaderNodeData CreateDummyTextNode(string attributeValue, int { _textNode = new ValidatingReaderNodeData(XmlNodeType.Text); } + _textNode.Depth = depth; _textNode.RawValue = attributeValue; return _textNode; @@ -2603,7 +2786,7 @@ internal ValidatingReaderNodeData CreateDummyTextNode(string attributeValue, int internal void CachingCallBack(XsdCachingReader cachingReader) { - _coreReader = cachingReader.GetCoreReader(); //re-switch the core-reader after caching reader is done + _coreReader = cachingReader.GetCoreReader(); // re-switch the core-reader after caching reader is done _lineInfo = cachingReader.GetLineInfo(); _replayCache = false; } @@ -2622,6 +2805,7 @@ private string GetOriginalAtomicValueStringOfElement() { return _validator.GetConcatenatedValue(); } + return string.Empty; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReaderAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReaderAsync.cs index 24b68ff01ddba..a9953d2873af4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReaderAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReaderAsync.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.IO; using System.Text; using System.Xml.Schema; @@ -23,8 +24,10 @@ public override Task GetValueAsync() { if ((int)_validationState < 0) { + Debug.Assert(_cachedNode != null); return Task.FromResult(_cachedNode.RawValue); } + return _coreReader.GetValueAsync(); } @@ -44,8 +47,9 @@ public override async Task ReadContentAsStringAsync() { throw CreateReadContentAsException(nameof(ReadContentAsString)); } + object typedValue = await InternalReadContentAsObjectAsync().ConfigureAwait(false); - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -54,7 +58,7 @@ public override async Task ReadContentAsStringAsync() } else { - return typedValue as string; + return (typedValue as string)!; } } catch (InvalidCastException e) @@ -77,6 +81,7 @@ public override async Task ReadContentAsAsync(Type returnType, IXmlNames { throw CreateReadContentAsException(nameof(ReadContentAs)); } + string originalStringValue; var tuple_0 = await InternalReadContentAsObjectTupleAsync(false).ConfigureAwait(false); @@ -84,7 +89,7 @@ public override async Task ReadContentAsAsync(Type returnType, IXmlNames object typedValue = tuple_0.Item2; - XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; + XmlSchemaType? xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType; try { if (xmlType != null) @@ -95,6 +100,7 @@ public override async Task ReadContentAsAsync(Type returnType, IXmlNames { typedValue = originalStringValue; } + return xmlType.ValueConverter.ChangeType(typedValue, returnType); } else @@ -134,12 +140,13 @@ public override async Task ReadElementContentAsStringAsync() { throw CreateReadElementContentAsException(nameof(ReadElementContentAsString)); } + XmlSchemaType xmlType; - var tuple_9 = await InternalReadElementContentAsObjectAsync().ConfigureAwait(false); - xmlType = tuple_9.Item1; + var content = await InternalReadElementContentAsObjectAsync().ConfigureAwait(false); + xmlType = content.Item1; - object typedValue = tuple_9.Item2; + object typedValue = content.Item2; try { @@ -149,6 +156,7 @@ public override async Task ReadElementContentAsStringAsync() } else { + Debug.Assert(false, $"{nameof(typedValue)} should never be null"); return typedValue as string; } } @@ -172,14 +180,15 @@ public override async Task ReadElementContentAsAsync(Type returnType, IX { throw CreateReadElementContentAsException(nameof(ReadElementContentAs)); } + XmlSchemaType xmlType; string originalStringValue; - var tuple_10 = await InternalReadElementContentAsObjectTupleAsync(false).ConfigureAwait(false); - xmlType = tuple_10.Item1; - originalStringValue = tuple_10.Item2; + var content = await InternalReadElementContentAsObjectTupleAsync(false).ConfigureAwait(false); + xmlType = content.Item1; + originalStringValue = content.Item2; - object typedValue = tuple_10.Item3; + object typedValue = content.Item3; try { @@ -191,6 +200,7 @@ public override async Task ReadElementContentAsAsync(Type returnType, IX { typedValue = originalStringValue; } + return xmlType.ValueConverter.ChangeType(typedValue, returnType, namespaceResolver); } else @@ -227,6 +237,7 @@ private Task ReadAsync_Read(Task task) { _validationState = ValidatingReaderState.EOF; } + return AsyncHelper.DoneTaskFalse; } } @@ -250,6 +261,7 @@ private async Task _ReadAsync_Read(Task task) { _validationState = ValidatingReaderState.EOF; } + return false; } } @@ -302,19 +314,21 @@ public override Task ReadAsync() goto case ValidatingReaderState.Read; } - case ValidatingReaderState.ReadAhead: //Will enter here on calling Skip() + case ValidatingReaderState.ReadAhead: // Will enter here on calling Skip() ClearAttributesInfo(); Task task = ProcessReaderEventAsync(); return ReadAsync_ReadAhead(task); case ValidatingReaderState.OnReadBinaryContent: _validationState = _savedState; + Debug.Assert(_readBinaryHelper != null); return _readBinaryHelper.FinishAsync().CallBoolTaskFuncWhenFinishAsync(thisRef => thisRef.ReadAsync(), this); case ValidatingReaderState.Init: _validationState = ValidatingReaderState.Read; if (_coreReader.ReadState == ReadState.Interactive) - { //If the underlying reader is already positioned on a ndoe, process it + { + // If the underlying reader is already positioned on a ndoe, process it return ProcessReaderEventAsync().ReturnTrueTaskWhenFinishAsync(); } else @@ -342,26 +356,29 @@ public override async Task SkipAsync() { break; } + bool callSkipToEndElem = true; - //If union and unionValue has been parsed till EndElement, then validator.ValidateEndElement has been called - //Hence should not call SkipToEndElement as the current context has already been popped in the validator + // If union and unionValue has been parsed till EndElement, then validator.ValidateEndElement has been called + // Hence should not call SkipToEndElement as the current context has already been popped in the validator if ((_xmlSchemaInfo.IsUnionType || _xmlSchemaInfo.IsDefault) && _coreReader is XsdCachingReader) { callSkipToEndElem = false; } + await _coreReader.SkipAsync().ConfigureAwait(false); _validationState = ValidatingReaderState.ReadAhead; if (callSkipToEndElem) { _validator.SkipToEndElement(_xmlSchemaInfo); } + break; case XmlNodeType.Attribute: MoveToElement(); goto case XmlNodeType.Element; } - //For all other NodeTypes Skip() same as Read() + // For all other NodeTypes Skip() same as Read() await ReadAsync().ConfigureAwait(false); return; } @@ -384,6 +401,7 @@ public override async Task ReadContentAsBase64Async(byte[] buffer, int inde _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = await _readBinaryHelper.ReadContentAsBase64Async(buffer, index, count).ConfigureAwait(false); // set OnReadBinaryContent state again and return @@ -410,6 +428,7 @@ public override async Task ReadContentAsBinHexAsync(byte[] buffer, int inde _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = await _readBinaryHelper.ReadContentAsBinHexAsync(buffer, index, count).ConfigureAwait(false); // set OnReadBinaryContent state again and return @@ -436,6 +455,7 @@ public override async Task ReadElementContentAsBase64Async(byte[] buffer, i _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = await _readBinaryHelper.ReadElementContentAsBase64Async(buffer, index, count).ConfigureAwait(false); // set OnReadBinaryContent state again and return @@ -462,6 +482,7 @@ public override async Task ReadElementContentAsBinHexAsync(byte[] buffer, i _validationState = _savedState; // call to the helper + Debug.Assert(_readBinaryHelper != null); int readCount = await _readBinaryHelper.ReadElementContentAsBinHexAsync(buffer, index, count).ConfigureAwait(false); // set OnReadBinaryContent state again and return @@ -473,11 +494,13 @@ public override async Task ReadElementContentAsBinHexAsync(byte[] buffer, i private Task ProcessReaderEventAsync() { if (_replayCache) - { //if in replay mode, do nothing since nodes have been validated already - //If NodeType == XmlNodeType.EndElement && if manageNamespaces, may need to pop namespace scope, since scope is not popped in ReadAheadForMemberType + { + // if in replay mode, do nothing since nodes have been validated already + // If NodeType == XmlNodeType.EndElement && if manageNamespaces, may need to pop namespace scope, since scope is not popped in ReadAheadForMemberType return Task.CompletedTask; } + switch (_coreReader.NodeType) { case XmlNodeType.Element: @@ -523,7 +546,8 @@ private async Task ProcessElementEventAsync() _xmlSchemaInfo.Clear(); _attributeCount = _coreReaderAttributeCount = _coreReader.AttributeCount; if (!_coreReader.IsEmptyElement) - { //If its not empty schema, then parse else ignore + { + // If its not empty schema, then parse else ignore _inlineSchemaParser = new Parser(SchemaType.XSD, _coreReaderNameTable, _validator.SchemaSet.GetSchemaNames(_coreReaderNameTable), _validationEvent); await _inlineSchemaParser.StartParsingAsync(_coreReader, null).ConfigureAwait(false); _inlineSchemaParser.ParseReaderNode(); @@ -535,21 +559,25 @@ private async Task ProcessElementEventAsync() } } else - { //Validate element - //Clear previous data + { + // Validate element + // Clear previous data _atomicValue = null; _originalAtomicValueString = null; _xmlSchemaInfo.Clear(); if (_manageNamespaces) { + Debug.Assert(_nsManager != null); _nsManager.PushScope(); } - //Find Xsi attributes that need to be processed before validating the element - string xsiSchemaLocation = null; - string xsiNoNamespaceSL = null; - string xsiNil = null; - string xsiType = null; + + // Find Xsi attributes that need to be processed before validating the element + string? xsiSchemaLocation = null; + string? xsiNoNamespaceSL = null; + string? xsiNil = null; + string? xsiType = null; + if (_coreReader.MoveToFirstAttribute()) { do @@ -575,13 +603,16 @@ private async Task ProcessElementEventAsync() xsiNil = _coreReader.Value; } } + if (_manageNamespaces && Ref.Equal(_coreReader.NamespaceURI, _nsXmlNs)) { + Debug.Assert(_nsManager != null); _nsManager.AddNamespace(_coreReader.Prefix.Length == 0 ? string.Empty : _coreReader.LocalName, _coreReader.Value); } } while (_coreReader.MoveToNextAttribute()); _coreReader.MoveToElement(); } + _validator.ValidateElement(_coreReader.LocalName, _coreReader.NamespaceURI, _xmlSchemaInfo, xsiType, xsiNil, xsiSchemaLocation, xsiNoNamespaceSL); ValidateAttributes(); _validator.ValidateEndOfAttributes(_xmlSchemaInfo); @@ -589,6 +620,7 @@ private async Task ProcessElementEventAsync() { await ProcessEndElementEventAsync().ConfigureAwait(false); } + _validationState = ValidatingReaderState.ClearAttributes; } } @@ -598,10 +630,12 @@ private async Task ProcessEndElementEventAsync() _atomicValue = _validator.ValidateEndElement(_xmlSchemaInfo); _originalAtomicValueString = GetOriginalAtomicValueStringOfElement(); if (_xmlSchemaInfo.IsDefault) - { //The atomicValue returned is a default value + { + // The atomicValue returned is a default value Debug.Assert(_atomicValue != null); int depth = _coreReader.Depth; _coreReader = GetCachingReader(); + Debug.Assert(_cachingReader != null); _cachingReader.RecordTextNode(_xmlSchemaInfo.XmlType.ValueConverter.ToString(_atomicValue), _originalAtomicValueString, depth + 1, 0, 0); _cachingReader.RecordEndElementNode(); await _cachingReader.SetToReplayModeAsync().ConfigureAwait(false); @@ -609,6 +643,7 @@ private async Task ProcessEndElementEventAsync() } else if (_manageNamespaces) { + Debug.Assert(_nsManager != null); _nsManager.PopScope(); } } @@ -623,9 +658,11 @@ private async Task ProcessInlineSchemaAsync() _attributeCount = _coreReaderAttributeCount = _coreReader.AttributeCount; } else - { //Clear attributes info if nodeType is not element + { + // Clear attributes info if nodeType is not element ClearAttributesInfo(); } + if (!_inlineSchemaParser.ParseReaderNode()) { _inlineSchemaParser.FinishParsing(); @@ -644,9 +681,8 @@ private Task InternalReadContentAsObjectAsync() private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValue) { - var tuple_11 = await InternalReadContentAsObjectTupleAsync(unwrapTypedValue).ConfigureAwait(false); - - return tuple_11.Item2; + var content = await InternalReadContentAsObjectTupleAsync(unwrapTypedValue).ConfigureAwait(false); + return content.Item2; } private async Task> InternalReadContentAsObjectTupleAsync(bool unwrapTypedValue) @@ -666,11 +702,12 @@ private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValu originalStringValue = (schemaAttr.DefaultValue != null) ? schemaAttr.DefaultValue : schemaAttr.FixedValue; } - tuple = new Tuple(originalStringValue, ReturnBoxedValue(_attributePSVI.typedAttributeValue, AttributeSchemaInfo.XmlType, unwrapTypedValue)); + tuple = new Tuple(originalStringValue, ReturnBoxedValue(_attributePSVI.typedAttributeValue, AttributeSchemaInfo.XmlType, unwrapTypedValue)!); return tuple; } else - { //return string value + { + // return string value tuple = new Tuple(originalStringValue, this.Value); return tuple; } @@ -679,6 +716,7 @@ private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValu { if (_atomicValue != null) { + Debug.Assert(_originalAtomicValueString != null); originalStringValue = _originalAtomicValueString; tuple = new Tuple(originalStringValue, _atomicValue); @@ -693,10 +731,15 @@ private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValu } } else - { //Positioned on text, CDATA, PI, Comment etc + { + // Positioned on text, CDATA, PI, Comment etc if (_validator.CurrentContentType == XmlSchemaContentType.TextOnly) - { //if current element is of simple type - object value = ReturnBoxedValue(await ReadTillEndElementAsync().ConfigureAwait(false), _xmlSchemaInfo.XmlType, unwrapTypedValue); + { + // if current element is of simple type + object? value = ReturnBoxedValue(await ReadTillEndElementAsync().ConfigureAwait(false), _xmlSchemaInfo.XmlType, unwrapTypedValue)!; + Debug.Assert(value != null); + + Debug.Assert(_originalAtomicValueString != null); originalStringValue = _originalAtomicValueString; tuple = new Tuple(originalStringValue, value); @@ -704,7 +747,7 @@ private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValu } else { - XsdCachingReader cachingReader = _coreReader as XsdCachingReader; + XsdCachingReader? cachingReader = _coreReader as XsdCachingReader; if (cachingReader != null) { originalStringValue = cachingReader.ReadOriginalContentAsString(); @@ -727,71 +770,77 @@ private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValu private async Task> InternalReadElementContentAsObjectAsync(bool unwrapTypedValue) { - var tuple_13 = await InternalReadElementContentAsObjectTupleAsync(unwrapTypedValue).ConfigureAwait(false); + var content = await InternalReadElementContentAsObjectTupleAsync(unwrapTypedValue).ConfigureAwait(false); - return new Tuple(tuple_13.Item1, tuple_13.Item3); + return new Tuple(content.Item1, content.Item3); } private async Task> InternalReadElementContentAsObjectTupleAsync(bool unwrapTypedValue) { - Tuple tuple; - XmlSchemaType xmlType; + XmlSchemaType? xmlType = null; string originalString; Debug.Assert(this.NodeType == XmlNodeType.Element); - object typedValue = null; - xmlType = null; - //If its an empty element, can have default/fixed value + object typedValue; + // If its an empty element, can have default/fixed value if (this.IsEmptyElement) { if (_xmlSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) { - typedValue = ReturnBoxedValue(_atomicValue, _xmlSchemaInfo.XmlType, unwrapTypedValue); + typedValue = ReturnBoxedValue(_atomicValue, _xmlSchemaInfo.XmlType, unwrapTypedValue)!; } else { - typedValue = _atomicValue; + typedValue = _atomicValue!; } + + Debug.Assert(_originalAtomicValueString != null); originalString = _originalAtomicValueString; - xmlType = ElementXmlType; //Set this for default values + xmlType = ElementXmlType; // Set this for default values await this.ReadAsync().ConfigureAwait(false); - tuple = new Tuple(xmlType, originalString, typedValue); - return tuple; + return new Tuple(xmlType, originalString, typedValue); } + // move to content and read typed value await this.ReadAsync().ConfigureAwait(false); if (this.NodeType == XmlNodeType.EndElement) - { //If IsDefault is true, the next node will be EndElement + { + // If IsDefault is true, the next node will be EndElement if (_xmlSchemaInfo.IsDefault) { if (_xmlSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) { - typedValue = ReturnBoxedValue(_atomicValue, _xmlSchemaInfo.XmlType, unwrapTypedValue); + typedValue = ReturnBoxedValue(_atomicValue, _xmlSchemaInfo.XmlType, unwrapTypedValue)!; } else - { //anyType has default value - typedValue = _atomicValue; + { + // anyType has default value + typedValue = _atomicValue!; } + + Debug.Assert(_originalAtomicValueString != null); originalString = _originalAtomicValueString; } else - { //Empty content + { + // Empty content typedValue = string.Empty; originalString = string.Empty; } } else if (this.NodeType == XmlNodeType.Element) - { //the first child is again element node + { + // the first child is again element node throw new XmlException(SR.Xml_MixedReadElementContentAs, string.Empty, this as IXmlLineInfo); } else { - var tuple_14 = await InternalReadContentAsObjectTupleAsync(unwrapTypedValue).ConfigureAwait(false); - originalString = tuple_14.Item1; + var content = await InternalReadContentAsObjectTupleAsync(unwrapTypedValue).ConfigureAwait(false); + originalString = content.Item1; - typedValue = tuple_14.Item2; + typedValue = content.Item2; // ReadElementContentAsXXX cannot be called on mixed content, if positioned on node other than EndElement, Error if (this.NodeType != XmlNodeType.EndElement) @@ -799,25 +848,27 @@ private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValu throw new XmlException(SR.Xml_MixedReadElementContentAs, string.Empty, this as IXmlLineInfo); } } - xmlType = ElementXmlType; //Set this as we are moving ahead to the next node + + xmlType = ElementXmlType; // Set this as we are moving ahead to the next node // move to next node await this.ReadAsync().ConfigureAwait(false); - tuple = new Tuple(xmlType, originalString, typedValue); - return tuple; + return new Tuple(xmlType, originalString, typedValue); } - private async Task ReadTillEndElementAsync() + private async Task ReadTillEndElementAsync() { if (_atomicValue == null) { while (await _coreReader.ReadAsync().ConfigureAwait(false)) { if (_replayCache) - { //If replaying nodes in the cache, they have already been validated + { + // If replaying nodes in the cache, they have already been validated continue; } + switch (_coreReader.NodeType) { case XmlNodeType.Element: @@ -843,23 +894,30 @@ private async Task ReadTillEndElementAsync() _originalAtomicValueString = GetOriginalAtomicValueStringOfElement(); if (_manageNamespaces) { + Debug.Assert(_nsManager != null); _nsManager.PopScope(); } + goto breakWhile; } + continue; breakWhile: break; } } else - { //atomicValue != null, meaning already read ahead - Switch reader + { + // atomicValue != null, meaning already read ahead - Switch reader if (_atomicValue == this) - { //switch back invalid marker; dont need it since coreReader moved to endElement + { + // switch back invalid marker; dont need it since coreReader moved to endElement _atomicValue = null; } + SwitchReader(); } + return _atomicValue; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/AutoValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/AutoValidator.cs index 4ae13d948b817..70f9dfa5833f3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/AutoValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/AutoValidator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { using System.Diagnostics; @@ -43,7 +44,7 @@ public override void Validate() public override void CompleteValidation() { } - public override object FindId(string name) + public override object? FindId(string name) { return null; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseValidator.cs index c9f730028286f..237d763960885 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseValidator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { using System.IO; @@ -9,25 +10,26 @@ namespace System.Xml.Schema using System.Xml; using System.Text; using System.Collections; + using System.Diagnostics.CodeAnalysis; #pragma warning disable 618 internal class BaseValidator { - private readonly XmlSchemaCollection _schemaCollection; + private readonly XmlSchemaCollection? _schemaCollection; private readonly IValidationEventHandling _eventHandling; private readonly XmlNameTable _nameTable; - private SchemaNames _schemaNames; + private SchemaNames? _schemaNames; private readonly PositionInfo _positionInfo; - private XmlResolver _xmlResolver; - private Uri _baseUri; + private XmlResolver? _xmlResolver; + private Uri? _baseUri; - protected SchemaInfo schemaInfo; + protected SchemaInfo? schemaInfo; protected XmlValidatingReaderImpl reader; protected XmlQualifiedName elementName; - protected ValidationState context; - protected StringBuilder textValue; - protected string textString; + protected ValidationState? context; + protected StringBuilder? textValue; + protected string? textString; protected bool hasSibling; protected bool checkDatatype; @@ -44,7 +46,7 @@ public BaseValidator(BaseValidator other) elementName = other.elementName; } - public BaseValidator(XmlValidatingReaderImpl reader, XmlSchemaCollection schemaCollection, IValidationEventHandling eventHandling) + public BaseValidator(XmlValidatingReaderImpl reader, XmlSchemaCollection? schemaCollection, IValidationEventHandling eventHandling) { Debug.Assert(schemaCollection == null || schemaCollection.NameTable == reader.NameTable); this.reader = reader; @@ -60,7 +62,7 @@ public XmlValidatingReaderImpl Reader get { return reader; } } - public XmlSchemaCollection SchemaCollection + public XmlSchemaCollection? SchemaCollection { get { return _schemaCollection; } } @@ -78,6 +80,7 @@ public SchemaNames SchemaNames { return _schemaNames; } + if (_schemaCollection != null) { _schemaNames = _schemaCollection.GetSchemaNames(_nameTable); @@ -86,6 +89,7 @@ public SchemaNames SchemaNames { _schemaNames = new SchemaNames(_nameTable); } + return _schemaNames; } } @@ -95,13 +99,13 @@ public PositionInfo PositionInfo get { return _positionInfo; } } - public XmlResolver XmlResolver + public XmlResolver? XmlResolver { get { return _xmlResolver; } set { _xmlResolver = value; } } - public Uri BaseUri + public Uri? BaseUri { get { return _baseUri; } set { _baseUri = value; } @@ -112,7 +116,7 @@ public ValidationEventHandler EventHandler get { return (ValidationEventHandler)_eventHandling.EventHandler; } } - public SchemaInfo SchemaInfo + public SchemaInfo? SchemaInfo { get { @@ -124,7 +128,8 @@ public SchemaInfo SchemaInfo } } - public IDtdInfo DtdInfo + [DisallowNull] + public IDtdInfo? DtdInfo { get { @@ -132,11 +137,12 @@ public IDtdInfo DtdInfo } set { - SchemaInfo tmpSchemaInfo = value as SchemaInfo; + SchemaInfo? tmpSchemaInfo = value as SchemaInfo; if (tmpSchemaInfo == null) { throw new XmlException(SR.Xml_InternalError, string.Empty); } + this.schemaInfo = tmpSchemaInfo; } } @@ -157,13 +163,14 @@ public virtual void CompleteValidation() { } - public virtual object FindId(string name) + public virtual object? FindId(string name) { return null; } public void ValidateText() { + Debug.Assert(context != null); if (context.NeedValidateChildren) { if (context.IsNill) @@ -171,6 +178,7 @@ public void ValidateText() SendValidationEvent(SR.Sch_ContentInNill, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace)); return; } + ContentValidator contentValidator = context.ElementDecl.ContentValidator; XmlSchemaContentType contentType = contentValidator.ContentType; if (contentType == XmlSchemaContentType.ElementOnly) @@ -190,6 +198,7 @@ public void ValidateText() { SendValidationEvent(SR.Sch_InvalidTextInEmpty, string.Empty); } + if (checkDatatype) { SaveTextValue(reader.Value); @@ -199,6 +208,7 @@ public void ValidateText() public void ValidateWhitespace() { + Debug.Assert(context != null); if (context.NeedValidateChildren) { XmlSchemaContentType contentType = context.ElementDecl.ContentValidator.ContentType; @@ -206,10 +216,12 @@ public void ValidateWhitespace() { SendValidationEvent(SR.Sch_ContentInNill, XmlSchemaValidator.QNameString(context.LocalName, context.Namespace)); } + if (contentType == XmlSchemaContentType.Empty) { SendValidationEvent(SR.Sch_InvalidWhitespaceInEmpty, string.Empty); } + if (checkDatatype) { SaveTextValue(reader.Value); @@ -219,17 +231,20 @@ public void ValidateWhitespace() private void SaveTextValue(string value) { + Debug.Assert(textString != null); if (textString.Length == 0) { textString = value; } else { + Debug.Assert(textValue != null); if (!hasSibling) { textValue.Append(textString); hasSibling = true; } + textValue.Append(value); } } @@ -278,8 +293,8 @@ protected void SendValidationEvent(XmlSchemaException e, XmlSeverityType severit protected static void ProcessEntity(SchemaInfo sinfo, string name, object sender, ValidationEventHandler eventhandler, string baseUri, int lineNumber, int linePosition) { - SchemaEntity en; - XmlSchemaException e = null; + SchemaEntity? en; + XmlSchemaException? e = null; if (!sinfo.GeneralEntities.TryGetValue(new XmlQualifiedName(name), out en)) { // validation error, see xml spec [68] @@ -289,6 +304,7 @@ protected static void ProcessEntity(SchemaInfo sinfo, string name, object sender { e = new XmlSchemaException(SR.Sch_UnparsedEntityRef, name, baseUri, lineNumber, linePosition); } + if (e != null) { if (eventhandler != null) @@ -304,8 +320,8 @@ protected static void ProcessEntity(SchemaInfo sinfo, string name, object sender protected static void ProcessEntity(SchemaInfo sinfo, string name, IValidationEventHandling eventHandling, string baseUriStr, int lineNumber, int linePosition) { - SchemaEntity en; - string errorResId = null; + SchemaEntity? en; + string? errorResId = null; if (!sinfo.GeneralEntities.TryGetValue(new XmlQualifiedName(name), out en)) { // validation error, see xml spec [68] @@ -330,7 +346,7 @@ protected static void ProcessEntity(SchemaInfo sinfo, string name, IValidationEv } } - public static BaseValidator CreateInstance(ValidationType valType, XmlValidatingReaderImpl reader, XmlSchemaCollection schemaCollection, IValidationEventHandling eventHandling, bool processIdentityConstraints) + public static BaseValidator? CreateInstance(ValidationType valType, XmlValidatingReaderImpl reader, XmlSchemaCollection schemaCollection, IValidationEventHandling eventHandling, bool processIdentityConstraints) { switch (valType) { @@ -352,6 +368,7 @@ public static BaseValidator CreateInstance(ValidationType valType, XmlValidating default: break; } + return null; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/Inference/XmlSchemaInferenceException.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/Inference/XmlSchemaInferenceException.cs index cdcf3fec2d59b..6a93ab0365366 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/Inference/XmlSchemaInferenceException.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/Inference/XmlSchemaInferenceException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.IO; using System.Resources; @@ -29,15 +30,15 @@ public XmlSchemaInferenceException() : base(null) { } - public XmlSchemaInferenceException(string message) : base(message, ((Exception)null), 0, 0) + public XmlSchemaInferenceException(string message) : base(message, ((Exception?)null), 0, 0) { } - public XmlSchemaInferenceException(string message, Exception innerException) : base(message, innerException, 0, 0) + public XmlSchemaInferenceException(string message, Exception? innerException) : base(message, innerException, 0, 0) { } - public XmlSchemaInferenceException(string message, Exception innerException, int lineNumber, int linePosition) : + public XmlSchemaInferenceException(string message, Exception? innerException, int lineNumber, int linePosition) : base(message, innerException, lineNumber, linePosition) { } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaType.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaType.cs index 50e33a20c7625..c70077e05c69d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaType.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections; using System.ComponentModel; using System.Xml.Serialization; @@ -13,15 +14,15 @@ namespace System.Xml.Schema /// public class XmlSchemaType : XmlSchemaAnnotated { - private string _name; + private string? _name; private XmlSchemaDerivationMethod _final = XmlSchemaDerivationMethod.None; private XmlSchemaDerivationMethod _derivedBy; - private XmlSchemaType _baseSchemaType; - private XmlSchemaDatatype _datatype; + private XmlSchemaType? _baseSchemaType; + private XmlSchemaDatatype? _datatype; private XmlSchemaDerivationMethod _finalResolved; - private volatile SchemaElementDecl _elementDecl; + private volatile SchemaElementDecl? _elementDecl; private volatile XmlQualifiedName _qname = XmlQualifiedName.Empty; - private XmlSchemaType _redefined; + private XmlSchemaType? _redefined; //compiled information private XmlSchemaContentType _contentType; @@ -35,6 +36,7 @@ public static XmlSchemaSimpleType GetBuiltInSimpleType(XmlQualifiedName qualifie { throw new ArgumentNullException(nameof(qualifiedName)); } + return DatatypeImplementation.GetSimpleTypeFromXsdType(qualifiedName); } @@ -49,32 +51,36 @@ public static XmlSchemaSimpleType GetBuiltInSimpleType(XmlTypeCode typeCode) /// /// [To be supplied.] /// - public static XmlSchemaComplexType GetBuiltInComplexType(XmlTypeCode typeCode) + public static XmlSchemaComplexType? GetBuiltInComplexType(XmlTypeCode typeCode) { if (typeCode == XmlTypeCode.Item) { return XmlSchemaComplexType.AnyType; } + return null; } /// /// [To be supplied.] /// - public static XmlSchemaComplexType GetBuiltInComplexType(XmlQualifiedName qualifiedName) + public static XmlSchemaComplexType? GetBuiltInComplexType(XmlQualifiedName qualifiedName) { if (qualifiedName == null) { throw new ArgumentNullException(nameof(qualifiedName)); } + if (qualifiedName.Equals(XmlSchemaComplexType.AnyType.QualifiedName)) { return XmlSchemaComplexType.AnyType; } + if (qualifiedName.Equals(XmlSchemaComplexType.UntypedAnyType.QualifiedName)) { return XmlSchemaComplexType.UntypedAnyType; } + return null; } @@ -82,7 +88,7 @@ public static XmlSchemaComplexType GetBuiltInComplexType(XmlQualifiedName qualif /// [To be supplied.] /// [XmlAttribute("name")] - public string Name + public string? Name { get { return _name; } set { _name = value; } @@ -121,7 +127,7 @@ public XmlSchemaDerivationMethod FinalResolved /// [XmlIgnore] [Obsolete("This property has been deprecated. Please use BaseXmlSchemaType property that returns a strongly typed base schema type. https://go.microsoft.com/fwlink/?linkid=14202")] - public object BaseSchemaType + public object? BaseSchemaType { get { @@ -132,6 +138,7 @@ public object BaseSchemaType { return _baseSchemaType.Datatype; } + return _baseSchemaType; } } @@ -140,7 +147,7 @@ public object BaseSchemaType /// [To be supplied.] /// [XmlIgnore] - public XmlSchemaType BaseXmlSchemaType + public XmlSchemaType? BaseXmlSchemaType { get { return _baseSchemaType; } } @@ -158,7 +165,7 @@ public XmlSchemaDerivationMethod DerivedBy /// [To be supplied.] /// [XmlIgnore] - public XmlSchemaDatatype Datatype + public XmlSchemaDatatype? Datatype { get { return _datatype; } } @@ -203,7 +210,7 @@ internal XmlValueConverter ValueConverter } } - internal XmlReader Validate(XmlReader reader, XmlResolver resolver, XmlSchemaSet schemaSet, ValidationEventHandler valEventHandler) + internal XmlReader? Validate(XmlReader reader, XmlResolver resolver, XmlSchemaSet schemaSet, ValidationEventHandler valEventHandler) { if (schemaSet != null) { @@ -213,6 +220,7 @@ internal XmlReader Validate(XmlReader reader, XmlResolver resolver, XmlSchemaSet readerSettings.ValidationEventHandler += valEventHandler; return new XsdValidatingReader(reader, resolver, readerSettings, this); } + return null; } @@ -249,14 +257,14 @@ internal void SetDatatype(XmlSchemaDatatype value) _datatype = value; } - internal SchemaElementDecl ElementDecl + internal SchemaElementDecl? ElementDecl { get { return _elementDecl; } set { _elementDecl = value; } } [XmlIgnore] - internal XmlSchemaType Redefined + internal XmlSchemaType? Redefined { get { return _redefined; } set { _redefined = value; } @@ -272,7 +280,7 @@ internal void SetContentType(XmlSchemaContentType value) _contentType = value; } - public static bool IsDerivedFrom(XmlSchemaType derivedType, XmlSchemaType baseType, XmlSchemaDerivationMethod except) + public static bool IsDerivedFrom(XmlSchemaType? derivedType, XmlSchemaType? baseType, XmlSchemaDerivationMethod except) { if (derivedType == null || baseType == null) { @@ -288,17 +296,19 @@ public static bool IsDerivedFrom(XmlSchemaType derivedType, XmlSchemaType baseTy { //Not checking for restriction blocked since all types are implicitly derived by restriction from xs:anyType return true; } + do { - XmlSchemaSimpleType dt = derivedType as XmlSchemaSimpleType; - XmlSchemaSimpleType bt = baseType as XmlSchemaSimpleType; + XmlSchemaSimpleType? dt = derivedType as XmlSchemaSimpleType; + XmlSchemaSimpleType? bt = baseType as XmlSchemaSimpleType; if (bt != null && dt != null) { //SimpleTypes if (bt == DatatypeImplementation.AnySimpleType) { //Not checking block=restriction return true; } - if ((except & derivedType.DerivedBy) != 0 || !dt.Datatype.IsDerivedFrom(bt.Datatype)) + + if ((except & derivedType.DerivedBy) != 0 || !dt.Datatype!.IsDerivedFrom(bt.Datatype)) { return false; } @@ -310,6 +320,7 @@ public static bool IsDerivedFrom(XmlSchemaType derivedType, XmlSchemaType baseTy { return false; } + derivedType = derivedType.BaseXmlSchemaType; if (derivedType == baseType) { @@ -332,7 +343,7 @@ internal static bool IsDerivedFromDatatype(XmlSchemaDatatype derivedDataType, Xm } [XmlIgnore] - internal override string NameAttribute + internal override string? NameAttribute { get { return Name; } set { Name = value; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaUse.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaUse.cs index b39996f93f58b..3f320dfdd3699 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaUse.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaUse.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { using System.Xml.Serialization; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs index d751e088b866d..00f3c76b63e99 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs @@ -735,6 +735,7 @@ public void GetUnspecifiedDefaultAttributes(ArrayList defaultAttributes) { throw new ArgumentNullException(nameof(defaultAttributes)); } + CheckStateTransition(ValidatorState.Attribute, "GetUnspecifiedDefaultAttributes"); GetUnspecifiedDefaultAttributes(defaultAttributes, false); } @@ -1066,6 +1067,7 @@ internal void GetUnspecifiedDefaultAttributes(ArrayList defaultAttributes, bool continue; } } + XmlSchemaDatatype datatype = attdef.Datatype; if (createNodeData) { @@ -1090,6 +1092,7 @@ internal void GetUnspecifiedDefaultAttributes(ArrayList defaultAttributes, bool { attrValidInfo.typedAttributeValue = attdef.DefaultValueTyped; } + attSchemaInfo.IsDefault = true; attSchemaInfo.Validity = XmlSchemaValidity.Valid; attSchemaInfo.SchemaType = attdef.SchemaType; @@ -1103,6 +1106,7 @@ internal void GetUnspecifiedDefaultAttributes(ArrayList defaultAttributes, bool { defaultAttributes.Add(attdef.SchemaAttribute); } + CheckTokenizedTypes(datatype, attdef.DefaultValueTyped, true); if (HasIdentityConstraints) { @@ -1111,7 +1115,6 @@ internal void GetUnspecifiedDefaultAttributes(ArrayList defaultAttributes, bool } } } - return; } internal XmlSchemaSet SchemaSet diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidity.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidity.cs index 6c3aaa9c82c27..2902fee222562 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidity.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidity.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { public enum XmlSchemaValidity diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSeverityType.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSeverityType.cs index d5d74ec1ab190..2fc305eff8e0d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSeverityType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSeverityType.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { //UE Atention diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTokenizedType.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTokenizedType.cs index 9277fd46ce54c..26c3b874d8a50 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTokenizedType.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTokenizedType.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml { // NOTE: Absolute numbering is utilized in DtdParser. -HelenaK diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTypeCode.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTypeCode.cs index 43ad4c8e3c98d..c39a138c968c5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTypeCode.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlTypeCode.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { public enum XmlTypeCode diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdDuration.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdDuration.cs index 9a73084017a7c..4567d8d119911 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdDuration.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdDuration.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Xml.Schema { using System; @@ -40,7 +41,7 @@ public enum DurationType Duration, YearMonthDuration, DayTimeDuration, - }; + } /// /// Construct an XsdDuration from component parts. @@ -143,11 +144,12 @@ public XsdDuration(string s) : this(s, DurationType.Duration) public XsdDuration(string s, DurationType durationType) { XsdDuration result; - Exception exception = TryParse(s, durationType, out result); + Exception? exception = TryParse(s, durationType, out result); if (exception != null) { throw exception; } + _years = result.Years; _months = result.Months; _days = result.Days; @@ -159,6 +161,7 @@ public XsdDuration(string s, DurationType durationType) { _nanoseconds |= NegativeBit; } + return; } @@ -242,22 +245,23 @@ public TimeSpan ToTimeSpan() public TimeSpan ToTimeSpan(DurationType durationType) { TimeSpan result; - Exception exception = TryToTimeSpan(durationType, out result); + Exception? exception = TryToTimeSpan(durationType, out result); if (exception != null) { throw exception; } + return result; } - internal Exception TryToTimeSpan(out TimeSpan result) + internal Exception? TryToTimeSpan(out TimeSpan result) { return TryToTimeSpan(DurationType.Duration, out result); } - internal Exception TryToTimeSpan(DurationType durationType, out TimeSpan result) + internal Exception? TryToTimeSpan(DurationType durationType, out TimeSpan result) { - Exception exception = null; + Exception? exception = null; ulong ticks = 0; // Throw error if result cannot fit into a long @@ -426,14 +430,14 @@ internal string ToString(DurationType durationType) return sb.ToString(); } - internal static Exception TryParse(string s, out XsdDuration result) + internal static Exception? TryParse(string s, out XsdDuration result) { return TryParse(s, DurationType.Duration, out result); } - internal static Exception TryParse(string s, DurationType durationType, out XsdDuration result) + internal static Exception? TryParse(string s, DurationType durationType, out XsdDuration result) { - string errorCode; + string? errorCode; int length; int value, pos, numDigits; Parts parts = Parts.HasNone; @@ -605,6 +609,7 @@ internal static Exception TryParse(string s, DurationType durationType, out XsdD if ((parts & ~(XsdDuration.Parts.HasYears | XsdDuration.Parts.HasMonths)) != 0) goto InvalidFormat; } + return null; InvalidFormat: @@ -619,7 +624,7 @@ internal static Exception TryParse(string s, DurationType durationType, out XsdD /// cntDigits. The integer is returned (0 if no digits). If the digits cannot fit into an Int32: /// 1. If eatDigits is true, then additional digits will be silently discarded (don't count towards numDigits) /// 2. If eatDigits is false, an overflow exception is thrown - private static string TryParseDigits(string s, ref int offset, bool eatDigits, out int result, out int numDigits) + private static string? TryParseDigits(string s, ref int offset, bool eatDigits, out int result, out int numDigits) { int offsetStart = offset; int offsetEnd = s.Length; From ad57eff7e6bf1cec6958ddbfe7bbd4a3528963b9 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Thu, 2 Apr 2020 22:02:40 -0700 Subject: [PATCH 017/420] Provide opt-in for converters to handle null --- .../System.Text.Json/ref/System.Text.Json.cs | 2 + .../Collection/DictionaryDefaultConverter.cs | 2 +- .../Collection/IEnumerableDefaultConverter.cs | 2 +- .../Converters/Value/NullableConverter.cs | 4 + .../Text/Json/Serialization/JsonConverter.cs | 6 - .../Json/Serialization/JsonConverterOfT.cs | 48 ++- .../Serialization/JsonParameterInfoOfT.cs | 9 +- .../Json/Serialization/JsonPropertyInfoOfT.cs | 26 +- .../System.Text.Json/tests/JsonTestHelper.cs | 3 + .../ConstructorTests.ParameterMatching.cs | 18 +- .../CustomConverterTests.HandleNull.cs | 406 ++++++++++++++++++ .../TestClasses/TestClasses.Constructor.cs | 7 + .../tests/System.Text.Json.Tests.csproj | 3 +- 13 files changed, 503 insertions(+), 33 deletions(-) create mode 100644 src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index 7b5d7a1dfe77f..c4c74cf1a43a2 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -489,6 +489,8 @@ public abstract partial class JsonConverter : System.Text.Json.Serialization. { protected internal JsonConverter() { } public override bool CanConvert(System.Type typeToConvert) { throw null; } + public virtual bool HandleNull { get { throw null; } } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] public abstract T Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options); public abstract void Write(System.Text.Json.Utf8JsonWriter writer, T value, System.Text.Json.JsonSerializerOptions options); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs index 3548737459413..2b65d740fd280 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs @@ -103,7 +103,7 @@ protected static JsonConverter GetValueConverter(ref WriteStack state) // Read the value and add. reader.ReadWithVerify(); - TValue element = elementConverter.Read(ref reader, typeof(TValue), options); + TValue element = elementConverter.Read(ref reader, typeof(TValue), options)!; Add(element, options, ref state); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs index dad477364d6d7..fd55e9aded820 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs @@ -66,7 +66,7 @@ protected static JsonConverter GetElementConverter(ref WriteStack stat } // Obtain the CLR value from the JSON and apply to the object. - TElement element = elementConverter.Read(ref reader, elementConverter.TypeToConvert, options); + TElement element = elementConverter.Read(ref reader, elementConverter.TypeToConvert, options)!; Add(element, ref state); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/NullableConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/NullableConverter.cs index 000fcd7d000aa..1fb68dfcdac30 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/NullableConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/NullableConverter.cs @@ -17,6 +17,8 @@ public NullableConverter(JsonConverter converter) public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + // We do not check _converter.HandleNull, as the underlying struct cannot be null. + // A custom converter for some type T? can handle null. if (reader.TokenType == JsonTokenType.Null) { return null; @@ -30,6 +32,8 @@ public override void Write(Utf8JsonWriter writer, T? value, JsonSerializerOption { if (!value.HasValue) { + // We do not check _converter.HandleNull, as the underlying struct cannot be null. + // A custom converter for some type T? can handle null. writer.WriteNullValue(); } else diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs index 9b7a706678c36..65045d4c84f8e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs @@ -40,12 +40,6 @@ public abstract partial class JsonConverter internal abstract Type? ElementType { get; } - /// - /// Cached value of ShouldHandleNullValue. It is cached since the converter should never - /// change the value depending on state and because it may contain non-trival logic. - /// - internal bool HandleNullValue { get; set; } - /// /// Cached value of TypeToConvert.IsValueType, which is an expensive call. /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs index 158094fd661eb..e4978f9d940d0 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs @@ -22,7 +22,7 @@ protected internal JsonConverter() // In the future, this will be check for !IsSealed (and excluding value types). CanBePolymorphic = TypeToConvert == typeof(object); IsValueType = TypeToConvert.IsValueType; - HandleNullValue = ShouldHandleNullValue; + HandleNull = IsValueType; IsInternalConverter = GetType().Assembly == typeof(JsonConverter).Assembly; CanUseDirectReadOrWrite = !CanBePolymorphic && IsInternalConverter && ClassType == ClassType.Value; } @@ -54,10 +54,14 @@ internal override sealed JsonParameterInfo CreateJsonParameterInfo() internal override Type? ElementType => null; - // Allow a converter that can't be null to return a null value representation, such as JsonElement or Nullable<>. - // In other cases, this will likely cause an JsonException in the converter. - // Do not call this directly; it is cached in HandleNullValue. - internal virtual bool ShouldHandleNullValue => IsValueType; + /// + /// Indicates whether should be passed to the converter on serialization, + /// and whether should be passed on deserialization. + /// + /// + /// The default value is for converters for value types, and for converters for reference types. + /// + public virtual bool HandleNull { get; } /// /// Is the converter built-in. @@ -81,7 +85,7 @@ internal virtual bool OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerO // Provide a default implementation for value converters. internal virtual bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, [MaybeNullWhen(false)] out T value) { - value = Read(ref reader, typeToConvert, options); + value = Read(ref reader, typeToConvert, options)!; return true; } @@ -95,6 +99,7 @@ internal virtual bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, J /// The being converted. /// The being used. /// The value that was converted. + [return: MaybeNull] public abstract T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options); internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, out T value) @@ -105,7 +110,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali Debug.Assert(!state.IsContinuation); // For perf and converter simplicity, handle null here instead of forwarding to the converter. - if (reader.TokenType == JsonTokenType.Null && !HandleNullValue) + if (reader.TokenType == JsonTokenType.Null && !HandleNull) { value = default!; return true; @@ -115,7 +120,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali // For performance, only perform validation on internal converters on debug builds. if (IsInternalConverter) { - value = Read(ref reader, typeToConvert, options); + value = Read(ref reader, typeToConvert, options)!; } else #endif @@ -124,7 +129,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali int originalPropertyDepth = reader.CurrentDepth; long originalPropertyBytesConsumed = reader.BytesConsumed; - value = Read(ref reader, typeToConvert, options); + value = Read(ref reader, typeToConvert, options)!; VerifyRead( originalPropertyTokenType, originalPropertyDepth, @@ -147,7 +152,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali // For performance, only perform validation on internal converters on debug builds. if (IsInternalConverter) { - if (reader.TokenType == JsonTokenType.Null && !HandleNullValue && !wasContinuation) + if (reader.TokenType == JsonTokenType.Null && !HandleNull && !wasContinuation) { // For perf and converter simplicity, handle null here instead of forwarding to the converter. value = default!; @@ -164,7 +169,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali if (!wasContinuation) { // For perf and converter simplicity, handle null here instead of forwarding to the converter. - if (reader.TokenType == JsonTokenType.Null && !HandleNullValue) + if (reader.TokenType == JsonTokenType.Null && !HandleNull) { value = default!; state.Pop(true); @@ -178,7 +183,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali state.Current.OriginalDepth = reader.CurrentDepth; } - success = OnTryRead(ref reader, typeToConvert, options, ref state, out value); + success = OnTryRead(ref reader, typeToConvert, options, ref state, out value!); if (success) { if (state.IsContinuation) @@ -213,7 +218,20 @@ internal bool TryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions opt { if (value == null) { - writer.WriteNullValue(); + if (!HandleNull) + { + writer.WriteNullValue(); + } + else + { + Debug.Assert(ClassType == ClassType.Value); + Debug.Assert(!state.IsContinuation); + + int originalPropertyDepth = writer.CurrentDepth; + Write(writer, value, options); + VerifyWrite(originalPropertyDepth, writer); + } + return true; } @@ -238,9 +256,9 @@ internal bool TryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions opt } else { - // We do not pass null values to converters unless HandleNullValue is true. Null values for properties were + // We do not pass null values to converters unless HandleNull is true. Null values for properties were // already handled in GetMemberAndWriteJson() so we don't need to check for IgnoreNullValues here. - if (value == null && !HandleNullValue) + if (value == null && !HandleNull) { writer.WriteNullValue(); return true; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfoOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfoOfT.cs index 52a68effdc3aa..89447d153cebd 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfoOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfoOfT.cs @@ -53,9 +53,9 @@ public override bool ReadJson(ref ReadStack state, ref Utf8JsonReader reader, ou bool success; bool isNullToken = reader.TokenType == JsonTokenType.Null; - if (isNullToken && !_converter.HandleNullValue && !state.IsContinuation) + if (isNullToken && !_converter.HandleNull && !state.IsContinuation) { - // Don't have to check for IgnoreNullValue option here because we set the default value (likely null) regardless + // Don't have to check for IgnoreNullValue option here because we set the default value regardless. value = DefaultValue; return true; } @@ -82,8 +82,9 @@ public bool ReadJsonTyped(ref ReadStack state, ref Utf8JsonReader reader, out T bool success; bool isNullToken = reader.TokenType == JsonTokenType.Null; - if (isNullToken && !_converter.HandleNullValue && !state.IsContinuation) + if (isNullToken && !_converter.HandleNull && !state.IsContinuation) { + // Don't have to check for IgnoreNullValue option here because we set the default value regardless. value = TypedDefaultValue; return true; } @@ -92,7 +93,7 @@ public bool ReadJsonTyped(ref ReadStack state, ref Utf8JsonReader reader, out T // Optimize for internal converters by avoiding the extra call to TryRead. if (_converter.CanUseDirectReadOrWrite) { - value = _converter.Read(ref reader, _runtimePropertyType, Options); + value = _converter.Read(ref reader, _runtimePropertyType, Options)!; return true; } else diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs index 863590f3b5f2b..bacb5e19352a8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs @@ -102,7 +102,25 @@ public override bool GetMemberAndWriteJson(object obj, ref WriteStack state, Utf { if (!IgnoreNullValues) { - writer.WriteNull(EscapedName.Value); + if (!Converter.HandleNull) + { + writer.WriteNull(EscapedName.Value); + } + else + { + if (state.Current.PropertyState < StackFramePropertyState.Name) + { + state.Current.PropertyState = StackFramePropertyState.Name; + writer.WritePropertyName(EscapedName.Value); + } + + int originalDepth = writer.CurrentDepth; + Converter.Write(writer, value, Options); + if (originalDepth != writer.CurrentDepth) + { + ThrowHelper.ThrowJsonException_SerializationConverterWrite(Converter); + } + } } success = true; @@ -142,7 +160,7 @@ public override bool ReadJsonAndSetMember(object obj, ref ReadStack state, ref U { bool success; bool isNullToken = reader.TokenType == JsonTokenType.Null; - if (isNullToken && !Converter.HandleNullValue && !state.IsContinuation) + if (isNullToken && !Converter.HandleNull && !state.IsContinuation) { if (!IgnoreNullValues) { @@ -158,7 +176,7 @@ public override bool ReadJsonAndSetMember(object obj, ref ReadStack state, ref U if (Converter.CanUseDirectReadOrWrite) { // Optimize for internal converters by avoiding the extra call to TryRead. - T fastvalue = Converter.Read(ref reader, RuntimePropertyType!, Options); + T fastvalue = Converter.Read(ref reader, RuntimePropertyType!, Options)!; if (!IgnoreNullValues || (!isNullToken && fastvalue != null)) { Set!(obj, fastvalue); @@ -186,7 +204,7 @@ public override bool ReadJsonAsObject(ref ReadStack state, ref Utf8JsonReader re { bool success; bool isNullToken = reader.TokenType == JsonTokenType.Null; - if (isNullToken && !Converter.HandleNullValue && !state.IsContinuation) + if (isNullToken && !Converter.HandleNull && !state.IsContinuation) { value = default(T)!; success = true; diff --git a/src/libraries/System.Text.Json/tests/JsonTestHelper.cs b/src/libraries/System.Text.Json/tests/JsonTestHelper.cs index b83fcbe3f1a92..960e613502e5c 100644 --- a/src/libraries/System.Text.Json/tests/JsonTestHelper.cs +++ b/src/libraries/System.Text.Json/tests/JsonTestHelper.cs @@ -867,6 +867,9 @@ private static void AssertJsonEqual(JsonElement expected, JsonElement actual) case JsonValueKind.String: Assert.Equal(expected.GetString(), actual.GetString()); break; + case JsonValueKind.Number: + Assert.Equal(expected.GetRawText(), actual.GetRawText()); + break; default: throw new NotImplementedException(); } diff --git a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.ParameterMatching.cs b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.ParameterMatching.cs index f6979cf22c967..a69c9ad6b9a58 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.ParameterMatching.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ConstructorTests/ConstructorTests.ParameterMatching.cs @@ -339,19 +339,35 @@ public void PropertiesNotSet_WhenJSON_MapsToConstructorParameters() [Fact] public void IgnoreNullValues_DontSetNull_ToConstructorArguments_ThatCantBeNull() { - // Throw JsonException when null applied to types that can't be null. + // Throw JsonException when null applied to types that can't be null. Behavior should align with properties deserialized with setters. + Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}")); + Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}")); + Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null}")); + Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null}")); + Assert.Throws(() => Serializer.Deserialize(@"{""Int"":null}")); + Assert.Throws(() => Serializer.Deserialize(@"{""Int"":null}")); + Assert.Throws(() => Serializer.Deserialize(@"{""ImmutableArray"":null}")); + Assert.Throws(() => Serializer.Deserialize(@"{""ImmutableArray"":null}")); // Throw even when IgnoreNullValues is true for symmetry with property deserialization, // until https://github.com/dotnet/runtime/issues/30795 is addressed. + var options = new JsonSerializerOptions { IgnoreNullValues = true }; Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); + Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); + Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null}", options)); + Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); + Assert.Throws(() => Serializer.Deserialize(@"{""Int"":null}", options)); + Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); + Assert.Throws(() => Serializer.Deserialize(@"{""ImmutableArray"":null}", options)); + Assert.Throws(() => Serializer.Deserialize(@"{""Point3DStruct"":null,""Int"":null,""ImmutableArray"":null}", options)); } [Fact] diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs new file mode 100644 index 0000000000000..e81f47ac95658 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs @@ -0,0 +1,406 @@ +// 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. + +using System.Text.Json.Tests; +using Xunit; + +namespace System.Text.Json.Serialization.Tests +{ + public static partial class CustomConverterTests + { + [Fact] + public static void ValueTypeConverter_NoOverride() + { + // Baseline + Assert.Throws(() => JsonSerializer.Deserialize("null")); + + // Per null handling default value for value types (true), converter handles null. + var options = new JsonSerializerOptions(); + options.Converters.Add(new Int32NullConverter_SpecialCaseNull()); + + Assert.Equal(-1, JsonSerializer.Deserialize("null", options)); + } + + private class Int32NullConverter_SpecialCaseNull : JsonConverter + { + public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + { + return -1; + } + + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options) + { + throw new NotImplementedException(); + } + } + + [Fact] + public static void ValueTypeConverter_OptOut() + { + // Per null handling opt-out, serializer handles null. + var options = new JsonSerializerOptions(); + options.Converters.Add(new Int32NullConverter_OptOut()); + + Assert.Equal(0, JsonSerializer.Deserialize("null", options)); + } + + private class Int32NullConverter_OptOut : Int32NullConverter_SpecialCaseNull + { + public override bool HandleNull => false; + } + + [Fact] + public static void ValueTypeConverter_NullOptIn() + { + // Per null handling opt-in, converter handles null. + var options = new JsonSerializerOptions(); + options.Converters.Add(new Int32NullConverter_NullOptIn()); + + Assert.Equal(-1, JsonSerializer.Deserialize("null", options)); + } + + private class Int32NullConverter_NullOptIn : Int32NullConverter_SpecialCaseNull + { + public override bool HandleNull => true; + } + + [Fact] + public static void ComplexValueTypeConverter_NoOverride() + { + // Baseline + Assert.Throws(() => JsonSerializer.Deserialize("null")); + + var options = new JsonSerializerOptions(); + options.Converters.Add(new PointStructConverter_SpecialCaseNull()); + + // Per null handling default value for value types (true), converter handles null. + var obj = JsonSerializer.Deserialize("null", options); + Assert.Equal(-1, obj.X); + Assert.Equal(-1, obj.Y); + } + + private class PointStructConverter_SpecialCaseNull : JsonConverter + { + public override Point_2D_Struct Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + { + return new Point_2D_Struct(-1, -1); + } + + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, Point_2D_Struct value, JsonSerializerOptions options) + { + throw new NotImplementedException(); + } + } + + [Fact] + public static void ComplexValueTypeConverter_OptOut() + { + // Per null handling opt-out, serializer handles null. + var options = new JsonSerializerOptions(); + options.Converters.Add(new PointStructConverter_OptOut()); + + var obj = JsonSerializer.Deserialize("null", options); + Assert.Equal(0, obj.X); + Assert.Equal(0, obj.Y); + } + + private class PointStructConverter_OptOut : PointStructConverter_SpecialCaseNull + { + public override bool HandleNull => false; + } + + [Fact] + public static void ComplexValueTypeConverter_NullOptIn() + { + // Baseline + Assert.Throws(() => JsonSerializer.Deserialize("null")); + + // Per null handling opt-in, converter handles null. + var options = new JsonSerializerOptions(); + options.Converters.Add(new PointStructConverter_NullOptIn()); + + var obj = JsonSerializer.Deserialize("null", options); + Assert.Equal(-1, obj.X); + Assert.Equal(-1, obj.Y); + } + + private class PointStructConverter_NullOptIn : PointStructConverter_SpecialCaseNull + { + public override bool HandleNull => true; + } + + [Fact] + public static void NullableValueTypeConverter_NoOverride() + { + // Baseline + int? val = JsonSerializer.Deserialize("null"); + Assert.Null(val); + Assert.Equal("null", JsonSerializer.Serialize(val)); + + // Per null handling default value for value types (true), converter handles null. + var options = new JsonSerializerOptions(); + options.Converters.Add(new NullableInt32NullConverter_SpecialCaseNull()); + + val = JsonSerializer.Deserialize("null", options); + Assert.Equal(-1, val); + + val = null; + Assert.Equal("-1", JsonSerializer.Serialize(val, options)); + } + + private class NullableInt32NullConverter_SpecialCaseNull : JsonConverter + { + public override int? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + { + return -1; + } + + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, int? value, JsonSerializerOptions options) + { + if (!value.HasValue) + { + writer.WriteNumberValue(-1); + return; + } + + throw new NotSupportedException(); + } + } + + [Fact] + public static void NullableValueTypeConverter_OptOut() + { + // Baseline + int? val = JsonSerializer.Deserialize("null"); + Assert.Null(val); + Assert.Equal("null", JsonSerializer.Serialize(val)); + + // Per null handling opt-out, serializer handles null. + var options = new JsonSerializerOptions(); + options.Converters.Add(new NullableInt32NullConverter_NullOptOut()); + + val = JsonSerializer.Deserialize("null", options); + Assert.Null(val); + Assert.Equal("null", JsonSerializer.Serialize(val, options)); + } + + private class NullableInt32NullConverter_NullOptOut : NullableInt32NullConverter_SpecialCaseNull + { + public override bool HandleNull => false; + } + + [Fact] + public static void ReferenceTypeConverter_NoOverride() + { + // Baseline + Uri val = JsonSerializer.Deserialize("null"); + Assert.Null(val); + Assert.Equal("null", JsonSerializer.Serialize(val)); + + // Per null handling default value for reference types (false), serializer handles null. + var options = new JsonSerializerOptions(); + options.Converters.Add(new Int32NullConverter_SpecialCaseNull()); + + val = JsonSerializer.Deserialize("null", options); + Assert.Null(val); + Assert.Equal("null", JsonSerializer.Serialize(val, options)); + } + + private class UriNullConverter_SpecialCaseNull : JsonConverter + { + public override Uri Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + { + return new Uri("https://default"); + } + + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, Uri value, JsonSerializerOptions options) + { + if (value == null) + { + writer.WriteStringValue("https://default"); + return; + } + + throw new NotSupportedException(); + } + } + + [Fact] + public static void ReferenceTypeConverter_OptOut() + { + // Per null handling opt-out, serializer handles null. + var options = new JsonSerializerOptions(); + options.Converters.Add(new UriNullConverter_OptOut()); + + Uri val = JsonSerializer.Deserialize("null", options); + Assert.Null(val); + Assert.Equal("null", JsonSerializer.Serialize(val, options)); + } + + private class UriNullConverter_OptOut : UriNullConverter_SpecialCaseNull + { + public override bool HandleNull => false; + } + + [Fact] + public static void ReferenceTypeConverter_NullOptIn() + { + // Per null handling opt-in, converter handles null. + var options = new JsonSerializerOptions(); + options.Converters.Add(new UriNullConverter_NullOptIn()); + + Uri val = JsonSerializer.Deserialize("null", options); + Assert.Equal(new Uri("https://default"), val); + + val = null; + Assert.Equal(@"""https://default""", JsonSerializer.Serialize(val, options)); + } + + private class UriNullConverter_NullOptIn : UriNullConverter_SpecialCaseNull + { + public override bool HandleNull => true; + } + + [Fact] + public static void ComplexReferenceTypeConverter_NoOverride() + { + // Baseline + Point_2D obj = JsonSerializer.Deserialize("null"); + Assert.Null(obj); + Assert.Equal("null", JsonSerializer.Serialize(obj)); + + // Per null handling default value for reference types (false), serializer handles null. + var options = new JsonSerializerOptions(); + options.Converters.Add(new PointClassConverter_SpecialCaseNull()); + + obj = JsonSerializer.Deserialize("null", options); + Assert.Null(obj); + Assert.Equal("null", JsonSerializer.Serialize(obj)); + } + + private class PointClassConverter_SpecialCaseNull : JsonConverter + { + public override Point_2D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + { + return new Point_2D(-1, -1); + } + + throw new JsonException(); + } + + public override void Write(Utf8JsonWriter writer, Point_2D value, JsonSerializerOptions options) + { + if (value == null) + { + writer.WriteStartObject(); + writer.WriteNumber("X", -1); + writer.WriteNumber("Y", -1); + writer.WriteEndObject(); + return; + } + + throw new JsonException(); + } + } + + [Fact] + public static void ComplexReferenceTypeConverter_NullOptIn() + { + // Per null handling opt-in, converter handles null. + var options = new JsonSerializerOptions(); + options.Converters.Add(new PointClassConverter_NullOptIn()); + + Point_2D obj = JsonSerializer.Deserialize("null", options); + Assert.Equal(-1, obj.X); + Assert.Equal(-1, obj.Y); + + obj = null; + JsonTestHelper.AssertJsonEqual(@"{""X"":-1,""Y"":-1}", JsonSerializer.Serialize(obj, options)); + } + + private class PointClassConverter_NullOptIn : PointClassConverter_SpecialCaseNull + { + public override bool HandleNull => true; + } + + [Fact] + public static void ConverterNotCalled_IgnoreNullValues() + { + var options = new JsonSerializerOptions(); + options.Converters.Add(new UriNullConverter_NullOptIn()); + + // Converter is not called. + ClassWithIgnoredUri obj = JsonSerializer.Deserialize(@"{""MyUri"":null}", options); + Assert.Equal(new Uri("https://microsoft.com"), obj.MyUri); + + obj.MyUri = null; + Assert.Equal("{}", JsonSerializer.Serialize(obj, options)); + } + + private class ClassWithIgnoredUri + { + [JsonIgnore(Condition = JsonIgnoreCondition.WhenNull)] + public Uri MyUri { get; set; } = new Uri("https://microsoft.com"); + } + + [Fact] + public static void ConverterWritesBadAmount() + { + var options = new JsonSerializerOptions(); + options.Converters.Add(new BadUriConverter()); + options.Converters.Add(new BadObjectConverter()); + + Assert.Throws(() => JsonSerializer.Serialize(new ClassWithIgnoredUri(), options)); + Assert.Throws(() => JsonSerializer.Serialize(new StructWithObject(), options)); + } + + private class BadUriConverter : UriNullConverter_NullOptIn + { + public override void Write(Utf8JsonWriter writer, Uri value, JsonSerializerOptions options) { } + } + + private class BadObjectConverter : JsonConverter + { + public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + throw new NotImplementedException(); + } + + public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) + { + writer.WriteNullValue(); + writer.WritePropertyName("hello"); + } + + public override bool HandleNull => true; + } + + private class StructWithObject + { + public object MyObj { get; set; } + } + } +} diff --git a/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.Constructor.cs b/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.Constructor.cs index 8fce473d62993..1d02e33d7f6a0 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.Constructor.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.Constructor.cs @@ -917,6 +917,13 @@ public NullArgTester(Point_3D_Struct point3DStruct, ImmutableArray immutabl } } + public class NullArgTester_Mutable + { + public Point_3D_Struct Point3DStruct { get; set; } + public ImmutableArray ImmutableArray { get; set; } + public int Int { get; set; } + } + public class ClassWithConstructor_SimpleAndComplexParameters : ITestClassWithParameterizedCtor { public byte MyByte { get; } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj index 881b2d8450fe1..cebf7e44807f9 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);$(NetFrameworkCurrent) true @@ -70,6 +70,7 @@ + From 541b4f6e63bfa7342c8238a335fca713c322e053 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Tue, 5 May 2020 09:12:45 -0700 Subject: [PATCH 018/420] Fix test failing in release mode --- .../Text/Json/Serialization/JsonConverterOfT.cs | 10 +++------- .../CustomConverterTests.HandleNull.cs | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs index e4978f9d940d0..a7ca76e0cbfb6 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs @@ -254,15 +254,12 @@ internal bool TryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions opt } } } - else + else if (value == null && !HandleNull) { // We do not pass null values to converters unless HandleNull is true. Null values for properties were // already handled in GetMemberAndWriteJson() so we don't need to check for IgnoreNullValues here. - if (value == null && !HandleNull) - { - writer.WriteNullValue(); - return true; - } + writer.WriteNullValue(); + return true; } if (ClassType == ClassType.Value) @@ -273,7 +270,6 @@ internal bool TryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions opt Write(writer, value, options); VerifyWrite(originalPropertyDepth, writer); - return true; } diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs index e81f47ac95658..6a8a62db2628c 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Text.Json.Tests; +using System.Buffers; using Xunit; namespace System.Text.Json.Serialization.Tests @@ -373,8 +373,11 @@ public static void ConverterWritesBadAmount() options.Converters.Add(new BadUriConverter()); options.Converters.Add(new BadObjectConverter()); - Assert.Throws(() => JsonSerializer.Serialize(new ClassWithIgnoredUri(), options)); - Assert.Throws(() => JsonSerializer.Serialize(new StructWithObject(), options)); + var writerOptions = new JsonWriterOptions { SkipValidation = false }; + using Utf8JsonWriter writer = new Utf8JsonWriter(new ArrayBufferWriter(), writerOptions); + + Assert.Throws(() => JsonSerializer.Serialize(writer, new ClassWithUri(), options)); + Assert.Throws(() => JsonSerializer.Serialize(writer, new StructWithObject(), options)); } private class BadUriConverter : UriNullConverter_NullOptIn @@ -398,6 +401,12 @@ public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOp public override bool HandleNull => true; } + private class ClassWithUri + { + public Uri MyUri { get; set; } + } + + private class StructWithObject { public object MyObj { get; set; } From 23f40ac8a7cf2068860de18a4d16827addad2254 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Tue, 5 May 2020 12:39:14 -0700 Subject: [PATCH 019/420] Add more tests --- .../Json/Serialization/JsonConverterOfT.cs | 48 ++++-------- .../CustomConverterTests.HandleNull.cs | 77 ++++++++++++++++++- 2 files changed, 88 insertions(+), 37 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs index a7ca76e0cbfb6..80ff653510068 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs @@ -313,48 +313,30 @@ internal bool TryWriteDataExtensionProperty(Utf8JsonWriter writer, T value, Json ThrowHelper.ThrowJsonException_SerializerCycleDetected(options.EffectiveMaxDepth); } - bool success; JsonDictionaryConverter dictionaryConverter = (JsonDictionaryConverter)this; - if (ClassType == ClassType.Value) - { - Debug.Assert(!state.IsContinuation); - - int originalPropertyDepth = writer.CurrentDepth; + bool isContinuation = state.IsContinuation; + bool success; - // Ignore the naming policy for extension data. - state.Current.IgnoreDictionaryKeyPolicy = true; + state.Push(); - success = dictionaryConverter.OnWriteResume(writer, value, options, ref state); - if (success) - { - VerifyWrite(originalPropertyDepth, writer); - } - } - else + if (!isContinuation) { - bool isContinuation = state.IsContinuation; - - state.Push(); - - if (!isContinuation) - { - Debug.Assert(state.Current.OriginalDepth == 0); - state.Current.OriginalDepth = writer.CurrentDepth; - } - - // Ignore the naming policy for extension data. - state.Current.IgnoreDictionaryKeyPolicy = true; + Debug.Assert(state.Current.OriginalDepth == 0); + state.Current.OriginalDepth = writer.CurrentDepth; + } - success = dictionaryConverter.OnWriteResume(writer, value, options, ref state); - if (success) - { - VerifyWrite(state.Current.OriginalDepth, writer); - } + // Ignore the naming policy for extension data. + state.Current.IgnoreDictionaryKeyPolicy = true; - state.Pop(success); + success = dictionaryConverter.OnWriteResume(writer, value, options, ref state); + if (success) + { + VerifyWrite(state.Current.OriginalDepth, writer); } + state.Pop(success); + return success; } diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs index 6a8a62db2628c..6ff06676cc79d 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs @@ -3,6 +3,8 @@ // See the LICENSE file in the project root for more information. using System.Buffers; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Xunit; namespace System.Text.Json.Serialization.Tests @@ -373,11 +375,17 @@ public static void ConverterWritesBadAmount() options.Converters.Add(new BadUriConverter()); options.Converters.Add(new BadObjectConverter()); + // Using serializer overload in Release mode uses a writer with SkipValidation = true. var writerOptions = new JsonWriterOptions { SkipValidation = false }; - using Utf8JsonWriter writer = new Utf8JsonWriter(new ArrayBufferWriter(), writerOptions); + using (Utf8JsonWriter writer = new Utf8JsonWriter(new ArrayBufferWriter(), writerOptions)) + { + Assert.Throws(() => JsonSerializer.Serialize(writer, new ClassWithUri(), options)); + } - Assert.Throws(() => JsonSerializer.Serialize(writer, new ClassWithUri(), options)); - Assert.Throws(() => JsonSerializer.Serialize(writer, new StructWithObject(), options)); + using (Utf8JsonWriter writer = new Utf8JsonWriter(new ArrayBufferWriter(), writerOptions)) + { + Assert.Throws(() => JsonSerializer.Serialize(new StructWithObject(), options)); + } } private class BadUriConverter : UriNullConverter_NullOptIn @@ -394,8 +402,9 @@ public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonS public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) { - writer.WriteNullValue(); + writer.WriteStartObject(); writer.WritePropertyName("hello"); + writer.WriteNullValue(); } public override bool HandleNull => true; @@ -411,5 +420,65 @@ private class StructWithObject { public object MyObj { get; set; } } + + [Fact] + public static void ObjectAsRootValue() + { + var options = new JsonSerializerOptions(); + options.Converters.Add(new ObjectConverter()); + + object obj = null; + Assert.Equal(@"""NullObject""", JsonSerializer.Serialize(obj, options)); + Assert.Equal("NullObject", JsonSerializer.Deserialize("null", options)); + + options = new JsonSerializerOptions(); + options.Converters.Add(new BadObjectConverter()); + Assert.Throws(() => JsonSerializer.Serialize(obj, options)); + } + + [Fact] + public static void ObjectAsCollectionElement() + { + var options = new JsonSerializerOptions(); + options.Converters.Add(new ObjectConverter()); + + List list = new List { null }; + Assert.Equal(@"[""NullObject""]", JsonSerializer.Serialize(list, options)); + + list = JsonSerializer.Deserialize>("[null]", options); + Assert.Equal("NullObject", list[0]); + + options = new JsonSerializerOptions(); + options.Converters.Add(new BadObjectConverter()); + + list[0] = null; + Assert.Throws(() => JsonSerializer.Serialize(list, options)); + } + + public class ObjectConverter : JsonConverter + { + public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + { + return "NullObject"; + } + + throw new NotSupportedException(); + } + + public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) + { + if (value == null) + { + writer.WriteStringValue("NullObject"); + return; + } + + throw new NotSupportedException(); + } + + public override bool HandleNull => true; + } } } From b0329b19adf831cf81e9488c3de3547472784b2f Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Tue, 5 May 2020 23:59:10 -0700 Subject: [PATCH 020/420] Fix nullability annotations --- .../Converters/Collection/ArrayConverter.cs | 5 +++-- .../Collection/ConcurrentQueueOfTConverter.cs | 5 +++-- .../Collection/ConcurrentStackOfTConverter.cs | 5 +++-- .../Collection/DictionaryDefaultConverter.cs | 4 ++-- .../DictionaryOfStringTValueConverter.cs | 6 +++--- .../Collection/ICollectionOfTConverter.cs | 5 +++-- .../Collection/IDictionaryConverter.cs | 1 + .../IDictionaryOfStringTValueConverter.cs | 5 +++-- .../Collection/IEnumerableDefaultConverter.cs | 2 +- .../Collection/IEnumerableOfTConverter.cs | 5 +++-- .../Converters/Collection/IListOfTConverter.cs | 5 +++-- ...IReadOnlyDictionaryOfStringTValueConverter.cs | 5 +++-- .../Converters/Collection/ISetOfTConverter.cs | 5 +++-- ...ImmutableDictionaryOfStringTValueConverter.cs | 5 +++-- .../ImmutableEnumerableOfTConverter.cs | 5 +++-- .../Converters/Collection/ListOfTConverter.cs | 5 +++-- .../Converters/Collection/QueueOfTConverter.cs | 5 +++-- .../Converters/Collection/StackOfTConverter.cs | 5 +++-- .../Converters/Value/KeyValuePairConverter.cs | 2 +- .../Serialization/JsonConverterOfT.ReadCore.cs | 3 +++ .../Text/Json/Serialization/JsonConverterOfT.cs | 16 ++++++++-------- .../Json/Serialization/JsonPropertyInfoOfT.cs | 2 +- .../Serialization/JsonResumableConverterOfT.cs | 7 +++++-- .../Serialization/JsonSerializer.Read.Helpers.cs | 3 +++ .../Serialization/JsonSerializer.Read.String.cs | 3 ++- .../JsonSerializer.Read.Utf8JsonReader.cs | 2 ++ .../Json/Serialization/JsonValueConverterOfT.cs | 7 +++++-- .../CollectionTests.Generic.Read.cs | 8 ++++++++ 28 files changed, 87 insertions(+), 49 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ArrayConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ArrayConverter.cs index 70d0c611dd5ba..c7e576f6e02f8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ArrayConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ArrayConverter.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -16,9 +17,9 @@ internal sealed class ArrayConverter { internal override bool CanHaveIdMetadata => false; - protected override void Add(TElement value, ref ReadStack state) + protected override void Add([AllowNull] TElement value, ref ReadStack state) { - ((List)state.Current.ReturnValue!).Add(value); + ((List)state.Current.ReturnValue!).Add(value!); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentQueueOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentQueueOfTConverter.cs index aa54f0956e41e..71c9a7c69cb9b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentQueueOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentQueueOfTConverter.cs @@ -4,6 +4,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -11,9 +12,9 @@ internal sealed class ConcurrentQueueOfTConverter : IEnumerableDefaultConverter where TCollection : ConcurrentQueue { - protected override void Add(TElement value, ref ReadStack state) + protected override void Add([AllowNull] TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Enqueue(value); + ((TCollection)state.Current.ReturnValue!).Enqueue(value!); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentStackOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentStackOfTConverter.cs index 9ba01b68df2dd..e1c3855da8c04 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentStackOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentStackOfTConverter.cs @@ -4,6 +4,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -11,9 +12,9 @@ internal sealed class ConcurrentStackOfTConverter : IEnumerableDefaultConverter where TCollection : ConcurrentStack { - protected override void Add(TElement value, ref ReadStack state) + protected override void Add([AllowNull] TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Push(value); + ((TCollection)state.Current.ReturnValue!).Push(value!); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs index 2b65d740fd280..b45db09122256 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs @@ -16,7 +16,7 @@ internal abstract class DictionaryDefaultConverter /// /// When overridden, adds the value to the collection. /// - protected abstract void Add(TValue value, JsonSerializerOptions options, ref ReadStack state); + protected abstract void Add([AllowNull] TValue value, JsonSerializerOptions options, ref ReadStack state); /// /// When overridden, converts the temporary collection held in state.Current.ReturnValue to the final collection. @@ -103,7 +103,7 @@ protected static JsonConverter GetValueConverter(ref WriteStack state) // Read the value and add. reader.ReadWithVerify(); - TValue element = elementConverter.Read(ref reader, typeof(TValue), options)!; + TValue element = elementConverter.Read(ref reader, typeof(TValue), options); Add(element, options, ref state); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfStringTValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfStringTValueConverter.cs index 79aa533d14664..4633bb0b0b37d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfStringTValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfStringTValueConverter.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -15,10 +15,10 @@ internal sealed class DictionaryOfStringTValueConverter : DictionaryDefaultConverter where TCollection : Dictionary { - protected override void Add(TValue value, JsonSerializerOptions options, ref ReadStack state) + protected override void Add([AllowNull] TValue value, JsonSerializerOptions options, ref ReadStack state) { string key = state.Current.JsonPropertyNameAsString!; - ((TCollection)state.Current.ReturnValue!)[key] = value; + ((TCollection)state.Current.ReturnValue!)[key] = value!; } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ICollectionOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ICollectionOfTConverter.cs index cb1b66ac18371..4606603bda9cb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ICollectionOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ICollectionOfTConverter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -13,9 +14,9 @@ internal sealed class ICollectionOfTConverter : IEnumerableDefaultConverter where TCollection : ICollection { - protected override void Add(TElement value, ref ReadStack state) + protected override void Add([AllowNull] TElement value, ref ReadStack state) { - ((ICollection)state.Current.ReturnValue!).Add(value); + ((ICollection)state.Current.ReturnValue!).Add(value!); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs index 6ef56753427f4..d1719e7ed1b8b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryOfStringTValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryOfStringTValueConverter.cs index 6115fada07dec..05a599a68b007 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryOfStringTValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryOfStringTValueConverter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -14,10 +15,10 @@ internal sealed class IDictionaryOfStringTValueConverter : DictionaryDefaultConverter where TCollection : IDictionary { - protected override void Add(TValue value, JsonSerializerOptions options, ref ReadStack state) + protected override void Add([AllowNull] TValue value, JsonSerializerOptions options, ref ReadStack state) { string key = state.Current.JsonPropertyNameAsString!; - ((TCollection)state.Current.ReturnValue!)[key] = value; + ((TCollection)state.Current.ReturnValue!)[key] = value!; } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs index fd55e9aded820..f3afd6a3a8b1d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs @@ -13,7 +13,7 @@ namespace System.Text.Json.Serialization.Converters internal abstract class IEnumerableDefaultConverter : JsonCollectionConverter { - protected abstract void Add(TElement value, ref ReadStack state); + protected abstract void Add([AllowNull] TElement value, ref ReadStack state); protected abstract void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options); protected virtual void ConvertCollection(ref ReadStack state, JsonSerializerOptions options) { } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableOfTConverter.cs index 26e83873ec24d..4ded06890f7c0 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableOfTConverter.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -14,9 +15,9 @@ internal sealed class IEnumerableOfTConverter : IEnumerableDefaultConverter where TCollection : IEnumerable { - protected override void Add(TElement value, ref ReadStack state) + protected override void Add([AllowNull] TElement value, ref ReadStack state) { - ((List)state.Current.ReturnValue!).Add(value); + ((List)state.Current.ReturnValue!).Add(value!); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListOfTConverter.cs index c349280bbb4e4..6c97169ceec5c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListOfTConverter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -13,9 +14,9 @@ internal sealed class IListOfTConverter : IEnumerableDefaultConverter where TCollection : IList { - protected override void Add(TElement value, ref ReadStack state) + protected override void Add([AllowNull] TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Add(value); + ((TCollection)state.Current.ReturnValue!).Add(value!); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IReadOnlyDictionaryOfStringTValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IReadOnlyDictionaryOfStringTValueConverter.cs index a4552cba9a271..3493144408fdc 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IReadOnlyDictionaryOfStringTValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IReadOnlyDictionaryOfStringTValueConverter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -10,10 +11,10 @@ internal sealed class IReadOnlyDictionaryOfStringTValueConverter where TCollection : IReadOnlyDictionary { - protected override void Add(TValue value, JsonSerializerOptions options, ref ReadStack state) + protected override void Add([AllowNull] TValue value, JsonSerializerOptions options, ref ReadStack state) { string key = state.Current.JsonPropertyNameAsString!; - ((Dictionary)state.Current.ReturnValue!)[key] = value; + ((Dictionary)state.Current.ReturnValue!)[key] = value!; } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ISetOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ISetOfTConverter.cs index 29645584b3536..c26198749489c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ISetOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ISetOfTConverter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -10,9 +11,9 @@ internal sealed class ISetOfTConverter : IEnumerableDefaultConverter where TCollection : ISet { - protected override void Add(TElement value, ref ReadStack state) + protected override void Add([AllowNull] TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Add(value); + ((TCollection)state.Current.ReturnValue!).Add(value!); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableDictionaryOfStringTValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableDictionaryOfStringTValueConverter.cs index 9cde8e4233f28..d5deebfbcabd7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableDictionaryOfStringTValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableDictionaryOfStringTValueConverter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -10,10 +11,10 @@ internal sealed class ImmutableDictionaryOfStringTValueConverter where TCollection : IReadOnlyDictionary { - protected override void Add(TValue value, JsonSerializerOptions options, ref ReadStack state) + protected override void Add([AllowNull] TValue value, JsonSerializerOptions options, ref ReadStack state) { string key = state.Current.JsonPropertyNameAsString!; - ((Dictionary)state.Current.ReturnValue!)[key] = value; + ((Dictionary)state.Current.ReturnValue!)[key] = value!; } internal override bool CanHaveIdMetadata => false; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableEnumerableOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableEnumerableOfTConverter.cs index cfa1f0bf3d60f..126797e604c7f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableEnumerableOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableEnumerableOfTConverter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -10,9 +11,9 @@ internal sealed class ImmutableEnumerableOfTConverter : IEnumerableDefaultConverter where TCollection : IEnumerable { - protected override void Add(TElement value, ref ReadStack state) + protected override void Add([AllowNull] TElement value, ref ReadStack state) { - ((List)state.Current.ReturnValue!).Add(value); + ((List)state.Current.ReturnValue!).Add(value!); } internal override bool CanHaveIdMetadata => false; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ListOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ListOfTConverter.cs index a977fededc3ae..0c6466fbdd365 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ListOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ListOfTConverter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -11,9 +12,9 @@ internal sealed class ListOfTConverter : IEnumerableDefaultConverter where TCollection: List { - protected override void Add(TElement value, ref ReadStack state) + protected override void Add([AllowNull] TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Add(value); + ((TCollection)state.Current.ReturnValue!).Add(value!); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/QueueOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/QueueOfTConverter.cs index dfea6e1480844..f98ac2bf15b60 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/QueueOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/QueueOfTConverter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -10,9 +11,9 @@ internal sealed class QueueOfTConverter : IEnumerableDefaultConverter where TCollection : Queue { - protected override void Add(TElement value, ref ReadStack state) + protected override void Add([AllowNull] TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Enqueue(value); + ((TCollection)state.Current.ReturnValue!).Enqueue(value!); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/StackOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/StackOfTConverter.cs index 5725e7f1a04f4..77aefc70d13ae 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/StackOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/StackOfTConverter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -10,9 +11,9 @@ internal sealed class StackOfTConverter : IEnumerableDefaultConverter where TCollection : Stack { - protected override void Add(TElement value, ref ReadStack state) + protected override void Add([AllowNull] TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Push(value); + ((TCollection)state.Current.ReturnValue!).Push(value!); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs index fc5035deeb78e..f74a7de0cdbe1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs @@ -99,7 +99,7 @@ internal sealed class KeyValuePairConverter : JsonValueConverter(k, v); + value = new KeyValuePair(k!, v!); return true; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.ReadCore.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.ReadCore.cs index 1785b669b2552..c49fd0d7947db 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.ReadCore.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.ReadCore.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; + namespace System.Text.Json.Serialization { public partial class JsonConverter @@ -14,6 +16,7 @@ public partial class JsonConverter return ReadCore(ref reader, options, ref state); } + [return: MaybeNull] internal T ReadCore( ref Utf8JsonReader reader, JsonSerializerOptions options, diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs index 80ff653510068..c7781f9442a98 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs @@ -83,7 +83,7 @@ internal virtual bool OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerO } // Provide a default implementation for value converters. - internal virtual bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, [MaybeNullWhen(false)] out T value) + internal virtual bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, [MaybeNull] out T value) { value = Read(ref reader, typeToConvert, options)!; return true; @@ -102,7 +102,7 @@ internal virtual bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, J [return: MaybeNull] public abstract T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options); - internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, out T value) + internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, [MaybeNull] out T value) { if (ClassType == ClassType.Value) { @@ -112,7 +112,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali // For perf and converter simplicity, handle null here instead of forwarding to the converter. if (reader.TokenType == JsonTokenType.Null && !HandleNull) { - value = default!; + value = default; return true; } @@ -120,7 +120,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali // For performance, only perform validation on internal converters on debug builds. if (IsInternalConverter) { - value = Read(ref reader, typeToConvert, options)!; + value = Read(ref reader, typeToConvert, options); } else #endif @@ -129,7 +129,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali int originalPropertyDepth = reader.CurrentDepth; long originalPropertyBytesConsumed = reader.BytesConsumed; - value = Read(ref reader, typeToConvert, options)!; + value = Read(ref reader, typeToConvert, options); VerifyRead( originalPropertyTokenType, originalPropertyDepth, @@ -155,7 +155,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali if (reader.TokenType == JsonTokenType.Null && !HandleNull && !wasContinuation) { // For perf and converter simplicity, handle null here instead of forwarding to the converter. - value = default!; + value = default; success = true; } else @@ -171,7 +171,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali // For perf and converter simplicity, handle null here instead of forwarding to the converter. if (reader.TokenType == JsonTokenType.Null && !HandleNull) { - value = default!; + value = default; state.Pop(true); return true; } @@ -183,7 +183,7 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali state.Current.OriginalDepth = reader.CurrentDepth; } - success = OnTryRead(ref reader, typeToConvert, options, ref state, out value!); + success = OnTryRead(ref reader, typeToConvert, options, ref state, out value); if (success) { if (state.IsContinuation) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs index bacb5e19352a8..bea0046a8a0b4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs @@ -191,7 +191,7 @@ public override bool ReadJsonAndSetMember(object obj, ref ReadStack state, ref U { if (!IgnoreNullValues || (!isNullToken && value != null)) { - Set!(obj, value); + Set!(obj, value!); } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs index e2aabd2ceacb9..7aedf11cc799e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; + namespace System.Text.Json.Serialization { /// @@ -11,7 +13,8 @@ namespace System.Text.Json.Serialization /// internal abstract class JsonResumableConverter : JsonConverter { - public override sealed T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + [return: MaybeNull] + public sealed override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // Bridge from resumable to value converters. if (options == null) @@ -25,7 +28,7 @@ public override sealed T Read(ref Utf8JsonReader reader, Type typeToConvert, Jso return value; } - public override sealed void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + public sealed override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { // Bridge from resumable to value converters. if (options == null) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs index f8bf98def8199..bfdbd5993c65b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs @@ -3,12 +3,14 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; namespace System.Text.Json { public static partial class JsonSerializer { + [return: MaybeNull] private static TValue ReadCore(ref Utf8JsonReader reader, Type returnType, JsonSerializerOptions options) { ReadStack state = default; @@ -17,6 +19,7 @@ private static TValue ReadCore(ref Utf8JsonReader reader, Type returnTyp return ReadCore(jsonConverter, ref reader, options, ref state); } + [return: MaybeNull] private static TValue ReadCore(JsonConverter jsonConverter, ref Utf8JsonReader reader, JsonSerializerOptions options, ref ReadStack state) { if (jsonConverter is JsonConverter converter) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs index 5215d184204db..082c49645379e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs @@ -43,7 +43,7 @@ public static TValue Deserialize(string json, JsonSerializerOptions? opt throw new ArgumentNullException(nameof(json)); } - return Deserialize(json, typeof(TValue), options)!; + return Deserialize(json, typeof(TValue), options); } /// @@ -85,6 +85,7 @@ public static TValue Deserialize(string json, JsonSerializerOptions? opt return value; } + [return: MaybeNull] private static TValue Deserialize(string json, Type returnType, JsonSerializerOptions? options) { const long ArrayPoolMaxSizeBeforeUsingNormalAlloc = 1024 * 1024; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs index b7182ede223aa..666a6847094a3 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs @@ -14,6 +14,7 @@ public static partial class JsonSerializer /// /// Internal version that allows re-entry with preserving ReadStack so that JsonPath works correctly. /// + [return: MaybeNull] internal static TValue Deserialize(ref Utf8JsonReader reader, JsonSerializerOptions options, ref ReadStack state, string? propertyName = null) { if (options == null) @@ -162,6 +163,7 @@ private static void CheckSupportedOptions(JsonReaderOptions readerOptions, strin } } + [return: MaybeNull] private static TValue ReadValueCore(JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack state) { JsonReaderState readerState = reader.CurrentState; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonValueConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonValueConverterOfT.cs index 5332509163f1d..94af2f7adf5d0 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonValueConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonValueConverterOfT.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; + namespace System.Text.Json.Serialization { // Used for value converters that need to re-enter the serializer since it will support JsonPath @@ -10,7 +12,8 @@ internal abstract class JsonValueConverter : JsonConverter { internal sealed override ClassType ClassType => ClassType.NewValue; - public override sealed T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + [return: MaybeNull] + public sealed override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // Bridge from resumable to value converters. if (options == null) @@ -24,7 +27,7 @@ public override sealed T Read(ref Utf8JsonReader reader, Type typeToConvert, Jso return value; } - public override sealed void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + public sealed override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { // Bridge from resumable to value converters. if (options == null) diff --git a/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Generic.Read.cs b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Generic.Read.cs index 2d72329f49480..d1cb10248613a 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Generic.Read.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Generic.Read.cs @@ -1115,6 +1115,14 @@ public static void ReadClassWithNullKeyValuePairValues() Assert.Null(obj.KvpWClassKvpVal.Value.Value); } + [Fact] + public static void Kvp_NullKeyIsFine() + { + KeyValuePair kvp = JsonSerializer.Deserialize>(@"{""Key"":null,""Value"":null}"); + Assert.Null(kvp.Key); + Assert.Null(kvp.Value); + } + [Fact] public static void ReadSimpleTestClass_GenericCollectionWrappers() { From d600e91871e88e055d6e3b5cd45bdb3482907c0e Mon Sep 17 00:00:00 2001 From: YohDeadfall Date: Thu, 7 May 2020 00:10:21 +0300 Subject: [PATCH 021/420] Fixed rebase issues --- .../src/System/Text/Json/Serialization/JsonClassInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs index 1b87ef779a9c9..184492ae5c4c6 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs @@ -104,7 +104,7 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) for (Type? currentType = type; currentType != null; currentType = currentType.BaseType) { - foreach (PropertyInfo propertyInfo in currentType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) + foreach (PropertyInfo propertyInfo in currentType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)) { // Ignore indexers if (propertyInfo.GetIndexParameters().Length > 0) From 75845b5223c1a72ae6372638844eed4612990f40 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Wed, 6 May 2020 13:21:05 -0700 Subject: [PATCH 022/420] Apply review feedback - test & nullability fixes --- .../Converters/Collection/ArrayConverter.cs | 5 ++--- .../Collection/ConcurrentQueueOfTConverter.cs | 5 ++--- .../Collection/ConcurrentStackOfTConverter.cs | 5 ++--- .../Collection/DictionaryDefaultConverter.cs | 8 ++++---- .../Collection/DictionaryOfStringTValueConverter.cs | 5 ++--- .../Converters/Collection/ICollectionOfTConverter.cs | 5 ++--- .../Converters/Collection/IDictionaryConverter.cs | 1 - .../Collection/IDictionaryOfStringTValueConverter.cs | 5 ++--- .../Collection/IEnumerableDefaultConverter.cs | 10 +++++----- .../Converters/Collection/IEnumerableOfTConverter.cs | 5 ++--- .../Converters/Collection/IListOfTConverter.cs | 5 ++--- .../IReadOnlyDictionaryOfStringTValueConverter.cs | 5 ++--- .../Converters/Collection/ISetOfTConverter.cs | 5 ++--- .../ImmutableDictionaryOfStringTValueConverter.cs | 5 ++--- .../Collection/ImmutableEnumerableOfTConverter.cs | 5 ++--- .../Converters/Collection/ListOfTConverter.cs | 5 ++--- .../Converters/Collection/QueueOfTConverter.cs | 5 ++--- .../Converters/Collection/StackOfTConverter.cs | 5 ++--- ...bjectWithParameterizedConstructorConverter.Small.cs | 8 ++++---- .../System/Text/Json/Serialization/JsonConverterOfT.cs | 2 +- .../Text/Json/Serialization/JsonParameterInfoOfT.cs | 5 +++-- .../Text/Json/Serialization/JsonPropertyInfoOfT.cs | 4 ++-- .../CustomConverterTests.HandleNull.cs | 6 +++++- 23 files changed, 54 insertions(+), 65 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ArrayConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ArrayConverter.cs index c7e576f6e02f8..70d0c611dd5ba 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ArrayConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ArrayConverter.cs @@ -4,7 +4,6 @@ using System.Collections; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -17,9 +16,9 @@ internal sealed class ArrayConverter { internal override bool CanHaveIdMetadata => false; - protected override void Add([AllowNull] TElement value, ref ReadStack state) + protected override void Add(TElement value, ref ReadStack state) { - ((List)state.Current.ReturnValue!).Add(value!); + ((List)state.Current.ReturnValue!).Add(value); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentQueueOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentQueueOfTConverter.cs index 71c9a7c69cb9b..aa54f0956e41e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentQueueOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentQueueOfTConverter.cs @@ -4,7 +4,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -12,9 +11,9 @@ internal sealed class ConcurrentQueueOfTConverter : IEnumerableDefaultConverter where TCollection : ConcurrentQueue { - protected override void Add([AllowNull] TElement value, ref ReadStack state) + protected override void Add(TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Enqueue(value!); + ((TCollection)state.Current.ReturnValue!).Enqueue(value); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentStackOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentStackOfTConverter.cs index e1c3855da8c04..9ba01b68df2dd 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentStackOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ConcurrentStackOfTConverter.cs @@ -4,7 +4,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -12,9 +11,9 @@ internal sealed class ConcurrentStackOfTConverter : IEnumerableDefaultConverter where TCollection : ConcurrentStack { - protected override void Add([AllowNull] TElement value, ref ReadStack state) + protected override void Add(TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Push(value!); + ((TCollection)state.Current.ReturnValue!).Push(value); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs index b45db09122256..a657398ca2d3f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs @@ -16,7 +16,7 @@ internal abstract class DictionaryDefaultConverter /// /// When overridden, adds the value to the collection. /// - protected abstract void Add([AllowNull] TValue value, JsonSerializerOptions options, ref ReadStack state); + protected abstract void Add(TValue value, JsonSerializerOptions options, ref ReadStack state); /// /// When overridden, converts the temporary collection held in state.Current.ReturnValue to the final collection. @@ -104,7 +104,7 @@ protected static JsonConverter GetValueConverter(ref WriteStack state) // Read the value and add. reader.ReadWithVerify(); TValue element = elementConverter.Read(ref reader, typeof(TValue), options); - Add(element, options, ref state); + Add(element!, options, ref state); } } else @@ -129,7 +129,7 @@ protected static JsonConverter GetValueConverter(ref WriteStack state) // Get the value from the converter and add it. elementConverter.TryRead(ref reader, typeof(TValue), options, ref state, out TValue element); - Add(element, options, ref state); + Add(element!, options, ref state); } } } @@ -247,7 +247,7 @@ protected static JsonConverter GetValueConverter(ref WriteStack state) return false; } - Add(element, options, ref state); + Add(element!, options, ref state); state.Current.EndElement(); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfStringTValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfStringTValueConverter.cs index 4633bb0b0b37d..14ecb4526999c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfStringTValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfStringTValueConverter.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -15,10 +14,10 @@ internal sealed class DictionaryOfStringTValueConverter : DictionaryDefaultConverter where TCollection : Dictionary { - protected override void Add([AllowNull] TValue value, JsonSerializerOptions options, ref ReadStack state) + protected override void Add(TValue value, JsonSerializerOptions options, ref ReadStack state) { string key = state.Current.JsonPropertyNameAsString!; - ((TCollection)state.Current.ReturnValue!)[key] = value!; + ((TCollection)state.Current.ReturnValue!)[key] = value; } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ICollectionOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ICollectionOfTConverter.cs index 4606603bda9cb..cb1b66ac18371 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ICollectionOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ICollectionOfTConverter.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -14,9 +13,9 @@ internal sealed class ICollectionOfTConverter : IEnumerableDefaultConverter where TCollection : ICollection { - protected override void Add([AllowNull] TElement value, ref ReadStack state) + protected override void Add(TElement value, ref ReadStack state) { - ((ICollection)state.Current.ReturnValue!).Add(value!); + ((ICollection)state.Current.ReturnValue!).Add(value); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs index d1719e7ed1b8b..6ef56753427f4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs @@ -4,7 +4,6 @@ using System.Collections; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryOfStringTValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryOfStringTValueConverter.cs index 05a599a68b007..6115fada07dec 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryOfStringTValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryOfStringTValueConverter.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -15,10 +14,10 @@ internal sealed class IDictionaryOfStringTValueConverter : DictionaryDefaultConverter where TCollection : IDictionary { - protected override void Add([AllowNull] TValue value, JsonSerializerOptions options, ref ReadStack state) + protected override void Add(TValue value, JsonSerializerOptions options, ref ReadStack state) { string key = state.Current.JsonPropertyNameAsString!; - ((TCollection)state.Current.ReturnValue!)[key] = value!; + ((TCollection)state.Current.ReturnValue!)[key] = value; } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs index f3afd6a3a8b1d..6803e9d58454f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs @@ -13,7 +13,7 @@ namespace System.Text.Json.Serialization.Converters internal abstract class IEnumerableDefaultConverter : JsonCollectionConverter { - protected abstract void Add([AllowNull] TElement value, ref ReadStack state); + protected abstract void Add(TElement value, ref ReadStack state); protected abstract void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options); protected virtual void ConvertCollection(ref ReadStack state, JsonSerializerOptions options) { } @@ -66,8 +66,8 @@ protected static JsonConverter GetElementConverter(ref WriteStack stat } // Obtain the CLR value from the JSON and apply to the object. - TElement element = elementConverter.Read(ref reader, elementConverter.TypeToConvert, options)!; - Add(element, ref state); + TElement element = elementConverter.Read(ref reader, elementConverter.TypeToConvert, options); + Add(element!, ref state); } } else @@ -83,7 +83,7 @@ protected static JsonConverter GetElementConverter(ref WriteStack stat // Get the value from the converter and add it. elementConverter.TryRead(ref reader, typeof(TElement), options, ref state, out TElement element); - Add(element, ref state); + Add(element!, ref state); } } } @@ -184,7 +184,7 @@ protected static JsonConverter GetElementConverter(ref WriteStack stat return false; } - Add(element, ref state); + Add(element!, ref state); // No need to set PropertyState to TryRead since we're done with this element now. state.Current.EndElement(); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableOfTConverter.cs index 4ded06890f7c0..26e83873ec24d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableOfTConverter.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -15,9 +14,9 @@ internal sealed class IEnumerableOfTConverter : IEnumerableDefaultConverter where TCollection : IEnumerable { - protected override void Add([AllowNull] TElement value, ref ReadStack state) + protected override void Add(TElement value, ref ReadStack state) { - ((List)state.Current.ReturnValue!).Add(value!); + ((List)state.Current.ReturnValue!).Add(value); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListOfTConverter.cs index 6c97169ceec5c..c349280bbb4e4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListOfTConverter.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -14,9 +13,9 @@ internal sealed class IListOfTConverter : IEnumerableDefaultConverter where TCollection : IList { - protected override void Add([AllowNull] TElement value, ref ReadStack state) + protected override void Add(TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Add(value!); + ((TCollection)state.Current.ReturnValue!).Add(value); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IReadOnlyDictionaryOfStringTValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IReadOnlyDictionaryOfStringTValueConverter.cs index 3493144408fdc..a4552cba9a271 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IReadOnlyDictionaryOfStringTValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IReadOnlyDictionaryOfStringTValueConverter.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -11,10 +10,10 @@ internal sealed class IReadOnlyDictionaryOfStringTValueConverter where TCollection : IReadOnlyDictionary { - protected override void Add([AllowNull] TValue value, JsonSerializerOptions options, ref ReadStack state) + protected override void Add(TValue value, JsonSerializerOptions options, ref ReadStack state) { string key = state.Current.JsonPropertyNameAsString!; - ((Dictionary)state.Current.ReturnValue!)[key] = value!; + ((Dictionary)state.Current.ReturnValue!)[key] = value; } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ISetOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ISetOfTConverter.cs index c26198749489c..29645584b3536 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ISetOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ISetOfTConverter.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -11,9 +10,9 @@ internal sealed class ISetOfTConverter : IEnumerableDefaultConverter where TCollection : ISet { - protected override void Add([AllowNull] TElement value, ref ReadStack state) + protected override void Add(TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Add(value!); + ((TCollection)state.Current.ReturnValue!).Add(value); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableDictionaryOfStringTValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableDictionaryOfStringTValueConverter.cs index d5deebfbcabd7..9cde8e4233f28 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableDictionaryOfStringTValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableDictionaryOfStringTValueConverter.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -11,10 +10,10 @@ internal sealed class ImmutableDictionaryOfStringTValueConverter where TCollection : IReadOnlyDictionary { - protected override void Add([AllowNull] TValue value, JsonSerializerOptions options, ref ReadStack state) + protected override void Add(TValue value, JsonSerializerOptions options, ref ReadStack state) { string key = state.Current.JsonPropertyNameAsString!; - ((Dictionary)state.Current.ReturnValue!)[key] = value!; + ((Dictionary)state.Current.ReturnValue!)[key] = value; } internal override bool CanHaveIdMetadata => false; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableEnumerableOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableEnumerableOfTConverter.cs index 126797e604c7f..cfa1f0bf3d60f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableEnumerableOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableEnumerableOfTConverter.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -11,9 +10,9 @@ internal sealed class ImmutableEnumerableOfTConverter : IEnumerableDefaultConverter where TCollection : IEnumerable { - protected override void Add([AllowNull] TElement value, ref ReadStack state) + protected override void Add(TElement value, ref ReadStack state) { - ((List)state.Current.ReturnValue!).Add(value!); + ((List)state.Current.ReturnValue!).Add(value); } internal override bool CanHaveIdMetadata => false; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ListOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ListOfTConverter.cs index 0c6466fbdd365..a977fededc3ae 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ListOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ListOfTConverter.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -12,9 +11,9 @@ internal sealed class ListOfTConverter : IEnumerableDefaultConverter where TCollection: List { - protected override void Add([AllowNull] TElement value, ref ReadStack state) + protected override void Add(TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Add(value!); + ((TCollection)state.Current.ReturnValue!).Add(value); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/QueueOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/QueueOfTConverter.cs index f98ac2bf15b60..dfea6e1480844 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/QueueOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/QueueOfTConverter.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -11,9 +10,9 @@ internal sealed class QueueOfTConverter : IEnumerableDefaultConverter where TCollection : Queue { - protected override void Add([AllowNull] TElement value, ref ReadStack state) + protected override void Add(TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Enqueue(value!); + ((TCollection)state.Current.ReturnValue!).Enqueue(value); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/StackOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/StackOfTConverter.cs index 77aefc70d13ae..5725e7f1a04f4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/StackOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/StackOfTConverter.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -11,9 +10,9 @@ internal sealed class StackOfTConverter : IEnumerableDefaultConverter where TCollection : Stack { - protected override void Add([AllowNull] TElement value, ref ReadStack state) + protected override void Add(TElement value, ref ReadStack state) { - ((TCollection)state.Current.ReturnValue!).Push(value!); + ((TCollection)state.Current.ReturnValue!).Push(value); } protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.Small.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.Small.cs index 391a5710204b8..1e98384d117c6 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.Small.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.Small.cs @@ -33,28 +33,28 @@ protected override bool ReadAndCacheConstructorArgument(ref ReadStack state, ref success = ((JsonParameterInfo)jsonParameterInfo).ReadJsonTyped(ref state, ref reader, out TArg0 arg0); if (success) { - arguments.Arg0 = arg0; + arguments.Arg0 = arg0!; } break; case 1: success = ((JsonParameterInfo)jsonParameterInfo).ReadJsonTyped(ref state, ref reader, out TArg1 arg1); if (success) { - arguments.Arg1 = arg1; + arguments.Arg1 = arg1!; } break; case 2: success = ((JsonParameterInfo)jsonParameterInfo).ReadJsonTyped(ref state, ref reader, out TArg2 arg2); if (success) { - arguments.Arg2 = arg2; + arguments.Arg2 = arg2!; } break; case 3: success = ((JsonParameterInfo)jsonParameterInfo).ReadJsonTyped(ref state, ref reader, out TArg3 arg3); if (success) { - arguments.Arg3 = arg3; + arguments.Arg3 = arg3!; } break; default: diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs index c7781f9442a98..e18a31a0c7088 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs @@ -85,7 +85,7 @@ internal virtual bool OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerO // Provide a default implementation for value converters. internal virtual bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, [MaybeNull] out T value) { - value = Read(ref reader, typeToConvert, options)!; + value = Read(ref reader, typeToConvert, options); return true; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfoOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfoOfT.cs index 89447d153cebd..a2b20294510ee 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfoOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfoOfT.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text.Json.Serialization; @@ -77,7 +78,7 @@ public override bool ReadJson(ref ReadStack state, ref Utf8JsonReader reader, ou return success; } - public bool ReadJsonTyped(ref ReadStack state, ref Utf8JsonReader reader, out T value) + public bool ReadJsonTyped(ref ReadStack state, ref Utf8JsonReader reader, [MaybeNull] out T value) { bool success; bool isNullToken = reader.TokenType == JsonTokenType.Null; @@ -93,7 +94,7 @@ public bool ReadJsonTyped(ref ReadStack state, ref Utf8JsonReader reader, out T // Optimize for internal converters by avoiding the extra call to TryRead. if (_converter.CanUseDirectReadOrWrite) { - value = _converter.Read(ref reader, _runtimePropertyType, Options)!; + value = _converter.Read(ref reader, _runtimePropertyType, Options); return true; } else diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs index bea0046a8a0b4..fe1e77e701678 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs @@ -176,10 +176,10 @@ public override bool ReadJsonAndSetMember(object obj, ref ReadStack state, ref U if (Converter.CanUseDirectReadOrWrite) { // Optimize for internal converters by avoiding the extra call to TryRead. - T fastvalue = Converter.Read(ref reader, RuntimePropertyType!, Options)!; + T fastvalue = Converter.Read(ref reader, RuntimePropertyType!, Options); if (!IgnoreNullValues || (!isNullToken && fastvalue != null)) { - Set!(obj, fastvalue); + Set!(obj, fastvalue!); } return true; diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs index 6ff06676cc79d..ac7165b15bb3c 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs @@ -49,6 +49,7 @@ public static void ValueTypeConverter_OptOut() var options = new JsonSerializerOptions(); options.Converters.Add(new Int32NullConverter_OptOut()); + // Serializer sets default value (doesn't fallback to built-in converter). Assert.Equal(0, JsonSerializer.Deserialize("null", options)); } @@ -217,10 +218,13 @@ public static void ReferenceTypeConverter_NoOverride() // Per null handling default value for reference types (false), serializer handles null. var options = new JsonSerializerOptions(); - options.Converters.Add(new Int32NullConverter_SpecialCaseNull()); + options.Converters.Add(new UriNullConverter_SpecialCaseNull()); + // Serializer sets default value. val = JsonSerializer.Deserialize("null", options); Assert.Null(val); + + // Serializer serializes null. Assert.Equal("null", JsonSerializer.Serialize(val, options)); } From 5199a8c92315272fe87c7fce898bee583abe9af3 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 7 May 2020 10:24:20 -0700 Subject: [PATCH 023/420] Use C++11 alias templates instead of macro-defined types to implement specialized holder wrappers. (#35863) --- src/coreclr/src/debug/di/process.cpp | 3 +- src/coreclr/src/inc/appxutil.h | 2 - src/coreclr/src/inc/ex.h | 8 +- src/coreclr/src/inc/holder.h | 169 ++++++++++++------------ src/coreclr/src/inc/strongnameholders.h | 3 +- src/coreclr/src/vm/vmholder.h | 3 +- src/coreclr/src/vm/wrappers.h | 9 +- 7 files changed, 95 insertions(+), 102 deletions(-) diff --git a/src/coreclr/src/debug/di/process.cpp b/src/coreclr/src/debug/di/process.cpp index 4e6fe0bf64984..f13e7b9f0eaa1 100644 --- a/src/coreclr/src/debug/di/process.cpp +++ b/src/coreclr/src/debug/di/process.cpp @@ -10990,8 +10990,7 @@ void CordbWin32EventThread::ThreadProc() } // Define a holder that calls code:DeleteIPCEventHelper -NEW_WRAPPER_TEMPLATE1(DeleteIPCEventHolderHelper, DeleteIPCEventHelper); -typedef DeleteIPCEventHolderHelper DeleteIPCEventHolder; +using DeleteIPCEventHolder = SpecializedWrapper; //--------------------------------------------------------------------------------------- // diff --git a/src/coreclr/src/inc/appxutil.h b/src/coreclr/src/inc/appxutil.h index c5fce6967eed7..644d3b9fce04a 100644 --- a/src/coreclr/src/inc/appxutil.h +++ b/src/coreclr/src/inc/appxutil.h @@ -14,8 +14,6 @@ //--------------------------------------------------------------------------------------------- // Forward declarations -template -class NewArrayHolder; BOOL WinRTSupported(); diff --git a/src/coreclr/src/inc/ex.h b/src/coreclr/src/inc/ex.h index 21ce9d3d4b0ec..48a3572bca3ec 100644 --- a/src/coreclr/src/inc/ex.h +++ b/src/coreclr/src/inc/ex.h @@ -278,17 +278,13 @@ class Exception }; #if 1 -template -inline void Exception__Delete(T* pvMemory); -template <> -inline void Exception__Delete(Exception* pvMemory) +inline void Exception__Delete(Exception* pvMemory) { Exception::Delete(pvMemory); } -NEW_WRAPPER_TEMPLATE1(ExceptionHolderTemplate, Exception__Delete<_TYPE>); -typedef ExceptionHolderTemplate ExceptionHolder; +using ExceptionHolder = SpecializedWrapper; #else //------------------------------------------------------------------------------ diff --git a/src/coreclr/src/inc/holder.h b/src/coreclr/src/inc/holder.h index c1f86b1ee0ff8..a5781d5570dde 100644 --- a/src/coreclr/src/inc/holder.h +++ b/src/coreclr/src/inc/holder.h @@ -824,84 +824,68 @@ class Wrapper : public BaseWrapper, #define INDEBUG_AND_WINDOWS_FOR_HOLDERS(x) #endif -//--------------------------------------------------------------------------------------- -// -// New template wrapper type macros. These save some effort when specializing -// existing holder templates. (We would rather use a construct like: -// -// template -// typedef Holder<...> NewHolder; -// -// But this construct doesn't exist in C++. These macros ease some of the cruft necessary -// to get similar functionality out of class templates. -//----------------------------------------------------------------------------- +template +class SpecializedWrapper : public Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL> +{ + using BaseT = Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL>; +public: + FORCEINLINE SpecializedWrapper() : BaseT(NULL, FALSE) + { + STATIC_CONTRACT_WRAPPER; + INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) + } + FORCEINLINE SpecializedWrapper(_TYPE* value) : BaseT(value) + { + STATIC_CONTRACT_WRAPPER; + INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) + } + FORCEINLINE SpecializedWrapper(_TYPE* value, BOOL takeOwnership) : BaseT(value, takeOwnership) + { + STATIC_CONTRACT_WRAPPER; + INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) + } + FORCEINLINE ~SpecializedWrapper() + { + } -// Dev10 VC++ has some of the new C++0x language extensions. Of particular interest here: -// rvalue references, which enables differentiation between named (lvalue) and -// temporary (rvalue) object references, enabling move semantics and perfect forwarding. -// See http://msdn.microsoft.com/en-us/library/dd293668.aspx for more information. - -// Enable copy construction and assignment from temporary objects. This permits Wrapper objects -// to be returned from methods, and for move assignment. -#define NEW_WRAPPER_TEMPLATE_RVALREF_METHODS(_NAME) \ - public: \ - FORCEINLINE _NAME(_NAME && other) \ - : BaseT(NULL, FALSE) \ - { \ - STATIC_CONTRACT_WRAPPER; \ - INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) \ - *this = std::move(other); \ - } \ - FORCEINLINE _NAME& operator=(_NAME && other) \ - { \ - std::swap(BaseT::m_value, other.BaseT::m_value); \ - std::swap(BaseT::m_acquired, other.BaseT::m_acquired); \ - return *this; \ - } + SpecializedWrapper(SpecializedWrapper const &) = delete; + SpecializedWrapper & operator=(SpecializedWrapper const &) = delete; -#define NEW_WRAPPER_TEMPLATE1(_NAME, _RELEASEF) \ - template \ - class _NAME : public Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL> \ - { \ - typedef Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL> BaseT; \ - public: \ - FORCEINLINE _NAME() : BaseT(NULL, FALSE) \ - { \ - STATIC_CONTRACT_WRAPPER; \ - INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) \ - } \ - FORCEINLINE _NAME(_TYPE* value) : BaseT(value) \ - { \ - STATIC_CONTRACT_WRAPPER; \ - INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) \ - } \ - FORCEINLINE _NAME(_TYPE* value, BOOL takeOwnership) : BaseT(value, takeOwnership) \ - { \ - STATIC_CONTRACT_WRAPPER; \ - INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) \ - } \ - FORCEINLINE ~_NAME() \ - { \ - } \ - FORCEINLINE _NAME& operator=(_TYPE * value) \ - { \ - STATIC_CONTRACT_WRAPPER; \ - BaseT::operator=(value); \ - return *this; \ - } \ - /* Since operator& is overloaded we need a way to get a type safe this pointer. */ \ - FORCEINLINE _NAME* GetAddr() \ - { \ - STATIC_CONTRACT_LEAF; \ - return this; \ - } \ - NEW_WRAPPER_TEMPLATE_RVALREF_METHODS(_NAME) \ - HIDE_GENERATED_METHODS(_NAME) \ - private: \ - /* m_ppValue: Do not use from source code: Only for convenient use from debugger */ \ - /* watch windows - saves five mouseclicks when inspecting holders. */ \ - INDEBUG_AND_WINDOWS_FOR_HOLDERS(_TYPE ** m_pvalue;) \ - }; + FORCEINLINE SpecializedWrapper& operator=(_TYPE * value) + { + STATIC_CONTRACT_WRAPPER; + BaseT::operator=(value); + return *this; + } + + FORCEINLINE SpecializedWrapper(SpecializedWrapper && other) + : BaseT(NULL, FALSE) + { + STATIC_CONTRACT_WRAPPER; + INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;) + *this = std::move(other); + } + + FORCEINLINE SpecializedWrapper& operator=(SpecializedWrapper && other) + { + BaseT::m_value = std::move(other.BaseT::m_value); + BaseT::m_acquired = std::move(other.BaseT::m_acquired); + other.BaseT::m_value = nullptr; + other.BaseT::m_acquired = FALSE; + return *this; + } + + /* Since operator& is overloaded we need a way to get a type safe this pointer. */ + FORCEINLINE SpecializedWrapper* GetAddr() + { + STATIC_CONTRACT_LEAF; + return this; + } + private: + /* m_ppValue: Do not use from source code: Only for convenient use from debugger */ + /* watch windows - saves five mouseclicks when inspecting holders. */ + INDEBUG_AND_WINDOWS_FOR_HOLDERS(_TYPE ** m_pvalue;) +}; //----------------------------------------------------------------------------- // NOTE: THIS IS UNSAFE TO USE IN THE VM for interop COM objects!! @@ -930,11 +914,14 @@ FORCEINLINE void DoTheRelease(TYPE *value) } } -NEW_WRAPPER_TEMPLATE1(DoNothingHolder, DoNothing<_TYPE*>); +template +using DoNothingHolder = SpecializedWrapper<_TYPE, DoNothing<_TYPE*>>; -NEW_WRAPPER_TEMPLATE1(ReleaseHolder, DoTheRelease<_TYPE>); +template +using ReleaseHolder = SpecializedWrapper<_TYPE, DoTheRelease<_TYPE>>; -NEW_WRAPPER_TEMPLATE1(NonVMComHolder, DoTheRelease<_TYPE>); +template +using NonVMComHolder = SpecializedWrapper<_TYPE, DoTheRelease<_TYPE>>; //----------------------------------------------------------------------------- @@ -957,7 +944,8 @@ FORCEINLINE void StubRelease(TYPE* value) value->DecRef(); } -NEW_WRAPPER_TEMPLATE1(StubHolder, StubRelease<_TYPE>); +template +using StubHolder = SpecializedWrapper<_TYPE, StubRelease<_TYPE>>; //----------------------------------------------------------------------------- // CoTaskMemHolder : CoTaskMemAlloc allocated memory holder @@ -974,7 +962,8 @@ FORCEINLINE void DeleteCoTaskMem(TYPE *value) CoTaskMemFree(value); } -NEW_WRAPPER_TEMPLATE1(CoTaskMemHolder, DeleteCoTaskMem<_TYPE>); +template +using CoTaskMemHolder = SpecializedWrapper<_TYPE, DeleteCoTaskMem<_TYPE>>; //----------------------------------------------------------------------------- // NewHolder : New'ed memory holder @@ -997,7 +986,8 @@ FORCEINLINE void Delete(TYPE *value) delete value; } -NEW_WRAPPER_TEMPLATE1(NewHolder, Delete<_TYPE>); +template +using NewHolder = SpecializedWrapper<_TYPE, Delete<_TYPE>>; //----------------------------------------------------------------------------- // NewExecutableHolder : New'ed memory holder for executable memory. @@ -1009,7 +999,8 @@ NEW_WRAPPER_TEMPLATE1(NewHolder, Delete<_TYPE>); // IJW template void DeleteExecutable(T *p); -NEW_WRAPPER_TEMPLATE1(NewExecutableHolder, DeleteExecutable<_TYPE>); +template +using NewExecutableHolder = SpecializedWrapper<_TYPE, DeleteExecutable<_TYPE>>; //----------------------------------------------------------------------------- // NewArrayHolder : New []'ed pointer holder @@ -1026,7 +1017,8 @@ FORCEINLINE void DeleteArray(TYPE *value) value = NULL; } -NEW_WRAPPER_TEMPLATE1(NewArrayHolder, DeleteArray<_TYPE>); +template +using NewArrayHolder = SpecializedWrapper<_TYPE, DeleteArray<_TYPE>>; typedef NewArrayHolder AStringHolder; typedef NewArrayHolder WStringHolder; @@ -1113,8 +1105,10 @@ namespace detail } #undef VISIBLE -NEW_WRAPPER_TEMPLATE1(ResetPointerHolder, detail::ZeroMem<_TYPE>::Invoke); -NEW_WRAPPER_TEMPLATE1(FieldNuller, detail::ZeroMem<_TYPE>::Invoke); +template +using ResetPointerHolder = SpecializedWrapper<_TYPE, detail::ZeroMem<_TYPE>::Invoke>; +template +using FieldNuller = SpecializedWrapper<_TYPE, detail::ZeroMem<_TYPE>::Invoke>; //----------------------------------------------------------------------------- // Wrap win32 functions using HANDLE @@ -1157,7 +1151,8 @@ typedef Wrapper, HolderFreeLibrary, NULL> HModuleHol template FORCEINLINE void DoLocalFree(T* pMem) { (LocalFree)((HLOCAL)pMem); } -NEW_WRAPPER_TEMPLATE1(LocalAllocHolder, DoLocalFree<_TYPE>); +template +using LocalAllocHolder = SpecializedWrapper<_TYPE, DoLocalFree<_TYPE>>; inline void BoolSet( _Out_ bool * val ) { *val = true; } inline void BoolUnset( _Out_ bool * val ) { *val = false; } diff --git a/src/coreclr/src/inc/strongnameholders.h b/src/coreclr/src/inc/strongnameholders.h index ecec99432af1b..d684e9d3a032a 100644 --- a/src/coreclr/src/inc/strongnameholders.h +++ b/src/coreclr/src/inc/strongnameholders.h @@ -18,6 +18,7 @@ void VoidStrongNameFreeBuffer(__in T *pBuffer) { StrongNameFreeBuffer(reinterpret_cast(pBuffer)); } -NEW_WRAPPER_TEMPLATE1(StrongNameBufferHolder, VoidStrongNameFreeBuffer<_TYPE>); +template +using StrongNameBufferHolder = SpecializedWrapper<_TYPE, VoidStrongNameFreeBuffer<_TYPE>>; #endif // !__STRONGNAME_HOLDERS_H__ diff --git a/src/coreclr/src/vm/vmholder.h b/src/coreclr/src/vm/vmholder.h index 9c265a1b366d7..003892b07addc 100644 --- a/src/coreclr/src/vm/vmholder.h +++ b/src/coreclr/src/vm/vmholder.h @@ -18,6 +18,7 @@ inline void DoTheReleaseHost(TYPE *value) } } -NEW_WRAPPER_TEMPLATE1(HostComHolder, DoTheReleaseHost<_TYPE>); +template +using HostComHolder = SpecializedWrapper<_TYPE, DoTheReleaseHost<_TYPE>>; #endif diff --git a/src/coreclr/src/vm/wrappers.h b/src/coreclr/src/vm/wrappers.h index b9e40e89979b8..a256cb56ea3b2 100644 --- a/src/coreclr/src/vm/wrappers.h +++ b/src/coreclr/src/vm/wrappers.h @@ -109,11 +109,13 @@ inline void SafeComReleasePreemp(TYPE *value) SafeReleasePreemp((IUnknown*)value); } -NEW_WRAPPER_TEMPLATE1(SafeComHolder, SafeComRelease<_TYPE>); +template +using SafeComHolder = SpecializedWrapper<_TYPE, SafeComRelease<_TYPE>>; // Use this holder if you're already in preemptive mode for other reasons, // use SafeComHolder otherwise. -NEW_WRAPPER_TEMPLATE1(SafeComHolderPreemp, SafeComReleasePreemp<_TYPE>); +template +using SafeComHolderPreemp = SpecializedWrapper<_TYPE, SafeComReleasePreemp<_TYPE>>; @@ -166,7 +168,8 @@ void DeletePreemp(TYPE *value) delete value; } -NEW_WRAPPER_TEMPLATE1(NewPreempHolder, DeletePreemp<_TYPE>); +template +using NewPreempHolder = SpecializedWrapper<_TYPE, DeletePreemp<_TYPE>>; //----------------------------------------------------------------------------- From 6985ce6107465dd9c46e96de87bc67c8a1c45a67 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Thu, 7 May 2020 19:26:42 +0200 Subject: [PATCH 024/420] Fix the stackoverflow test output checks (#35914) * Fix the stackoverflow test output checks The System.Threading.ThreadHelper.ThreadStart can tail call the System.Threading.ExecutionContext.RunInternal (and some other methods in the runtime as well) and thus it would not be visible on the stack trace. So the fix is to not to look at the System.Threading.ThreadHelper.ThreadStart in the stack trace and use a method in the test itself instead. Since the test is compiled with optimizations disabled, JIT should not do any "interesting" things. * Add NoInlining attribute and do a little unification --- .../exceptions/stackoverflow/stackoverflow.cs | 24 +++++++++---------- .../stackoverflow/stackoverflowtester.cs | 18 +++++++++----- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflow.cs b/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflow.cs index 2cb9aa6ae82f4..3a4a363c7425b 100644 --- a/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflow.cs +++ b/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflow.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; using System.Threading; +using System.Runtime.CompilerServices; namespace TestStackOverflow { @@ -67,39 +68,47 @@ struct LargeStruct65536 } class Program { + [MethodImpl(MethodImplOptions.NoInlining)] static void InfiniteRecursionA() { InfiniteRecursionB(); } + [MethodImpl(MethodImplOptions.NoInlining)] static void InfiniteRecursionB() { InfiniteRecursionC(); } + + [MethodImpl(MethodImplOptions.NoInlining)] static void InfiniteRecursionC() { InfiniteRecursionA(); } + [MethodImpl(MethodImplOptions.NoInlining)] static void InfiniteRecursionA2() { LargeStruct65536 s; InfiniteRecursionB2(); } + [MethodImpl(MethodImplOptions.NoInlining)] static void InfiniteRecursionB2() { LargeStruct65536 s; InfiniteRecursionC2(); } + [MethodImpl(MethodImplOptions.NoInlining)] static void InfiniteRecursionC2() { LargeStruct65536 s; InfiniteRecursionA2(); } - static void MainThreadTest(bool smallframe) + [MethodImpl(MethodImplOptions.NoInlining)] + static void Test(bool smallframe) { if (smallframe) { @@ -116,16 +125,7 @@ static void SecondaryThreadsTest(bool smallframe) Thread[] threads = new Thread[32]; for (int i = 0; i < threads.Length; i++) { - threads[i] = new Thread(() => { - if (smallframe) - { - InfiniteRecursionA(); - } - else - { - InfiniteRecursionA2(); - } - }); + threads[i] = new Thread(() => Test(smallframe)); threads[i].Start(); } @@ -144,7 +144,7 @@ static void Main(string[] args) } else if (args[1] == "main") { - MainThreadTest(smallframe); + Test(smallframe); } } } diff --git a/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflowtester.cs b/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflowtester.cs index f30305658c100..d8326ff6666bf 100644 --- a/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflowtester.cs +++ b/src/coreclr/tests/src/baseservices/exceptions/stackoverflow/stackoverflowtester.cs @@ -77,6 +77,12 @@ static bool TestStackOverflowSmallFrameMainThread() return false; } + if (!lines.Exists(elem => elem.EndsWith("TestStackOverflow.Program.Test(Boolean)"))) + { + Console.WriteLine("Missing \"Test\" method frame"); + return false; + } + if (!lines.Exists(elem => elem.EndsWith("at TestStackOverflow.Program.InfiniteRecursionA()"))) { Console.WriteLine("Missing \"InfiniteRecursionA\" method frame"); @@ -112,9 +118,9 @@ static bool TestStackOverflowLargeFrameMainThread() return false; } - if (!lines.Exists(elem => elem.EndsWith("TestStackOverflow.Program.MainThreadTest(Boolean)"))) + if (!lines.Exists(elem => elem.EndsWith("TestStackOverflow.Program.Test(Boolean)"))) { - Console.WriteLine("Missing \"MainThreadTest\" method frame"); + Console.WriteLine("Missing \"Test\" method frame"); return false; } @@ -147,9 +153,9 @@ static bool TestStackOverflowSmallFrameSecondaryThread() List lines; if (TestStackOverflow("stackoverflow", "smallframe secondary", out lines)) { - if (!lines[lines.Count - 1].EndsWith("at System.Threading.ThreadHelper.ThreadStart()")) + if (!lines.Exists(elem => elem.EndsWith("at TestStackOverflow.Program.Test(Boolean)"))) { - Console.WriteLine("Missing \"System.Threading.ThreadHelper.ThreadStart\" method frame at the last line"); + Console.WriteLine("Missing \"TestStackOverflow.Program.Test\" method frame"); return false; } @@ -182,9 +188,9 @@ static bool TestStackOverflowLargeFrameSecondaryThread() List lines; if (TestStackOverflow("stackoverflow", "largeframe secondary", out lines)) { - if (!lines[lines.Count - 1].EndsWith("at System.Threading.ThreadHelper.ThreadStart()")) + if (!lines.Exists(elem => elem.EndsWith("at TestStackOverflow.Program.Test(Boolean)"))) { - Console.WriteLine("Missing \"System.Threading.ThreadHelper.ThreadStart\" method frame at the last line"); + Console.WriteLine("Missing \"TestStackOverflow.Program.Test\" method frame"); return false; } From 08b244ed43b1684d8ee1fce9b6ed0e913f4cdba4 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 7 May 2020 10:30:27 -0700 Subject: [PATCH 025/420] [Arm64] ASIMD Rename AddReturningHighNarrow to AddHighNarrow (#35919) * Rename AddReturning{Rounded}HighNarrow to Add{Rounded}HighNarrow in AdvSimd.PlatformNotSupported.cs AdvSimd.cs * Rename SubtractReturning{Rounded}HighNarrow to Subtract{Rounded}HighNarrow in AdvSimd.PlatformNotSupported.cs AdvSimd.cs * Rename Add/SubtractReturning{Rounded}HighNarrow to Add/Subtract{Rounded}HighNarrow in hwintrinsiclistarm64.h * Update System.Runtime.Intrinsics.Experimental.cs * Rename Add/SubtractReturning{Rounded}HighNarrow to Add/Subtract{Rounded}HighNarrow in GenerateTests.csx * Update Helpers.cs Helpers.tt * Update AdvSimd/ --- src/coreclr/src/jit/hwintrinsiclistarm64.h | 16 +- ...cs => AddHighNarrowLower.Vector64.Byte.cs} | 54 ++-- ...s => AddHighNarrowLower.Vector64.Int16.cs} | 54 ++-- ...s => AddHighNarrowLower.Vector64.Int32.cs} | 54 ++-- ...s => AddHighNarrowLower.Vector64.SByte.cs} | 54 ++-- ... => AddHighNarrowLower.Vector64.UInt16.cs} | 54 ++-- ... => AddHighNarrowLower.Vector64.UInt32.cs} | 54 ++-- ...s => AddHighNarrowUpper.Vector128.Byte.cs} | 54 ++-- ... => AddHighNarrowUpper.Vector128.Int16.cs} | 54 ++-- ... => AddHighNarrowUpper.Vector128.Int32.cs} | 54 ++-- ... => AddHighNarrowUpper.Vector128.SByte.cs} | 54 ++-- ...=> AddHighNarrowUpper.Vector128.UInt16.cs} | 54 ++-- ...=> AddHighNarrowUpper.Vector128.UInt32.cs} | 54 ++-- ...ddRoundedHighNarrowLower.Vector64.Byte.cs} | 54 ++-- ...dRoundedHighNarrowLower.Vector64.Int16.cs} | 54 ++-- ...dRoundedHighNarrowLower.Vector64.Int32.cs} | 54 ++-- ...dRoundedHighNarrowLower.Vector64.SByte.cs} | 54 ++-- ...RoundedHighNarrowLower.Vector64.UInt16.cs} | 54 ++-- ...RoundedHighNarrowLower.Vector64.UInt32.cs} | 54 ++-- ...dRoundedHighNarrowUpper.Vector128.Byte.cs} | 54 ++-- ...RoundedHighNarrowUpper.Vector128.Int16.cs} | 54 ++-- ...RoundedHighNarrowUpper.Vector128.Int32.cs} | 54 ++-- ...RoundedHighNarrowUpper.Vector128.SByte.cs} | 54 ++-- ...oundedHighNarrowUpper.Vector128.UInt16.cs} | 54 ++-- ...oundedHighNarrowUpper.Vector128.UInt32.cs} | 54 ++-- .../Arm/AdvSimd/AdvSimd_r.csproj | 96 +++--- .../Arm/AdvSimd/AdvSimd_ro.csproj | 96 +++--- .../Arm/AdvSimd/Program.AdvSimd.cs | 96 +++--- ... SubtractHighNarrowLower.Vector64.Byte.cs} | 54 ++-- ...SubtractHighNarrowLower.Vector64.Int16.cs} | 54 ++-- ...SubtractHighNarrowLower.Vector64.Int32.cs} | 54 ++-- ...SubtractHighNarrowLower.Vector64.SByte.cs} | 54 ++-- ...ubtractHighNarrowLower.Vector64.UInt16.cs} | 54 ++-- ...ubtractHighNarrowLower.Vector64.UInt32.cs} | 54 ++-- ...SubtractHighNarrowUpper.Vector128.Byte.cs} | 54 ++-- ...ubtractHighNarrowUpper.Vector128.Int16.cs} | 54 ++-- ...ubtractHighNarrowUpper.Vector128.Int32.cs} | 54 ++-- ...ubtractHighNarrowUpper.Vector128.SByte.cs} | 54 ++-- ...btractHighNarrowUpper.Vector128.UInt16.cs} | 54 ++-- ...btractHighNarrowUpper.Vector128.UInt32.cs} | 54 ++-- ...ctRoundedHighNarrowLower.Vector64.Byte.cs} | 54 ++-- ...tRoundedHighNarrowLower.Vector64.Int16.cs} | 54 ++-- ...tRoundedHighNarrowLower.Vector64.Int32.cs} | 54 ++-- ...tRoundedHighNarrowLower.Vector64.SByte.cs} | 54 ++-- ...RoundedHighNarrowLower.Vector64.UInt16.cs} | 54 ++-- ...RoundedHighNarrowLower.Vector64.UInt32.cs} | 54 ++-- ...tRoundedHighNarrowUpper.Vector128.Byte.cs} | 54 ++-- ...RoundedHighNarrowUpper.Vector128.Int16.cs} | 54 ++-- ...RoundedHighNarrowUpper.Vector128.Int32.cs} | 54 ++-- ...RoundedHighNarrowUpper.Vector128.SByte.cs} | 54 ++-- ...oundedHighNarrowUpper.Vector128.UInt16.cs} | 54 ++-- ...oundedHighNarrowUpper.Vector128.UInt32.cs} | 54 ++-- .../Arm/Shared/GenerateTests.csx | 96 +++--- .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 96 +++--- .../HardwareIntrinsics/Arm/Shared/Helpers.tt | 16 +- .../Arm/AdvSimd.PlatformNotSupported.cs | 276 +++++++++--------- .../System/Runtime/Intrinsics/Arm/AdvSimd.cs | 276 +++++++++--------- .../System.Runtime.Intrinsics.Experimental.cs | 96 +++--- 58 files changed, 1876 insertions(+), 1876 deletions(-) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningRoundedHighNarrowLower.Vector64.Byte.cs => AddHighNarrowLower.Vector64.Byte.cs} (89%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningRoundedHighNarrowLower.Vector64.Int16.cs => AddHighNarrowLower.Vector64.Int16.cs} (89%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningRoundedHighNarrowLower.Vector64.Int32.cs => AddHighNarrowLower.Vector64.Int32.cs} (89%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningRoundedHighNarrowLower.Vector64.SByte.cs => AddHighNarrowLower.Vector64.SByte.cs} (89%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningRoundedHighNarrowLower.Vector64.UInt16.cs => AddHighNarrowLower.Vector64.UInt16.cs} (89%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningRoundedHighNarrowLower.Vector64.UInt32.cs => AddHighNarrowLower.Vector64.UInt32.cs} (89%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningHighNarrowUpper.Vector128.Byte.cs => AddHighNarrowUpper.Vector128.Byte.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningRoundedHighNarrowUpper.Vector128.Int16.cs => AddHighNarrowUpper.Vector128.Int16.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningRoundedHighNarrowUpper.Vector128.Int32.cs => AddHighNarrowUpper.Vector128.Int32.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningRoundedHighNarrowUpper.Vector128.SByte.cs => AddHighNarrowUpper.Vector128.SByte.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningHighNarrowUpper.Vector128.UInt16.cs => AddHighNarrowUpper.Vector128.UInt16.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningHighNarrowUpper.Vector128.UInt32.cs => AddHighNarrowUpper.Vector128.UInt32.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningHighNarrowLower.Vector64.Byte.cs => AddRoundedHighNarrowLower.Vector64.Byte.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningHighNarrowLower.Vector64.Int16.cs => AddRoundedHighNarrowLower.Vector64.Int16.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningHighNarrowLower.Vector64.Int32.cs => AddRoundedHighNarrowLower.Vector64.Int32.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningHighNarrowLower.Vector64.SByte.cs => AddRoundedHighNarrowLower.Vector64.SByte.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningHighNarrowLower.Vector64.UInt16.cs => AddRoundedHighNarrowLower.Vector64.UInt16.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningHighNarrowLower.Vector64.UInt32.cs => AddRoundedHighNarrowLower.Vector64.UInt32.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningRoundedHighNarrowUpper.Vector128.Byte.cs => AddRoundedHighNarrowUpper.Vector128.Byte.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningRoundedHighNarrowUpper.Vector128.Int16.cs => AddRoundedHighNarrowUpper.Vector128.Int16.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningRoundedHighNarrowUpper.Vector128.Int32.cs => AddRoundedHighNarrowUpper.Vector128.Int32.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningRoundedHighNarrowUpper.Vector128.SByte.cs => AddRoundedHighNarrowUpper.Vector128.SByte.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningRoundedHighNarrowUpper.Vector128.UInt16.cs => AddRoundedHighNarrowUpper.Vector128.UInt16.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningRoundedHighNarrowUpper.Vector128.UInt32.cs => AddRoundedHighNarrowUpper.Vector128.UInt32.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningHighNarrowLower.Vector64.Byte.cs => SubtractHighNarrowLower.Vector64.Byte.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningHighNarrowLower.Vector64.Int16.cs => SubtractHighNarrowLower.Vector64.Int16.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningHighNarrowLower.Vector64.Int32.cs => SubtractHighNarrowLower.Vector64.Int32.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningHighNarrowLower.Vector64.SByte.cs => SubtractHighNarrowLower.Vector64.SByte.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningHighNarrowLower.Vector64.UInt16.cs => SubtractHighNarrowLower.Vector64.UInt16.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningHighNarrowLower.Vector64.UInt32.cs => SubtractHighNarrowLower.Vector64.UInt32.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningHighNarrowUpper.Vector128.Byte.cs => SubtractHighNarrowUpper.Vector128.Byte.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningHighNarrowUpper.Vector128.Int16.cs => SubtractHighNarrowUpper.Vector128.Int16.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningHighNarrowUpper.Vector128.Int32.cs => SubtractHighNarrowUpper.Vector128.Int32.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningHighNarrowUpper.Vector128.SByte.cs => SubtractHighNarrowUpper.Vector128.SByte.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningHighNarrowUpper.Vector128.UInt16.cs => SubtractHighNarrowUpper.Vector128.UInt16.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningHighNarrowUpper.Vector128.UInt32.cs => SubtractHighNarrowUpper.Vector128.UInt32.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningRoundedHighNarrowLower.Vector64.Byte.cs => SubtractRoundedHighNarrowLower.Vector64.Byte.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningRoundedHighNarrowLower.Vector64.Int16.cs => SubtractRoundedHighNarrowLower.Vector64.Int16.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningRoundedHighNarrowLower.Vector64.Int32.cs => SubtractRoundedHighNarrowLower.Vector64.Int32.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningRoundedHighNarrowLower.Vector64.SByte.cs => SubtractRoundedHighNarrowLower.Vector64.SByte.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningRoundedHighNarrowLower.Vector64.UInt16.cs => SubtractRoundedHighNarrowLower.Vector64.UInt16.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningRoundedHighNarrowLower.Vector64.UInt32.cs => SubtractRoundedHighNarrowLower.Vector64.UInt32.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningRoundedHighNarrowUpper.Vector128.Byte.cs => SubtractRoundedHighNarrowUpper.Vector128.Byte.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningHighNarrowUpper.Vector128.Int16.cs => SubtractRoundedHighNarrowUpper.Vector128.Int16.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningHighNarrowUpper.Vector128.Int32.cs => SubtractRoundedHighNarrowUpper.Vector128.Int32.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractReturningHighNarrowUpper.Vector128.SByte.cs => SubtractRoundedHighNarrowUpper.Vector128.SByte.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningRoundedHighNarrowUpper.Vector128.UInt16.cs => SubtractRoundedHighNarrowUpper.Vector128.UInt16.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddReturningRoundedHighNarrowUpper.Vector128.UInt32.cs => SubtractRoundedHighNarrowUpper.Vector128.UInt32.cs} (91%) diff --git a/src/coreclr/src/jit/hwintrinsiclistarm64.h b/src/coreclr/src/jit/hwintrinsiclistarm64.h index bd192bd217bfb..ec39efddb4441 100644 --- a/src/coreclr/src/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/src/jit/hwintrinsiclistarm64.h @@ -69,15 +69,15 @@ HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningLowerAndAdd, HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningUpper, 16, 2, {INS_sabdl2, INS_uabdl2, INS_sabdl2, INS_uabdl2, INS_sabdl2, INS_uabdl2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningUpperAndAdd, 16, 3, {INS_sabal2, INS_uabal2, INS_sabal2, INS_uabal2, INS_sabal2, INS_uabal2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) HARDWARE_INTRINSIC(AdvSimd, Add, -1, 2, {INS_add, INS_add, INS_add, INS_add, INS_add, INS_add, INS_add, INS_add, INS_fadd, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, AddHighNarrowLower, 8, 2, {INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, AddHighNarrowUpper, 16, 3, {INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(AdvSimd, AddPairwise, 8, 2, {INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_invalid, INS_invalid, INS_faddp, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWidening, -1, 1, {INS_saddlp, INS_uaddlp, INS_saddlp, INS_uaddlp, INS_saddlp, INS_uaddlp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWideningAndAdd, -1, 2, {INS_sadalp, INS_uadalp, INS_sadalp, INS_uadalp, INS_sadalp, INS_uadalp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWideningAndAddScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sadalp, INS_uadalp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWideningScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_saddlp, INS_uaddlp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd, AddReturningHighNarrowLower, 8, 2, {INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, AddReturningHighNarrowUpper, 16, 3, {INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, AddReturningRoundedHighNarrowLower, 8, 2, {INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, AddReturningRoundedHighNarrowUpper, 16, 3, {INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, AddRoundedHighNarrowLower, 8, 2, {INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, AddRoundedHighNarrowUpper, 16, 3, {INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(AdvSimd, AddSaturate, -1, 2, {INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AdvSimd, AddSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqadd, INS_uqadd, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_Commutative) HARDWARE_INTRINSIC(AdvSimd, AddScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_add, INS_add, INS_fadd, INS_fadd}, HW_Category_SIMDScalar, HW_Flag_Commutative) @@ -144,10 +144,10 @@ HARDWARE_INTRINSIC(AdvSimd, ReciprocalStep, - HARDWARE_INTRINSIC(AdvSimd, SqrtScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fsqrt, INS_fsqrt}, HW_Category_SIMDScalar, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, Store, -1, 2, {INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1}, HW_Category_MemoryStore, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) HARDWARE_INTRINSIC(AdvSimd, Subtract, -1, 2, {INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_fsub, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, SubtractReturningHighNarrowLower, 8, 2, {INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, SubtractReturningHighNarrowUpper, 16, 3, {INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, SubtractReturningRoundedHighNarrowLower, 8, 2, {INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, SubtractReturningRoundedHighNarrowUpper, 16, 3, {INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, SubtractHighNarrowLower, 8, 2, {INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, SubtractHighNarrowUpper, 16, 3, {INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, SubtractRoundedHighNarrowLower, 8, 2, {INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, SubtractRoundedHighNarrowUpper, 16, 3, {INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(AdvSimd, SubtractSaturate, -1, 2, {INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, SubtractSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqsub, INS_uqsub, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, SubtractScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sub, INS_sub, INS_fsub, INS_fsub}, HW_Category_SIMDScalar, HW_Flag_NoFlag) diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Byte.cs similarity index 89% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Byte.cs index 5d8bd3f85dc95..3afd373050037 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningRoundedHighNarrowLower_Vector64_Byte() + private static void AddHighNarrowLower_Vector64_Byte() { - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningRoundedHighNarrowLower_Vector64_Byte() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Byte + public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte testClass) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningRound private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Byte() + static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Byte Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Byte() + public SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Byte(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte(); + var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Int16.cs similarity index 89% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Int16.cs index 461a9e67c239c..5b7b69db8a75f 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningRoundedHighNarrowLower_Vector64_Int16() + private static void AddHighNarrowLower_Vector64_Int16() { - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningRoundedHighNarrowLower_Vector64_Int16() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int16 + public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16 testClass) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningRound private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int16() + static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int1 Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int16() + public SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int16(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16(); + var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Int32.cs similarity index 89% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Int32.cs index 620812e188efc..dd832dd534564 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningRoundedHighNarrowLower_Vector64_Int32() + private static void AddHighNarrowLower_Vector64_Int32() { - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningRoundedHighNarrowLower_Vector64_Int32() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int32 + public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32 testClass) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningRound private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int32() + static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int3 Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int32() + public SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int32(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32(); + var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int64*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.SByte.cs similarity index 89% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.SByte.cs index 910c8781999c7..89fe1b5029ecb 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningRoundedHighNarrowLower_Vector64_SByte() + private static void AddHighNarrowLower_Vector64_SByte() { - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningRoundedHighNarrowLower_Vector64_SByte() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_SByte + public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte testClass) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningRound private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_SByte() + static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_SByt Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_SByte() + public SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_SByte(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte(); + var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.UInt16.cs similarity index 89% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.UInt16.cs index a94328c85d3f6..b61ff798ed8cf 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningRoundedHighNarrowLower_Vector64_UInt16() + private static void AddHighNarrowLower_Vector64_UInt16() { - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningRoundedHighNarrowLower_Vector64_UInt16() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt16 + public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16 testClass) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningRound private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt16() + static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt16() + public SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt16(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16(); + var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.UInt32.cs similarity index 89% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.UInt32.cs index 6f720f8dc5da8..9d3c0769354f9 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowLower.Vector64.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningRoundedHighNarrowLower_Vector64_UInt32() + private static void AddHighNarrowLower_Vector64_UInt32() { - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningRoundedHighNarrowLower_Vector64_UInt32() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt32 + public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32 testClass) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningRound private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt32() + static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt32() + public SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt32(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32(); + var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractReturningRoundedHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowLower( + var result = AdvSimd.AddHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Byte.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Byte.cs index 062f43f5629bb..7a070b8a17920 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningHighNarrowUpper_Vector128_Byte() + private static void AddHighNarrowUpper_Vector128_Byte() { - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningHighNarrowUpper_Vector128_Byte() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Byte + public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte testClass) { - var result = AdvSimd.SubtractReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningHigh private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Byte() + static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Byte() + public SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)), AdvSimd.LoadVector128((UInt16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Byte(); - var result = AdvSimd.SubtractReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte(); + var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)), AdvSimd.LoadVector128((UInt16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Int16.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Int16.cs index d9c07e12e15c6..a3897efe7c132 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningRoundedHighNarrowUpper_Vector128_Int16() + private static void AddHighNarrowUpper_Vector128_Int16() { - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningRoundedHighNarrowUpper_Vector128_Int16() } } - public sealed unsafe class SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int16 + public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16 testClass) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningRoundedHi private DataTable _dataTable; - static SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int16() + static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int16() + public SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)), AdvSimd.LoadVector128((Int32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int16(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16(); + var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)), AdvSimd.LoadVector128((Int32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Int32.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Int32.cs index a16ee2d136605..45740dbbcee63 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningRoundedHighNarrowUpper_Vector128_Int32() + private static void AddHighNarrowUpper_Vector128_Int32() { - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningRoundedHighNarrowUpper_Vector128_Int32() } } - public sealed unsafe class SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int32 + public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32 testClass) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningRoundedHi private DataTable _dataTable; - static SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int32() + static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int32() + public SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)), AdvSimd.LoadVector128((Int64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int32(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32(); + var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)), AdvSimd.LoadVector128((Int64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.SByte.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.SByte.cs index cf1a0a0d823d3..23d291db07c17 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningRoundedHighNarrowUpper_Vector128_SByte() + private static void AddHighNarrowUpper_Vector128_SByte() { - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningRoundedHighNarrowUpper_Vector128_SByte() } } - public sealed unsafe class SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_SByte + public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte testClass) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningRoundedHi private DataTable _dataTable; - static SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_SByte() + static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_SByte() + public SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)), AdvSimd.LoadVector128((Int16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_SByte(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte(); + var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)), AdvSimd.LoadVector128((Int16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.UInt16.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.UInt16.cs index 8d2aeb28ff964..aab766401538c 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningHighNarrowUpper_Vector128_UInt16() + private static void AddHighNarrowUpper_Vector128_UInt16() { - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningHighNarrowUpper_Vector128_UInt16() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt16 + public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16 testClass) { - var result = AdvSimd.SubtractReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningHigh private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt16() + static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt16() + public SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)), AdvSimd.LoadVector128((UInt32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt16(); - var result = AdvSimd.SubtractReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16(); + var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)), AdvSimd.LoadVector128((UInt32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.UInt32.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.UInt32.cs index 858e3db611b20..dd881a90a4467 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningHighNarrowUpper_Vector128_UInt32() + private static void AddHighNarrowUpper_Vector128_UInt32() { - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningHighNarrowUpper_Vector128_UInt32() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt32 + public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32 testClass) { - var result = AdvSimd.SubtractReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningHigh private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt32() + static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt32() + public SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)), AdvSimd.LoadVector128((UInt64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt32(); - var result = AdvSimd.SubtractReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32(); + var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.AddHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)), AdvSimd.LoadVector128((UInt64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Byte.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Byte.cs index dd37156add5ab..b05d6361fbd20 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningHighNarrowLower_Vector64_Byte() + private static void AddRoundedHighNarrowLower_Vector64_Byte() { - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningHighNarrowLower_Vector64_Byte() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Byte + public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte testClass) { - var result = AdvSimd.SubtractReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningHighN private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Byte() + static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Byte() + public SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractReturningHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractReturningHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Byte(); - var result = AdvSimd.SubtractReturningHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte(); + var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Int16.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Int16.cs index c5e972fa4694b..07985b071e27c 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningHighNarrowLower_Vector64_Int16() + private static void AddRoundedHighNarrowLower_Vector64_Int16() { - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningHighNarrowLower_Vector64_Int16() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int16 + public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16 testClass) { - var result = AdvSimd.SubtractReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningHighN private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int16() + static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int16() + public SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractReturningHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractReturningHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int16(); - var result = AdvSimd.SubtractReturningHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16(); + var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Int32.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Int32.cs index 3595251d62901..70291f629f7be 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningHighNarrowLower_Vector64_Int32() + private static void AddRoundedHighNarrowLower_Vector64_Int32() { - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningHighNarrowLower_Vector64_Int32() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int32 + public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32 testClass) { - var result = AdvSimd.SubtractReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningHighN private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int32() + static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int32() + public SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractReturningHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractReturningHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int32(); - var result = AdvSimd.SubtractReturningHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32(); + var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int64*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.SByte.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.SByte.cs index f0a908558b14a..3ff7bbe113b0c 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningHighNarrowLower_Vector64_SByte() + private static void AddRoundedHighNarrowLower_Vector64_SByte() { - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningHighNarrowLower_Vector64_SByte() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_SByte + public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte testClass) { - var result = AdvSimd.SubtractReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningHighN private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_SByte() + static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_SByte() + public SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractReturningHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractReturningHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_SByte(); - var result = AdvSimd.SubtractReturningHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte(); + var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.UInt16.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.UInt16.cs index eca511d7675be..d8c3191bcf669 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningHighNarrowLower_Vector64_UInt16() + private static void AddRoundedHighNarrowLower_Vector64_UInt16() { - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningHighNarrowLower_Vector64_UInt16() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt16 + public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16 testClass) { - var result = AdvSimd.SubtractReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningHighN private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt16() + static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt16() + public SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractReturningHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractReturningHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt16(); - var result = AdvSimd.SubtractReturningHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16(); + var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.UInt32.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.UInt32.cs index 84e08fc67ec36..baab52fe7dae7 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowLower.Vector64.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningHighNarrowLower_Vector64_UInt32() + private static void AddRoundedHighNarrowLower_Vector64_UInt32() { - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningHighNarrowLower_Vector64_UInt32() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt32 + public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32 testClass) { - var result = AdvSimd.SubtractReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractReturningHighN private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt32() + static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt32() + public SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractReturningHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractReturningHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt32(); - var result = AdvSimd.SubtractReturningHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32(); + var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractReturningHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Byte.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Byte.cs index 562d71f9d67d0..e6abcafcc588b 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningRoundedHighNarrowUpper_Vector128_Byte() + private static void AddRoundedHighNarrowUpper_Vector128_Byte() { - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningRoundedHighNarrowUpper_Vector128_Byte() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Byte + public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte testClass) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningRoun private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Byte() + static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_By Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Byte() + public SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)), AdvSimd.LoadVector128((UInt16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Byte(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte(); + var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)), AdvSimd.LoadVector128((UInt16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Int16.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Int16.cs index ce3bb0f3705f8..bbfae2866920e 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningRoundedHighNarrowUpper_Vector128_Int16() + private static void AddRoundedHighNarrowUpper_Vector128_Int16() { - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningRoundedHighNarrowUpper_Vector128_Int16() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int16 + public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16 testClass) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningRoun private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int16() + static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_In Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int16() + public SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)), AdvSimd.LoadVector128((Int32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int16(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16(); + var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)), AdvSimd.LoadVector128((Int32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Int32.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Int32.cs index 773665aeb6d1e..9dc5d969279b1 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningRoundedHighNarrowUpper_Vector128_Int32() + private static void AddRoundedHighNarrowUpper_Vector128_Int32() { - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningRoundedHighNarrowUpper_Vector128_Int32() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int32 + public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32 testClass) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningRoun private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int32() + static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_In Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int32() + public SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)), AdvSimd.LoadVector128((Int64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int32(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32(); + var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)), AdvSimd.LoadVector128((Int64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.SByte.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.SByte.cs index bdc097d7fb5f9..5ac9c441385ec 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningRoundedHighNarrowUpper_Vector128_SByte() + private static void AddRoundedHighNarrowUpper_Vector128_SByte() { - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningRoundedHighNarrowUpper_Vector128_SByte() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_SByte + public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte testClass) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningRoun private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_SByte() + static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_SB Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_SByte() + public SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)), AdvSimd.LoadVector128((Int16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_SByte(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte(); + var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)), AdvSimd.LoadVector128((Int16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.UInt16.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.UInt16.cs index 03f61e4b9e4d5..7eddbc5f6d780 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningRoundedHighNarrowUpper_Vector128_UInt16() + private static void AddRoundedHighNarrowUpper_Vector128_UInt16() { - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningRoundedHighNarrowUpper_Vector128_UInt16() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt16 + public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16 testClass) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningRoun private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt16() + static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UI Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt16() + public SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)), AdvSimd.LoadVector128((UInt32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt16(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16(); + var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)), AdvSimd.LoadVector128((UInt32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.UInt32.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.UInt32.cs index 2e1e1af8a603e..fb7e068bd16de 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningRoundedHighNarrowUpper.Vector128.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningRoundedHighNarrowUpper_Vector128_UInt32() + private static void AddRoundedHighNarrowUpper_Vector128_UInt32() { - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningRoundedHighNarrowUpper_Vector128_UInt32() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt32 + public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32 testClass) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningRoun private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt32() + static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UI Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt32() + public SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)), AdvSimd.LoadVector128((UInt64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt32(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32(); + var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractReturningRoundedHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)), AdvSimd.LoadVector128((UInt64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj index 1d218c9af69eb..e31d1407a1671 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj @@ -92,6 +92,18 @@ + + + + + + + + + + + + @@ -123,30 +135,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + @@ -740,30 +740,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj index 67094c63b5267..22e73f0c0be11 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj @@ -92,6 +92,18 @@ + + + + + + + + + + + + @@ -123,30 +135,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + @@ -740,30 +740,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs index 47caf74ea0e22..246f31429980b 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs @@ -96,6 +96,18 @@ static Program() ["Add.Vector128.UInt16"] = Add_Vector128_UInt16, ["Add.Vector128.UInt32"] = Add_Vector128_UInt32, ["Add.Vector128.UInt64"] = Add_Vector128_UInt64, + ["AddHighNarrowLower.Vector64.Byte"] = AddHighNarrowLower_Vector64_Byte, + ["AddHighNarrowLower.Vector64.Int16"] = AddHighNarrowLower_Vector64_Int16, + ["AddHighNarrowLower.Vector64.Int32"] = AddHighNarrowLower_Vector64_Int32, + ["AddHighNarrowLower.Vector64.SByte"] = AddHighNarrowLower_Vector64_SByte, + ["AddHighNarrowLower.Vector64.UInt16"] = AddHighNarrowLower_Vector64_UInt16, + ["AddHighNarrowLower.Vector64.UInt32"] = AddHighNarrowLower_Vector64_UInt32, + ["AddHighNarrowUpper.Vector128.Byte"] = AddHighNarrowUpper_Vector128_Byte, + ["AddHighNarrowUpper.Vector128.Int16"] = AddHighNarrowUpper_Vector128_Int16, + ["AddHighNarrowUpper.Vector128.Int32"] = AddHighNarrowUpper_Vector128_Int32, + ["AddHighNarrowUpper.Vector128.SByte"] = AddHighNarrowUpper_Vector128_SByte, + ["AddHighNarrowUpper.Vector128.UInt16"] = AddHighNarrowUpper_Vector128_UInt16, + ["AddHighNarrowUpper.Vector128.UInt32"] = AddHighNarrowUpper_Vector128_UInt32, ["AddPairwise.Vector64.Byte"] = AddPairwise_Vector64_Byte, ["AddPairwise.Vector64.Int16"] = AddPairwise_Vector64_Int16, ["AddPairwise.Vector64.Int32"] = AddPairwise_Vector64_Int32, @@ -127,30 +139,18 @@ static Program() ["AddPairwiseWideningAndAddScalar.Vector64.UInt32"] = AddPairwiseWideningAndAddScalar_Vector64_UInt32, ["AddPairwiseWideningScalar.Vector64.Int32"] = AddPairwiseWideningScalar_Vector64_Int32, ["AddPairwiseWideningScalar.Vector64.UInt32"] = AddPairwiseWideningScalar_Vector64_UInt32, - ["AddReturningHighNarrowLower.Vector64.Byte"] = AddReturningHighNarrowLower_Vector64_Byte, - ["AddReturningHighNarrowLower.Vector64.Int16"] = AddReturningHighNarrowLower_Vector64_Int16, - ["AddReturningHighNarrowLower.Vector64.Int32"] = AddReturningHighNarrowLower_Vector64_Int32, - ["AddReturningHighNarrowLower.Vector64.SByte"] = AddReturningHighNarrowLower_Vector64_SByte, - ["AddReturningHighNarrowLower.Vector64.UInt16"] = AddReturningHighNarrowLower_Vector64_UInt16, - ["AddReturningHighNarrowLower.Vector64.UInt32"] = AddReturningHighNarrowLower_Vector64_UInt32, - ["AddReturningHighNarrowUpper.Vector128.Byte"] = AddReturningHighNarrowUpper_Vector128_Byte, - ["AddReturningHighNarrowUpper.Vector128.Int16"] = AddReturningHighNarrowUpper_Vector128_Int16, - ["AddReturningHighNarrowUpper.Vector128.Int32"] = AddReturningHighNarrowUpper_Vector128_Int32, - ["AddReturningHighNarrowUpper.Vector128.SByte"] = AddReturningHighNarrowUpper_Vector128_SByte, - ["AddReturningHighNarrowUpper.Vector128.UInt16"] = AddReturningHighNarrowUpper_Vector128_UInt16, - ["AddReturningHighNarrowUpper.Vector128.UInt32"] = AddReturningHighNarrowUpper_Vector128_UInt32, - ["AddReturningRoundedHighNarrowLower.Vector64.Byte"] = AddReturningRoundedHighNarrowLower_Vector64_Byte, - ["AddReturningRoundedHighNarrowLower.Vector64.Int16"] = AddReturningRoundedHighNarrowLower_Vector64_Int16, - ["AddReturningRoundedHighNarrowLower.Vector64.Int32"] = AddReturningRoundedHighNarrowLower_Vector64_Int32, - ["AddReturningRoundedHighNarrowLower.Vector64.SByte"] = AddReturningRoundedHighNarrowLower_Vector64_SByte, - ["AddReturningRoundedHighNarrowLower.Vector64.UInt16"] = AddReturningRoundedHighNarrowLower_Vector64_UInt16, - ["AddReturningRoundedHighNarrowLower.Vector64.UInt32"] = AddReturningRoundedHighNarrowLower_Vector64_UInt32, - ["AddReturningRoundedHighNarrowUpper.Vector128.Byte"] = AddReturningRoundedHighNarrowUpper_Vector128_Byte, - ["AddReturningRoundedHighNarrowUpper.Vector128.Int16"] = AddReturningRoundedHighNarrowUpper_Vector128_Int16, - ["AddReturningRoundedHighNarrowUpper.Vector128.Int32"] = AddReturningRoundedHighNarrowUpper_Vector128_Int32, - ["AddReturningRoundedHighNarrowUpper.Vector128.SByte"] = AddReturningRoundedHighNarrowUpper_Vector128_SByte, - ["AddReturningRoundedHighNarrowUpper.Vector128.UInt16"] = AddReturningRoundedHighNarrowUpper_Vector128_UInt16, - ["AddReturningRoundedHighNarrowUpper.Vector128.UInt32"] = AddReturningRoundedHighNarrowUpper_Vector128_UInt32, + ["AddRoundedHighNarrowLower.Vector64.Byte"] = AddRoundedHighNarrowLower_Vector64_Byte, + ["AddRoundedHighNarrowLower.Vector64.Int16"] = AddRoundedHighNarrowLower_Vector64_Int16, + ["AddRoundedHighNarrowLower.Vector64.Int32"] = AddRoundedHighNarrowLower_Vector64_Int32, + ["AddRoundedHighNarrowLower.Vector64.SByte"] = AddRoundedHighNarrowLower_Vector64_SByte, + ["AddRoundedHighNarrowLower.Vector64.UInt16"] = AddRoundedHighNarrowLower_Vector64_UInt16, + ["AddRoundedHighNarrowLower.Vector64.UInt32"] = AddRoundedHighNarrowLower_Vector64_UInt32, + ["AddRoundedHighNarrowUpper.Vector128.Byte"] = AddRoundedHighNarrowUpper_Vector128_Byte, + ["AddRoundedHighNarrowUpper.Vector128.Int16"] = AddRoundedHighNarrowUpper_Vector128_Int16, + ["AddRoundedHighNarrowUpper.Vector128.Int32"] = AddRoundedHighNarrowUpper_Vector128_Int32, + ["AddRoundedHighNarrowUpper.Vector128.SByte"] = AddRoundedHighNarrowUpper_Vector128_SByte, + ["AddRoundedHighNarrowUpper.Vector128.UInt16"] = AddRoundedHighNarrowUpper_Vector128_UInt16, + ["AddRoundedHighNarrowUpper.Vector128.UInt32"] = AddRoundedHighNarrowUpper_Vector128_UInt32, ["AddSaturate.Vector64.Byte"] = AddSaturate_Vector64_Byte, ["AddSaturate.Vector64.Int16"] = AddSaturate_Vector64_Int16, ["AddSaturate.Vector64.Int32"] = AddSaturate_Vector64_Int32, @@ -744,30 +744,30 @@ static Program() ["Subtract.Vector128.UInt16"] = Subtract_Vector128_UInt16, ["Subtract.Vector128.UInt32"] = Subtract_Vector128_UInt32, ["Subtract.Vector128.UInt64"] = Subtract_Vector128_UInt64, - ["SubtractReturningHighNarrowLower.Vector64.Byte"] = SubtractReturningHighNarrowLower_Vector64_Byte, - ["SubtractReturningHighNarrowLower.Vector64.Int16"] = SubtractReturningHighNarrowLower_Vector64_Int16, - ["SubtractReturningHighNarrowLower.Vector64.Int32"] = SubtractReturningHighNarrowLower_Vector64_Int32, - ["SubtractReturningHighNarrowLower.Vector64.SByte"] = SubtractReturningHighNarrowLower_Vector64_SByte, - ["SubtractReturningHighNarrowLower.Vector64.UInt16"] = SubtractReturningHighNarrowLower_Vector64_UInt16, - ["SubtractReturningHighNarrowLower.Vector64.UInt32"] = SubtractReturningHighNarrowLower_Vector64_UInt32, - ["SubtractReturningHighNarrowUpper.Vector128.Byte"] = SubtractReturningHighNarrowUpper_Vector128_Byte, - ["SubtractReturningHighNarrowUpper.Vector128.Int16"] = SubtractReturningHighNarrowUpper_Vector128_Int16, - ["SubtractReturningHighNarrowUpper.Vector128.Int32"] = SubtractReturningHighNarrowUpper_Vector128_Int32, - ["SubtractReturningHighNarrowUpper.Vector128.SByte"] = SubtractReturningHighNarrowUpper_Vector128_SByte, - ["SubtractReturningHighNarrowUpper.Vector128.UInt16"] = SubtractReturningHighNarrowUpper_Vector128_UInt16, - ["SubtractReturningHighNarrowUpper.Vector128.UInt32"] = SubtractReturningHighNarrowUpper_Vector128_UInt32, - ["SubtractReturningRoundedHighNarrowLower.Vector64.Byte"] = SubtractReturningRoundedHighNarrowLower_Vector64_Byte, - ["SubtractReturningRoundedHighNarrowLower.Vector64.Int16"] = SubtractReturningRoundedHighNarrowLower_Vector64_Int16, - ["SubtractReturningRoundedHighNarrowLower.Vector64.Int32"] = SubtractReturningRoundedHighNarrowLower_Vector64_Int32, - ["SubtractReturningRoundedHighNarrowLower.Vector64.SByte"] = SubtractReturningRoundedHighNarrowLower_Vector64_SByte, - ["SubtractReturningRoundedHighNarrowLower.Vector64.UInt16"] = SubtractReturningRoundedHighNarrowLower_Vector64_UInt16, - ["SubtractReturningRoundedHighNarrowLower.Vector64.UInt32"] = SubtractReturningRoundedHighNarrowLower_Vector64_UInt32, - ["SubtractReturningRoundedHighNarrowUpper.Vector128.Byte"] = SubtractReturningRoundedHighNarrowUpper_Vector128_Byte, - ["SubtractReturningRoundedHighNarrowUpper.Vector128.Int16"] = SubtractReturningRoundedHighNarrowUpper_Vector128_Int16, - ["SubtractReturningRoundedHighNarrowUpper.Vector128.Int32"] = SubtractReturningRoundedHighNarrowUpper_Vector128_Int32, - ["SubtractReturningRoundedHighNarrowUpper.Vector128.SByte"] = SubtractReturningRoundedHighNarrowUpper_Vector128_SByte, - ["SubtractReturningRoundedHighNarrowUpper.Vector128.UInt16"] = SubtractReturningRoundedHighNarrowUpper_Vector128_UInt16, - ["SubtractReturningRoundedHighNarrowUpper.Vector128.UInt32"] = SubtractReturningRoundedHighNarrowUpper_Vector128_UInt32, + ["SubtractHighNarrowLower.Vector64.Byte"] = SubtractHighNarrowLower_Vector64_Byte, + ["SubtractHighNarrowLower.Vector64.Int16"] = SubtractHighNarrowLower_Vector64_Int16, + ["SubtractHighNarrowLower.Vector64.Int32"] = SubtractHighNarrowLower_Vector64_Int32, + ["SubtractHighNarrowLower.Vector64.SByte"] = SubtractHighNarrowLower_Vector64_SByte, + ["SubtractHighNarrowLower.Vector64.UInt16"] = SubtractHighNarrowLower_Vector64_UInt16, + ["SubtractHighNarrowLower.Vector64.UInt32"] = SubtractHighNarrowLower_Vector64_UInt32, + ["SubtractHighNarrowUpper.Vector128.Byte"] = SubtractHighNarrowUpper_Vector128_Byte, + ["SubtractHighNarrowUpper.Vector128.Int16"] = SubtractHighNarrowUpper_Vector128_Int16, + ["SubtractHighNarrowUpper.Vector128.Int32"] = SubtractHighNarrowUpper_Vector128_Int32, + ["SubtractHighNarrowUpper.Vector128.SByte"] = SubtractHighNarrowUpper_Vector128_SByte, + ["SubtractHighNarrowUpper.Vector128.UInt16"] = SubtractHighNarrowUpper_Vector128_UInt16, + ["SubtractHighNarrowUpper.Vector128.UInt32"] = SubtractHighNarrowUpper_Vector128_UInt32, + ["SubtractRoundedHighNarrowLower.Vector64.Byte"] = SubtractRoundedHighNarrowLower_Vector64_Byte, + ["SubtractRoundedHighNarrowLower.Vector64.Int16"] = SubtractRoundedHighNarrowLower_Vector64_Int16, + ["SubtractRoundedHighNarrowLower.Vector64.Int32"] = SubtractRoundedHighNarrowLower_Vector64_Int32, + ["SubtractRoundedHighNarrowLower.Vector64.SByte"] = SubtractRoundedHighNarrowLower_Vector64_SByte, + ["SubtractRoundedHighNarrowLower.Vector64.UInt16"] = SubtractRoundedHighNarrowLower_Vector64_UInt16, + ["SubtractRoundedHighNarrowLower.Vector64.UInt32"] = SubtractRoundedHighNarrowLower_Vector64_UInt32, + ["SubtractRoundedHighNarrowUpper.Vector128.Byte"] = SubtractRoundedHighNarrowUpper_Vector128_Byte, + ["SubtractRoundedHighNarrowUpper.Vector128.Int16"] = SubtractRoundedHighNarrowUpper_Vector128_Int16, + ["SubtractRoundedHighNarrowUpper.Vector128.Int32"] = SubtractRoundedHighNarrowUpper_Vector128_Int32, + ["SubtractRoundedHighNarrowUpper.Vector128.SByte"] = SubtractRoundedHighNarrowUpper_Vector128_SByte, + ["SubtractRoundedHighNarrowUpper.Vector128.UInt16"] = SubtractRoundedHighNarrowUpper_Vector128_UInt16, + ["SubtractRoundedHighNarrowUpper.Vector128.UInt32"] = SubtractRoundedHighNarrowUpper_Vector128_UInt32, ["SubtractSaturate.Vector64.Byte"] = SubtractSaturate_Vector64_Byte, ["SubtractSaturate.Vector64.Int16"] = SubtractSaturate_Vector64_Int16, ["SubtractSaturate.Vector64.Int32"] = SubtractSaturate_Vector64_Int32, diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Byte.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Byte.cs index 2e8bf9f87d7ec..e4eca0b5ec0c3 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningHighNarrowLower_Vector64_Byte() + private static void SubtractHighNarrowLower_Vector64_Byte() { - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningHighNarrowLower_Vector64_Byte() } } - public sealed unsafe class SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Byte + public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte testClass) { - var result = AdvSimd.AddReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningHighNarrow private DataTable _dataTable; - static SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Byte() + static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Byte() + public SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddReturningHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddReturningHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Byte(); - var result = AdvSimd.AddReturningHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte(); + var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Int16.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Int16.cs index 491b2bb6b8c6d..6232f7360d1d3 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningHighNarrowLower_Vector64_Int16() + private static void SubtractHighNarrowLower_Vector64_Int16() { - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningHighNarrowLower_Vector64_Int16() } } - public sealed unsafe class SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int16 + public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16 testClass) { - var result = AdvSimd.AddReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningHighNarrow private DataTable _dataTable; - static SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int16() + static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int16() + public SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddReturningHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddReturningHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int16(); - var result = AdvSimd.AddReturningHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16(); + var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Int32.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Int32.cs index af0e0e56953ac..5fd57683f17da 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningHighNarrowLower_Vector64_Int32() + private static void SubtractHighNarrowLower_Vector64_Int32() { - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningHighNarrowLower_Vector64_Int32() } } - public sealed unsafe class SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int32 + public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32 testClass) { - var result = AdvSimd.AddReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningHighNarrow private DataTable _dataTable; - static SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int32() + static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int32() + public SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddReturningHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddReturningHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int32(); - var result = AdvSimd.AddReturningHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32(); + var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int64*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.SByte.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.SByte.cs index b0774c25a3f8e..4156595e1a54a 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningHighNarrowLower_Vector64_SByte() + private static void SubtractHighNarrowLower_Vector64_SByte() { - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningHighNarrowLower_Vector64_SByte() } } - public sealed unsafe class SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_SByte + public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte testClass) { - var result = AdvSimd.AddReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningHighNarrow private DataTable _dataTable; - static SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_SByte() + static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_SByte() + public SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddReturningHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddReturningHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_SByte(); - var result = AdvSimd.AddReturningHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte(); + var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.UInt16.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.UInt16.cs index c6d49f3fdd5de..652291a79460d 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningHighNarrowLower_Vector64_UInt16() + private static void SubtractHighNarrowLower_Vector64_UInt16() { - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningHighNarrowLower_Vector64_UInt16() } } - public sealed unsafe class SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt16 + public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16 testClass) { - var result = AdvSimd.AddReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningHighNarrow private DataTable _dataTable; - static SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt16() + static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt16() + public SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddReturningHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddReturningHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt16(); - var result = AdvSimd.AddReturningHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16(); + var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.UInt32.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.UInt32.cs index b2171fbb91d30..a0db7ab73cc49 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowLower.Vector64.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningHighNarrowLower_Vector64_UInt32() + private static void SubtractHighNarrowLower_Vector64_UInt32() { - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningHighNarrowLower_Vector64_UInt32() } } - public sealed unsafe class SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt32 + public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32 testClass) { - var result = AdvSimd.AddReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningHighNarrow private DataTable _dataTable; - static SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt32() + static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt32() + public SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddReturningHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddReturningHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt32(); - var result = AdvSimd.AddReturningHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32(); + var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddReturningHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Byte.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Byte.cs index 1415f01db140c..a12435926fe8c 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningHighNarrowUpper_Vector128_Byte() + private static void SubtractHighNarrowUpper_Vector128_Byte() { - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningHighNarrowUpper_Vector128_Byte() } } - public sealed unsafe class SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Byte + public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte testClass) { - var result = AdvSimd.AddReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningHighNarro private DataTable _dataTable; - static SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Byte() + static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Byte() + public SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)), AdvSimd.LoadVector128((UInt16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Byte(); - var result = AdvSimd.AddReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte(); + var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)), AdvSimd.LoadVector128((UInt16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Int16.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Int16.cs index dadff1b0f9c60..f2942febe2343 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningHighNarrowUpper_Vector128_Int16() + private static void SubtractHighNarrowUpper_Vector128_Int16() { - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningHighNarrowUpper_Vector128_Int16() } } - public sealed unsafe class SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int16 + public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16 testClass) { - var result = AdvSimd.AddReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningHighNarro private DataTable _dataTable; - static SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int16() + static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int16() + public SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)), AdvSimd.LoadVector128((Int32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int16(); - var result = AdvSimd.AddReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16(); + var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)), AdvSimd.LoadVector128((Int32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Int32.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Int32.cs index 20f1ac3dd78b0..3b33e723b49b3 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningHighNarrowUpper_Vector128_Int32() + private static void SubtractHighNarrowUpper_Vector128_Int32() { - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningHighNarrowUpper_Vector128_Int32() } } - public sealed unsafe class SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int32 + public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32 testClass) { - var result = AdvSimd.AddReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningHighNarro private DataTable _dataTable; - static SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int32() + static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int32() + public SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)), AdvSimd.LoadVector128((Int64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int32(); - var result = AdvSimd.AddReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32(); + var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)), AdvSimd.LoadVector128((Int64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.SByte.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.SByte.cs index c4c9e278bfe8e..7ba09a938529d 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningHighNarrowUpper_Vector128_SByte() + private static void SubtractHighNarrowUpper_Vector128_SByte() { - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningHighNarrowUpper_Vector128_SByte() } } - public sealed unsafe class SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_SByte + public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte testClass) { - var result = AdvSimd.AddReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningHighNarro private DataTable _dataTable; - static SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_SByte() + static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_SByte() + public SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)), AdvSimd.LoadVector128((Int16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_SByte(); - var result = AdvSimd.AddReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte(); + var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)), AdvSimd.LoadVector128((Int16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.UInt16.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.UInt16.cs index 54bf48bb0e2b5..374f10f1119d0 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningHighNarrowUpper_Vector128_UInt16() + private static void SubtractHighNarrowUpper_Vector128_UInt16() { - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningHighNarrowUpper_Vector128_UInt16() } } - public sealed unsafe class SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt16 + public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16 testClass) { - var result = AdvSimd.AddReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningHighNarro private DataTable _dataTable; - static SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt16() + static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt16() + public SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)), AdvSimd.LoadVector128((UInt32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt16(); - var result = AdvSimd.AddReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16(); + var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)), AdvSimd.LoadVector128((UInt32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.UInt32.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.UInt32.cs index 602ac9643592e..4111c8ef3c8ec 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningHighNarrowUpper.Vector128.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningHighNarrowUpper_Vector128_UInt32() + private static void SubtractHighNarrowUpper_Vector128_UInt32() { - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningHighNarrowUpper_Vector128_UInt32() } } - public sealed unsafe class SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt32 + public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32 testClass) { - var result = AdvSimd.AddReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningHighNarro private DataTable _dataTable; - static SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt32() + static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt32() + public SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)), AdvSimd.LoadVector128((UInt64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt32(); - var result = AdvSimd.AddReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32(); + var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddReturningHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)), AdvSimd.LoadVector128((UInt64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Byte.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Byte.cs index 964bdb8fb0bf0..710e688d27d42 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningRoundedHighNarrowLower_Vector64_Byte() + private static void SubtractRoundedHighNarrowLower_Vector64_Byte() { - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningRoundedHighNarrowLower_Vector64_Byte() } } - public sealed unsafe class SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Byte + public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte testClass) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningRoundedHig private DataTable _dataTable; - static SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Byte() + static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Byte() + public SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Byte(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte(); + var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Int16.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Int16.cs index e39162ea8e3ff..b8af6dd6714ec 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningRoundedHighNarrowLower_Vector64_Int16() + private static void SubtractRoundedHighNarrowLower_Vector64_Int16() { - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningRoundedHighNarrowLower_Vector64_Int16() } } - public sealed unsafe class SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int16 + public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16 testClass) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningRoundedHig private DataTable _dataTable; - static SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int16() + static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int16() + public SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int16(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16(); + var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Int32.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Int32.cs index 4ca831f705a8b..65c74cb30dc0e 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningRoundedHighNarrowLower_Vector64_Int32() + private static void SubtractRoundedHighNarrowLower_Vector64_Int32() { - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningRoundedHighNarrowLower_Vector64_Int32() } } - public sealed unsafe class SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int32 + public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32 testClass) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningRoundedHig private DataTable _dataTable; - static SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int32() + static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int32() + public SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int32(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32(); + var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int64*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.SByte.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.SByte.cs index 831ecd0cf389f..b3dff057ddcf3 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningRoundedHighNarrowLower_Vector64_SByte() + private static void SubtractRoundedHighNarrowLower_Vector64_SByte() { - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningRoundedHighNarrowLower_Vector64_SByte() } } - public sealed unsafe class SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_SByte + public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte testClass) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningRoundedHig private DataTable _dataTable; - static SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_SByte() + static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_SByte() + public SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_SByte(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte(); + var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.UInt16.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.UInt16.cs index c69e2c8bd6eb9..0678507a1eb1e 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningRoundedHighNarrowLower_Vector64_UInt16() + private static void SubtractRoundedHighNarrowLower_Vector64_UInt16() { - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningRoundedHighNarrowLower_Vector64_UInt16() } } - public sealed unsafe class SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt16 + public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16 testClass) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningRoundedHig private DataTable _dataTable; - static SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt16() + static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt16() + public SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt16(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16(); + var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.UInt32.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.UInt32.cs index 1c9c3025bc7cd..abdaa0b05c407 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowLower.Vector64.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningRoundedHighNarrowLower_Vector64_UInt32() + private static void SubtractRoundedHighNarrowLower_Vector64_UInt32() { - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningRoundedHighNarrowLower_Vector64_UInt32() } } - public sealed unsafe class SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt32 + public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32 testClass) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddReturningRoundedHig private DataTable _dataTable; - static SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt32() + static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt32() + public SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt32(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32(); + var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddReturningRoundedHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowLower( AdvSimd.LoadVector128((UInt64*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Byte.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Byte.cs index 1e2a7cb14bfbe..5a91e9841e399 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningRoundedHighNarrowUpper_Vector128_Byte() + private static void SubtractRoundedHighNarrowUpper_Vector128_Byte() { - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningRoundedHighNarrowUpper_Vector128_Byte() } } - public sealed unsafe class SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Byte + public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte testClass) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningRoundedHi private DataTable _dataTable; - static SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Byte() + static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Byte() + public SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)), AdvSimd.LoadVector128((UInt16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Byte(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte(); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Byte*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)), AdvSimd.LoadVector128((UInt16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Int16.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Int16.cs index 0edd0a17b47e8..f2766313b1f5d 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningHighNarrowUpper_Vector128_Int16() + private static void SubtractRoundedHighNarrowUpper_Vector128_Int16() { - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningHighNarrowUpper_Vector128_Int16() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int16 + public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16 testClass) { - var result = AdvSimd.SubtractReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningHigh private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int16() + static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int16() + public SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)), AdvSimd.LoadVector128((Int32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int16(); - var result = AdvSimd.SubtractReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16(); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)), AdvSimd.LoadVector128((Int32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Int32.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Int32.cs index 3d342d4bfb5b4..29090eaed32a8 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningHighNarrowUpper_Vector128_Int32() + private static void SubtractRoundedHighNarrowUpper_Vector128_Int32() { - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningHighNarrowUpper_Vector128_Int32() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int32 + public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32 testClass) { - var result = AdvSimd.SubtractReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningHigh private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int32() + static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int32() + public SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)), AdvSimd.LoadVector128((Int64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int32(); - var result = AdvSimd.SubtractReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32(); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)), AdvSimd.LoadVector128((Int64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.SByte.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.SByte.cs index 5cbea75ba11c5..4158cf834c4b8 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractReturningHighNarrowUpper.Vector128.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractReturningHighNarrowUpper_Vector128_SByte() + private static void SubtractRoundedHighNarrowUpper_Vector128_SByte() { - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractReturningHighNarrowUpper_Vector128_SByte() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_SByte + public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte testClass) { - var result = AdvSimd.SubtractReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractReturningHigh private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_SByte() + static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_SByte() + public SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractReturningHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)), AdvSimd.LoadVector128((Int16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractReturningHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_SByte(); - var result = AdvSimd.SubtractReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte(); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractReturningHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractReturningHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractReturningHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((SByte*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)), AdvSimd.LoadVector128((Int16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractReturningHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.UInt16.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.UInt16.cs index 70e20fec0f4f0..af38718e5770a 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningRoundedHighNarrowUpper_Vector128_UInt16() + private static void SubtractRoundedHighNarrowUpper_Vector128_UInt16() { - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningRoundedHighNarrowUpper_Vector128_UInt16() } } - public sealed unsafe class SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt16 + public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16 testClass) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningRoundedHi private DataTable _dataTable; - static SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt16() + static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt16( Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt16() + public SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)), AdvSimd.LoadVector128((UInt32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt16(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16(); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)), AdvSimd.LoadVector128((UInt32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.UInt32.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.UInt32.cs index 91f4bd718438b..12d1186105614 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddReturningRoundedHighNarrowUpper.Vector128.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddReturningRoundedHighNarrowUpper_Vector128_UInt32() + private static void SubtractRoundedHighNarrowUpper_Vector128_UInt32() { - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddReturningRoundedHighNarrowUpper_Vector128_UInt32() } } - public sealed unsafe class SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt32 + public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32 testClass) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddReturningRoundedHi private DataTable _dataTable; - static SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt32() + static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt32( Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt32() + public SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddReturningRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)), AdvSimd.LoadVector128((UInt64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt32(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32(); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddReturningRoundedHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddReturningRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowUpper( AdvSimd.LoadVector64((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)), AdvSimd.LoadVector128((UInt64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddReturningRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx index c7bea91cb434a..9130ef1424b3d 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx @@ -186,6 +186,18 @@ private static readonly (string templateFileName, Dictionary tem ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrow(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), @@ -217,30 +229,18 @@ private static readonly (string templateFileName, Dictionary tem ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAddScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWidening(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWidening(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddReturningHighNarrowLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddReturningHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddReturningHighNarrowLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddReturningHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddReturningHighNarrowLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddReturningHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddReturningHighNarrowLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddReturningHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddReturningHighNarrowLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddReturningHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddReturningHighNarrowLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddReturningHighNarrow(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddReturningHighNarrowUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddReturningHighNarrowUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddReturningHighNarrowUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddReturningHighNarrowUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddReturningHighNarrowUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddReturningHighNarrowUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddReturningRoundedHighNarrowLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddReturningRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddReturningRoundedHighNarrowLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddReturningRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddReturningRoundedHighNarrowLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddReturningRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddReturningRoundedHighNarrowLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddReturningRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddReturningRoundedHighNarrowLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddReturningRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddReturningRoundedHighNarrowLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddReturningRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddReturningRoundedHighNarrowUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddReturningRoundedHighNarrowUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddReturningRoundedHighNarrowUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddReturningRoundedHighNarrowUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddReturningRoundedHighNarrowUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddReturningRoundedHighNarrowUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddReturningRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), @@ -834,30 +834,30 @@ private static readonly (string templateFileName, Dictionary tem ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningHighNarrowLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractReturningHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningHighNarrowLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractReturningHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningHighNarrowLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractReturningHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningHighNarrowLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractReturningHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningHighNarrowLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractReturningHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningHighNarrowLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractReturningHighNarrow(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningHighNarrowUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningHighNarrowUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningHighNarrowUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningHighNarrowUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningHighNarrowUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningHighNarrowUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractReturningHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningRoundedHighNarrowLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractReturningRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningRoundedHighNarrowLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractReturningRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningRoundedHighNarrowLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractReturningRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningRoundedHighNarrowLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractReturningRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningRoundedHighNarrowLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractReturningRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningRoundedHighNarrowLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractReturningRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningRoundedHighNarrowUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningRoundedHighNarrowUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningRoundedHighNarrowUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningRoundedHighNarrowUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningRoundedHighNarrowUpper_Vector128_UInt16",["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractReturningRoundedHighNarrowUpper_Vector128_UInt32",["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractReturningRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractReturningRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 7ece1a765ccb9..3b766823195b4 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -1457,13 +1457,13 @@ private static sbyte HighNarrow(short op1, bool round) return (sbyte)(((ushort)op1 + roundConst) >> (8 * sizeof(sbyte))); } - public static sbyte AddReturningHighNarrow(short op1, short op2) => HighNarrow((short)(op1 + op2), round: false); + public static sbyte AddHighNarrow(short op1, short op2) => HighNarrow((short)(op1 + op2), round: false); - public static sbyte AddReturningHighNarrowUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : AddReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static sbyte AddHighNarrowUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static sbyte AddReturningRoundedHighNarrow(short op1, short op2) => HighNarrow((short)(op1 + op2), round: true); + public static sbyte AddRoundedHighNarrow(short op1, short op2) => HighNarrow((short)(op1 + op2), round: true); - public static short AddReturningRoundedHighNarrowUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : AddReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static short AddRoundedHighNarrowUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static short AddWidening(sbyte op1, sbyte op2) => (short)((short)op1 + (short)op2); @@ -1491,13 +1491,13 @@ private static sbyte HighNarrow(short op1, bool round) public static short MultiplyWideningUpperAndSubtract(short[] op1, sbyte[] op2, sbyte[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static sbyte SubtractReturningHighNarrow(short op1, short op2) => HighNarrow((short)(op1 - op2), round: false); + public static sbyte SubtractHighNarrow(short op1, short op2) => HighNarrow((short)(op1 - op2), round: false); - public static short SubtractReturningHighNarrowUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static short SubtractHighNarrowUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static sbyte SubtractReturningRoundedHighNarrow(short op1, short op2) => HighNarrow((short)(op1 - op2), round: true); + public static sbyte SubtractRoundedHighNarrow(short op1, short op2) => HighNarrow((short)(op1 - op2), round: true); - public static short SubtractReturningRoundedHighNarrowUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static short SubtractRoundedHighNarrowUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static short SubtractWidening(sbyte op1, sbyte op2) => (short)((short)op1 - (short)op2); @@ -1529,13 +1529,13 @@ private static short HighNarrow(int op1, bool round) return (short)(((uint)op1 + roundConst) >> (8 * sizeof(short))); } - public static short AddReturningHighNarrow(int op1, int op2) => HighNarrow((int)(op1 + op2), round: false); + public static short AddHighNarrow(int op1, int op2) => HighNarrow((int)(op1 + op2), round: false); - public static short AddReturningHighNarrowUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : AddReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static short AddHighNarrowUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static short AddReturningRoundedHighNarrow(int op1, int op2) => HighNarrow((int)(op1 + op2), round: true); + public static short AddRoundedHighNarrow(int op1, int op2) => HighNarrow((int)(op1 + op2), round: true); - public static int AddReturningRoundedHighNarrowUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : AddReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static int AddRoundedHighNarrowUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static int AddWidening(short op1, short op2) => (int)((int)op1 + (int)op2); @@ -1563,13 +1563,13 @@ private static short HighNarrow(int op1, bool round) public static int MultiplyWideningUpperAndSubtract(int[] op1, short[] op2, short[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static short SubtractReturningHighNarrow(int op1, int op2) => HighNarrow((int)(op1 - op2), round: false); + public static short SubtractHighNarrow(int op1, int op2) => HighNarrow((int)(op1 - op2), round: false); - public static int SubtractReturningHighNarrowUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static int SubtractHighNarrowUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static short SubtractReturningRoundedHighNarrow(int op1, int op2) => HighNarrow((int)(op1 - op2), round: true); + public static short SubtractRoundedHighNarrow(int op1, int op2) => HighNarrow((int)(op1 - op2), round: true); - public static int SubtractReturningRoundedHighNarrowUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static int SubtractRoundedHighNarrowUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static int SubtractWidening(short op1, short op2) => (int)((int)op1 - (int)op2); @@ -1601,13 +1601,13 @@ private static int HighNarrow(long op1, bool round) return (int)(((ulong)op1 + roundConst) >> (8 * sizeof(int))); } - public static int AddReturningHighNarrow(long op1, long op2) => HighNarrow((long)(op1 + op2), round: false); + public static int AddHighNarrow(long op1, long op2) => HighNarrow((long)(op1 + op2), round: false); - public static int AddReturningHighNarrowUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : AddReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static int AddHighNarrowUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static int AddReturningRoundedHighNarrow(long op1, long op2) => HighNarrow((long)(op1 + op2), round: true); + public static int AddRoundedHighNarrow(long op1, long op2) => HighNarrow((long)(op1 + op2), round: true); - public static long AddReturningRoundedHighNarrowUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : AddReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static long AddRoundedHighNarrowUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static long AddWidening(int op1, int op2) => (long)((long)op1 + (long)op2); @@ -1635,13 +1635,13 @@ private static int HighNarrow(long op1, bool round) public static long MultiplyWideningUpperAndSubtract(long[] op1, int[] op2, int[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static int SubtractReturningHighNarrow(long op1, long op2) => HighNarrow((long)(op1 - op2), round: false); + public static int SubtractHighNarrow(long op1, long op2) => HighNarrow((long)(op1 - op2), round: false); - public static long SubtractReturningHighNarrowUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static long SubtractHighNarrowUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static int SubtractReturningRoundedHighNarrow(long op1, long op2) => HighNarrow((long)(op1 - op2), round: true); + public static int SubtractRoundedHighNarrow(long op1, long op2) => HighNarrow((long)(op1 - op2), round: true); - public static long SubtractReturningRoundedHighNarrowUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static long SubtractRoundedHighNarrowUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static long SubtractWidening(int op1, int op2) => (long)((long)op1 - (long)op2); @@ -1673,13 +1673,13 @@ private static byte HighNarrow(ushort op1, bool round) return (byte)(((ushort)op1 + roundConst) >> (8 * sizeof(byte))); } - public static byte AddReturningHighNarrow(ushort op1, ushort op2) => HighNarrow((ushort)(op1 + op2), round: false); + public static byte AddHighNarrow(ushort op1, ushort op2) => HighNarrow((ushort)(op1 + op2), round: false); - public static byte AddReturningHighNarrowUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : AddReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static byte AddHighNarrowUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static byte AddReturningRoundedHighNarrow(ushort op1, ushort op2) => HighNarrow((ushort)(op1 + op2), round: true); + public static byte AddRoundedHighNarrow(ushort op1, ushort op2) => HighNarrow((ushort)(op1 + op2), round: true); - public static ushort AddReturningRoundedHighNarrowUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : AddReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ushort AddRoundedHighNarrowUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static ushort AddWidening(byte op1, byte op2) => (ushort)((ushort)op1 + (ushort)op2); @@ -1707,13 +1707,13 @@ private static byte HighNarrow(ushort op1, bool round) public static ushort MultiplyWideningUpperAndSubtract(ushort[] op1, byte[] op2, byte[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static byte SubtractReturningHighNarrow(ushort op1, ushort op2) => HighNarrow((ushort)(op1 - op2), round: false); + public static byte SubtractHighNarrow(ushort op1, ushort op2) => HighNarrow((ushort)(op1 - op2), round: false); - public static ushort SubtractReturningHighNarrowUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ushort SubtractHighNarrowUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static byte SubtractReturningRoundedHighNarrow(ushort op1, ushort op2) => HighNarrow((ushort)(op1 - op2), round: true); + public static byte SubtractRoundedHighNarrow(ushort op1, ushort op2) => HighNarrow((ushort)(op1 - op2), round: true); - public static ushort SubtractReturningRoundedHighNarrowUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ushort SubtractRoundedHighNarrowUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static ushort SubtractWidening(byte op1, byte op2) => (ushort)((ushort)op1 - (ushort)op2); @@ -1745,13 +1745,13 @@ private static ushort HighNarrow(uint op1, bool round) return (ushort)(((uint)op1 + roundConst) >> (8 * sizeof(ushort))); } - public static ushort AddReturningHighNarrow(uint op1, uint op2) => HighNarrow((uint)(op1 + op2), round: false); + public static ushort AddHighNarrow(uint op1, uint op2) => HighNarrow((uint)(op1 + op2), round: false); - public static ushort AddReturningHighNarrowUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : AddReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ushort AddHighNarrowUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static ushort AddReturningRoundedHighNarrow(uint op1, uint op2) => HighNarrow((uint)(op1 + op2), round: true); + public static ushort AddRoundedHighNarrow(uint op1, uint op2) => HighNarrow((uint)(op1 + op2), round: true); - public static uint AddReturningRoundedHighNarrowUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : AddReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static uint AddRoundedHighNarrowUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static uint AddWidening(ushort op1, ushort op2) => (uint)((uint)op1 + (uint)op2); @@ -1779,13 +1779,13 @@ private static ushort HighNarrow(uint op1, bool round) public static uint MultiplyWideningUpperAndSubtract(uint[] op1, ushort[] op2, ushort[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static ushort SubtractReturningHighNarrow(uint op1, uint op2) => HighNarrow((uint)(op1 - op2), round: false); + public static ushort SubtractHighNarrow(uint op1, uint op2) => HighNarrow((uint)(op1 - op2), round: false); - public static uint SubtractReturningHighNarrowUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static uint SubtractHighNarrowUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static ushort SubtractReturningRoundedHighNarrow(uint op1, uint op2) => HighNarrow((uint)(op1 - op2), round: true); + public static ushort SubtractRoundedHighNarrow(uint op1, uint op2) => HighNarrow((uint)(op1 - op2), round: true); - public static uint SubtractReturningRoundedHighNarrowUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static uint SubtractRoundedHighNarrowUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static uint SubtractWidening(ushort op1, ushort op2) => (uint)((uint)op1 - (uint)op2); @@ -1817,13 +1817,13 @@ private static uint HighNarrow(ulong op1, bool round) return (uint)(((ulong)op1 + roundConst) >> (8 * sizeof(uint))); } - public static uint AddReturningHighNarrow(ulong op1, ulong op2) => HighNarrow((ulong)(op1 + op2), round: false); + public static uint AddHighNarrow(ulong op1, ulong op2) => HighNarrow((ulong)(op1 + op2), round: false); - public static uint AddReturningHighNarrowUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : AddReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static uint AddHighNarrowUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static uint AddReturningRoundedHighNarrow(ulong op1, ulong op2) => HighNarrow((ulong)(op1 + op2), round: true); + public static uint AddRoundedHighNarrow(ulong op1, ulong op2) => HighNarrow((ulong)(op1 + op2), round: true); - public static ulong AddReturningRoundedHighNarrowUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : AddReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ulong AddRoundedHighNarrowUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static ulong AddWidening(uint op1, uint op2) => (ulong)((ulong)op1 + (ulong)op2); @@ -1851,13 +1851,13 @@ private static uint HighNarrow(ulong op1, bool round) public static ulong MultiplyWideningUpperAndSubtract(ulong[] op1, uint[] op2, uint[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static uint SubtractReturningHighNarrow(ulong op1, ulong op2) => HighNarrow((ulong)(op1 - op2), round: false); + public static uint SubtractHighNarrow(ulong op1, ulong op2) => HighNarrow((ulong)(op1 - op2), round: false); - public static ulong SubtractReturningHighNarrowUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ulong SubtractHighNarrowUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static uint SubtractReturningRoundedHighNarrow(ulong op1, ulong op2) => HighNarrow((ulong)(op1 - op2), round: true); + public static uint SubtractRoundedHighNarrow(ulong op1, ulong op2) => HighNarrow((ulong)(op1 - op2), round: true); - public static ulong SubtractReturningRoundedHighNarrowUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ulong SubtractRoundedHighNarrowUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static ulong SubtractWidening(uint op1, uint op2) => (ulong)((ulong)op1 - (ulong)op2); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt index b10aa7fe23a29..a1086d6cef26d 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt @@ -355,13 +355,13 @@ namespace JIT.HardwareIntrinsics.Arm return (<#= type.name #>)(((<#= type.wideUnsigned #>)op1 + roundConst) >> (8 * sizeof(<#= type.name #>))); } - public static <#= type.name #> AddReturningHighNarrow(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrow((<#= type.wide #>)(op1 + op2), round: false); + public static <#= type.name #> AddHighNarrow(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrow((<#= type.wide #>)(op1 + op2), round: false); - public static <#= type.name #> AddReturningHighNarrowUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : AddReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static <#= type.name #> AddHighNarrowUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static <#= type.name #> AddReturningRoundedHighNarrow(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrow((<#= type.wide #>)(op1 + op2), round: true); + public static <#= type.name #> AddRoundedHighNarrow(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrow((<#= type.wide #>)(op1 + op2), round: true); - public static <#= type.wide #> AddReturningRoundedHighNarrowUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : AddReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static <#= type.wide #> AddRoundedHighNarrowUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static <#= type.wide #> AddWidening(<#= type.name #> op1, <#= type.name #> op2) => (<#= type.wide #>)((<#= type.wide #>)op1 + (<#= type.wide #>)op2); @@ -389,13 +389,13 @@ namespace JIT.HardwareIntrinsics.Arm public static <#= type.wide #> MultiplyWideningUpperAndSubtract(<#= type.wide #>[] op1, <#= type.name #>[] op2, <#= type.name #>[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static <#= type.name #> SubtractReturningHighNarrow(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrow((<#= type.wide #>)(op1 - op2), round: false); + public static <#= type.name #> SubtractHighNarrow(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrow((<#= type.wide #>)(op1 - op2), round: false); - public static <#= type.wide #> SubtractReturningHighNarrowUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static <#= type.wide #> SubtractHighNarrowUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); - public static <#= type.name #> SubtractReturningRoundedHighNarrow(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrow((<#= type.wide #>)(op1 - op2), round: true); + public static <#= type.name #> SubtractRoundedHighNarrow(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrow((<#= type.wide #>)(op1 - op2), round: true); - public static <#= type.wide #> SubtractReturningRoundedHighNarrowUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : SubtractReturningRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static <#= type.wide #> SubtractRoundedHighNarrowUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); public static <#= type.wide #> SubtractWidening(<#= type.name #> op1, <#= type.name #> op2) => (<#= type.wide #>)((<#= type.wide #>)op1 - (<#= type.wide #>)op2); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs index 9bae02e39f7ee..d480608fcf2be 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs @@ -2474,6 +2474,90 @@ public new abstract class Arm64 : ArmBase.Arm64 /// public static Vector128 Add(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + /// + /// uint8x8_t vaddhn_u16 (uint16x8_t a, uint16x8_t b) + /// A32: VADDHN.I16 Dd, Qn, Qm + /// A64: ADDHN Vd.8B, Vn.8H, Vm.8H + /// + public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vaddhn_s32 (int32x4_t a, int32x4_t b) + /// A32: VADDHN.I32 Dd, Qn, Qm + /// A64: ADDHN Vd.4H, Vn.4S, Vm.4S + /// + public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vaddhn_s64 (int64x2_t a, int64x2_t b) + /// A32: VADDHN.I64 Dd, Qn, Qm + /// A64: ADDHN Vd.2S, Vn.2D, Vm.2D + /// + public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vaddhn_s16 (int16x8_t a, int16x8_t b) + /// A32: VADDHN.I16 Dd, Qn, Qm + /// A64: ADDHN Vd.8B, Vn.8H, Vm.8H + /// + public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vaddhn_u32 (uint32x4_t a, uint32x4_t b) + /// A32: VADDHN.I32 Dd, Qn, Qm + /// A64: ADDHN Vd.4H, Vn.4S, Vm.4S + /// + public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vaddhn_u64 (uint64x2_t a, uint64x2_t b) + /// A32: VADDHN.I64 Dd, Qn, Qm + /// A64: ADDHN Vd.2S, Vn.2D, Vm.2D + /// + public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vaddhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) + /// A32: VADDHN.I16 Dd+1, Qn, Qm + /// A64: ADDHN2 Vd.16B, Vn.8H, Vm.8H + /// + public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vaddhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) + /// A32: VADDHN.I32 Dd+1, Qn, Qm + /// A64: ADDHN2 Vd.8H, Vn.4S, Vm.4S + /// + public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vaddhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) + /// A32: VADDHN.I64 Dd+1, Qn, Qm + /// A64: ADDHN2 Vd.4S, Vn.2D, Vm.2D + /// + public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vaddhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) + /// A32: VADDHN.I16 Dd+1, Qn, Qm + /// A64: ADDHN2 Vd.16B, Vn.8H, Vm.8H + /// + public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vaddhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) + /// A32: VADDHN.I32 Dd+1, Qn, Qm + /// A64: ADDHN2 Vd.8H, Vn.4S, Vm.4S + /// + public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vaddhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) + /// A32: VADDHN.I64 Dd+1, Qn, Qm + /// A64: ADDHN2 Vd.4S, Vn.2D, Vm.2D + /// + public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + /// /// uint8x8_t vpadd_u8 (uint8x8_t a, uint8x8_t b) /// A32: VPADD.I8 Dd, Dn, Dm @@ -2691,173 +2775,89 @@ public new abstract class Arm64 : ArmBase.Arm64 /// public static Vector64 AddPairwiseWideningScalar(Vector64 value) { throw new PlatformNotSupportedException(); } - /// - /// uint8x8_t vaddhn_u16 (uint16x8_t a, uint16x8_t b) - /// A32: VADDHN.I16 Dd, Qn, Qm - /// A64: ADDHN Vd.8B, Vn.8H, Vm.8H - /// - public static Vector64 AddReturningHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } - - /// - /// int16x4_t vaddhn_s32 (int32x4_t a, int32x4_t b) - /// A32: VADDHN.I32 Dd, Qn, Qm - /// A64: ADDHN Vd.4H, Vn.4S, Vm.4S - /// - public static Vector64 AddReturningHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } - - /// - /// int32x2_t vaddhn_s64 (int64x2_t a, int64x2_t b) - /// A32: VADDHN.I64 Dd, Qn, Qm - /// A64: ADDHN Vd.2S, Vn.2D, Vm.2D - /// - public static Vector64 AddReturningHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } - - /// - /// int8x8_t vaddhn_s16 (int16x8_t a, int16x8_t b) - /// A32: VADDHN.I16 Dd, Qn, Qm - /// A64: ADDHN Vd.8B, Vn.8H, Vm.8H - /// - public static Vector64 AddReturningHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } - - /// - /// uint16x4_t vaddhn_u32 (uint32x4_t a, uint32x4_t b) - /// A32: VADDHN.I32 Dd, Qn, Qm - /// A64: ADDHN Vd.4H, Vn.4S, Vm.4S - /// - public static Vector64 AddReturningHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } - - /// - /// uint32x2_t vaddhn_u64 (uint64x2_t a, uint64x2_t b) - /// A32: VADDHN.I64 Dd, Qn, Qm - /// A64: ADDHN Vd.2S, Vn.2D, Vm.2D - /// - public static Vector64 AddReturningHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } - - /// - /// uint8x16_t vaddhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) - /// A32: VADDHN.I16 Dd+1, Qn, Qm - /// A64: ADDHN2 Vd.16B, Vn.8B, Vm.8H - /// - public static Vector128 AddReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } - - /// - /// int16x8_t vaddhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) - /// A32: VADDHN.I32 Dd+1, Qn, Qm - /// A64: ADDHN2 Vd.8H, Vn.4H, Vm.4S - /// - public static Vector128 AddReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } - - /// - /// int32x4_t vaddhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) - /// A32: VADDHN.I64 Dd+1, Qn, Qm - /// A64: ADDHN2 Vd.4S, Vn.2S, Vm.2D - /// - public static Vector128 AddReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } - - /// - /// int8x16_t vaddhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) - /// A32: VADDHN.I16 Dd+1, Qn, Qm - /// A64: ADDHN2 Vd.16B, Vn.8B, Vm.8H - /// - public static Vector128 AddReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } - - /// - /// uint16x8_t vaddhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) - /// A32: VADDHN.I32 Dd+1, Qn, Qm - /// A64: ADDHN2 Vd.8H, Vn.4H, Vm.4S - /// - public static Vector128 AddReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } - - /// - /// uint32x4_t vaddhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) - /// A32: VADDHN.I64 Dd+1, Qn, Qm - /// A64: ADDHN2 Vd.4S, Vn.2S, Vm.2D - /// - public static Vector128 AddReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } - /// /// uint8x8_t vraddhn_u16 (uint16x8_t a, uint16x8_t b) /// A32: VRADDHN.I16 Dd, Qn, Qm /// A64: RADDHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 AddReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x4_t vraddhn_s32 (int32x4_t a, int32x4_t b) /// A32: VRADDHN.I32 Dd, Qn, Qm /// A64: RADDHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 AddReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x2_t vraddhn_s64 (int64x2_t a, int64x2_t b) /// A32: VRADDHN.I64 Dd, Qn, Qm /// A64: RADDHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 AddReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x8_t vraddhn_s16 (int16x8_t a, int16x8_t b) /// A32: VRADDHN.I16 Dd, Qn, Qm /// A64: RADDHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 AddReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x4_t vraddhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VRADDHN.I32 Dd, Qn, Qm /// A64: RADDHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 AddReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x2_t vraddhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VRADDHN.I64 Dd, Qn, Qm /// A64: RADDHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 AddReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x16_t vraddhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VRADDHN.I16 Dd+1, Qn, Qm - /// A64: RADDHN2 Vd.16B, Vn.8B, Vm.8H + /// A64: RADDHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 AddReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x8_t vraddhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VRADDHN.I32 Dd+1, Qn, Qm - /// A64: RADDHN2 Vd.8H, Vn.4H, Vm.4S + /// A64: RADDHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 AddReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x4_t vraddhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VRADDHN.I64 Dd+1, Qn, Qm - /// A64: RADDHN2 Vd.4S, Vn.2S, Vm.2D + /// A64: RADDHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 AddReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x16_t vraddhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VRADDHN.I16 Dd+1, Qn, Qm - /// A64: RADDHN2 Vd.16B, Vn.8B, Vm.8H + /// A64: RADDHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 AddReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x8_t vraddhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VRADDHN.I32 Dd+1, Qn, Qm - /// A64: RADDHN2 Vd.8H, Vn.4H, Vm.4S + /// A64: RADDHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 AddReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x4_t vraddhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VRADDHN.I64 Dd+1, Qn, Qm - /// A64: RADDHN2 Vd.4S, Vn.2S, Vm.2D + /// A64: RADDHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 AddReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x8_t vqadd_u8 (uint8x8_t a, uint8x8_t b) @@ -7048,168 +7048,168 @@ public new abstract class Arm64 : ArmBase.Arm64 /// A32: VSUBHN.I16 Dd, Qn, Qm /// A64: SUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractReturningHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x4_t vsubhn_s32 (int32x4_t a, int32x4_t b) /// A32: VSUBHN.I32 Dd, Qn, Qm /// A64: SUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractReturningHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x2_t vsubhn_s64 (int64x2_t a, int64x2_t b) /// A32: VSUBHN.I64 Dd, Qn, Qm /// A64: SUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractReturningHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x8_t vsubhn_s16 (int16x8_t a, int16x8_t b) /// A32: VSUBHN.I16 Dd, Qn, Qm /// A64: SUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractReturningHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x4_t vsubhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VSUBHN.I32 Dd, Qn, Qm /// A64: SUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractReturningHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x2_t vsubhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VSUBHN.I64 Dd, Qn, Qm /// A64: SUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractReturningHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x16_t vsubhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VSUBHN.I16 Dd+1, Qn, Qm - /// A64: SUBHN2 Vd.16B, Vn.8B, Vm.8H + /// A64: SUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x8_t vsubhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VSUBHN.I32 Dd+1, Qn, Qm - /// A64: SUBHN2 Vd.8H, Vn.4H, Vm.4S + /// A64: SUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x4_t vsubhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VSUBHN.I64 Dd+1, Qn, Qm - /// A64: SUBHN2 Vd.4S, Vn.2S, Vm.2D + /// A64: SUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x16_t vsubhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VSUBHN.I16 Dd+1, Qn, Qm - /// A64: SUBHN2 Vd.16B, Vn.8B, Vm.8H + /// A64: SUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x8_t vsubhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VSUBHN.I32 Dd+1, Qn, Qm - /// A64: SUBHN2 Vd.8H, Vn.4H, Vm.4S + /// A64: SUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x4_t vsubhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VSUBHN.I64 Dd+1, Qn, Qm - /// A64: SUBHN2 Vd.4S, Vn.2S, Vm.2D + /// A64: SUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x8_t vrsubhn_u16 (uint16x8_t a, uint16x8_t b) /// A32: VRSUBHN.I16 Dd, Qn, Qm /// A64: RSUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x4_t vrsubhn_s32 (int32x4_t a, int32x4_t b) /// A32: VRSUBHN.I32 Dd, Qn, Qm /// A64: RSUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x2_t vrsubhn_s64 (int64x2_t a, int64x2_t b) /// A32: VRSUBHN.I64 Dd, Qn, Qm /// A64: RSUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x8_t vrsubhn_s16 (int16x8_t a, int16x8_t b) /// A32: VRSUBHN.I16 Dd, Qn, Qm /// A64: RSUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x4_t vrsubhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VRSUBHN.I32 Dd, Qn, Qm /// A64: RSUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x2_t vrsubhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VRSUBHN.I64 Dd, Qn, Qm /// A64: RSUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x16_t vrsubhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VRSUBHN.I16 Dd+1, Qn, Qm - /// A64: RSUBHN2 Vd.16B, Vn.8B, Vm.8H + /// A64: RSUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x8_t vrsubhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VRSUBHN.I32 Dd+1, Qn, Qm - /// A64: RSUBHN2 Vd.8H, Vn.4H, Vm.4S + /// A64: RSUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x4_t vrsubhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VRSUBHN.I64 Dd+1, Qn, Qm - /// A64: RSUBHN2 Vd.4S, Vn.2S, Vm.2D + /// A64: RSUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x16_t vrsubhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VRSUBHN.I16 Dd+1, Qn, Qm - /// A64: RSUBHN2 Vd.16B, Vn.8B, Vm.8H + /// A64: RSUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x8_t vrsubhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VRSUBHN.I32 Dd+1, Qn, Qm - /// A64: RSUBHN2 Vd.8H, Vn.4H, Vm.4S + /// A64: RSUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x4_t vrsubhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VRSUBHN.I64 Dd+1, Qn, Qm - /// A64: RSUBHN2 Vd.4S, Vn.2S, Vm.2D + /// A64: RSUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x8_t vqsub_u8 (uint8x8_t a, uint8x8_t b) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs index fa20a0a87a2f7..f5432dd94ac2b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs @@ -2476,6 +2476,90 @@ public new abstract class Arm64 : ArmBase.Arm64 /// public static Vector128 Add(Vector128 left, Vector128 right) => Add(left, right); + /// + /// uint8x8_t vaddhn_u16 (uint16x8_t a, uint16x8_t b) + /// A32: VADDHN.I16 Dd, Qn, Qm + /// A64: ADDHN Vd.8B, Vn.8H, Vm.8H + /// + public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) => AddHighNarrowLower(left, right); + + /// + /// int16x4_t vaddhn_s32 (int32x4_t a, int32x4_t b) + /// A32: VADDHN.I32 Dd, Qn, Qm + /// A64: ADDHN Vd.4H, Vn.4S, Vm.4S + /// + public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) => AddHighNarrowLower(left, right); + + /// + /// int32x2_t vaddhn_s64 (int64x2_t a, int64x2_t b) + /// A32: VADDHN.I64 Dd, Qn, Qm + /// A64: ADDHN Vd.2S, Vn.2D, Vm.2D + /// + public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) => AddHighNarrowLower(left, right); + + /// + /// int8x8_t vaddhn_s16 (int16x8_t a, int16x8_t b) + /// A32: VADDHN.I16 Dd, Qn, Qm + /// A64: ADDHN Vd.8B, Vn.8H, Vm.8H + /// + public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) => AddHighNarrowLower(left, right); + + /// + /// uint16x4_t vaddhn_u32 (uint32x4_t a, uint32x4_t b) + /// A32: VADDHN.I32 Dd, Qn, Qm + /// A64: ADDHN Vd.4H, Vn.4S, Vm.4S + /// + public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) => AddHighNarrowLower(left, right); + + /// + /// uint32x2_t vaddhn_u64 (uint64x2_t a, uint64x2_t b) + /// A32: VADDHN.I64 Dd, Qn, Qm + /// A64: ADDHN Vd.2S, Vn.2D, Vm.2D + /// + public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) => AddHighNarrowLower(left, right); + + /// + /// uint8x16_t vaddhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) + /// A32: VADDHN.I16 Dd+1, Qn, Qm + /// A64: ADDHN2 Vd.16B, Vn.8H, Vm.8H + /// + public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowUpper(lower, left, right); + + /// + /// int16x8_t vaddhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) + /// A32: VADDHN.I32 Dd+1, Qn, Qm + /// A64: ADDHN2 Vd.8H, Vn.4S, Vm.4S + /// + public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowUpper(lower, left, right); + + /// + /// int32x4_t vaddhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) + /// A32: VADDHN.I64 Dd+1, Qn, Qm + /// A64: ADDHN2 Vd.4S, Vn.2D, Vm.2D + /// + public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowUpper(lower, left, right); + + /// + /// int8x16_t vaddhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) + /// A32: VADDHN.I16 Dd+1, Qn, Qm + /// A64: ADDHN2 Vd.16B, Vn.8H, Vm.8H + /// + public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowUpper(lower, left, right); + + /// + /// uint16x8_t vaddhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) + /// A32: VADDHN.I32 Dd+1, Qn, Qm + /// A64: ADDHN2 Vd.8H, Vn.4S, Vm.4S + /// + public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowUpper(lower, left, right); + + /// + /// uint32x4_t vaddhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) + /// A32: VADDHN.I64 Dd+1, Qn, Qm + /// A64: ADDHN2 Vd.4S, Vn.2D, Vm.2D + /// + public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowUpper(lower, left, right); + /// /// uint8x8_t vpadd_u8 (uint8x8_t a, uint8x8_t b) /// A32: VPADD.I8 Dd, Dn, Dm @@ -2693,173 +2777,89 @@ public new abstract class Arm64 : ArmBase.Arm64 /// public static Vector64 AddPairwiseWideningScalar(Vector64 value) => AddPairwiseWideningScalar(value); - /// - /// uint8x8_t vaddhn_u16 (uint16x8_t a, uint16x8_t b) - /// A32: VADDHN.I16 Dd, Qn, Qm - /// A64: ADDHN Vd.8B, Vn.8H, Vm.8H - /// - public static Vector64 AddReturningHighNarrowLower(Vector128 left, Vector128 right) => AddReturningHighNarrowLower(left, right); - - /// - /// int16x4_t vaddhn_s32 (int32x4_t a, int32x4_t b) - /// A32: VADDHN.I32 Dd, Qn, Qm - /// A64: ADDHN Vd.4H, Vn.4S, Vm.4S - /// - public static Vector64 AddReturningHighNarrowLower(Vector128 left, Vector128 right) => AddReturningHighNarrowLower(left, right); - - /// - /// int32x2_t vaddhn_s64 (int64x2_t a, int64x2_t b) - /// A32: VADDHN.I64 Dd, Qn, Qm - /// A64: ADDHN Vd.2S, Vn.2D, Vm.2D - /// - public static Vector64 AddReturningHighNarrowLower(Vector128 left, Vector128 right) => AddReturningHighNarrowLower(left, right); - - /// - /// int8x8_t vaddhn_s16 (int16x8_t a, int16x8_t b) - /// A32: VADDHN.I16 Dd, Qn, Qm - /// A64: ADDHN Vd.8B, Vn.8H, Vm.8H - /// - public static Vector64 AddReturningHighNarrowLower(Vector128 left, Vector128 right) => AddReturningHighNarrowLower(left, right); - - /// - /// uint16x4_t vaddhn_u32 (uint32x4_t a, uint32x4_t b) - /// A32: VADDHN.I32 Dd, Qn, Qm - /// A64: ADDHN Vd.4H, Vn.4S, Vm.4S - /// - public static Vector64 AddReturningHighNarrowLower(Vector128 left, Vector128 right) => AddReturningHighNarrowLower(left, right); - - /// - /// uint32x2_t vaddhn_u64 (uint64x2_t a, uint64x2_t b) - /// A32: VADDHN.I64 Dd, Qn, Qm - /// A64: ADDHN Vd.2S, Vn.2D, Vm.2D - /// - public static Vector64 AddReturningHighNarrowLower(Vector128 left, Vector128 right) => AddReturningHighNarrowLower(left, right); - - /// - /// uint8x16_t vaddhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) - /// A32: VADDHN.I16 Dd+1, Qn, Qm - /// A64: ADDHN2 Vd.16B, Vn.8B, Vm.8H - /// - public static Vector128 AddReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddReturningHighNarrowUpper(lower, left, right); - - /// - /// int16x8_t vaddhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) - /// A32: VADDHN.I32 Dd+1, Qn, Qm - /// A64: ADDHN2 Vd.8H, Vn.4H, Vm.4S - /// - public static Vector128 AddReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddReturningHighNarrowUpper(lower, left, right); - - /// - /// int32x4_t vaddhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) - /// A32: VADDHN.I64 Dd+1, Qn, Qm - /// A64: ADDHN2 Vd.4S, Vn.2S, Vm.2D - /// - public static Vector128 AddReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddReturningHighNarrowUpper(lower, left, right); - - /// - /// int8x16_t vaddhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) - /// A32: VADDHN.I16 Dd+1, Qn, Qm - /// A64: ADDHN2 Vd.16B, Vn.8B, Vm.8H - /// - public static Vector128 AddReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddReturningHighNarrowUpper(lower, left, right); - - /// - /// uint16x8_t vaddhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) - /// A32: VADDHN.I32 Dd+1, Qn, Qm - /// A64: ADDHN2 Vd.8H, Vn.4H, Vm.4S - /// - public static Vector128 AddReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddReturningHighNarrowUpper(lower, left, right); - - /// - /// uint32x4_t vaddhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) - /// A32: VADDHN.I64 Dd+1, Qn, Qm - /// A64: ADDHN2 Vd.4S, Vn.2S, Vm.2D - /// - public static Vector128 AddReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddReturningHighNarrowUpper(lower, left, right); - /// /// uint8x8_t vraddhn_u16 (uint16x8_t a, uint16x8_t b) /// A32: VRADDHN.I16 Dd, Qn, Qm /// A64: RADDHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 AddReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddReturningRoundedHighNarrowLower(left, right); + public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowLower(left, right); /// /// int16x4_t vraddhn_s32 (int32x4_t a, int32x4_t b) /// A32: VRADDHN.I32 Dd, Qn, Qm /// A64: RADDHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 AddReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddReturningRoundedHighNarrowLower(left, right); + public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowLower(left, right); /// /// int32x2_t vraddhn_s64 (int64x2_t a, int64x2_t b) /// A32: VRADDHN.I64 Dd, Qn, Qm /// A64: RADDHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 AddReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddReturningRoundedHighNarrowLower(left, right); + public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowLower(left, right); /// /// int8x8_t vraddhn_s16 (int16x8_t a, int16x8_t b) /// A32: VRADDHN.I16 Dd, Qn, Qm /// A64: RADDHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 AddReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddReturningRoundedHighNarrowLower(left, right); + public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowLower(left, right); /// /// uint16x4_t vraddhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VRADDHN.I32 Dd, Qn, Qm /// A64: RADDHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 AddReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddReturningRoundedHighNarrowLower(left, right); + public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowLower(left, right); /// /// uint32x2_t vraddhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VRADDHN.I64 Dd, Qn, Qm /// A64: RADDHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 AddReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddReturningRoundedHighNarrowLower(left, right); + public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowLower(left, right); /// /// uint8x16_t vraddhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VRADDHN.I16 Dd+1, Qn, Qm - /// A64: RADDHN2 Vd.16B, Vn.8B, Vm.8H + /// A64: RADDHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 AddReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddReturningRoundedHighNarrowUpper(lower, left, right); + public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowUpper(lower, left, right); /// /// int16x8_t vraddhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VRADDHN.I32 Dd+1, Qn, Qm - /// A64: RADDHN2 Vd.8H, Vn.4H, Vm.4S + /// A64: RADDHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 AddReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddReturningRoundedHighNarrowUpper(lower, left, right); + public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowUpper(lower, left, right); /// /// int32x4_t vraddhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VRADDHN.I64 Dd+1, Qn, Qm - /// A64: RADDHN2 Vd.4S, Vn.2S, Vm.2D + /// A64: RADDHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 AddReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddReturningRoundedHighNarrowUpper(lower, left, right); + public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowUpper(lower, left, right); /// /// int8x16_t vraddhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VRADDHN.I16 Dd+1, Qn, Qm - /// A64: RADDHN2 Vd.16B, Vn.8B, Vm.8H + /// A64: RADDHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 AddReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddReturningRoundedHighNarrowUpper(lower, left, right); + public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowUpper(lower, left, right); /// /// uint16x8_t vraddhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VRADDHN.I32 Dd+1, Qn, Qm - /// A64: RADDHN2 Vd.8H, Vn.4H, Vm.4S + /// A64: RADDHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 AddReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddReturningRoundedHighNarrowUpper(lower, left, right); + public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowUpper(lower, left, right); /// /// uint32x4_t vraddhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VRADDHN.I64 Dd+1, Qn, Qm - /// A64: RADDHN2 Vd.4S, Vn.2S, Vm.2D + /// A64: RADDHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 AddReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddReturningRoundedHighNarrowUpper(lower, left, right); + public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowUpper(lower, left, right); /// /// uint8x8_t vqadd_u8 (uint8x8_t a, uint8x8_t b) @@ -7050,168 +7050,168 @@ public new abstract class Arm64 : ArmBase.Arm64 /// A32: VSUBHN.I16 Dd, Qn, Qm /// A64: SUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractReturningHighNarrowLower(Vector128 left, Vector128 right) => SubtractReturningHighNarrowLower(left, right); + public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) => SubtractHighNarrowLower(left, right); /// /// int16x4_t vsubhn_s32 (int32x4_t a, int32x4_t b) /// A32: VSUBHN.I32 Dd, Qn, Qm /// A64: SUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractReturningHighNarrowLower(Vector128 left, Vector128 right) => SubtractReturningHighNarrowLower(left, right); + public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) => SubtractHighNarrowLower(left, right); /// /// int32x2_t vsubhn_s64 (int64x2_t a, int64x2_t b) /// A32: VSUBHN.I64 Dd, Qn, Qm /// A64: SUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractReturningHighNarrowLower(Vector128 left, Vector128 right) => SubtractReturningHighNarrowLower(left, right); + public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) => SubtractHighNarrowLower(left, right); /// /// int8x8_t vsubhn_s16 (int16x8_t a, int16x8_t b) /// A32: VSUBHN.I16 Dd, Qn, Qm /// A64: SUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractReturningHighNarrowLower(Vector128 left, Vector128 right) => SubtractReturningHighNarrowLower(left, right); + public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) => SubtractHighNarrowLower(left, right); /// /// uint16x4_t vsubhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VSUBHN.I32 Dd, Qn, Qm /// A64: SUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractReturningHighNarrowLower(Vector128 left, Vector128 right) => SubtractReturningHighNarrowLower(left, right); + public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) => SubtractHighNarrowLower(left, right); /// /// uint32x2_t vsubhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VSUBHN.I64 Dd, Qn, Qm /// A64: SUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractReturningHighNarrowLower(Vector128 left, Vector128 right) => SubtractReturningHighNarrowLower(left, right); + public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) => SubtractHighNarrowLower(left, right); /// /// uint8x16_t vsubhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VSUBHN.I16 Dd+1, Qn, Qm - /// A64: SUBHN2 Vd.16B, Vn.8B, Vm.8H + /// A64: SUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractReturningHighNarrowUpper(lower, left, right); + public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowUpper(lower, left, right); /// /// int16x8_t vsubhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VSUBHN.I32 Dd+1, Qn, Qm - /// A64: SUBHN2 Vd.8H, Vn.4H, Vm.4S + /// A64: SUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractReturningHighNarrowUpper(lower, left, right); + public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowUpper(lower, left, right); /// /// int32x4_t vsubhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VSUBHN.I64 Dd+1, Qn, Qm - /// A64: SUBHN2 Vd.4S, Vn.2S, Vm.2D + /// A64: SUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractReturningHighNarrowUpper(lower, left, right); + public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowUpper(lower, left, right); /// /// int8x16_t vsubhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VSUBHN.I16 Dd+1, Qn, Qm - /// A64: SUBHN2 Vd.16B, Vn.8B, Vm.8H + /// A64: SUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractReturningHighNarrowUpper(lower, left, right); + public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowUpper(lower, left, right); /// /// uint16x8_t vsubhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VSUBHN.I32 Dd+1, Qn, Qm - /// A64: SUBHN2 Vd.8H, Vn.4H, Vm.4S + /// A64: SUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractReturningHighNarrowUpper(lower, left, right); + public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowUpper(lower, left, right); /// /// uint32x4_t vsubhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VSUBHN.I64 Dd+1, Qn, Qm - /// A64: SUBHN2 Vd.4S, Vn.2S, Vm.2D + /// A64: SUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractReturningHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractReturningHighNarrowUpper(lower, left, right); + public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowUpper(lower, left, right); /// /// uint8x8_t vrsubhn_u16 (uint16x8_t a, uint16x8_t b) /// A32: VRSUBHN.I16 Dd, Qn, Qm /// A64: RSUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractReturningRoundedHighNarrowLower(left, right); + public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowLower(left, right); /// /// int16x4_t vrsubhn_s32 (int32x4_t a, int32x4_t b) /// A32: VRSUBHN.I32 Dd, Qn, Qm /// A64: RSUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractReturningRoundedHighNarrowLower(left, right); + public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowLower(left, right); /// /// int32x2_t vrsubhn_s64 (int64x2_t a, int64x2_t b) /// A32: VRSUBHN.I64 Dd, Qn, Qm /// A64: RSUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractReturningRoundedHighNarrowLower(left, right); + public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowLower(left, right); /// /// int8x8_t vrsubhn_s16 (int16x8_t a, int16x8_t b) /// A32: VRSUBHN.I16 Dd, Qn, Qm /// A64: RSUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractReturningRoundedHighNarrowLower(left, right); + public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowLower(left, right); /// /// uint16x4_t vrsubhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VRSUBHN.I32 Dd, Qn, Qm /// A64: RSUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractReturningRoundedHighNarrowLower(left, right); + public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowLower(left, right); /// /// uint32x2_t vrsubhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VRSUBHN.I64 Dd, Qn, Qm /// A64: RSUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractReturningRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractReturningRoundedHighNarrowLower(left, right); + public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowLower(left, right); /// /// uint8x16_t vrsubhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VRSUBHN.I16 Dd+1, Qn, Qm - /// A64: RSUBHN2 Vd.16B, Vn.8B, Vm.8H + /// A64: RSUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractReturningRoundedHighNarrowUpper(lower, left, right); + public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowUpper(lower, left, right); /// /// int16x8_t vrsubhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VRSUBHN.I32 Dd+1, Qn, Qm - /// A64: RSUBHN2 Vd.8H, Vn.4H, Vm.4S + /// A64: RSUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractReturningRoundedHighNarrowUpper(lower, left, right); + public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowUpper(lower, left, right); /// /// int32x4_t vrsubhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VRSUBHN.I64 Dd+1, Qn, Qm - /// A64: RSUBHN2 Vd.4S, Vn.2S, Vm.2D + /// A64: RSUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractReturningRoundedHighNarrowUpper(lower, left, right); + public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowUpper(lower, left, right); /// /// int8x16_t vrsubhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VRSUBHN.I16 Dd+1, Qn, Qm - /// A64: RSUBHN2 Vd.16B, Vn.8B, Vm.8H + /// A64: RSUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractReturningRoundedHighNarrowUpper(lower, left, right); + public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowUpper(lower, left, right); /// /// uint16x8_t vrsubhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VRSUBHN.I32 Dd+1, Qn, Qm - /// A64: RSUBHN2 Vd.8H, Vn.4H, Vm.4S + /// A64: RSUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractReturningRoundedHighNarrowUpper(lower, left, right); + public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowUpper(lower, left, right); /// /// uint32x4_t vrsubhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VRSUBHN.I64 Dd+1, Qn, Qm - /// A64: RSUBHN2 Vd.4S, Vn.2S, Vm.2D + /// A64: RSUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractReturningRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractReturningRoundedHighNarrowUpper(lower, left, right); + public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowUpper(lower, left, right); /// /// uint8x8_t vqsub_u8 (uint8x8_t a, uint8x8_t b) diff --git a/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs b/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs index 181e20a22c3ca..dee537db82298 100644 --- a/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs +++ b/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs @@ -96,6 +96,18 @@ public abstract partial class AdvSimd : System.Runtime.Intrinsics.Arm.ArmBase public static System.Runtime.Intrinsics.Vector64 Add(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Add(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Add(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 AddPairwise(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 AddPairwise(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 AddPairwise(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } @@ -127,30 +139,18 @@ public abstract partial class AdvSimd : System.Runtime.Intrinsics.Arm.ArmBase public static System.Runtime.Intrinsics.Vector64 AddPairwiseWideningAndAddScalar(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value) { throw null; } public static System.Runtime.Intrinsics.Vector64 AddPairwiseWideningScalar(System.Runtime.Intrinsics.Vector64 value) { throw null; } public static System.Runtime.Intrinsics.Vector64 AddPairwiseWideningScalar(System.Runtime.Intrinsics.Vector64 value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddReturningHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddReturningHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddReturningHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddReturningHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddReturningHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddReturningHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddReturningHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddReturningHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddReturningHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddReturningHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddReturningHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddReturningHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddReturningRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddReturningRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddReturningRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddReturningRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddReturningRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddReturningRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddReturningRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddReturningRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddReturningRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddReturningRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddReturningRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddReturningRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 AddSaturate(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 AddSaturate(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 AddSaturate(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } @@ -744,30 +744,30 @@ public abstract partial class AdvSimd : System.Runtime.Intrinsics.Arm.ArmBase public static System.Runtime.Intrinsics.Vector64 Subtract(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Subtract(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Subtract(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractReturningHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractReturningHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractReturningHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractReturningHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractReturningHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractReturningHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractReturningHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractReturningHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractReturningHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractReturningHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractReturningHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractReturningHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractReturningRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractReturningRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractReturningRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractReturningRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractReturningRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractReturningRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractReturningRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractReturningRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractReturningRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractReturningRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractReturningRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractReturningRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 SubtractSaturate(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 SubtractSaturate(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 SubtractSaturate(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } From 866b7ee100029928d69e7ac85c0a52100bac4bea Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Thu, 7 May 2020 10:40:04 -0700 Subject: [PATCH 026/420] Add logic to throw when converter doesn't handle null and null can't be assigned to property --- .../Json/Serialization/JsonConverterOfT.cs | 21 +++++++++++++++++++ .../Serialization/JsonParameterInfoOfT.cs | 10 +++++++++ .../Json/Serialization/JsonPropertyInfoOfT.cs | 10 +++++++++ .../CustomConverterTests.HandleNull.cs | 8 +++---- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs index e18a31a0c7088..058e7dc395bd8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs @@ -23,6 +23,7 @@ protected internal JsonConverter() CanBePolymorphic = TypeToConvert == typeof(object); IsValueType = TypeToConvert.IsValueType; HandleNull = IsValueType; + CanBeNull = !IsValueType || Nullable.GetUnderlyingType(TypeToConvert) != null; IsInternalConverter = GetType().Assembly == typeof(JsonConverter).Assembly; CanUseDirectReadOrWrite = !CanBePolymorphic && IsInternalConverter && ClassType == ClassType.Value; } @@ -63,6 +64,11 @@ internal override sealed JsonParameterInfo CreateJsonParameterInfo() /// public virtual bool HandleNull { get; } + /// + /// Can be assigned to ? + /// + internal bool CanBeNull { get; } + /// /// Is the converter built-in. /// @@ -112,6 +118,11 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali // For perf and converter simplicity, handle null here instead of forwarding to the converter. if (reader.TokenType == JsonTokenType.Null && !HandleNull) { + if (!CanBeNull) + { + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert); + } + value = default; return true; } @@ -154,6 +165,11 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali { if (reader.TokenType == JsonTokenType.Null && !HandleNull && !wasContinuation) { + if (!CanBeNull) + { + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert); + } + // For perf and converter simplicity, handle null here instead of forwarding to the converter. value = default; success = true; @@ -171,6 +187,11 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali // For perf and converter simplicity, handle null here instead of forwarding to the converter. if (reader.TokenType == JsonTokenType.Null && !HandleNull) { + if (!CanBeNull) + { + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert); + } + value = default; state.Pop(true); return true; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfoOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfoOfT.cs index a2b20294510ee..a03982f4e40d8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfoOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfoOfT.cs @@ -56,6 +56,11 @@ public override bool ReadJson(ref ReadStack state, ref Utf8JsonReader reader, ou if (isNullToken && !_converter.HandleNull && !state.IsContinuation) { + if (!_converter.CanBeNull) + { + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(_converter.TypeToConvert); + } + // Don't have to check for IgnoreNullValue option here because we set the default value regardless. value = DefaultValue; return true; @@ -85,6 +90,11 @@ public bool ReadJsonTyped(ref ReadStack state, ref Utf8JsonReader reader, [Maybe if (isNullToken && !_converter.HandleNull && !state.IsContinuation) { + if (!_converter.CanBeNull) + { + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(_converter.TypeToConvert); + } + // Don't have to check for IgnoreNullValue option here because we set the default value regardless. value = TypedDefaultValue; return true; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs index fe1e77e701678..357a247185a92 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs @@ -164,6 +164,11 @@ public override bool ReadJsonAndSetMember(object obj, ref ReadStack state, ref U { if (!IgnoreNullValues) { + if (!Converter.CanBeNull) + { + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Converter.TypeToConvert); + } + T value = default; Set!(obj, value!); } @@ -206,6 +211,11 @@ public override bool ReadJsonAsObject(ref ReadStack state, ref Utf8JsonReader re bool isNullToken = reader.TokenType == JsonTokenType.Null; if (isNullToken && !Converter.HandleNull && !state.IsContinuation) { + if (!Converter.CanBeNull) + { + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Converter.TypeToConvert); + } + value = default(T)!; success = true; } diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs index ac7165b15bb3c..30ee15ea9980d 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs @@ -49,8 +49,8 @@ public static void ValueTypeConverter_OptOut() var options = new JsonSerializerOptions(); options.Converters.Add(new Int32NullConverter_OptOut()); - // Serializer sets default value (doesn't fallback to built-in converter). - Assert.Equal(0, JsonSerializer.Deserialize("null", options)); + // Serializer throws JsonException if null is assigned to value that can't be null. + Assert.Throws(() => JsonSerializer.Deserialize("null", options)); } private class Int32NullConverter_OptOut : Int32NullConverter_SpecialCaseNull @@ -113,9 +113,7 @@ public static void ComplexValueTypeConverter_OptOut() var options = new JsonSerializerOptions(); options.Converters.Add(new PointStructConverter_OptOut()); - var obj = JsonSerializer.Deserialize("null", options); - Assert.Equal(0, obj.X); - Assert.Equal(0, obj.Y); + Assert.Throws(() => JsonSerializer.Deserialize("null", options)); } private class PointStructConverter_OptOut : PointStructConverter_SpecialCaseNull From 88a78d29bea1803679dbf9353fb951a954729829 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Thu, 7 May 2020 20:29:52 +0200 Subject: [PATCH 027/420] Change epoll thread count (#35800) * use struct wrapper for better perf * check the most common case first * don't access static variable in a loop * use Span instead of raw pointers * change the heuristic, single epoll thread is not always enough * simplify the heuristic and add a comment * apply the naming suggestions --- .../Net/Sockets/SocketAsyncContext.Unix.cs | 3 +- .../Net/Sockets/SocketAsyncEngine.Unix.cs | 111 +++++++++++------- 2 files changed, 72 insertions(+), 42 deletions(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs index 1e4242a251ab4..a0479bfc33629 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs @@ -1995,7 +1995,8 @@ public SocketError SendFileAsync(SafeFileHandle fileHandle, long offset, long co // be scheduled instead. It's not functionally incorrect to schedule the release of a synchronous operation, just it may // lead to thread pool starvation issues if the synchronous operations are blocking thread pool threads (typically not // advised) and more threads are not immediately available to run work items that would release those operations. - public unsafe Interop.Sys.SocketEvents HandleSyncEventsSpeculatively(Interop.Sys.SocketEvents events) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Interop.Sys.SocketEvents HandleSyncEventsSpeculatively(Interop.Sys.SocketEvents events) { if ((events & Interop.Sys.SocketEvents.Error) != 0) { diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs index 26a8be4bf128a..badf27e85d358 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs @@ -2,13 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Concurrent; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; -using System.Threading.Tasks; namespace System.Net.Sockets { @@ -56,22 +54,40 @@ public bool TryRegister(SafeSocketHandle socket, out Interop.Error error) private static readonly object s_lock = new object(); - // In debug builds, force there to be 2 engines. In release builds, use half the number of processors when - // there are at least 6. The lower bound is to avoid using multiple engines on systems which aren't servers. -#pragma warning disable CA1802 // const works for debug, but needs to be static readonly for release - private static readonly int s_engineCount = -#if DEBUG - 2; -#else - Environment.ProcessorCount >= 6 ? Environment.ProcessorCount / 2 : 1; -#endif -#pragma warning restore CA1802 + private static readonly int s_maxEngineCount = GetEngineCount(); + + private static int GetEngineCount() + { + // The responsibility of SocketAsyncEngine is to get notifications from epoll|kqueue + // and schedule corresponding work items to ThreadPool (socket reads and writes). + // + // Using TechEmpower benchmarks that generate a LOT of SMALL socket reads and writes under a VERY HIGH load + // we have observed that a single engine is capable of keeping busy up to thirty x64 and eight ARM64 CPU Cores. + // + // The vast majority of real-life scenarios is never going to generate such a huge load (hundreds of thousands of requests per second) + // and having a single producer should be almost always enough. + // + // We want to be sure that we can handle extreme loads and that's why we have decided to use these values. + // + // It's impossible to predict all possible scenarios so we have added a possibility to configure this value using environment variables. + if (uint.TryParse(Environment.GetEnvironmentVariable("DOTNET_SYSTEM_NET_SOCKETS_THREAD_COUNT"), out uint count)) + { + return (int)count; + } + + Architecture architecture = RuntimeInformation.ProcessArchitecture; + int coresPerEngine = architecture == Architecture.Arm64 || architecture == Architecture.Arm + ? 8 + : 30; + + return Math.Max(1, (int)Math.Round(Environment.ProcessorCount / (double)coresPerEngine)); + } // // The current engines. We replace an engine when it runs out of "handle" values. // Must be accessed under s_lock. // - private static readonly SocketAsyncEngine?[] s_currentEngines = new SocketAsyncEngine?[s_engineCount]; + private static readonly SocketAsyncEngine?[] s_currentEngines = new SocketAsyncEngine?[s_maxEngineCount]; private static int s_allocateFromEngine = 0; private readonly IntPtr _port; @@ -106,7 +122,7 @@ public bool TryRegister(SafeSocketHandle socket, out Interop.Error error) // private static readonly IntPtr MaxHandles = IntPtr.Size == 4 ? (IntPtr)int.MaxValue : (IntPtr)long.MaxValue; #endif - private static readonly IntPtr MinHandlesForAdditionalEngine = s_engineCount == 1 ? MaxHandles : (IntPtr)32; + private static readonly IntPtr MinHandlesForAdditionalEngine = s_maxEngineCount == 1 ? MaxHandles : (IntPtr)32; // // Sentinel handle value to identify events from the "shutdown pipe," used to signal an event loop to stop @@ -129,7 +145,7 @@ public bool TryRegister(SafeSocketHandle socket, out Interop.Error error) // // Maps handle values to SocketAsyncContext instances. // - private readonly ConcurrentDictionary _handleToContextMap = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _handleToContextMap = new ConcurrentDictionary(); // // Queue of events generated by EventLoop() that would be processed by the thread pool @@ -197,7 +213,7 @@ private static void AllocateToken(SocketAsyncContext context, out SocketAsyncEng // Round-robin to the next engine once we have sufficient sockets on this one. if (!engine.HasLowNumberOfSockets) { - s_allocateFromEngine = (s_allocateFromEngine + 1) % s_engineCount; + s_allocateFromEngine = (s_allocateFromEngine + 1) % s_maxEngineCount; } } } @@ -208,7 +224,8 @@ private IntPtr AllocateHandle(SocketAsyncContext context) Debug.Assert(!IsFull, "Expected !IsFull"); IntPtr handle = _nextHandle; - _handleToContextMap.TryAdd(handle, context); + Debug.Assert(handle != ShutdownHandle, "ShutdownHandle must not be added to the dictionary"); + _handleToContextMap.TryAdd(handle, new SocketAsyncContextWrapper(context)); _nextHandle = IntPtr.Add(_nextHandle, 1); _outstandingHandles = IntPtr.Add(_outstandingHandles, 1); @@ -318,8 +335,10 @@ private void EventLoop() { bool shutdown = false; Interop.Sys.SocketEvent* buffer = _buffer; - ConcurrentDictionary handleToContextMap = _handleToContextMap; + ConcurrentDictionary handleToContextMap = _handleToContextMap; ConcurrentQueue eventQueue = _eventQueue; + IntPtr shutdownHandle = ShutdownHandle; + SocketAsyncContext? context = null; while (!shutdown) { int numEvents = EventBufferCount; @@ -333,38 +352,36 @@ private void EventLoop() Debug.Assert(numEvents > 0, $"Unexpected numEvents: {numEvents}"); bool enqueuedEvent = false; - for (int i = 0; i < numEvents; i++) + foreach (var socketEvent in new ReadOnlySpan(buffer, numEvents)) { - IntPtr handle = buffer[i].Data; - if (handle == ShutdownHandle) - { - shutdown = true; - } - else + IntPtr handle = socketEvent.Data; + + if (handleToContextMap.TryGetValue(handle, out SocketAsyncContextWrapper contextWrapper) && (context = contextWrapper.Context) != null) { Debug.Assert(handle.ToInt64() < MaxHandles.ToInt64(), $"Unexpected values: handle={handle}, MaxHandles={MaxHandles}"); - handleToContextMap.TryGetValue(handle, out SocketAsyncContext? context); - if (context != null) + + Interop.Sys.SocketEvents events = context.HandleSyncEventsSpeculatively(socketEvent.Events); + if (events != Interop.Sys.SocketEvents.None) { - Interop.Sys.SocketEvents events = buffer[i].Events; - events = context.HandleSyncEventsSpeculatively(events); - if (events != Interop.Sys.SocketEvents.None) - { - var ev = new SocketIOEvent(context, events); - eventQueue.Enqueue(ev); - enqueuedEvent = true; - - // This is necessary when the JIT generates unoptimized code (debug builds, live debugging, - // quick JIT, etc.) to ensure that the context does not remain referenced by this method, as - // such code may keep the stack location live for longer than necessary - ev = default; - } + var ev = new SocketIOEvent(context, events); + eventQueue.Enqueue(ev); + enqueuedEvent = true; // This is necessary when the JIT generates unoptimized code (debug builds, live debugging, // quick JIT, etc.) to ensure that the context does not remain referenced by this method, as // such code may keep the stack location live for longer than necessary - context = null; + ev = default; } + + // This is necessary when the JIT generates unoptimized code (debug builds, live debugging, + // quick JIT, etc.) to ensure that the context does not remain referenced by this method, as + // such code may keep the stack location live for longer than necessary + context = null; + contextWrapper = default; + } + else if (handle == shutdownHandle) + { + shutdown = true; } } @@ -488,6 +505,18 @@ private bool TryRegister(SafeSocketHandle socket, IntPtr handle, out Interop.Err return error == Interop.Error.SUCCESS; } + // struct wrapper is used in order to improve the performance of the epoll thread hot path by up to 3% of some TechEmpower benchmarks + // the goal is to have a dedicated generic instantiation and using: + // System.Collections.Concurrent.ConcurrentDictionary`2[System.IntPtr,System.Net.Sockets.SocketAsyncContextWrapper]::TryGetValueInternal(!0,int32,!1&) + // instead of: + // System.Collections.Concurrent.ConcurrentDictionary`2[System.IntPtr,System.__Canon]::TryGetValueInternal(!0,int32,!1&) + private readonly struct SocketAsyncContextWrapper + { + public SocketAsyncContextWrapper(SocketAsyncContext context) => Context = context; + + internal SocketAsyncContext Context { get; } + } + private readonly struct SocketIOEvent { public SocketAsyncContext Context { get; } From e8f3ac16d4627d800ee8cc97ebc56ae414642c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Thu, 7 May 2020 20:35:26 +0200 Subject: [PATCH 028/420] Re-enable default interface methods tests on ARM64 (#35889) These are all disabled on an unrelated bug. I couldn't dig out how this happened. If they are failing, I would want to see a high priority bug to look at them. For some reason tiering-related tests were also disabled on the mystery bug. --- src/coreclr/tests/issues.targets | 45 -------------------------------- 1 file changed, 45 deletions(-) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index 27e894d2e8947..be29df300d538 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -596,57 +596,12 @@ https://github.com/dotnet/runtime/issues/31729 - - https://github.com/dotnet/runtime/issues/7430 - extremely memory/time intensive test - - https://github.com/dotnet/runtime/issues/7430 - - - https://github.com/dotnet/runtime/issues/7430 - - - https://github.com/dotnet/runtime/issues/7430 - - - https://github.com/dotnet/runtime/issues/7430 - - - https://github.com/dotnet/runtime/issues/7430 - - - https://github.com/dotnet/runtime/issues/7430 - - - https://github.com/dotnet/runtime/issues/7430 - - - https://github.com/dotnet/runtime/issues/7430 - - - https://github.com/dotnet/runtime/issues/7430 - - - https://github.com/dotnet/runtime/issues/7430 - - - https://github.com/dotnet/runtime/issues/7430 - - - https://github.com/dotnet/runtime/issues/7430 - https://github.com/dotnet/runtime/issues/9270 - - https://github.com/dotnet/runtime/issues/7430 - - - https://github.com/dotnet/runtime/issues/7430 - needs triage From 5178041776634bfbc4f868425710e60d95f7066f Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 7 May 2020 11:58:16 -0700 Subject: [PATCH 029/420] Delete FEATURE_CORRUPTING_EXCEPTIONS (#35938) * Delete HCORMODULE * Delete FEATURE_CORRUPTING_EXCEPTIONS Ability to catch corrupting exceptions was disabled in .NET Core since early days for security reasons. This is still disabled after this change, but achieved in much simpler way without the full corrupting exceptions machinery. * Delete unused bSecurityCheck argument of GetComIPFromObjectRef --- src/coreclr/clrdefinitions.cmake | 1 - src/coreclr/src/inc/clrconfigvalues.h | 1 - src/coreclr/src/inc/corpriv.h | 62 - src/coreclr/src/inc/ex.h | 84 +- src/coreclr/src/inc/utilcode.h | 7 - src/coreclr/src/md/runtime/mdinternaldisp.h | 8 - src/coreclr/src/utilcode/util.cpp | 52 - .../src/vm/.vscode/c_cpp_properties.json | 1 - src/coreclr/src/vm/castcache.cpp | 4 +- src/coreclr/src/vm/clrex.h | 77 +- src/coreclr/src/vm/comcallablewrapper.cpp | 3 +- src/coreclr/src/vm/comcallablewrapper.h | 3 +- src/coreclr/src/vm/comdelegate.cpp | 39 +- src/coreclr/src/vm/commodule.cpp | 3 +- src/coreclr/src/vm/dispatchinfo.cpp | 4 +- src/coreclr/src/vm/eeconfig.cpp | 5 - src/coreclr/src/vm/eeconfig.h | 9 - src/coreclr/src/vm/eventtrace.cpp | 30 +- src/coreclr/src/vm/excep.cpp | 1076 +---------------- src/coreclr/src/vm/excep.h | 79 +- src/coreclr/src/vm/exceptionhandling.cpp | 82 +- src/coreclr/src/vm/exceptionhandling.h | 29 - src/coreclr/src/vm/exceptmacros.h | 32 - src/coreclr/src/vm/exinfo.cpp | 5 - src/coreclr/src/vm/exinfo.h | 19 - src/coreclr/src/vm/exstate.cpp | 7 - src/coreclr/src/vm/exstate.h | 50 - src/coreclr/src/vm/frames.h | 6 +- src/coreclr/src/vm/i386/excepx86.cpp | 124 +- src/coreclr/src/vm/interopconverter.cpp | 3 +- src/coreclr/src/vm/interopconverter.h | 2 +- src/coreclr/src/vm/jithelpers.cpp | 17 - src/coreclr/src/vm/listlock.h | 8 - src/coreclr/src/vm/marshalnative.cpp | 2 +- src/coreclr/src/vm/methodtable.cpp | 61 +- src/coreclr/src/vm/rcwwalker.cpp | 2 +- src/coreclr/src/vm/reflectioninvocation.cpp | 21 +- src/coreclr/src/vm/stdinterfaces.cpp | 2 +- src/coreclr/src/vm/threads.cpp | 11 - 39 files changed, 94 insertions(+), 1937 deletions(-) diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index ce2bc382a9937..aa071ea69fe3d 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -105,7 +105,6 @@ endif(CLR_CMAKE_TARGET_WIN32) add_definitions(-DFEATURE_BASICFREEZE) add_definitions(-DFEATURE_CORECLR) add_definitions(-DFEATURE_CORESYSTEM) -add_definitions(-DFEATURE_CORRUPTING_EXCEPTIONS) if(FEATURE_DBGIPC) add_definitions(-DFEATURE_DBGIPC_TRANSPORT_DI) add_definitions(-DFEATURE_DBGIPC_TRANSPORT_VM) diff --git a/src/coreclr/src/inc/clrconfigvalues.h b/src/coreclr/src/inc/clrconfigvalues.h index 51b47e4f7ec19..f4cf1d192905c 100644 --- a/src/coreclr/src/inc/clrconfigvalues.h +++ b/src/coreclr/src/inc/clrconfigvalues.h @@ -253,7 +253,6 @@ CONFIG_DWORD_INFO(INTERNAL_SuppressLockViolationsOnReentryFromOS, W("SuppressLoc CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_AssertOnFailFast, W("AssertOnFailFast"), "") RETAIL_CONFIG_DWORD_INFO_EX(UNSUPPORTED_legacyCorruptedStateExceptionsPolicy, W("legacyCorruptedStateExceptionsPolicy"), 0, "Enabled Pre-V4 CSE behavior", CLRConfig::EEConfig_default) CONFIG_DWORD_INFO_EX(INTERNAL_SuppressLostExceptionTypeAssert, W("SuppressLostExceptionTypeAssert"), 0, "", CLRConfig::EEConfig_default) -RETAIL_CONFIG_DWORD_INFO_EX(UNSUPPORTED_FailFastOnCorruptedStateException, W("FailFastOnCorruptedStateException"), 0, "Failfast if a CSE is encountered", CLRConfig::EEConfig_default) RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_UseEntryPointFilter, W("UseEntryPointFilter"), 0, "", CLRConfig::EEConfig_default) RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_Corhost_Swallow_Uncaught_Exceptions, W("Corhost_Swallow_Uncaught_Exceptions"), 0, "", CLRConfig::EEConfig_default) diff --git a/src/coreclr/src/inc/corpriv.h b/src/coreclr/src/inc/corpriv.h index f0261b3381cc4..6b92458ec40f1 100644 --- a/src/coreclr/src/inc/corpriv.h +++ b/src/coreclr/src/inc/corpriv.h @@ -25,9 +25,6 @@ interface IAssemblyName; -// PE images loaded through the runtime. -typedef struct _dummyCOR { BYTE b; } *HCORMODULE; - class UTSemReadWrite; // Helper function to get a pointer to the Dispenser interface. @@ -70,11 +67,6 @@ STDAPI GetAssemblyMDInternalImport( // Return code. REFIID riid, // [IN] The interface desired. IUnknown **ppIUnk); // [OUT] Return interface on success. -HRESULT GetAssemblyMDInternalImportFromImage( - HCORMODULE hImage, //[IN] pointer to module handle to get the metadata from. - REFIID riid, //[IN] The interface desired. - IUnknown **ppIUnk); //[OUT] Return Interface on success. - STDAPI GetAssemblyMDInternalImportByStream( // Return code. IStream *pIStream, // [IN] The IStream for the file UINT64 AssemblyId, // [IN] Unique Id for the assembly @@ -303,60 +295,6 @@ typedef enum CorOpenFlagsInternal #define COR_MODULE_CLASS "" #define COR_WMODULE_CLASS W("") -STDAPI RuntimeOpenImage(LPCWSTR pszFileName, HCORMODULE* hHandle); -STDAPI RuntimeOpenImageInternal(LPCWSTR pszFileName, HCORMODULE* hHandle, - DWORD *pdwLength, MDInternalImportFlags flags, HANDLE hFile = INVALID_HANDLE_VALUE); -STDAPI RuntimeOpenImageByStream(IStream* pIStream, UINT64 AssemblyId, DWORD dwModuleId, - HCORMODULE* hHandle, DWORD *pdwLength, MDInternalImportFlags flags); - -void RuntimeAddRefHandle(HCORMODULE hHandle); -STDAPI RuntimeReleaseHandle(HCORMODULE hHandle); -STDAPI RuntimeGetImageBase(HCORMODULE hHandle, LPVOID* base, BOOL bMapped, COUNT_T* dwSize); -STDAPI RuntimeGetImageKind(HCORMODULE hHandle, DWORD* pdwKind, DWORD* pdwMachine); -STDAPI RuntimeOSHandle(HCORMODULE hHandle, HMODULE* hModule); -STDAPI RuntimeGetAssemblyStrongNameHashForModule(HCORMODULE hModule, - IMetaDataImport *pMDimport, - BYTE *pbSNHash, - DWORD *pcbSNHash); -STDAPI RuntimeGetMDInternalImport(HCORMODULE hHandle, - MDInternalImportFlags flags, - IMDInternalImport** ppMDImport); - -FORCEINLINE -void ReleaseHCorModule(HCORMODULE hModule) -{ - HRESULT hr = RuntimeReleaseHandle(hModule); - _ASSERTE(SUCCEEDED(hr)); -} - -typedef Wrapper, ReleaseHCorModule, (UINT_PTR) NULL> HCORMODULEHolder; - - -// =========================================================================== -// ISNAssemblySignature (similar to IAssemblySignature in V1) -// -// This is a private interface that allows querying of the strong name -// signature. -// This can be used for (strong-named) assemblies added to the GAC as -// a unique identifier. -// - -// {848845BC-0C4A-42e3-8915-DC850112443D} -EXTERN_GUID(IID_ISNAssemblySignature, 0x848845BC, 0x0C4A, 0x42e3, 0x89, 0x15, 0xDC, 0x85, 0x01, 0x12, 0x44, 0x3D); - -#undef INTERFACE -#define INTERFACE ISNAssemblySignature -DECLARE_INTERFACE_(ISNAssemblySignature, IUnknown) -{ - // Returns the strong-name signature if the assembly is strong-name-signed - // Returns the MVID if the assembly is delay-signed. - // Fails if the assembly is not signed at all. - STDMETHOD(GetSNAssemblySignature) ( - BYTE *pbSig, // [IN, OUT] Buffer to write signature - DWORD *pcbSig // [IN, OUT] Size of buffer, bytes written - ) PURE; -}; - //------------------------------------- //--- ICeeGenInternal //------------------------------------- diff --git a/src/coreclr/src/inc/ex.h b/src/coreclr/src/inc/ex.h index 48a3572bca3ec..6d008c6febecf 100644 --- a/src/coreclr/src/inc/ex.h +++ b/src/coreclr/src/inc/ex.h @@ -706,93 +706,17 @@ class CAutoTryCleanup EX_RETHROW; \ } \ -// Don't use this - use RethrowCorruptingExceptions (see below) instead. #define SwallowAllExceptions ; -////////////////////////////////////////////////////////////////////// -// -// Corrupted State Exception Support -// -///////////////////////////////////////////////////////////////////// - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - -#define CORRUPTING_EXCEPTIONS_ONLY(expr) expr -#define COMMA_CORRUPTING_EXCEPTIONS_ONLY(expr) ,expr - -// EX_END_CATCH has been modified to not swallow Corrupting Exceptions (CE) when one of the -// following arguments are passed to it: -// -// 1) RethrowTerminalExceptions - rethrows both terminal and corrupting exceptions -// 2) RethrowCorruptingExceptions - swallows all exceptions exception corrupting exceptions. This SHOULD BE USED instead of SwallowAllExceptions. -// 3) RethrowTerminalExceptionsEx - same as (1) but rethrow of CE can be controlled via a condition. -// 4) RethrowCorruptingExceptionsEx - same as (2) but rethrow of CE can be controlled via a condition. -// -// By default, if a CE is encountered when one of the above policies are applied, the runtime will -// ensure that the CE propagates up the stack and not get swallowed unless the developer chooses to override the behaviour. -// This can be done by using the "Ex" versions above that take a conditional which evaluates to a BOOL. In such a case, -// the CE will *only* be rethrown if the conditional evalutes to TRUE. For examples, refer to COMToCLRWorker or -// DispatchInfo::InvokeMember implementations. -// -// SET_CE_RETHROW_FLAG_FOR_EX_CATCH macros helps evaluate if the CE is to be rethrown or not. This has been redefined in -// Clrex.h to add the condition of evaluating the throwable as well (which is not available outside the VM folder). -// -// Passing FALSE as the second argument to IsProcessCorruptedStateException implies that SET_CE_RETHROW_FLAG_FOR_EX_CATCH -// will ensure that we dont rethrow SO and allow EX_ENDTRY to SO specific processing. If none is done, then EX_ENDTRY will -// rethrow SO. By that time stack has been reclaimed and thus, throwing SO will be safe. -// -// We also check the global override flag incase it has been set to force pre-V4 beahviour. "0" implies it has not -// been overriden. -#define SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr) ((((expr) == TRUE) && \ - (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_legacyCorruptedStateExceptionsPolicy) == 0) && \ - IsProcessCorruptedStateException(GetCurrentExceptionCode(), FALSE))) - -// This rethrow policy can be used in EX_END_CATCH to swallow all exceptions except the corrupting ones. -// This macro can be used to rethrow the CE based upon a BOOL condition. -#define RethrowCorruptingExceptionsEx(expr) \ - if (SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr)) \ - { \ - STATIC_CONTRACT_THROWS_TERMINAL; \ - EX_RETHROW; \ - } - -#define RethrowCorruptingExceptionsExAndHookRethrow(shouldRethrowExpr, aboutToRethrowExpr) \ - if (SET_CE_RETHROW_FLAG_FOR_EX_CATCH(shouldRethrowExpr)) \ - { \ - STATIC_CONTRACT_THROWS_TERMINAL; \ - aboutToRethrowExpr; \ - EX_RETHROW; \ - } - -#else // !FEATURE_CORRUPTING_EXCEPTIONS - -#define CORRUPTING_EXCEPTIONS_ONLY(expr) -#define COMMA_CORRUPTING_EXCEPTIONS_ONLY(expr) - -// When we dont have support for CE, just map it to SwallowAllExceptions -#define RethrowCorruptingExceptionsEx(expr) SwallowAllExceptions -#define RethrowCorruptingExceptionsExAndHookRethrow(shouldRethrowExpr, aboutToRethrowExpr) SwallowAllExceptions -#define SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr) !TRUE -#endif // FEATURE_CORRUPTING_EXCEPTIONS - -// Map to RethrowCorruptingExceptionsEx so that it does the "right" thing -#define RethrowCorruptingExceptions RethrowCorruptingExceptionsEx(TRUE) - -// This macro can be used to rethrow the CE based upon a BOOL condition. It will continue to rethrow terminal -// exceptions unconditionally. -#define RethrowTerminalExceptionsEx(expr) \ - if (GET_EXCEPTION()->IsTerminal() || \ - SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr)) \ +// When applied to EX_END_CATCH, this policy will always rethrow Terminal exceptions if they are +// encountered. +#define RethrowTerminalExceptions \ + if (GET_EXCEPTION()->IsTerminal()) \ { \ STATIC_CONTRACT_THROWS_TERMINAL; \ EX_RETHROW; \ } \ - -// When applied to EX_END_CATCH, this policy will always rethrow Terminal and Corrupting exceptions if they are -// encountered. -#define RethrowTerminalExceptions RethrowTerminalExceptionsEx(TRUE) - // Special define to be used in EEStartup that will also check for VM initialization before // commencing on a path that may use the managed thread object. #define RethrowTerminalExceptionsWithInitCheck \ diff --git a/src/coreclr/src/inc/utilcode.h b/src/coreclr/src/inc/utilcode.h index 1721db03dc01f..14b261b08ad07 100644 --- a/src/coreclr/src/inc/utilcode.h +++ b/src/coreclr/src/inc/utilcode.h @@ -4715,13 +4715,6 @@ BOOL IsIPInModule(HMODULE_TGT hModule, PCODE ip); extern HINSTANCE g_hmodCoreCLR; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - -// Corrupting Exception limited support for outside the VM folder -BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO = TRUE); - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - namespace UtilCode { // These are type-safe versions of Interlocked[Compare]Exchange diff --git a/src/coreclr/src/md/runtime/mdinternaldisp.h b/src/coreclr/src/md/runtime/mdinternaldisp.h index 510e87351f354..530a141989565 100644 --- a/src/coreclr/src/md/runtime/mdinternaldisp.h +++ b/src/coreclr/src/md/runtime/mdinternaldisp.h @@ -16,7 +16,6 @@ #include "mdinternalro.h" - enum MDFileFormat { MDFormat_ReadOnly = 0, @@ -25,8 +24,6 @@ enum MDFileFormat MDFormat_Invalid = 3 }; - -HRESULT CheckFileFormat(LPVOID pData, ULONG cbData, MDFileFormat *pFormat); STDAPI GetMDInternalInterface( LPVOID pData, // [IN] Buffer with the metadata. ULONG cbData, // [IN] Size of the data in the buffer. @@ -34,11 +31,6 @@ STDAPI GetMDInternalInterface( REFIID riid, // [in] The interface desired. void **ppIUnk); // [out] Return interface on success. -HRESULT GetAssemblyMDInternalImportHelper(HCORMODULE hModule, - REFIID riid, - MDInternalImportFlags flags, - IUnknown **ppIUnk); - #endif //FEATURE_METADATA_INTERNAL_APIS #endif // __MDInternalDispenser__h__ diff --git a/src/coreclr/src/utilcode/util.cpp b/src/coreclr/src/utilcode/util.cpp index f1f004d3897d5..8c980df45dea1 100644 --- a/src/coreclr/src/utilcode/util.cpp +++ b/src/coreclr/src/utilcode/util.cpp @@ -3031,58 +3031,6 @@ lDone: ; return param.fRet; } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - -// To include definition of EXCEPTION_SOFTSO -#include "corexcep.h" - -// These functions provide limited support for corrupting exceptions -// outside the VM folder. Its limited since we don't have access to the -// throwable. -// -// These functions are also wrapped by the corresponding CEHelper -// methods in excep.cpp. - -// Given an exception code, this method returns a BOOL to indicate if the -// code belongs to a corrupting exception or not. -BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO /*=TRUE*/) -{ - LIMITED_METHOD_CONTRACT; - - // By default, assume its not corrupting - BOOL fIsCorruptedStateException = FALSE; - - if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_legacyCorruptedStateExceptionsPolicy) == 1) - { - return fIsCorruptedStateException; - } - - // If we have been asked not to include SO in the CSE check - // and the code represent SO, then exit now. - if ((fCheckForSO == FALSE) && (dwExceptionCode == STATUS_STACK_OVERFLOW)) - { - return fIsCorruptedStateException; - } - - switch(dwExceptionCode) - { - case STATUS_ACCESS_VIOLATION: - case STATUS_STACK_OVERFLOW: - case EXCEPTION_ILLEGAL_INSTRUCTION: - case EXCEPTION_IN_PAGE_ERROR: - case EXCEPTION_INVALID_DISPOSITION: - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - case EXCEPTION_PRIV_INSTRUCTION: - case STATUS_UNWIND_CONSOLIDATE: - fIsCorruptedStateException = TRUE; - break; - } - - return fIsCorruptedStateException; -} - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - namespace Clr { namespace Util diff --git a/src/coreclr/src/vm/.vscode/c_cpp_properties.json b/src/coreclr/src/vm/.vscode/c_cpp_properties.json index a4c0ec931c99a..2a68e99359295 100644 --- a/src/coreclr/src/vm/.vscode/c_cpp_properties.json +++ b/src/coreclr/src/vm/.vscode/c_cpp_properties.json @@ -53,7 +53,6 @@ "FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION", "FEATURE_CORECLR", "FEATURE_CORESYSTEM", - "FEATURE_CORRUPTING_EXCEPTIONS", "FEATURE_DATABREAKPOINT", "FEATURE_DEFAULT_INTERFACES", "FEATURE_EVENT_TRACE=1", diff --git a/src/coreclr/src/vm/castcache.cpp b/src/coreclr/src/vm/castcache.cpp index 9fb5f7a61c7e7..829d8b331e012 100644 --- a/src/coreclr/src/vm/castcache.cpp +++ b/src/coreclr/src/vm/castcache.cpp @@ -40,7 +40,7 @@ BASEARRAYREF CastCache::CreateCastCache(DWORD size) EX_CATCH { } - EX_END_CATCH(RethrowCorruptingExceptions) + EX_END_CATCH(RethrowTerminalExceptions) if (!table) { @@ -54,7 +54,7 @@ BASEARRAYREF CastCache::CreateCastCache(DWORD size) EX_CATCH { } - EX_END_CATCH(RethrowCorruptingExceptions) + EX_END_CATCH(RethrowTerminalExceptions) if (!table) { diff --git a/src/coreclr/src/vm/clrex.h b/src/coreclr/src/vm/clrex.h index 16b32574f5a39..3a570a5480f26 100644 --- a/src/coreclr/src/vm/clrex.h +++ b/src/coreclr/src/vm/clrex.h @@ -735,7 +735,7 @@ class EEFileLoadException : public EEException // { // EX_RETHROW() // } -// EX_END_CATCH(RethrowTerminalExceptions or RethrowCorruptingExceptions) +// EX_END_CATCH(RethrowTerminalExceptions) // -------------------------------------------------------------------------------------------------------- // In DAC builds, we don't want to override the normal utilcode exception handling. @@ -746,62 +746,6 @@ class EEFileLoadException : public EEException #define GET_THROWABLE() CLRException::GetThrowableFromException(GET_EXCEPTION()) -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - -// For the VM folder, we redefine SET_CE_RETHROW_FLAG_FOR_EX_CATCH to also check the -// corruption severity when deciding whether to rethrow them or not. -// -// We also check the global override flag incase it has been set to force pre-V4 behaviour. -// -// Doing the checks for "__fCaughtSO" and "__fCaughtNonCxx" will ensure that we check for -// corruption severity only if the last exception was a managed exception that could have been rethrown in the VM. -// When "(__fCaughtSO == FALSE) && (__fCaughtNonCxx == true)" is true, it implies we are dealing with a managed exception -// inside the VM that is represented by the CLRLastThrownObjectException instance (see EX_TRY/EX_CATCH implementation in VM -// folder to see how CLRLastThrownObjectException is used). -// -// This macro also supports the following scenarios: -// -// Scenario 1 -// ---------- -// -// [VM1] -> [VM2] -> -// -// If a managed exception is swallowed by an EX_CATCH in native function VM2, which then returns back -// to native function VM1 that throws, for example, a VM C++ exception, an EX_CATCH(RethrowCorruptingExceptions) -// in VM1 that catches the C++ exception will not rethrow since the last exception was not a managed CSE but -// a C++ exception. -// -// A variation of this is for VM2 to return back in VM1, which calls VM3 that throws a VM C++ exception that -// reaches VM1's EX_CATCH(RethrowCorruptingExceptions). VM1 shouldn't be rethrowing the exception in such a case. -// -// Scenario 2 -// ---------- -// -// [VM1 - RethrowCSE] -> [VM2 - RethrowCSE] -> [VM3 - RethrowCSE] -> -// -// When managed code throws a CSE (e.g. TargetInvocationException flagged as CSE), [VM3] will rethrow it and we will -// enter EX_CATCH in VM2 which is supposed to rethrow it as well. But if the implementation of EX_CATCH in VM2 throws -// another VM C++ exception (e.g. EEFileLoadException) *before* rethrow policy is applied, control will reach EX_CATCH -// in VM1 that *shouldn't* rethrow (even though it has RethrowCSE as the policy) since the last exception was a VM C++ -// exception. -// -// Scenario 3 -// ---------- -// -// This is about VM throwing a managed exception that gets handled either within the VM, with or without CLR's managed code -// exception handler coming into the picture. -// -// This is explained in detail (alongwith relevant changes) in the implementation of RaiseTheException (in excep.cpp). - -#undef SET_CE_RETHROW_FLAG_FOR_EX_CATCH -#define SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr) (((expr) == TRUE) && \ - (g_pConfig->LegacyCorruptedStateExceptionsPolicy() == false) && \ - (CEHelper::IsProcessCorruptedStateException(GetCurrentExceptionCode(), FALSE) || \ - (!__state.DidCatchCxx() && \ - CEHelper::IsLastActiveExceptionCorrupting(TRUE)))) - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - #undef EX_TRY #define EX_TRY \ EX_TRY_CUSTOM(CLRException::HandlerState, (::GetThreadNULLOk()), CLRLastThrownObjectException) @@ -1002,25 +946,6 @@ LONG CLRNoCatchHandler(EXCEPTION_POINTERS* pExceptionInfo, PVOID pv); } \ } \ -// This macro should be used at the entry points (e.g. COM interop boundaries) -// where CE's are not expected to get swallowed. -#define END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS_EX(fCond) \ - } \ - EX_CATCH \ - { \ - *__phr = GET_EXCEPTION()->GetHR(); \ - } \ - EX_END_CATCH(RethrowCorruptingExceptionsEx(fCond)); \ - } \ - } \ - -// This macro should be used at the entry points (e.g. COM interop boundaries) -// where CE's are not expected to get swallowed. -#define END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS \ - END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS_EX(TRUE) - - - //============================================================================== // --------------------------------------------------------------------------- diff --git a/src/coreclr/src/vm/comcallablewrapper.cpp b/src/coreclr/src/vm/comcallablewrapper.cpp index c621eeb74304d..583d52d1cf38d 100644 --- a/src/coreclr/src/vm/comcallablewrapper.cpp +++ b/src/coreclr/src/vm/comcallablewrapper.cpp @@ -3678,8 +3678,7 @@ IDispatch* ComCallWrapper::GetIDispatchIP() CorIfaceAttr ifaceType = hndDefItfClass.GetMethodTable()->GetComInterfaceType(); if (IsDispatchBasedItf(ifaceType)) { - RETURN (IDispatch*)GetComIPFromCCW(this, GUID_NULL, hndDefItfClass.GetMethodTable(), - GetComIPFromCCW::SuppressSecurityCheck); + RETURN (IDispatch*)GetComIPFromCCW(this, GUID_NULL, hndDefItfClass.GetMethodTable()); } else { diff --git a/src/coreclr/src/vm/comcallablewrapper.h b/src/coreclr/src/vm/comcallablewrapper.h index 51b6f88d87b86..9ef02ec63e384 100644 --- a/src/coreclr/src/vm/comcallablewrapper.h +++ b/src/coreclr/src/vm/comcallablewrapper.h @@ -957,8 +957,7 @@ struct GetComIPFromCCW { None = 0, CheckVisibility = 1, - SuppressSecurityCheck = 2, - SuppressCustomizedQueryInterface = 4 + SuppressCustomizedQueryInterface = 2 }; }; diff --git a/src/coreclr/src/vm/comdelegate.cpp b/src/coreclr/src/vm/comdelegate.cpp index 20a724bf0a908..e2b45fb108d1d 100644 --- a/src/coreclr/src/vm/comdelegate.cpp +++ b/src/coreclr/src/vm/comdelegate.cpp @@ -3282,44 +3282,7 @@ static void InvokeUnhandledSwallowing(OBJECTREF *pDelegate, EX_TRY { -#if defined(FEATURE_CORRUPTING_EXCEPTIONS) - BOOL fCanMethodHandleException = g_pConfig->LegacyCorruptedStateExceptionsPolicy(); - if (!fCanMethodHandleException) - { - // CSE policy has not been overridden - proceed with our checks. - // - // Notifications for CSE are only delivered if the delegate target follows CSE rules. - // So, get the corruption severity of the active exception that has gone unhandled. - // - // By Default, assume that the active exception is not corrupting. - CorruptionSeverity severity = NotCorrupting; - Thread *pCurThread = GetThread(); - _ASSERTE(pCurThread != NULL); - ThreadExceptionState *pExState = pCurThread->GetExceptionState(); - if (pExState->IsExceptionInProgress()) - { - // If an exception is active, it implies we have a tracker for it. - // Hence, get the corruption severity from the active exception tracker. - severity = pExState->GetCurrentExceptionTracker()->GetCorruptionSeverity(); - _ASSERTE(severity > NotSet); - } - - // Notifications are delivered based upon corruption severity of the exception - fCanMethodHandleException = ExceptionNotifications::CanDelegateBeInvokedForException(pDelegate, severity); - if (!fCanMethodHandleException) - { - LOG((LF_EH, LL_INFO100, "InvokeUnhandledSwallowing: ADUEN Delegate cannot be invoked for corruption severity %d\n", - severity)); - } - } - - if (fCanMethodHandleException) -#endif // defined(FEATURE_CORRUPTING_EXCEPTIONS) - { - // We've already exercised the prestub on this delegate's COMDelegate::GetMethodDesc, - // as part of wiring up a reliable event sink. Deliver the notification. - ExceptionNotifications::DeliverExceptionNotification(UnhandledExceptionHandler, pDelegate, pDomain, pEventArgs); - } + ExceptionNotifications::DeliverExceptionNotification(UnhandledExceptionHandler, pDelegate, pDomain, pEventArgs); } EX_CATCH { diff --git a/src/coreclr/src/vm/commodule.cpp b/src/coreclr/src/vm/commodule.cpp index 3a54696306675..51160cf2b896c 100644 --- a/src/coreclr/src/vm/commodule.cpp +++ b/src/coreclr/src/vm/commodule.cpp @@ -888,7 +888,7 @@ HINSTANCE QCALLTYPE COMModule::GetHINSTANCE(QCall::ModuleHandle pModule) BEGIN_QCALL; - // This returns the base address - this will work for either HMODULE or HCORMODULES + // This returns the base address // Other modules should have zero base PEFile *pPEFile = pModule->GetFile(); if (!pPEFile->IsDynamic() && !pPEFile->IsResource()) @@ -1093,4 +1093,3 @@ FCIMPL0(void*, COMPunkSafeHandle::nGetDReleaseTarget) } FCIMPLEND - diff --git a/src/coreclr/src/vm/dispatchinfo.cpp b/src/coreclr/src/vm/dispatchinfo.cpp index 8da1151b93c05..dca9108f1d853 100644 --- a/src/coreclr/src/vm/dispatchinfo.cpp +++ b/src/coreclr/src/vm/dispatchinfo.cpp @@ -2193,10 +2193,8 @@ HRESULT DispatchInfo::InvokeMember(SimpleComCallWrapper *pSimpleWrap, DISPID id, EX_CATCH { pThrowable = GET_THROWABLE(); - - // RethrowCorruptingExceptionsEx, in EX_END_CATCH below, will ensure that CEs are rethrown. } - EX_END_CATCH(RethrowCorruptingExceptionsEx(!CEHelper::CanIDispatchTargetHandleException())) + EX_END_CATCH(RethrowTerminalExceptions) catchFrame.Pop(); if (pThrowable != NULL) diff --git a/src/coreclr/src/vm/eeconfig.cpp b/src/coreclr/src/vm/eeconfig.cpp index bf0c602aa19c6..bb4266f86fb7f 100644 --- a/src/coreclr/src/vm/eeconfig.cpp +++ b/src/coreclr/src/vm/eeconfig.cpp @@ -126,11 +126,6 @@ HRESULT EEConfig::Init() fJitMinOpts = false; fPInvokeRestoreEsp = (DWORD)-1; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // By default, there is not pre-V4 CSE policy - fLegacyCorruptedStateExceptionsPolicy = false; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - fNgenBindOptimizeNonGac = false; fStressLog = false; fProbeForStackOverflow = true; diff --git a/src/coreclr/src/vm/eeconfig.h b/src/coreclr/src/vm/eeconfig.h index c6579786aa821..7ed91a49fc9d4 100644 --- a/src/coreclr/src/vm/eeconfig.h +++ b/src/coreclr/src/vm/eeconfig.h @@ -133,11 +133,6 @@ class EEConfig } } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Returns a bool to indicate if the legacy CSE (pre-v4) behaviour is enabled or not - bool LegacyCorruptedStateExceptionsPolicy(void) const {LIMITED_METHOD_CONTRACT; return fLegacyCorruptedStateExceptionsPolicy; } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - bool InteropValidatePinnedObjects() const { LIMITED_METHOD_CONTRACT; return m_fInteropValidatePinnedObjects; } bool InteropLogArguments() const { LIMITED_METHOD_CONTRACT; return m_fInteropLogArguments; } @@ -559,10 +554,6 @@ class EEConfig unsigned fPInvokeRestoreEsp; // -1=Default, 0=Never, Else=Always -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - bool fLegacyCorruptedStateExceptionsPolicy; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - LPUTF8 pszBreakOnClassLoad; // Halt just before loading this class #ifdef TEST_DATA_CONSISTENCY diff --git a/src/coreclr/src/vm/eventtrace.cpp b/src/coreclr/src/vm/eventtrace.cpp index aee5caebdf7f5..d5099e498c2a6 100644 --- a/src/coreclr/src/vm/eventtrace.cpp +++ b/src/coreclr/src/vm/eventtrace.cpp @@ -974,7 +974,7 @@ HRESULT ETW::GCLog::ForceGCForDiagnostics() #ifndef FEATURE_REDHAWK } EX_CATCH { } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); #endif // FEATURE_REDHAWK return hr; @@ -1752,7 +1752,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return -1; @@ -1791,7 +1791,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return -1; } @@ -1811,7 +1811,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return -1; } @@ -1850,7 +1850,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return -1; } @@ -1888,7 +1888,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) // won't have a name in it. pVal->sName.Clear(); } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); // Now that we know the full size of this type's data, see if it fits in our // batch or whether we need to flush @@ -1986,7 +1986,7 @@ void BulkTypeEventLogger::LogTypeAndParameters(ULONGLONG thAsAddr, ETW::TypeSyst { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return; @@ -2551,7 +2551,7 @@ VOID ETW::GCLog::SendFinalizeObjectEvent(MethodTable * pMT, Object * pObj) EX_CATCH { } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); } } @@ -2977,7 +2977,7 @@ BOOL ETW::TypeSystemLog::AddOrReplaceTypeLoggingInfo(ETW::LoggedTypesFromModule { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); return fSucceeded; } @@ -3384,7 +3384,7 @@ ETW::TypeLoggingInfo ETW::TypeSystemLog::LookupOrCreateTypeLoggingInfo(TypeHandl { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) { *pfCreatedNew = FALSE; @@ -3422,7 +3422,7 @@ ETW::TypeLoggingInfo ETW::TypeSystemLog::LookupOrCreateTypeLoggingInfo(TypeHandl { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) { *pfCreatedNew = FALSE; @@ -3518,7 +3518,7 @@ BOOL ETW::TypeSystemLog::AddTypeToGlobalCacheIfNotExists(TypeHandle th, BOOL * p { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) { *pfCreatedNew = FALSE; @@ -3550,7 +3550,7 @@ BOOL ETW::TypeSystemLog::AddTypeToGlobalCacheIfNotExists(TypeHandle th, BOOL * p { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) { *pfCreatedNew = FALSE; @@ -4641,7 +4641,6 @@ VOID ETW::ExceptionLog::ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownExcept pExInfo = pExState->GetCurrentExceptionTracker(); _ASSERTE(pExInfo != NULL); bIsNestedException = (pExInfo->GetPreviousExceptionTracker() != NULL); - bIsCSE = (pExInfo->GetCorruptionSeverity() == ProcessCorrupting); bIsCLSCompliant = IsException((gc.exceptionObj)->GetMethodTable()) && ((gc.exceptionObj)->GetMethodTable() != MscorlibBinder::GetException(kRuntimeWrappedException)); @@ -4656,7 +4655,6 @@ VOID ETW::ExceptionLog::ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownExcept exceptionFlags = ((bHasInnerException ? ETW::ExceptionLog::ExceptionStructs::HasInnerException : 0) | (bIsNestedException ? ETW::ExceptionLog::ExceptionStructs::IsNestedException : 0) | (bIsReThrownException ? ETW::ExceptionLog::ExceptionStructs::IsReThrownException : 0) | - (bIsCSE ? ETW::ExceptionLog::ExceptionStructs::IsCSE : 0) | (bIsCLSCompliant ? ETW::ExceptionLog::ExceptionStructs::IsCLSCompliant : 0)); if (pCf->IsFrameless()) @@ -6279,7 +6277,7 @@ VOID ETW::MethodLog::SendMethodDetailsEvent(MethodDesc *pMethodDesc) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) goto done; diff --git a/src/coreclr/src/vm/excep.cpp b/src/coreclr/src/vm/excep.cpp index 2dd54dbb42ac0..657717d6b3ada 100644 --- a/src/coreclr/src/vm/excep.cpp +++ b/src/coreclr/src/vm/excep.cpp @@ -121,11 +121,7 @@ typedef struct { PEXCEPTION_REGISTRATION_RECORD GetCurrentSEHRecord(); BOOL IsUnmanagedToManagedSEHHandler(EXCEPTION_REGISTRATION_RECORD*); -VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity = NotCorrupting -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); +VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow); //------------------------------------------------------------------------------- // Basically, this asks whether the exception is a managed exception thrown by @@ -2711,85 +2707,6 @@ LONG RaiseExceptionFilter(EXCEPTION_POINTERS* ep, LPVOID pv) return EXCEPTION_CONTINUE_SEARCH; } -//========================================================================== -// Throw an object. -//========================================================================== -VOID DECLSPEC_NORETURN RaiseTheException(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_TRIGGERS; - STATIC_CONTRACT_MODE_COOPERATIVE; - - LOG((LF_EH, LL_INFO100, "RealCOMPlusThrow throwing %s\n", - throwable->GetMethodTable()->GetDebugClassName())); - - if (throwable == NULL) - { - _ASSERTE(!"RealCOMPlusThrow(OBJECTREF) called with NULL argument. Somebody forgot to post an exception!"); - EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE); - } - - _ASSERTE(throwable != CLRException::GetPreallocatedStackOverflowException()); - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (!g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - // This is Scenario 3 described in clrex.h around the definition of SET_CE_RETHROW_FLAG_FOR_EX_CATCH macro. - // - // We are here because the VM is attempting to throw a managed exception. It is posssible this exception - // may not be seen by CLR's exception handler for managed code (e.g. there maybe an EX_CATCH up the stack - // that will swallow or rethrow this exception). In the following scenario: - // - // [VM1 - RethrowCSE] -> [VM2 - RethrowCSE] -> [VM3 - RethrowCSE] -> - // - // When managed code throws a CSE (e.g. TargetInvocationException flagged as CSE), [VM3] will rethrow it and we will - // enter EX_CATCH in VM2 which is supposed to rethrow it as well. Two things can happen: - // - // 1) The implementation of EX_CATCH in VM2 throws a new managed exception *before* rethrow policy is applied and control - // will reach EX_CATCH in VM1, OR - // - // 2) EX_CATCH in VM2 swallows the exception, comes out of the catch block and later throws a new managed exception that - // will be caught by EX_CATCH in VM1. - // - // In either of the cases, rethrow in VM1 should be on the basis of the new managed exception's corruption severity. - // - // To support this scenario, we set corruption severity of the managed exception VM is throwing. If its a rethrow, - // it implies we are rethrowing the last exception that was seen by CLR's managed code exception handler. In such a case, - // we will copy over the corruption severity of that exception. - - // If throwable indicates corrupted state, forcibly set the severity. - if (CEHelper::IsProcessCorruptedStateException(throwable)) - { - severity = ProcessCorrupting; - } - - // No one should have passed us an invalid severity. - _ASSERTE(severity > NotSet); - - if (severity == NotSet) - { - severity = NotCorrupting; - } - - // Update the corruption severity of the exception being thrown by the VM. - GetThread()->GetExceptionState()->SetLastActiveExceptionCorruptionSeverity(severity); - - // Exception's corruption severity should be reused in reraise if this exception leaks out from the VM - // into managed code - CEHelper::MarkLastActiveExceptionCorruptionSeverityForReraiseReuse(); - - LOG((LF_EH, LL_INFO100, "RaiseTheException - Set VM thrown managed exception severity to %d.\n", severity)); - } - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - - RaiseTheExceptionInternalOnly(throwable,rethrow); -} - HRESULT GetHRFromThrowable(OBJECTREF throwable) { STATIC_CONTRACT_THROWS; @@ -2965,11 +2882,8 @@ VOID DECLSPEC_NORETURN RaiseTheExceptionInternalOnly(OBJECTREF throwable, BOOL r // INSTALL_COMPLUS_EXCEPTION_HANDLER has a filter, so must put the call in a separate fcn -static VOID DECLSPEC_NORETURN RealCOMPlusThrowWorker(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS -) { +static VOID DECLSPEC_NORETURN RealCOMPlusThrowWorker(OBJECTREF throwable, BOOL rethrow) +{ STATIC_CONTRACT_THROWS; STATIC_CONTRACT_GC_TRIGGERS; STATIC_CONTRACT_MODE_ANY; @@ -2982,23 +2896,24 @@ static VOID DECLSPEC_NORETURN RealCOMPlusThrowWorker(OBJECTREF throwable, BOOL r // TODO: Do we need to install COMPlusFrameHandler here? INSTALL_COMPLUS_EXCEPTION_HANDLER(); - RaiseTheException(throwable, rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + if (throwable == NULL) + { + _ASSERTE(!"RealCOMPlusThrow(OBJECTREF) called with NULL argument. Somebody forgot to post an exception!"); + EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE); + } + RaiseTheExceptionInternalOnly(throwable, rethrow); UNINSTALL_COMPLUS_EXCEPTION_HANDLER(); } - -VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS -) { +VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow) +{ STATIC_CONTRACT_THROWS; STATIC_CONTRACT_GC_TRIGGERS; STATIC_CONTRACT_MODE_ANY; + + LOG((LF_EH, LL_INFO100, "RealCOMPlusThrow throwing %s\n", + throwable->GetMethodTable()->GetDebugClassName())); + GCPROTECT_BEGIN(throwable); _ASSERTE(IsException(throwable->GetMethodTable())); @@ -3019,20 +2934,12 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow ExceptionPreserveStackTrace(throwable); } - RealCOMPlusThrowWorker(throwable, rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + RealCOMPlusThrowWorker(throwable, rethrow); GCPROTECT_END(); } -VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) +VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable) { CONTRACTL { @@ -3042,11 +2949,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable } CONTRACTL_END; - RealCOMPlusThrow(throwable, FALSE -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + RealCOMPlusThrow(throwable, FALSE); } // this function finds the managed callback to get a resource @@ -3709,14 +3612,6 @@ BOOL IsUncatchable(OBJECTREF *pThrowable) if (OBJECTREFToObject(*pThrowable)->GetMethodTable() == g_pExecutionEngineExceptionClass) return TRUE; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Corrupting exceptions are also uncatchable - if (CEHelper::IsProcessCorruptedStateException(*pThrowable)) - { - return TRUE; - } -#endif //FEATURE_CORRUPTING_EXCEPTIONS } return FALSE; @@ -8552,35 +8447,6 @@ LONG ReflectionInvocationExceptionFilter( } #endif // !TARGET_UNIX - // If the application has opted into triggering a failfast when a CorruptedStateException enters the Reflection system, - // then do the needful. - if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_FailFastOnCorruptedStateException) == 1) - { - // Get the thread and the managed exception object - they must exist at this point - Thread *pCurThread = GetThread(); - _ASSERTE(pCurThread != NULL); - - // Get the thread exception state - ThreadExceptionState * pCurTES = pCurThread->GetExceptionState(); - _ASSERTE(pCurTES != NULL); - - // Get the exception tracker for the current exception -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#elif TARGET_X86 - PTR_ExInfo pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#else // !(HOST_64BIT || TARGET_X86) -#error Unsupported platform -#endif // HOST_64BIT - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (pEHTracker->GetCorruptionSeverity() == ProcessCorrupting) - { - EEPolicy::HandleFatalError(COR_E_FAILFAST, reinterpret_cast(pExceptionInfo->ExceptionRecord->ExceptionAddress), NULL, pExceptionInfo); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - } - return ret; } // LONG ReflectionInvocationExceptionFilter() @@ -11095,781 +10961,43 @@ PTR_ExInfo GetEHTrackerForException(OBJECTREF oThrowable, PTR_ExInfo pStartingEH return fFoundTracker ? pEHTracker : NULL; } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -// ----------------------------------------------------------------------- -// Support for CorruptedState Exceptions -// ----------------------------------------------------------------------- - // Given an exception code, this method returns a BOOL to indicate if the // code belongs to a corrupting exception or not. /* static */ -BOOL CEHelper::IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO /*= TRUE*/) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return FALSE; - } - - // Call into the utilcode helper function to check if this - // is a CE or not. - return (::IsProcessCorruptedStateException(dwExceptionCode, fCheckForSO)); -} - -// This is used in the VM folder version of "SET_CE_RETHROW_FLAG_FOR_EX_CATCH" (in clrex.h) -// to check if the managed exception caught by EX_END_CATCH is CSE or not. -// -// If you are using it from rethrow boundaries (e.g. SET_CE_RETHROW_FLAG_FOR_EX_CATCH -// macro that is used to automatically rethrow corrupting exceptions), then you may -// want to set the "fMarkForReuseIfCorrupting" to TRUE to enable propagation of the -// corruption severity when the reraised exception is seen by managed code again. -/* static */ -BOOL CEHelper::IsLastActiveExceptionCorrupting(BOOL fMarkForReuseIfCorrupting /* = FALSE */) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(GetThread() != NULL); - } - CONTRACTL_END; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return FALSE; - } - - BOOL fIsCorrupting = FALSE; - ThreadExceptionState *pCurTES = GetThread()->GetExceptionState(); - - // Check the corruption severity - CorruptionSeverity severity = pCurTES->GetLastActiveExceptionCorruptionSeverity(); - fIsCorrupting = (severity == ProcessCorrupting); - if (fIsCorrupting && fMarkForReuseIfCorrupting) - { - // Mark the corruption severity for reuse - CEHelper::MarkLastActiveExceptionCorruptionSeverityForReraiseReuse(); - } - - LOG((LF_EH, LL_INFO100, "CEHelper::IsLastActiveExceptionCorrupting - Using corruption severity from TES.\n")); - - return fIsCorrupting; -} - -// Given a MethodDesc, this method will return a BOOL to indicate if -// the containing assembly was built for PreV4 runtime or not. -/* static */ -BOOL CEHelper::IsMethodInPreV4Assembly(PTR_MethodDesc pMethodDesc) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(pMethodDesc != NULL); - } - CONTRACTL_END; - - // By default, assume that the containing assembly was not - // built for PreV4 runtimes. - BOOL fBuiltForPreV4Runtime = FALSE; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - LPCSTR pszVersion = NULL; - - // Retrieve the manifest metadata reference since that contains - // the "built-for" runtime details - IMDInternalImport *pImport = pMethodDesc->GetAssembly()->GetManifestImport(); - if (pImport && SUCCEEDED(pImport->GetVersionString(&pszVersion))) - { - if (pszVersion != NULL) - { - // If version begins with "v1.*" or "v2.*", it was built for preV4 runtime - if ((pszVersion[0] == 'v' || pszVersion[0] == 'V') && - IS_DIGIT(pszVersion[1]) && - (pszVersion[2] == '.') ) - { - // Looks like a version. Is it lesser than v4.0 major version where we start using new behavior? - fBuiltForPreV4Runtime = ((DIGIT_TO_INT(pszVersion[1]) != 0) && - (DIGIT_TO_INT(pszVersion[1]) <= HIGHEST_MAJOR_VERSION_OF_PREV4_RUNTIME)); - } - } - } - - return fBuiltForPreV4Runtime; -} - -// Given a MethodDesc and CorruptionSeverity, this method will return a -// BOOL indicating if the method can handle those kinds of CEs or not. -/* static */ -BOOL CEHelper::CanMethodHandleCE(PTR_MethodDesc pMethodDesc, CorruptionSeverity severity) -{ - BOOL fCanMethodHandleSeverity = FALSE; - -#ifndef DACCESS_COMPILE - CONTRACTL - { - GC_NOTRIGGER; - THROWS; - MODE_ANY; - PRECONDITION(pMethodDesc != NULL); - } - CONTRACTL_END; - - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - // Since the method is Security Critical, now check if it is - // attributed to handle the CE or not. - IMDInternalImport *pImport = pMethodDesc->GetMDImport(); - if (pImport != NULL) - { - mdMethodDef methodDef = pMethodDesc->GetMemberDef(); - switch(severity) - { - case ProcessCorrupting: - fCanMethodHandleSeverity = (S_OK == pImport->GetCustomAttributeByName( - methodDef, - HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE, - NULL, - NULL)); - break; - default: - _ASSERTE(!"Unknown Exception Corruption Severity!"); - break; - } - } -#endif // !DACCESS_COMPILE - - return fCanMethodHandleSeverity; -} - -// Given a MethodDesc, this method will return a BOOL to indicate if the method should be examined for exception -// handlers for the specified exception. -// -// This method accounts for both corrupting and non-corrupting exceptions. -/* static */ -BOOL CEHelper::CanMethodHandleException(CorruptionSeverity severity, PTR_MethodDesc pMethodDesc) -{ - CONTRACTL - { - GC_NOTRIGGER; - THROWS; - MODE_ANY; - PRECONDITION(pMethodDesc != NULL); - } - CONTRACTL_END; - - // By default, assume that the runtime shouldn't look for exception handlers - // in the method pointed by the MethodDesc - BOOL fLookForExceptionHandlersInMethod = FALSE; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - // If we have been asked to use the last active corruption severity (e.g. in cases of Reflection - // or COM interop), then retrieve it. - if (severity == UseLast) - { - LOG((LF_EH, LL_INFO100, "CEHelper::CanMethodHandleException - Using LastActiveExceptionCorruptionSeverity.\n")); - severity = GetThread()->GetExceptionState()->GetLastActiveExceptionCorruptionSeverity(); - } - - LOG((LF_EH, LL_INFO100, "CEHelper::CanMethodHandleException - Processing CorruptionSeverity: %d.\n", severity)); - - if (severity > NotCorrupting) - { - // If the method lies in an assembly built for pre-V4 runtime, allow the runtime - // to look for exception handler for the CE. - BOOL fIsMethodInPreV4Assembly = FALSE; - fIsMethodInPreV4Assembly = CEHelper::IsMethodInPreV4Assembly(pMethodDesc); - - if (!fIsMethodInPreV4Assembly) - { - // Method lies in an assembly built for V4 or later runtime. - LOG((LF_EH, LL_INFO100, "CEHelper::CanMethodHandleException - Method is in an assembly built for V4 or later runtime.\n")); - - // Depending upon the corruption severity of the exception, see if the - // method supports handling that. - LOG((LF_EH, LL_INFO100, "CEHelper::CanMethodHandleException - Exception is corrupting.\n")); - - // Check if the method can handle the severity specified in the exception object. - fLookForExceptionHandlersInMethod = CEHelper::CanMethodHandleCE(pMethodDesc, severity); - } - else - { - // Method is in a Pre-V4 assembly - allow it to be examined for processing the CE - fLookForExceptionHandlersInMethod = TRUE; - } - } - else - { - // Non-corrupting exceptions can continue to be delivered - fLookForExceptionHandlersInMethod = TRUE; - } - - return fLookForExceptionHandlersInMethod; -} - -// Given a managed exception object, this method will return a BOOL -// indicating if it corresponds to a ProcessCorruptedState exception -// or not. -/* static */ -BOOL CEHelper::IsProcessCorruptedStateException(OBJECTREF oThrowable) +BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, OBJECTREF throwable) { CONTRACTL { NOTHROW; GC_NOTRIGGER; MODE_COOPERATIVE; - PRECONDITION(oThrowable != NULL); } CONTRACTL_END; - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) + switch (dwExceptionCode) { + case STATUS_ACCESS_VIOLATION: + if (throwable != NULL && MscorlibBinder::IsException(throwable->GetMethodTable(), kNullReferenceException)) + return FALSE; + break; + case STATUS_STACK_OVERFLOW: + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_IN_PAGE_ERROR: + case EXCEPTION_INVALID_DISPOSITION: + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + case EXCEPTION_PRIV_INSTRUCTION: + case STATUS_UNWIND_CONSOLIDATE: + break; + default: return FALSE; } -#ifndef DACCESS_COMPILE - // If the throwable represents preallocated SO, then indicate it as a CSE - if (CLRException::GetPreallocatedStackOverflowException() == oThrowable) - { - return TRUE; - } -#endif // !DACCESS_COMPILE - - // Check if we have an exception tracker for this exception - // and if so, if it represents corrupting exception or not. - // Get the exception tracker for the current exception -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pEHTracker = GetEHTrackerForException(oThrowable, NULL); -#elif TARGET_X86 - PTR_ExInfo pEHTracker = GetEHTrackerForException(oThrowable, NULL); -#else -#error Unsupported platform -#endif - - if (pEHTracker != NULL) - { - // Found the tracker for exception object - check if its CSE or not. - return (pEHTracker->GetCorruptionSeverity() == ProcessCorrupting); - } - - return FALSE; -} - -#ifdef FEATURE_EH_FUNCLETS -void CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass(Thread *pCurThread, PTR_ExceptionTracker pEHTracker, BOOL fIsFirstPass, - DWORD dwExceptionCode) -{ -#ifndef DACCESS_COMPILE - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(!fIsFirstPass); // This method should only be called during an unwind - PRECONDITION(pCurThread != NULL); - } - CONTRACTL_END; - - // - // - // Typically, exception tracker is created for an exception when the OS is in the first pass. - // However, it may be created during the 2nd pass under specific cases. Managed C++ provides - // such a scenario. In the following, stack grows left to right: - // - // CallDescrWorker -> ILStub1 -> -> UMThunkStub -> IL_Stub2 -> - // - // If a CSE exception goes unhandled from managed main, it will reach the OS. The [CRT in?] OS triggers - // unwind that results in invoking the personality routine of UMThunkStub, called UMThunkStubUnwindFrameChainHandler, - // that releases all exception trackers below it. Thus, the tracker for the CSE, which went unhandled, is also - // released. This detail is 64bit specific and the crux of this issue. - // - // Now, it is expected that by the time we are in the unwind pass, the corruption severity would have already been setup in the - // exception tracker and thread exception state (TES) as part of the first pass, and thus, are identical. - // - // However, for the scenario above, when the unwind continues and reaches ILStub1, its personality routine (which is ProcessCLRException) - // is invoked. It attempts to get the exception tracker corresponding to the exception. Since none exists, it creates a brand new one, - // which has the exception corruption severity as NotSet. - // - // During the stack walk, we know (from TES) that the active exception was a CSE, and thus, ILStub1 cannot handle the exception. Prior - // to bailing out, we assert that our data structures are intact by comparing the exception severity in TES with the one in the current - // exception tracker. Since the tracker was recreated, it had the severity as NotSet and this does not match the severity in TES. - // Thus, the assert fires. [This check is performed in ProcessManagedCallFrame.] - // - // To address such a case, if we have created a new exception tracker in the unwind (2nd) pass, then set its - // exception corruption severity to what the TES holds currently. This will maintain the same semantic as the case - // where new tracker is not created (for e.g. the exception was caught in Managed main). - // - // The exception is the scenario of code that uses longjmp to jump to a different context. Longjmp results in a raise - // of a new exception with the longjmp exception code (0x80000026) but with ExceptionFlags set indicating unwind. When this is - // seen by ProcessCLRException (64bit personality routine), it will create a new tracker in the 2nd pass. - // - // Longjmp outside an exceptional path does not interest us, but the one in the exceptional - // path would only happen when a method attributed to handle CSE invokes it. Thus, if the longjmp happened during the 2nd pass of a CSE, - // we want it to proceed (and thus, jump) as expected and not apply the CSE severity to the tracker - this is equivalent to - // a catch block that handles a CSE and then does a "throw new Exception();". The new exception raised is - // non-CSE in nature as well. - // - // http://www.nynaeve.net/?p=105 has a brief description of how exception-safe setjmp/longjmp works. - // - // - if (pEHTracker->GetCorruptionSeverity() == NotSet) - { - // Get the thread exception state - ThreadExceptionState *pCurTES = pCurThread->GetExceptionState(); - - // Set the tracker to have the same corruption severity as the last active severity unless we are dealing - // with LONGJMP - if (dwExceptionCode == STATUS_LONGJUMP) - { - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotCorrupting); - } - - pEHTracker->SetCorruptionSeverity(pCurTES->GetLastActiveExceptionCorruptionSeverity()); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass - Setup the corruption severity in the second pass.\n")); - } -#endif // !DACCESS_COMPILE -} -#endif // FEATURE_EH_FUNCLETS - -// This method is invoked from the personality routine for managed code and is used to setup the -// corruption severity for the active exception on the thread exception state and the -// exception tracker corresponding to the exception. -/* static */ -void CEHelper::SetupCorruptionSeverityForActiveException(BOOL fIsRethrownException, BOOL fIsNestedException, BOOL fShouldTreatExceptionAsNonCorrupting /* = FALSE */) -{ -#ifndef DACCESS_COMPILE - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - // Get the thread and the managed exception object - they must exist at this point - Thread *pCurThread = GetThread(); - _ASSERTE(pCurThread != NULL); - - OBJECTREF oThrowable = pCurThread->GetThrowable(); - _ASSERTE(oThrowable != NULL); - - // Get the thread exception state - ThreadExceptionState * pCurTES = pCurThread->GetExceptionState(); - _ASSERTE(pCurTES != NULL); - - // Get the exception tracker for the current exception -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#elif TARGET_X86 - PTR_ExInfo pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#else // !(HOST_64BIT || TARGET_X86) -#error Unsupported platform -#endif // HOST_64BIT - - _ASSERTE(pEHTracker != NULL); - - // Get the current exception code from the tracker. - PEXCEPTION_RECORD pEHRecord = pCurTES->GetExceptionRecord(); - _ASSERTE(pEHRecord != NULL); - DWORD dwActiveExceptionCode = pEHRecord->ExceptionCode; - - if (pEHTracker->GetCorruptionSeverity() != NotSet) - { - // Since the exception tracker already has the corruption severity set, - // we dont have much to do. Just confirm that our assumptions are correct. - _ASSERTE(pEHTracker->GetCorruptionSeverity() == pCurTES->GetLastActiveExceptionCorruptionSeverity()); - - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Current tracker already has the corruption severity set.\n")); - return; - } - - // If the exception in question is to be treated as non-corrupting, - // then flag it and exit. - if (fShouldTreatExceptionAsNonCorrupting || g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - pEHTracker->SetCorruptionSeverity(NotCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Exception treated as non-corrupting.\n")); - goto done; - } - - if (!fIsRethrownException && !fIsNestedException) - { - // There should be no previously active exception for this case - _ASSERTE(pEHTracker->GetPreviousExceptionTracker() == NULL); - - CorruptionSeverity severityTES = NotSet; - - if (pCurTES->ShouldLastActiveExceptionCorruptionSeverityBeReused()) - { - // Get the corruption severity from the ThreadExceptionState (TES) for the last active exception - severityTES = pCurTES->GetLastActiveExceptionCorruptionSeverity(); - - // Incase of scenarios like AD transition or Reflection invocation, - // TES would hold corruption severity of the last active exception. To propagate it - // to the current exception, we will apply it to current tracker and only if the applied - // severity is "NotSet", will we proceed to check the current exception for corruption - // severity. - pEHTracker->SetCorruptionSeverity(severityTES); - } - - // Reset TES Corruption Severity - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotSet); - - if (severityTES == NotSet) - { - // Since the last active exception's severity was "NotSet", we will look up the - // exception code and the exception object to see if the exception should be marked - // corrupting. - // - // Since this exception was neither rethrown nor is nested, it implies that we are - // outside an active exception. Thus, even if it contains inner exceptions, we wont have - // corruption severity for them since that information is tracked in EH tracker and - // we wont have an EH tracker for the inner most exception. - - if (CEHelper::IsProcessCorruptedStateException(dwActiveExceptionCode) || - CEHelper::IsProcessCorruptedStateException(oThrowable)) - { - pEHTracker->SetCorruptionSeverity(ProcessCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Marked non-rethrow/non-nested exception as ProcessCorrupting.\n")); - } - else - { - pEHTracker->SetCorruptionSeverity(NotCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Marked non-rethrow/non-nested exception as NotCorrupting.\n")); - } - } - else - { - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Copied the corruption severity to tracker from ThreadExceptionState for non-rethrow/non-nested exception.\n")); - } - } - else - { - // Its either a rethrow or nested exception - -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pOrigEHTracker = NULL; -#elif TARGET_X86 - PTR_ExInfo pOrigEHTracker = NULL; -#else -#error Unsupported platform -#endif - - BOOL fDoWeHaveCorruptionSeverity = FALSE; - - if (fIsRethrownException) - { - // Rethrown exceptions are nested by nature (of our implementation). The - // original EHTracker will exist for the exception - infact, it will be - // the tracker previous to the current one. We will simply copy - // its severity to the current EH tracker representing the rethrow. - pOrigEHTracker = pEHTracker->GetPreviousExceptionTracker(); - _ASSERTE(pOrigEHTracker != NULL); - - // Ideally, we would like have the assert below enabled. But, as may happen under OOM - // stress, this can be false. Here's how it will happen: - // - // An exception is thrown, which is later caught and rethrown in the catch block. Rethrow - // results in calling IL_Rethrow that will call RaiseTheExceptionInternalOnly to actually - // raise the exception. Prior to the raise, we update the last thrown object on the thread - // by calling Thread::SafeSetLastThrownObject which, internally, could have an OOM, resulting - // in "changing" the throwable used to raise the exception to be preallocated OOM object. - // - // When the rethrow happens and CLR's exception handler for managed code sees the exception, - // the exception tracker created for the rethrown exception will contain the reference to - // the last thrown object, which will be the preallocated OOM object. - // - // Thus, though, we came here because of a rethrow, and logically, the throwable should remain - // the same, it neednt be. Simply put, rethrow can result in working with a completely different - // exception object than what was originally thrown. - // - // Hence, the assert cannot be enabled. - // - // Thus, we will use the EH tracker corresponding to the original exception, to get the - // rethrown exception's corruption severity, only when the rethrown throwable is the same - // as the original throwable. Otherwise, we will pretend that we didnt get the original tracker - // and will automatically enter the path below to set the corruption severity based upon the - // rethrown throwable. - - // _ASSERTE(pOrigEHTracker->GetThrowable() == oThrowable); - if (pOrigEHTracker->GetThrowable() != oThrowable) - { - pOrigEHTracker = NULL; - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Rethrown throwable does not match the original throwable. Corruption severity will be set based upon rethrown throwable.\n")); - } - } - else - { - // Get the corruption severity from the ThreadExceptionState (TES) for the last active exception - CorruptionSeverity severityTES = NotSet; - - if (pCurTES->ShouldLastActiveExceptionCorruptionSeverityBeReused()) - { - severityTES = pCurTES->GetLastActiveExceptionCorruptionSeverity(); - - // Incase of scenarios like AD transition or Reflection invocation, - // TES would hold corruption severity of the last active exception. To propagate it - // to the current exception, we will apply it to current tracker and only if the applied - // severity is "NotSet", will we proceed to check the current exception for corruption - // severity. - pEHTracker->SetCorruptionSeverity(severityTES); - } - - // Reset TES Corruption Severity - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotSet); - - // If the last exception didnt have any corruption severity, proceed to look for it. - if (severityTES == NotSet) - { - // This is a nested exception - check if it has an inner exception(s). If it does, - // find the EH tracker corresponding to the innermost exception and we will copy the - // corruption severity from the original tracker to the current one. - OBJECTREF oInnermostThrowable = ((EXCEPTIONREF)oThrowable)->GetBaseException(); - if (oInnermostThrowable != NULL) - { - // Find the tracker corresponding to the inner most exception, starting from - // the tracker previous to the current one. An EH tracker may not be found if - // the code did the following inside a catch clause: - // - // Exception ex = new Exception("inner exception"); - // throw new Exception("message", ex); - // - // Or, an exception like AV happened in the catch clause. - pOrigEHTracker = GetEHTrackerForException(oInnermostThrowable, pEHTracker->GetPreviousExceptionTracker()); - } - } - else - { - // We have the corruption severity from the TES. Set the flag indicating so. - fDoWeHaveCorruptionSeverity = TRUE; - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Copied the corruption severity to tracker from ThreadExceptionState for nested exception.\n")); - } - } - - if (!fDoWeHaveCorruptionSeverity) - { - if (pOrigEHTracker != NULL) - { - // Copy the severity from the original EH tracker to the current one - CorruptionSeverity origCorruptionSeverity = pOrigEHTracker->GetCorruptionSeverity(); - _ASSERTE(origCorruptionSeverity != NotSet); - pEHTracker->SetCorruptionSeverity(origCorruptionSeverity); - - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Copied the corruption severity (%d) from the original EH tracker for rethrown exception.\n", origCorruptionSeverity)); - } - else - { - if (CEHelper::IsProcessCorruptedStateException(dwActiveExceptionCode) || - CEHelper::IsProcessCorruptedStateException(oThrowable)) - { - pEHTracker->SetCorruptionSeverity(ProcessCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Marked nested exception as ProcessCorrupting.\n")); - } - else - { - pEHTracker->SetCorruptionSeverity(NotCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Marked nested exception as NotCorrupting.\n")); - } - } - } - } - -done: - // Save the current exception's corruption severity in the ThreadExceptionState (TES) - // for cases when we catch the managed exception in the runtime using EX_CATCH. - // At such a time, all exception trackers get released (due to unwind triggered - // by EX_END_CATCH) and yet we need the corruption severity information for - // scenarios like AD Transition, Reflection invocation, etc. - CorruptionSeverity currentSeverity = pEHTracker->GetCorruptionSeverity(); - - // We should be having a valid corruption severity at this point - _ASSERTE(currentSeverity != NotSet); - - // Save it in the TES - pCurTES->SetLastActiveExceptionCorruptionSeverity(currentSeverity); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Copied the corruption severity (%d) to ThreadExceptionState.\n", currentSeverity)); - -#endif // !DACCESS_COMPILE -} - -// CE can be caught in the VM and later reraised again. Examples of such scenarios -// include AD transition, COM interop, Reflection invocation, to name a few. -// In such cases, we want to mark the corruption severity for reuse upon reraise, -// implying that when the VM does a reraise of such an exception, we should use -// the original corruption severity for the new raised exception, instead of creating -// a new one for it. -/* static */ -void CEHelper::MarkLastActiveExceptionCorruptionSeverityForReraiseReuse() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(GetThread() != NULL); - } - CONTRACTL_END; - - // If the last active exception's corruption severity is anything but - // "NotSet", mark it for ReraiseReuse - ThreadExceptionState *pCurTES = GetThread()->GetExceptionState(); - _ASSERTE(pCurTES != NULL); - - CorruptionSeverity severityTES = pCurTES->GetLastActiveExceptionCorruptionSeverity(); - if (severityTES != NotSet) - { - pCurTES->SetLastActiveExceptionCorruptionSeverity((CorruptionSeverity)(severityTES | ReuseForReraise)); - } -} - -// This method will return a BOOL to indicate if the current exception is to be treated as -// non-corrupting. Currently, this returns true for NullReferenceException only. -/* static */ -BOOL CEHelper::ShouldTreatActiveExceptionAsNonCorrupting() -{ - BOOL fShouldTreatAsNonCorrupting = FALSE; - -#ifndef DACCESS_COMPILE - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(GetThread() != NULL); - } - CONTRACTL_END; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - DWORD dwActiveExceptionCode = GetThread()->GetExceptionState()->GetExceptionRecord()->ExceptionCode; - if (dwActiveExceptionCode == STATUS_ACCESS_VIOLATION) - { - // NullReference has the same exception code as AV - OBJECTREF oThrowable = NULL; - GCPROTECT_BEGIN(oThrowable); - - // Get the throwable and check if it represents null reference exception - oThrowable = GetThread()->GetThrowable(); - _ASSERTE(oThrowable != NULL); - if (MscorlibBinder::GetException(kNullReferenceException) == oThrowable->GetMethodTable()) - { - fShouldTreatAsNonCorrupting = TRUE; - } - GCPROTECT_END(); - } -#endif // !DACCESS_COMPILE - - return fShouldTreatAsNonCorrupting; -} - -// If we were working in a nested exception scenario, reset the corruption severity to the last -// exception we were processing, based upon its EH tracker. -// -// If none was present, reset it to NotSet. -// -// Note: This method must be called once the exception trackers have been adjusted post catch-block execution. -/* static */ -void CEHelper::ResetLastActiveCorruptionSeverityPostCatchHandler(Thread *pThread) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(pThread != NULL); - } - CONTRACTL_END; - - ThreadExceptionState *pCurTES = pThread->GetExceptionState(); - - // By this time, we would have set the correct exception tracker for the active exception domain, - // if applicable. An example is throwing and catching an exception within a catch block. We will update - // the LastActiveCorruptionSeverity based upon the active exception domain. If we are not in one, we will - // set it to "NotSet". -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#elif TARGET_X86 - PTR_ExInfo pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#else -#error Unsupported platform -#endif - - if (pEHTracker) - { - pCurTES->SetLastActiveExceptionCorruptionSeverity(pEHTracker->GetCorruptionSeverity()); - } - else - { - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotSet); - } - - LOG((LF_EH, LL_INFO100, "CEHelper::ResetLastActiveCorruptionSeverityPostCatchHandler - Reset LastActiveException corruption severity to %d.\n", - pCurTES->GetLastActiveExceptionCorruptionSeverity())); -} - -// This method will return a BOOL indicating if the target of IDispatch can handle the specified exception or not. -/* static */ -BOOL CEHelper::CanIDispatchTargetHandleException() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(GetThread() != NULL); - } - CONTRACTL_END; - - // By default, assume that the target of IDispatch cannot handle the exception. - BOOL fCanMethodHandleException = FALSE; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - // IDispatch implementation in COM interop works by invoking the actual target via reflection. - // Thus, a COM client could use the V4 runtime to invoke a V2 method. In such a case, a CSE - // could come unhandled at the actual target invoked via reflection. - // - // Reflection invocation would have set a flag for us, indicating if the actual target was - // enabled to handle the CE or not. If it is, then we should allow the COM client to get the - // hresult from the call and not let the exception continue up the stack. - ThreadExceptionState *pCurTES = GetThread()->GetExceptionState(); - fCanMethodHandleException = pCurTES->CanReflectionTargetHandleException(); - - // Reset the flag so that subsequent invocations work as expected. - pCurTES->SetCanReflectionTargetHandleException(FALSE); + if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_legacyCorruptedStateExceptionsPolicy)) + return FALSE; - return fCanMethodHandleException; + return TRUE; } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - #ifndef DACCESS_COMPILE // This method will deliver the actual exception notification. Its assumed that the caller has done the necessary checks, including // checking whether the delegate can be invoked for the exception's corruption severity. @@ -11964,7 +11092,7 @@ void ExceptionNotifications::GetEventArgsForNotification(ExceptionNotificationHa *pOutEventArgs = NULL; LOG((LF_EH, LL_INFO100, "ExceptionNotifications::GetEventArgsForNotification: Setting event args to NULL due to an exception.\n")); } - EX_END_CATCH(RethrowCorruptingExceptions); // Dont swallow any CSE that may come in from the .ctor. + EX_END_CATCH(RethrowTerminalExceptions); } // This SEH filter will be invoked when an exception escapes out of the exception notification @@ -11975,89 +11103,6 @@ static LONG ExceptionNotificationFilter(PEXCEPTION_POINTERS pExceptionInfo, LPVO return -1; } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -// This method will return a BOOL indicating if the delegate should be invoked for the exception -// of the specified corruption severity. -BOOL ExceptionNotifications::CanDelegateBeInvokedForException(OBJECTREF *pDelegate, CorruptionSeverity severity) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(pDelegate != NULL && IsProtectedByGCFrame(pDelegate) && (*pDelegate != NULL)); - PRECONDITION(severity > NotSet); - } - CONTRACTL_END; - - // Notifications for CSE are only delivered if the delegate target follows CSE rules. - BOOL fCanMethodHandleException = g_pConfig->LegacyCorruptedStateExceptionsPolicy() ? TRUE:(severity == NotCorrupting); - if (!fCanMethodHandleException) - { - EX_TRY - { - // Get the MethodDesc of the delegate to be invoked - MethodDesc *pMDDelegate = COMDelegate::GetMethodDesc(*pDelegate); - _ASSERTE(pMDDelegate != NULL); - - // Check the callback target and see if it is following CSE rules or not. - fCanMethodHandleException = CEHelper::CanMethodHandleException(severity, pMDDelegate); - } - EX_CATCH - { - // Incase of any exceptions, pretend we cannot handle the exception - fCanMethodHandleException = FALSE; - LOG((LF_EH, LL_INFO100, "ExceptionNotifications::CanDelegateBeInvokedForException: Exception while trying to determine if exception notification can be invoked or not.\n")); - } - EX_END_CATCH(RethrowCorruptingExceptions); // Dont swallow any CSEs. - } - - return fCanMethodHandleException; -} -#endif // FEATURE_CORRUPTING_EXCEPTIONS - -// This method will make the actual delegate invocation for the exception notification to be delivered. If an -// exception escapes out of the notification, our filter in ExceptionNotifications::DeliverNotification will -// address it. -void ExceptionNotifications::InvokeNotificationDelegate(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate, OBJECTREF *pEventArgs, - OBJECTREF *pAppDomain -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(pDelegate != NULL && IsProtectedByGCFrame(pDelegate) && (*pDelegate != NULL)); - PRECONDITION(pEventArgs != NULL && IsProtectedByGCFrame(pEventArgs)); - PRECONDITION(pAppDomain != NULL && IsProtectedByGCFrame(pAppDomain)); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - PRECONDITION(severity > NotSet); -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // Unhandled Exception Notification is delivered via Unhandled Exception Processing - // mechanism. - PRECONDITION(notificationType != UnhandledExceptionHandler); - } - CONTRACTL_END; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Notifications are delivered based upon corruption severity of the exception - if (!ExceptionNotifications::CanDelegateBeInvokedForException(pDelegate, severity)) - { - LOG((LF_EH, LL_INFO100, "ExceptionNotifications::InvokeNotificationDelegate: Delegate cannot be invoked for corruption severity %d\n", - severity)); - return; - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - - // We've already exercised the prestub on this delegate's COMDelegate::GetMethodDesc, - // as part of wiring up a reliable event sink in the BCL. Deliver the notification. - ExceptionNotifications::DeliverExceptionNotification(notificationType, pDelegate, pAppDomain, pEventArgs); -} - // This method returns a BOOL to indicate if the AppDomain is ready to receive exception notifications or not. BOOL ExceptionNotifications::CanDeliverNotificationToCurrentAppDomain(ExceptionNotificationHandlerType notificationType) { @@ -12087,11 +11132,7 @@ BOOL ExceptionNotifications::CanDeliverNotificationToCurrentAppDomain(ExceptionN // so that if an exception escapes out of the notification callback, we will trigger failfast from // our filter. void ExceptionNotifications::DeliverNotification(ExceptionNotificationHandlerType notificationType, - OBJECTREF *pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) + OBJECTREF *pThrowable) { STATIC_CONTRACT_GC_TRIGGERS; STATIC_CONTRACT_NOTHROW; // NOTHROW because incase of an exception, we will FailFast. @@ -12101,26 +11142,16 @@ void ExceptionNotifications::DeliverNotification(ExceptionNotificationHandlerTyp { ExceptionNotificationHandlerType notificationType; OBJECTREF *pThrowable; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - CorruptionSeverity severity; -#endif // FEATURE_CORRUPTING_EXCEPTIONS } args; args.notificationType = notificationType; args.pThrowable = pThrowable; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - args.severity = severity; -#endif // FEATURE_CORRUPTING_EXCEPTIONS PAL_TRY(TryArgs *, pArgs, &args) { // Make the call to the actual method that will invoke the callbacks ExceptionNotifications::DeliverNotificationInternal(pArgs->notificationType, - pArgs->pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , pArgs->severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + pArgs->pThrowable); } PAL_EXCEPT_FILTER(ExceptionNotificationFilter) { @@ -12134,11 +11165,7 @@ void ExceptionNotifications::DeliverNotification(ExceptionNotificationHandlerTyp // This method will deliver the exception notification to the current AppDomain. void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHandlerType notificationType, - OBJECTREF *pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) + OBJECTREF *pThrowable) { CONTRACTL { @@ -12151,9 +11178,6 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa PRECONDITION(notificationType != UnhandledExceptionHandler); PRECONDITION((pThrowable != NULL) && (*pThrowable != NULL)); PRECONDITION(ExceptionNotifications::CanDeliverNotificationToCurrentAppDomain(notificationType)); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - PRECONDITION(severity > NotSet); // Exception corruption severity must be valid at this point. -#endif // FEATURE_CORRUPTING_EXCEPTIONS } CONTRACTL_END; @@ -12220,12 +11244,7 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa gc.arrDelegates = (PTRARRAYREF) ((DELEGATEREF)(gc.oNotificationDelegate))->GetInvocationList(); if (gc.arrDelegates == NULL || !gc.arrDelegates->GetMethodTable()->IsArray()) { - ExceptionNotifications::InvokeNotificationDelegate(notificationType, &gc.oNotificationDelegate, &gc.oEventArgs, - &gc.oCurAppDomain -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + ExceptionNotifications::DeliverExceptionNotification(notificationType, &gc.oNotificationDelegate, &gc.oCurAppDomain, &gc.oEventArgs); } else { @@ -12237,12 +11256,7 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa for (UINT_PTR i=0; im_Array[i]; - ExceptionNotifications::InvokeNotificationDelegate(notificationType, &gc.oInnerDelegate, &gc.oEventArgs, - &gc.oCurAppDomain -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + ExceptionNotifications::DeliverExceptionNotification(notificationType, &gc.oInnerDelegate, &gc.oCurAppDomain, &gc.oEventArgs); } } } @@ -12282,11 +11296,7 @@ void ExceptionNotifications::DeliverFirstChanceNotification() oThrowable = pCurTES->GetThrowable(); _ASSERTE(oThrowable != NULL); - ExceptionNotifications::DeliverNotification(FirstChanceExceptionHandler, &oThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , pCurTES->GetCurrentExceptionTracker()->GetCorruptionSeverity() -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + ExceptionNotifications::DeliverNotification(FirstChanceExceptionHandler, &oThrowable); GCPROTECT_END(); } diff --git a/src/coreclr/src/vm/excep.h b/src/coreclr/src/vm/excep.h index c31ead4d38529..661eefe813bb7 100644 --- a/src/coreclr/src/vm/excep.h +++ b/src/coreclr/src/vm/excep.h @@ -26,6 +26,8 @@ BOOL IsExceptionFromManagedCode(const EXCEPTION_RECORD * pExceptionRecord); BOOL IsIPinVirtualStub(PCODE f_IP); bool IsIPInMarkedJitHelper(UINT_PTR uControlPc); +BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, OBJECTREF throwable); + BOOL AdjustContextForJITHelpers(EXCEPTION_RECORD *pExceptionRecord, CONTEXT *pContext); #if defined(FEATURE_HIJACK) && (!defined(TARGET_X86) || defined(TARGET_UNIX)) @@ -70,8 +72,6 @@ struct ThrowCallbackType void * pPrevExceptionRecord; #endif - // Is the current exception a longjmp? - CORRUPTING_EXCEPTIONS_ONLY(BOOL m_fIsLongJump;) void Init() { LIMITED_METHOD_CONTRACT; @@ -92,8 +92,6 @@ struct ThrowCallbackType pCurrentExceptionRecord = 0; pPrevExceptionRecord = 0; #endif - // By default, the current exception is not a longjmp - CORRUPTING_EXCEPTIONS_ONLY(m_fIsLongJump = FALSE;) } }; @@ -251,11 +249,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowNonLocalized(RuntimeExceptionKind reKind, // Throw an object. //========================================================================== -VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity = NotCorrupting -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); +VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable); //========================================================================== // Throw an undecorated runtime exception. @@ -800,44 +794,6 @@ LONG ReflectionInvocationExceptionFilter( EXCEPTION_POINTERS *pExceptionInfo, // the pExceptionInfo passed to a filter function. PVOID pParam); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -// ----------------------------------------------------------------------- -// Support for Corrupted State Exceptions -// ----------------------------------------------------------------------- -#ifndef HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE -#define HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE "System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute" -#endif // HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE - -#ifndef HIGHEST_MAJOR_VERSION_OF_PREV4_RUNTIME -#define HIGHEST_MAJOR_VERSION_OF_PREV4_RUNTIME 2 -#endif // HIGHEST_MAJOR_VERSION_OF_PREV4_RUNTIME - -// This helper class contains static method to support working with Corrupted State Exceptions, -// including checking if a method can handle it or not, copy state across throwables, etc. -class CEHelper -{ - BOOL static IsMethodInPreV4Assembly(PTR_MethodDesc pMethodDesc); - BOOL static CanMethodHandleCE(PTR_MethodDesc pMethodDesc, CorruptionSeverity severity); - -public: - BOOL static CanMethodHandleException(CorruptionSeverity severity, PTR_MethodDesc pMethodDesc); - BOOL static CanIDispatchTargetHandleException(); - BOOL static IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO = TRUE); - BOOL static IsProcessCorruptedStateException(OBJECTREF oThrowable); - BOOL static IsLastActiveExceptionCorrupting(BOOL fMarkForReuseIfCorrupting = FALSE); - BOOL static ShouldTreatActiveExceptionAsNonCorrupting(); - void static MarkLastActiveExceptionCorruptionSeverityForReraiseReuse(); - void static SetupCorruptionSeverityForActiveException(BOOL fIsRethrownException, BOOL fIsNestedException, BOOL fShouldTreatExceptionAsNonCorrupting = FALSE); -#ifdef FEATURE_EH_FUNCLETS - typedef DPTR(class ExceptionTracker) PTR_ExceptionTracker; - void static SetupCorruptionSeverityForActiveExceptionInUnwindPass(Thread *pCurThread, PTR_ExceptionTracker pEHTracker, BOOL fIsFirstPass, - DWORD dwExceptionCode); -#endif // FEATURE_EH_FUNCLETS - void static ResetLastActiveCorruptionSeverityPostCatchHandler(Thread *pThread); -}; - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - #ifndef DACCESS_COMPILE // exception filter invoked for unhandled exceptions on the entry point thread (thread 0) LONG EntryPointFilter(PEXCEPTION_POINTERS pExceptionInfo, PVOID _pData); @@ -860,36 +816,17 @@ class ExceptionNotifications OBJECTREF *pOutEventArgs, OBJECTREF *pThrowable); void static DeliverNotificationInternal(ExceptionNotificationHandlerType notificationType, - OBJECTREF *pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); - - void static InvokeNotificationDelegate(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate, OBJECTREF *pEventArgs, - OBJECTREF *pAppDomain -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + OBJECTREF *pThrowable); public: - BOOL static CanDeliverNotificationToCurrentAppDomain(ExceptionNotificationHandlerType notificationType); + void static DeliverExceptionNotification(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate, OBJECTREF *pEventArgs, + OBJECTREF *pAppDomain); - void static DeliverNotification(ExceptionNotificationHandlerType notificationType, - OBJECTREF *pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + BOOL static CanDeliverNotificationToCurrentAppDomain(ExceptionNotificationHandlerType notificationType); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - BOOL static CanDelegateBeInvokedForException(OBJECTREF *pDelegate, CorruptionSeverity severity); -#endif // FEATURE_CORRUPTING_EXCEPTIONS + void static DeliverNotification(ExceptionNotificationHandlerType notificationType, OBJECTREF *pThrowable); public: - void static DeliverExceptionNotification(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate, - OBJECTREF *pAppDomain, OBJECTREF *pEventArgs); void static DeliverFirstChanceNotification(); }; diff --git a/src/coreclr/src/vm/exceptionhandling.cpp b/src/coreclr/src/vm/exceptionhandling.cpp index 740678e978e17..c655fe8ded92c 100644 --- a/src/coreclr/src/vm/exceptionhandling.cpp +++ b/src/coreclr/src/vm/exceptionhandling.cpp @@ -1006,23 +1006,13 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord !(dwExceptionFlags & EXCEPTION_UNWINDING), &STState); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Only setup the Corruption Severity in the first pass if (!(dwExceptionFlags & EXCEPTION_UNWINDING)) { // Switch to COOP mode GCX_COOP(); - if (pTracker && pTracker->GetThrowable() != NULL) - { - // Setup the state in current exception tracker indicating the corruption severity - // of the active exception. - CEHelper::SetupCorruptionSeverityForActiveException((STState == ExceptionTracker::STS_FirstRethrowFrame), (pTracker->GetPreviousExceptionTracker() != NULL), - CEHelper::ShouldTreatActiveExceptionAsNonCorrupting()); - } - // Failfast if exception indicates corrupted process state - if (pTracker->GetCorruptionSeverity() == ProcessCorrupting) + if (IsProcessCorruptedStateException(pExceptionRecord->ExceptionCode, pTracker->GetThrowable())) { OBJECTREF oThrowable = NULL; SString message; @@ -1045,7 +1035,6 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(pExceptionRecord->ExceptionCode, (LPCWSTR)message); } } -#endif // FEATURE_CORRUPTING_EXCEPTIONS #ifndef TARGET_UNIX // Watson is on Windows only // Setup bucketing details for nested exceptions (rethrow and non-rethrow) only if we are in the first pass @@ -2446,25 +2435,6 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame( if (fIsILStub && !fIsFunclet) // only make this callback on the main method body of IL stubs pUserMDForILStub = GetUserMethodForILStub(pThread, sf.SP, pMD, &pILStubFrame); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - BOOL fCanMethodHandleException = TRUE; - CorruptionSeverity currentSeverity = NotCorrupting; - { - // Switch to COOP mode since we are going to request throwable - GCX_COOP(); - - // We must defer to the MethodDesc of the user method instead of the IL stub - // itself because the user can specify the policy on a per-method basis and - // that won't be reflected via the IL stub's MethodDesc. - MethodDesc * pMDWithCEAttribute = (pUserMDForILStub != NULL) ? pUserMDForILStub : pMD; - - // Check if the exception can be delivered to the method? It will check if the exception - // is a CE or not. If it is, it will check if the method can process it or not. - currentSeverity = pThread->GetExceptionState()->GetCurrentExceptionTracker()->GetCorruptionSeverity(); - fCanMethodHandleException = CEHelper::CanMethodHandleException(currentSeverity, pMDWithCEAttribute); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // Doing rude abort. Skip all non-constrained execution region code. // When rude abort is initiated, we cannot intercept any exceptions. if (pThread->IsRudeAbortInitiated()) @@ -2673,27 +2643,7 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame( const METHODTOKEN& MethToken = pcfThisFrame->GetMethodToken(); EH_CLAUSE_ENUMERATOR EnumState; - unsigned EHCount; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // The method cannot handle the exception (e.g. cannot handle the CE), then simply bail out - // without examining the EH clauses in it. - if (!fCanMethodHandleException) - { - LOG((LF_EH, LL_INFO100, "ProcessManagedCallFrame - CEHelper decided not to look for exception handlers in the method(MD:%p).\n", pMD)); - - // Set the flag to skip this frame since the CE cannot be delivered - _ASSERTE(currentSeverity == ProcessCorrupting); - - // Force EHClause count to be zero - EHCount = 0; - } - else -#endif // FEATURE_CORRUPTING_EXCEPTIONS - { - EHCount = pJitMan->InitializeEHEnumeration(MethToken, &EnumState); - } - + unsigned EHCount = pJitMan->InitializeEHEnumeration(MethToken, &EnumState); if (!fIsFirstPass) { @@ -3961,20 +3911,6 @@ ExceptionTracker* ExceptionTracker::GetOrCreateTracker( } } } - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (fCreateNewTracker) - { - // Exception tracker should be in the 2nd pass right now - _ASSERTE(!pTracker->IsInFirstPass()); - - // The corruption severity of a newly created tracker is NotSet - _ASSERTE(pTracker->GetCorruptionSeverity() == NotSet); - - // See comment in CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass for details - CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass(pThread, pTracker, FALSE, pExceptionRecord->ExceptionCode); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS } _ASSERTE(pTracker->m_pLimitFrame >= pThread->GetFrame()); @@ -4776,20 +4712,6 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar ThreadExceptionState * pCurTES = pCurThread->GetExceptionState(); _ASSERTE(pCurTES != NULL); - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - ExceptionTracker* pEHTracker = pCurTES->GetCurrentExceptionTracker(); - if (pEHTracker == NULL) - { - CorruptionSeverity severity = NotCorrupting; - if (CEHelper::IsProcessCorruptedStateException(ex.GetExceptionRecord()->ExceptionCode)) - { - severity = ProcessCorrupting; - } - - pCurTES->SetLastActiveExceptionCorruptionSeverity(severity); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS } throw std::move(ex); diff --git a/src/coreclr/src/vm/exceptionhandling.h b/src/coreclr/src/vm/exceptionhandling.h index 2f56f20340e77..dfdaf49726edc 100644 --- a/src/coreclr/src/vm/exceptionhandling.h +++ b/src/coreclr/src/vm/exceptionhandling.h @@ -70,11 +70,6 @@ class ExceptionTracker m_WatsonBucketTracker.Init(); #endif // !TARGET_UNIX -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Initialize the default exception severity to NotCorrupting - m_CorruptionSeverity = NotSet; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // By default, mark the tracker as not having delivered the first // chance exception notification m_fDeliveredFirstChanceNotification = FALSE; @@ -130,11 +125,6 @@ class ExceptionTracker m_WatsonBucketTracker.Init(); #endif // !TARGET_UNIX -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Initialize the default exception severity to NotCorrupting - m_CorruptionSeverity = NotSet; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // By default, mark the tracker as not having delivered the first // chance exception notification m_fDeliveredFirstChanceNotification = FALSE; @@ -586,25 +576,6 @@ class ExceptionTracker } #endif // !TARGET_UNIX -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -private: - CorruptionSeverity m_CorruptionSeverity; -public: - inline CorruptionSeverity GetCorruptionSeverity() - { - LIMITED_METHOD_CONTRACT; - - return (CorruptionSeverity)GET_CORRUPTION_SEVERITY(m_CorruptionSeverity); - } - - inline void SetCorruptionSeverity(CorruptionSeverity severityToSet) - { - LIMITED_METHOD_CONTRACT; - - m_CorruptionSeverity = severityToSet; - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - private: BOOL m_fDeliveredFirstChanceNotification; diff --git a/src/coreclr/src/vm/exceptmacros.h b/src/coreclr/src/vm/exceptmacros.h index 55bfec8f28ca3..31fb8c73cdf71 100644 --- a/src/coreclr/src/vm/exceptmacros.h +++ b/src/coreclr/src/vm/exceptmacros.h @@ -246,38 +246,6 @@ LONG WINAPI CLRVectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo); // Actual UEF worker prototype for use by GCUnhandledExceptionFilter. extern LONG InternalUnhandledExceptionFilter_Worker(PEXCEPTION_POINTERS pExceptionInfo); -//========================================================================== -// Installs a handler to unwind exception frames, but not catch the exception -//========================================================================== - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -// ----------------------------------------------------------------------- -// Support for Corrupted State Exceptions -// ----------------------------------------------------------------------- -// This enumeration defines the corruption severity of an exception and -// whether it should be reused for the next exception thrown or not. -enum CorruptionSeverity -{ - UseLast = 0x0, // When specified, the last active corruption severity from TES should be used - NotSet = 0x1, // Corruption Severity has not been set - this is the default/reset value - NotCorrupting = 0x2, // Indicates exception is not corrupting - ProcessCorrupting = 0x4, // Indicates exception represents process corrupted state - ReuseForReraise = 0x2000 // Indicates that the corruption severity should be reused for the next exception thrown, - // provided its not nested and isnt a rethrow. This flag is used typically for propagation of - // severity across boundaries like Reflection invocation, AD transition etc. -}; - -#define GET_CORRUPTION_SEVERITY(severity) (((severity) & (~ReuseForReraise))) -#define CAN_REUSE_CORRUPTION_SEVERITY(severity) (((severity) & ReuseForReraise) == ReuseForReraise) - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - -VOID DECLSPEC_NORETURN RaiseTheException(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS -); - VOID DECLSPEC_NORETURN RaiseTheExceptionInternalOnly(OBJECTREF throwable, BOOL rethrow, BOOL fForStackOverflow = FALSE); #if defined(DACCESS_COMPILE) || defined(CROSSGEN_COMPILE) diff --git a/src/coreclr/src/vm/exinfo.cpp b/src/coreclr/src/vm/exinfo.cpp index 8a9ed80d257f5..58e353a016016 100644 --- a/src/coreclr/src/vm/exinfo.cpp +++ b/src/coreclr/src/vm/exinfo.cpp @@ -110,11 +110,6 @@ void ExInfo::Init() DestroyExceptionHandle(); m_hThrowable = NULL; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Initialize the default exception severity to NotCorrupting - m_CorruptionSeverity = NotSet; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // By default, mark the tracker as not having delivered the first // chance exception notification m_fDeliveredFirstChanceNotification = FALSE; diff --git a/src/coreclr/src/vm/exinfo.h b/src/coreclr/src/vm/exinfo.h index 5e57e0ce77ae8..332d2248342ab 100644 --- a/src/coreclr/src/vm/exinfo.h +++ b/src/coreclr/src/vm/exinfo.h @@ -90,25 +90,6 @@ class ExInfo } #endif -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -private: - CorruptionSeverity m_CorruptionSeverity; -public: - inline CorruptionSeverity GetCorruptionSeverity() - { - LIMITED_METHOD_CONTRACT; - - return (CorruptionSeverity)GET_CORRUPTION_SEVERITY(m_CorruptionSeverity); - } - - inline void SetCorruptionSeverity(CorruptionSeverity severityToSet) - { - LIMITED_METHOD_CONTRACT; - - m_CorruptionSeverity = severityToSet; - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - private: BOOL m_fDeliveredFirstChanceNotification; public: diff --git a/src/coreclr/src/vm/exstate.cpp b/src/coreclr/src/vm/exstate.cpp index c2c2c0adb63f4..db238df8bafe1 100644 --- a/src/coreclr/src/vm/exstate.cpp +++ b/src/coreclr/src/vm/exstate.cpp @@ -43,13 +43,6 @@ ThreadExceptionState::ThreadExceptionState() // Init the UE Watson BucketTracker m_UEWatsonBucketTracker.Init(); #endif // !TARGET_UNIX - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Initialize the default exception severity to NotCorrupting - m_LastActiveExceptionCorruptionSeverity = NotSet; - m_fCanReflectionTargetHandleException = FALSE; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - } ThreadExceptionState::~ThreadExceptionState() diff --git a/src/coreclr/src/vm/exstate.h b/src/coreclr/src/vm/exstate.h index 1ea8790a11dc1..e3971d356b5a7 100644 --- a/src/coreclr/src/vm/exstate.h +++ b/src/coreclr/src/vm/exstate.h @@ -162,56 +162,6 @@ class ThreadExceptionState } #endif -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -private: - CorruptionSeverity m_LastActiveExceptionCorruptionSeverity; - BOOL m_fCanReflectionTargetHandleException; - -public: - // Returns the corruption severity of the last active exception - inline CorruptionSeverity GetLastActiveExceptionCorruptionSeverity() - { - LIMITED_METHOD_CONTRACT; - - return (CorruptionSeverity)GET_CORRUPTION_SEVERITY(m_LastActiveExceptionCorruptionSeverity); - } - - // Set the corruption severity of the last active exception - inline void SetLastActiveExceptionCorruptionSeverity(CorruptionSeverity severityToSet) - { - LIMITED_METHOD_CONTRACT; - - m_LastActiveExceptionCorruptionSeverity = severityToSet; - } - - // Returns a bool indicating if the last active exception's corruption severity should - // be used when exception is reraised (e.g. Reflection Invocation, AD transition, etc) - inline BOOL ShouldLastActiveExceptionCorruptionSeverityBeReused() - { - LIMITED_METHOD_CONTRACT; - - return CAN_REUSE_CORRUPTION_SEVERITY(m_LastActiveExceptionCorruptionSeverity); - } - - // Returns a BOOL to indicate if reflection target can handle CSE or not. - // This is used in DispatchInfo::CanIDispatchTargetHandleException. - inline BOOL CanReflectionTargetHandleException() - { - LIMITED_METHOD_CONTRACT; - - return m_fCanReflectionTargetHandleException; - } - - // Sets a BOOL indicate if the Reflection invocation target can handle exception or not. - // Used in ReflectionInvocation.cpp. - inline void SetCanReflectionTargetHandleException(BOOL fCanReflectionTargetHandleException) - { - LIMITED_METHOD_CONTRACT; - - m_fCanReflectionTargetHandleException = fCanReflectionTargetHandleException; - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - private: ThreadExceptionFlag m_flag; diff --git a/src/coreclr/src/vm/frames.h b/src/coreclr/src/vm/frames.h index 5c8a1ca869d74..3437030705f18 100644 --- a/src/coreclr/src/vm/frames.h +++ b/src/coreclr/src/vm/frames.h @@ -742,11 +742,7 @@ class Frame : public FrameBase friend class StackFrameIterator; friend class TailCallFrame; friend class AppDomain; - friend VOID RealCOMPlusThrow(OBJECTREF -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + friend VOID RealCOMPlusThrow(OBJECTREF); friend FCDECL0(VOID, JIT_StressGC); #ifdef _DEBUG friend LONG WINAPI CLRVectoredExceptionHandlerShim(PEXCEPTION_POINTERS pExceptionInfo); diff --git a/src/coreclr/src/vm/i386/excepx86.cpp b/src/coreclr/src/vm/i386/excepx86.cpp index 5b333e9f9857e..a89e715956692 100644 --- a/src/coreclr/src/vm/i386/excepx86.cpp +++ b/src/coreclr/src/vm/i386/excepx86.cpp @@ -1065,18 +1065,11 @@ CPFH_RealFirstPassHandler( // ExceptionContinueSearch, etc. GCPROTECT_BEGIN(throwable); throwable = pThread->GetThrowable(); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS + if (IsProcessCorruptedStateException(exceptionCode, throwable)) { - // Setup the state in current exception tracker indicating the corruption severity - // of the active exception. - CEHelper::SetupCorruptionSeverityForActiveException(bRethrownException, bNestedException, - CEHelper::ShouldTreatActiveExceptionAsNonCorrupting()); - // Failfast if exception indicates corrupted process state - if (pExInfo->GetCorruptionSeverity() == ProcessCorrupting) - EEPOLICY_HANDLE_FATAL_ERROR(exceptionCode); + EEPOLICY_HANDLE_FATAL_ERROR(exceptionCode); } -#endif // FEATURE_CORRUPTING_EXCEPTIONS // If we're out of memory, then we figure there's probably not memory to maintain a stack trace, so we skip it. // If we've got a stack overflow, then we figure the stack will be so huge as to make tracking the stack trace @@ -1392,10 +1385,6 @@ CPFH_UnwindFrames1(Thread* pThread, EXCEPTION_REGISTRATION_RECORD* pEstablisherF tct.pTopFrame = GetCurrFrame(pEstablisherFrame); // highest frame to search to tct.pBottomFrame = NULL; - // Set the flag indicating if the current exception represents a longjmp. - // See comment in COMPlusUnwindCallback for details. - CORRUPTING_EXCEPTIONS_ONLY(tct.m_fIsLongJump = (exceptionCode == STATUS_LONGJUMP);) - #ifdef _DEBUG tct.pCurrentExceptionRecord = pEstablisherFrame; tct.pPrevExceptionRecord = GetPrevSEHRecord(pEstablisherFrame); @@ -2366,20 +2355,6 @@ StackWalkAction COMPlusThrowCallback( // SWA value if (fIsILStub) pUserMDForILStub = GetUserMethodForILStub(pThread, currentSP, pFunc, &pILStubFrame); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - CorruptionSeverity currentSeverity = pThread->GetExceptionState()->GetCurrentExceptionTracker()->GetCorruptionSeverity(); - { - // We must defer to the MethodDesc of the user method instead of the IL stub - // itself because the user can specify the policy on a per-method basis and - // that won't be reflected via the IL stub's MethodDesc. - MethodDesc * pMDWithCEAttribute = fIsILStub ? pUserMDForILStub : pFunc; - - // Check if the exception can be delivered to the method? It will check if the exception - // is a CE or not. If it is, it will check if the method can process it or not. - fMethodCanHandleException = CEHelper::CanMethodHandleException(currentSeverity, pMDWithCEAttribute); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // Let the profiler know that we are searching for a handler within this function instance if (fGiveDebuggerAndProfilerNotification) EEToProfilerExceptionInterfaceWrapper::ExceptionSearchFunctionEnter(pFunc); @@ -2406,29 +2381,12 @@ StackWalkAction COMPlusThrowCallback( // SWA value ExceptionNotifications::DeliverFirstChanceNotification(); } } + IJitManager* pJitManager = pCf->GetJitManager(); _ASSERTE(pJitManager); - EH_CLAUSE_ENUMERATOR pEnumState; - unsigned EHCount = 0; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // If exception cannot be handled, then just bail out. We shouldnt examine the EH clauses - // in such a method. - if (!fMethodCanHandleException) - { - LOG((LF_EH, LL_INFO100, "COMPlusThrowCallback - CEHelper decided not to look for exception handlers in the method(MD:%p).\n", pFunc)); - // Set the flag to skip this frame since the CE cannot be delivered - _ASSERTE(currentSeverity == ProcessCorrupting); - - // Ensure EHClause count is zero - EHCount = 0; - } - else -#endif // FEATURE_CORRUPTING_EXCEPTIONS - { - EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); - } + EH_CLAUSE_ENUMERATOR pEnumState; + unsigned EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); if (EHCount == 0) { @@ -2708,59 +2666,6 @@ StackWalkAction COMPlusUnwindCallback (CrawlFrame *pCf, ThrowCallbackType *pData TypeHandle thrownType = TypeHandle(); - BOOL fCanMethodHandleException = TRUE; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // MethodDesc's security information (i.e. whether it is critical or transparent) is calculated lazily. - // If this method's security information was not precalculated, then it would have been in the first pass - // already using Security::IsMethodCritical which could take have taken us down a path which is GC_TRIGGERS. - // - // - // However, this unwind callback (for X86) is GC_NOTRIGGER and at this point the security information would have been - // calculated already. Hence, we wouldnt endup in the GC_TRIGGERS path. Thus, to keep SCAN.EXE (static contract analyzer) happy, - // we will pass a FALSE to the CanMethodHandleException call, indicating we dont need to calculate security information (and thus, - // not go down the GC_TRIGGERS path. - // - // Check if the exception can be delivered to the method? It will check if the exception - // is a CE or not. If it is, it will check if the method can process it or not. - CorruptionSeverity currentSeverity = pThread->GetExceptionState()->GetCurrentExceptionTracker()->GetCorruptionSeverity(); - - // We have to do this check for x86 since, unlike 64bit which will setup a new exception tracker for longjmp, - // x86 only sets up new trackers in the first pass (and longjmp is 2nd pass only exception). Hence, we pass - // this information in the callback structure without affecting any existing exception tracker (incase longjmp was - // a nested exception). - if (pData->m_fIsLongJump) - { - // Longjump is not a CSE. With a CSE in progress, this can be invoked by either: - // - // 1) Managed code (e.g. finally/fault/catch), OR - // 2) By native code - // - // In scenario (1), managed code can invoke it only if it was attributed with HPCSE attribute. Thus, - // longjmp is no different than managed code doing a "throw new Exception();". - // - // In scenario (2), longjmp is no different than any other non-CSE native exception raised. - // - // In both these case, longjmp should be treated as non-CSE. Since x86 does not setup a tracker for - // it (see comment above), we pass this information (of whether the current exception is a longjmp or not) - // to this callback (from UnwindFrames) to setup the correct corruption severity. - // - // http://www.nynaeve.net/?p=105 has a brief description of how exception-safe setjmp/longjmp works. - currentSeverity = NotCorrupting; - } - { - MethodDesc * pFuncWithCEAttribute = pFunc; - Frame * pILStubFrame = NULL; - if (pFunc->IsILStub()) - { - // We must defer to the MethodDesc of the user method instead of the IL stub - // itself because the user can specify the policy on a per-method basis and - // that won't be reflected via the IL stub's MethodDesc. - pFuncWithCEAttribute = GetUserMethodForILStub(pThread, (UINT_PTR)pStack, pFunc, &pILStubFrame); - } - fCanMethodHandleException = CEHelper::CanMethodHandleException(currentSeverity, pFuncWithCEAttribute); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - #ifdef DEBUGGING_SUPPORTED LOG((LF_EH, LL_INFO1000, "COMPlusUnwindCallback: Intercept %d, pData->pFunc 0x%X, pFunc 0x%X, pData->pStack 0x%X, pStack 0x%X\n", pExInfo->m_ExceptionFlags.DebuggerInterceptInfo(), @@ -2786,24 +2691,7 @@ StackWalkAction COMPlusUnwindCallback (CrawlFrame *pCf, ThrowCallbackType *pData EEToProfilerExceptionInterfaceWrapper::ExceptionUnwindFunctionEnter(pFunc); EH_CLAUSE_ENUMERATOR pEnumState; - unsigned EHCount; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (!fCanMethodHandleException) - { - LOG((LF_EH, LL_INFO100, "COMPlusUnwindCallback - CEHelper decided not to look for exception handlers in the method(MD:%p).\n", pFunc)); - - // Set the flag to skip this frame since the CE cannot be delivered - _ASSERTE(currentSeverity == ProcessCorrupting); - - // Force EHClause count to be zero - EHCount = 0; - } - else -#endif // FEATURE_CORRUPTING_EXCEPTIONS - { - EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); - } + unsigned EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); if (EHCount == 0) { diff --git a/src/coreclr/src/vm/interopconverter.cpp b/src/coreclr/src/vm/interopconverter.cpp index 64312e1438214..2c67182df9bd3 100644 --- a/src/coreclr/src/vm/interopconverter.cpp +++ b/src/coreclr/src/vm/interopconverter.cpp @@ -80,7 +80,7 @@ namespace //-------------------------------------------------------------------------------- // IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, ...) // Convert ObjectRef to a COM IP, based on MethodTable* pMT. -IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bSecurityCheck, BOOL bEnableCustomizedQueryInterface) +IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bEnableCustomizedQueryInterface) { CONTRACT (IUnknown*) { @@ -119,7 +119,6 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bSecuri CCWHolder pCCWHold = ComCallWrapper::InlineGetWrapper(poref); GetComIPFromCCW::flags flags = GetComIPFromCCW::None; - if (!bSecurityCheck) { flags |= GetComIPFromCCW::SuppressSecurityCheck; } if (!bEnableCustomizedQueryInterface) { flags |= GetComIPFromCCW::SuppressCustomizedQueryInterface; } pUnk = ComCallWrapper::GetComIPFromCCW(pCCWHold, GUID_NULL, pMT, flags); diff --git a/src/coreclr/src/vm/interopconverter.h b/src/coreclr/src/vm/interopconverter.h index ad6b9a0004d13..a41c169b716b5 100644 --- a/src/coreclr/src/vm/interopconverter.h +++ b/src/coreclr/src/vm/interopconverter.h @@ -113,7 +113,7 @@ enum ComIpType //-------------------------------------------------------------------------------- // IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, ...); // Convert ObjectRef to a COM IP, based on MethodTable* pMT. -IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bSecurityCheck = TRUE, BOOL bEnableCustomizedQueryInterface = TRUE); +IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bEnableCustomizedQueryInterface = TRUE); //-------------------------------------------------------------------------------- diff --git a/src/coreclr/src/vm/jithelpers.cpp b/src/coreclr/src/vm/jithelpers.cpp index 8e5d20d993ff6..38a6af10e6dfa 100644 --- a/src/coreclr/src/vm/jithelpers.cpp +++ b/src/coreclr/src/vm/jithelpers.cpp @@ -4185,23 +4185,6 @@ HCIMPL1(void, IL_Throw, Object* obj) } } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (!g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - // Within the VM, we could have thrown and caught a managed exception. This is done by - // RaiseTheException that will flag that exception's corruption severity to be used - // incase it leaks out to managed code. - // - // If it does not leak out, but ends up calling into managed code that throws, - // we will come here. In such a case, simply reset the corruption-severity - // since we want the exception being thrown to have its correct severity set - // when CLR's managed code exception handler sets it. - - ThreadExceptionState *pExState = GetThread()->GetExceptionState(); - pExState->SetLastActiveExceptionCorruptionSeverity(NotSet); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - RaiseTheExceptionInternalOnly(oref, FALSE); HELPER_METHOD_FRAME_END(); diff --git a/src/coreclr/src/vm/listlock.h b/src/coreclr/src/vm/listlock.h index 0fdaf6e68c91c..2b135b19d784b 100644 --- a/src/coreclr/src/vm/listlock.h +++ b/src/coreclr/src/vm/listlock.h @@ -55,10 +55,6 @@ class ListLockEntryBase HRESULT m_hrResultCode; LOADERHANDLE m_hInitException; PTR_LoaderAllocator m_pLoaderAllocator; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Field to maintain the corruption severity of the exception - CorruptionSeverity m_CorruptionSeverity; -#endif // FEATURE_CORRUPTING_EXCEPTIONS ListLockEntryBase(List_t *pList, ELEMENT data, const char *description = NULL) : m_deadlock(description), @@ -72,10 +68,6 @@ class ListLockEntryBase m_hrResultCode(S_FALSE), m_hInitException(NULL), m_pLoaderAllocator(dac_cast(nullptr)) -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , - m_CorruptionSeverity(NotCorrupting) -#endif // FEATURE_CORRUPTING_EXCEPTIONS { WRAPPER_NO_CONTRACT; } diff --git a/src/coreclr/src/vm/marshalnative.cpp b/src/coreclr/src/vm/marshalnative.cpp index 56657944eb8a5..2e068019c2ab2 100644 --- a/src/coreclr/src/vm/marshalnative.cpp +++ b/src/coreclr/src/vm/marshalnative.cpp @@ -923,7 +923,7 @@ FCIMPL4(IUnknown*, MarshalNative::GetComInterfaceForObjectNative, Object* orefUN if (fOnlyInContext && !IsObjectInContext(&oref)) retVal = NULL; else - retVal = GetComIPFromObjectRef(&oref, th.GetMethodTable(), TRUE, bEnableCustomizedQueryInterface); + retVal = GetComIPFromObjectRef(&oref, th.GetMethodTable(), bEnableCustomizedQueryInterface); HELPER_METHOD_FRAME_END(); return retVal; diff --git a/src/coreclr/src/vm/methodtable.cpp b/src/coreclr/src/vm/methodtable.cpp index 1706f0c327c4e..60925514bb715 100644 --- a/src/coreclr/src/vm/methodtable.cpp +++ b/src/coreclr/src/vm/methodtable.cpp @@ -3123,39 +3123,6 @@ BOOL MethodTable::RunClassInitEx(OBJECTREF *pThrowable) // a subclass of Error *pThrowable = GET_THROWABLE(); _ASSERTE(fRet == FALSE); - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // If active thread state does not have a CorruptionSeverity set for the exception, - // then set one up based upon the current exception code and/or the throwable. - // - // When can we be here and current exception tracker may not have corruption severity set? - // Incase of SO in managed code, SO is never seen by CLR's exception handler for managed code - // and if this happens in cctor, we can end up here without the corruption severity set. - Thread *pThread = GetThread(); - _ASSERTE(pThread != NULL); - ThreadExceptionState *pCurTES = pThread->GetExceptionState(); - _ASSERTE(pCurTES != NULL); - if (pCurTES->GetLastActiveExceptionCorruptionSeverity() == NotSet) - { - if (CEHelper::IsProcessCorruptedStateException(GetCurrentExceptionCode()) || - CEHelper::IsProcessCorruptedStateException(*pThrowable)) - { - // Process Corrupting - pCurTES->SetLastActiveExceptionCorruptionSeverity(ProcessCorrupting); - LOG((LF_EH, LL_INFO100, "MethodTable::RunClassInitEx - Exception treated as ProcessCorrupting.\n")); - } - else - { - // Not Corrupting - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotCorrupting); - LOG((LF_EH, LL_INFO100, "MethodTable::RunClassInitEx - Exception treated as non-corrupting.\n")); - } - } - else - { - LOG((LF_EH, LL_INFO100, "MethodTable::RunClassInitEx - Exception already has corruption severity set.\n")); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS } EX_END_CATCH(SwallowAllExceptions) @@ -3289,17 +3256,7 @@ void MethodTable::DoRunClassInitThrowing() ((EXCEPTIONREF)(gc.pThrowable))->ClearStackTraceForThrow(); } - // - // Specify the corruption severity to be used to raise this exception in COMPlusThrow below. - // This will ensure that when the exception is seen by the managed code personality routine, - // it will setup the correct corruption severity in the exception tracker. - // - - COMPlusThrow(gc.pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , pEntry->m_CorruptionSeverity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + COMPlusThrow(gc.pThrowable); } description = ".cctor lock"; @@ -3389,21 +3346,7 @@ void MethodTable::DoRunClassInitThrowing() pEntry->m_hrResultCode = E_FAIL; SetClassInitError(); - #ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Save the corruption severity of the exception so that if the type system - // attempts to pick it up from its cache list and throw again, it should - // treat the exception as corrupting, if applicable. - pEntry->m_CorruptionSeverity = pThread->GetExceptionState()->GetLastActiveExceptionCorruptionSeverity(); - - // We should be having a valid corruption severity at this point - _ASSERTE(pEntry->m_CorruptionSeverity != NotSet); - #endif // FEATURE_CORRUPTING_EXCEPTIONS - - COMPlusThrow(gc.pThrowable - #ifdef FEATURE_CORRUPTING_EXCEPTIONS - , pEntry->m_CorruptionSeverity - #endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + COMPlusThrow(gc.pThrowable); } GCPROTECT_END(); diff --git a/src/coreclr/src/vm/rcwwalker.cpp b/src/coreclr/src/vm/rcwwalker.cpp index 5c94a3ea53690..e10da3f46a133 100644 --- a/src/coreclr/src/vm/rcwwalker.cpp +++ b/src/coreclr/src/vm/rcwwalker.cpp @@ -570,7 +570,7 @@ void RCWWalker::WalkRCWs() { hr = GET_EXCEPTION()->GetHR(); } - EX_END_CATCH(RethrowCorruptingExceptions) // Make sure we crash on AV (instead of swallowing everything) + EX_END_CATCH(RethrowTerminalExceptions) if (FAILED(hr)) { diff --git a/src/coreclr/src/vm/reflectioninvocation.cpp b/src/coreclr/src/vm/reflectioninvocation.cpp index 2724de4771b1f..b604b1a52d913 100644 --- a/src/coreclr/src/vm/reflectioninvocation.cpp +++ b/src/coreclr/src/vm/reflectioninvocation.cpp @@ -882,15 +882,6 @@ void DECLSPEC_NORETURN ThrowInvokeMethodException(MethodDesc * pMethod, OBJECTRE } #endif // _DEBUG && !TARGET_UNIX -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Get the corruption severity of the exception that came in through reflection invocation. - CorruptionSeverity severity = GetThread()->GetExceptionState()->GetLastActiveExceptionCorruptionSeverity(); - - // Since we are dealing with an exception, set the flag indicating if the target of Reflection can handle exception or not. - // This flag is used in CEHelper::CanIDispatchTargetHandleException. - GetThread()->GetExceptionState()->SetCanReflectionTargetHandleException(CEHelper::CanMethodHandleException(severity, pMethod)); -#endif // FEATURE_CORRUPTING_EXCEPTIONS - OBJECTREF except = InvokeUtil::CreateTargetExcept(&targetException); #ifndef TARGET_UNIX @@ -944,11 +935,7 @@ void DECLSPEC_NORETURN ThrowInvokeMethodException(MethodDesc * pMethod, OBJECTRE // Since VM is throwing the exception, we set it to use the same corruption severity // that the original exception came in with from reflection invocation. - COMPlusThrow(except -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + COMPlusThrow(except); GCPROTECT_END(); } @@ -1254,12 +1241,6 @@ FCIMPL5(Object*, RuntimeMethodHandle::InvokeMethod, ENDFORBIDGC(); } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // By default, set the flag in TES indicating the reflection target can handle CSE. - // This flag is used in CEHelper::CanIDispatchTargetHandleException. - pThread->GetExceptionState()->SetCanReflectionTargetHandleException(TRUE); -#endif // FEATURE_CORRUPTING_EXCEPTIONS - if (pValueClasses != NULL) { pProtectValueClassFrame = new (_alloca (sizeof (FrameWithCookie))) diff --git a/src/coreclr/src/vm/stdinterfaces.cpp b/src/coreclr/src/vm/stdinterfaces.cpp index 7ca4975c32678..240bdc926bc3e 100644 --- a/src/coreclr/src/vm/stdinterfaces.cpp +++ b/src/coreclr/src/vm/stdinterfaces.cpp @@ -1502,7 +1502,7 @@ InternalDispatchImpl_Invoke hr = pDispInfo->InvokeMember(pSimpleWrap, dispidMember, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, NULL, puArgErr); } - END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS; // This will ensure that entry points wont swallow CE and continue to let them propagate out. + END_EXTERNAL_ENTRYPOINT; return hr; } diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index 19b318e58d598..324c65d67ce8c 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -4500,17 +4500,6 @@ void Thread::SyncManagedExceptionState(bool fIsDebuggerThread) // Syncup the LastThrownObject on the managed thread SafeUpdateLastThrownObject(); } - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Since the catch clause has successfully executed and we are exiting it, reset the corruption severity - // in the ThreadExceptionState for the last active exception. This will ensure that when the next exception - // gets thrown/raised, EH tracker wont pick up an invalid value. - if (!fIsDebuggerThread) - { - CEHelper::ResetLastActiveCorruptionSeverityPostCatchHandler(this); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - } void Thread::SetLastThrownObjectHandle(OBJECTHANDLE h) From 55eb2f246f24ce6188d40718c450e3c947096644 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Thu, 7 May 2020 12:04:24 -0700 Subject: [PATCH 030/420] Make resumable converters delegate null handling to the serializer --- .../System/Text/Json/Serialization/JsonResumableConverterOfT.cs | 2 ++ .../CustomConverterTests/CustomConverterTests.HandleNull.cs | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs index 7aedf11cc799e..77d588af38153 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs @@ -40,5 +40,7 @@ public sealed override void Write(Utf8JsonWriter writer, T value, JsonSerializer state.Initialize(typeof(T), options, supportContinuation: false); TryWrite(writer, value, options, ref state); } + + public override bool HandleNull => false; } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs index 30ee15ea9980d..87b2598a5c205 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs @@ -4,7 +4,6 @@ using System.Buffers; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using Xunit; namespace System.Text.Json.Serialization.Tests From 2019cd60fbaaf8f5004b9b90bd38b10efff0b5cb Mon Sep 17 00:00:00 2001 From: Simon Nattress Date: Thu, 7 May 2020 13:26:49 -0700 Subject: [PATCH 031/420] Use type system entities instead of strings for node identity (#35918) The calling method for interface dispatches is used to provide imports specific to each call site (actually currently a shared one per calling method). Replace the use of mangled calling method name with its `MethodDesc` object as the key for the interface dispatch cell. This saves ~4% working set measured on a large application. Also, removed mangled name as the key for method-specific readonly data blobs the JIT allocates. This was much more modest since most methods don't need a readonly blob. --- ...OnlyDataBlob.cs => MethodReadOnlyDataNode.cs} | 16 +++++++--------- .../src/tools/Common/JitInterface/CorInfoImpl.cs | 5 ++--- .../ReadyToRun/DelayLoadHelperImport.cs | 8 ++++---- .../ReadyToRun/DelayLoadHelperMethodImport.cs | 4 ++-- .../DependencyAnalysis/ReadyToRun/Import.cs | 9 +++++---- .../SignatureEmbeddedPointerIndirectionNode.cs | 4 ++-- .../ReadyToRunCodegenNodeFactory.cs | 12 ------------ .../ReadyToRunSymbolNodeFactory.cs | 16 ++++++++-------- .../ILCompiler.ReadyToRun.csproj | 2 +- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 2 +- 10 files changed, 32 insertions(+), 46 deletions(-) rename src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/{SettableReadOnlyDataBlob.cs => MethodReadOnlyDataNode.cs} (71%) diff --git a/src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/SettableReadOnlyDataBlob.cs b/src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/MethodReadOnlyDataNode.cs similarity index 71% rename from src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/SettableReadOnlyDataBlob.cs rename to src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/MethodReadOnlyDataNode.cs index bf7de904bb351..7c1ae117056b2 100644 --- a/src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/SettableReadOnlyDataBlob.cs +++ b/src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/MethodReadOnlyDataNode.cs @@ -10,24 +10,22 @@ namespace ILCompiler.DependencyAnalysis { - public class SettableReadOnlyDataBlob : ObjectNode, ISymbolDefinitionNode + public class MethodReadOnlyDataNode : ObjectNode, ISymbolDefinitionNode { - private Utf8String _name; - private ObjectNodeSection _section; + private MethodDesc _owningMethod; private ObjectData _data; - public SettableReadOnlyDataBlob(Utf8String name, ObjectNodeSection section) + public MethodReadOnlyDataNode(MethodDesc owningMethod) { - _name = name; - _section = section; + _owningMethod = owningMethod; } - public override ObjectNodeSection Section => _section; + public override ObjectNodeSection Section => ObjectNodeSection.ReadOnlyDataSection; public override bool StaticDependenciesAreComputed => _data != null; public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { - sb.Append(_name); + sb.Append("__readonlydata_" + nameMangler.GetMangledMethodName(_owningMethod)); } public int Offset => 0; public override bool IsShareable => true; @@ -50,7 +48,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) { - return _name.CompareTo(((SettableReadOnlyDataBlob)other)._name); + return comparer.Compare(_owningMethod, ((MethodReadOnlyDataNode)other)._owningMethod); } #endif } diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs index 753fc0ab96da5..dd6e4c89aaa65 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs @@ -2565,7 +2565,7 @@ private bool getTailCallHelpers(ref CORINFO_RESOLVED_TOKEN callToken, CORINFO_SI private byte[] _roData; - private SettableReadOnlyDataBlob _roDataBlob; + private MethodReadOnlyDataNode _roDataBlob; private int _roDataAlignment; private int _numFrameInfos; @@ -2611,8 +2611,7 @@ private void allocMem(uint hotCodeSize, uint coldCodeSize, uint roDataSize, uint _roData = new byte[roDataSize]; - _roDataBlob = _compilation.NodeFactory.SettableReadOnlyDataBlob( - "__readonlydata_" + _compilation.NameMangler.GetMangledMethodName(MethodBeingCompiled)); + _roDataBlob = new MethodReadOnlyDataNode(MethodBeingCompiled); roDataBlock = (void*)GetPin(_roData); } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DelayLoadHelperImport.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DelayLoadHelperImport.cs index df834649fdc5f..d8f6c8f8d2c30 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DelayLoadHelperImport.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DelayLoadHelperImport.cs @@ -27,8 +27,8 @@ public class DelayLoadHelperImport : Import ReadyToRunHelper helper, Signature instanceSignature, bool useVirtualCall = false, - string callSite = null) - : base(importSectionNode, instanceSignature, callSite) + MethodDesc callingMethod = null) + : base(importSectionNode, instanceSignature, callingMethod) { _helper = helper; _useVirtualCall = useVirtualCall; @@ -45,10 +45,10 @@ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilde sb.Append(_helper.ToString()); sb.Append(") -> "); ImportSignature.AppendMangledName(nameMangler, sb); - if (CallSite != null) + if (CallingMethod != null) { sb.Append(" @ "); - sb.Append(CallSite); + sb.Append(nameMangler.GetMangledMethodName(CallingMethod)); } } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DelayLoadHelperMethodImport.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DelayLoadHelperMethodImport.cs index 4002bfdbab0d7..656a68f40c841 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DelayLoadHelperMethodImport.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DelayLoadHelperMethodImport.cs @@ -30,8 +30,8 @@ public class DelayLoadHelperMethodImport : DelayLoadHelperImport, IMethodNode bool useVirtualCall, bool useInstantiatingStub, Signature instanceSignature, - string callSite = null) - : base(factory, importSectionNode, helper, instanceSignature, useVirtualCall, callSite) + MethodDesc callingMethod = null) + : base(factory, importSectionNode, helper, instanceSignature, useVirtualCall, callingMethod) { _method = method; _useInstantiatingStub = useInstantiatingStub; diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Import.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Import.cs index e276c75fa7718..ebd73a82552bd 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Import.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Import.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using Internal.Text; +using Internal.TypeSystem; namespace ILCompiler.DependencyAnalysis.ReadyToRun { @@ -17,12 +18,12 @@ public class Import : EmbeddedObjectNode, ISymbolDefinitionNode, ISortableSymbol internal readonly SignatureEmbeddedPointerIndirectionNode ImportSignature; - internal readonly string CallSite; + internal readonly MethodDesc CallingMethod; - public Import(ImportSectionNode tableNode, Signature importSignature, string callSite = null) + public Import(ImportSectionNode tableNode, Signature importSignature, MethodDesc callingMethod = null) { Table = tableNode; - CallSite = callSite; + CallingMethod = callingMethod; ImportSignature = new SignatureEmbeddedPointerIndirectionNode(this, importSignature); } @@ -66,7 +67,7 @@ public override IEnumerable GetStaticDependencies(NodeFacto public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) { Import otherNode = (Import)other; - int result = string.Compare(CallSite, otherNode.CallSite); + int result = comparer.Compare(CallingMethod, otherNode.CallingMethod); if (result != 0) return result; diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureEmbeddedPointerIndirectionNode.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureEmbeddedPointerIndirectionNode.cs index eec93744449fb..c07b78b10e2fe 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureEmbeddedPointerIndirectionNode.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureEmbeddedPointerIndirectionNode.cs @@ -38,10 +38,10 @@ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilde { sb.Append("SignaturePointer_"); Target.AppendMangledName(nameMangler, sb); - if (_import.CallSite != null) + if (_import.CallingMethod != null) { sb.Append(" @ "); - sb.Append(_import.CallSite); + sb.Append(nameMangler.GetMangledMethodName(_import.CallingMethod)); } } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs index e4b76f79f6278..f6bff77e9dc49 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs @@ -96,13 +96,6 @@ public ISymbolNode ReadyToRunHelperFromTypeLookup(ReadyToRunHelperId id, Object return _genericReadyToRunHelpersFromType.GetOrAdd(new ReadyToRunGenericHelperKey(id, target, dictionaryOwner)); } - private NodeCache _readOnlyDataBlobs; - - public SettableReadOnlyDataBlob SettableReadOnlyDataBlob(Utf8String name) - { - return _readOnlyDataBlobs.GetOrAdd(name); - } - private struct ReadyToRunGenericHelperKey : IEquatable { public readonly object Target; @@ -211,11 +204,6 @@ private void CreateNodeCaches() (TypeDesc)helperKey.Target)); }); - _readOnlyDataBlobs = new NodeCache(key => - { - return new SettableReadOnlyDataBlob(key, ObjectNodeSection.ReadOnlyDataSection); - }); - _constructedHelpers = new NodeCache(helperId => { return new Import(EagerImports, new ReadyToRunHelperSignature(helperId)); diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs index da85b63332288..aeca8c8da3b24 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs @@ -107,7 +107,7 @@ private void CreateNodeCaches() _codegenNodeFactory.MethodSignature(ReadyToRunFixupKind.VirtualEntry, cellKey.Method, cellKey.IsUnboxingStub, isInstantiatingStub: false), - cellKey.CallSite); + cellKey.CallingMethod); }); _delegateCtors = new NodeCache(ctorKey => @@ -423,9 +423,9 @@ public ISymbolNode FieldBaseOffset(TypeDesc typeDesc) private NodeCache _interfaceDispatchCells = new NodeCache(); - public ISymbolNode InterfaceDispatchCell(MethodWithToken method, bool isUnboxingStub, string callSite) + public ISymbolNode InterfaceDispatchCell(MethodWithToken method, bool isUnboxingStub, MethodDesc callingMethod) { - MethodAndCallSite cellKey = new MethodAndCallSite(method, isUnboxingStub, callSite); + MethodAndCallSite cellKey = new MethodAndCallSite(method, isUnboxingStub, callingMethod); return _interfaceDispatchCells.GetOrAdd(cellKey); } @@ -453,18 +453,18 @@ struct MethodAndCallSite : IEquatable { public readonly MethodWithToken Method; public readonly bool IsUnboxingStub; - public readonly string CallSite; + public readonly MethodDesc CallingMethod; - public MethodAndCallSite(MethodWithToken method, bool isUnboxingStub, string callSite) + public MethodAndCallSite(MethodWithToken method, bool isUnboxingStub, MethodDesc callingMethod) { - CallSite = callSite; IsUnboxingStub = isUnboxingStub; Method = method; + CallingMethod = callingMethod; } public bool Equals(MethodAndCallSite other) { - return CallSite == other.CallSite && Method.Equals(other.Method) && IsUnboxingStub == other.IsUnboxingStub; + return Method.Equals(other.Method) && IsUnboxingStub == other.IsUnboxingStub && CallingMethod == other.CallingMethod; } public override bool Equals(object obj) @@ -474,7 +474,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - return (CallSite != null ? CallSite.GetHashCode() : 0) + return (CallingMethod != null ? unchecked(199 * CallingMethod.GetHashCode()) : 0) ^ unchecked(31 * Method.GetHashCode()) ^ (IsUnboxingStub ? -0x80000000 : 0); } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj index 6c0babecc023e..798f7074b69ae 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj @@ -62,7 +62,7 @@ - + diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index a0691e4061bb5..53249708170fc 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -1549,7 +1549,7 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO _compilation.SymbolNodeFactory.InterfaceDispatchCell( new MethodWithToken(targetMethod, HandleToModuleToken(ref pResolvedToken, targetMethod), constrainedType: null), isUnboxingStub: false, - _compilation.NameMangler.GetMangledMethodName(MethodBeingCompiled).ToString())); + MethodBeingCompiled)); } break; From 55d3260ad5dc48988228ac0cb1278541e87e513d Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Thu, 7 May 2020 13:37:38 -0700 Subject: [PATCH 032/420] Adding Linux support to System.DirectoryServices.Protocols (#35380) --- .../Common/src/Interop/Interop.Ldap.cs | 176 ++++++++ .../src/Interop/Linux/Interop.Libraries.cs | 1 + .../src/Interop/Linux/OpenLdap/Interop.Ber.cs | 52 +++ .../Interop/Linux/OpenLdap/Interop.Ldap.cs | 145 +++++++ .../src/Interop/Windows/Interop.Libraries.cs | 1 + .../Interop/Windows/Wldap32/Interop.Ber.cs | 52 +++ .../Interop/Windows/Wldap32/Interop.Ldap.cs | 154 +++++++ .../System.DirectoryServices.Protocols.csproj | 44 +- .../Protocols/Interop/BerPal.Linux.cs | 35 ++ .../Protocols/Interop/BerPal.Windows.cs | 37 ++ .../Protocols/Interop/LdapPal.Linux.cs | 114 ++++++ .../Protocols/Interop/LdapPal.Windows.cs | 105 +++++ .../Protocols/Interop/SafeHandles.Linux.cs | 79 ++++ .../SafeHandles.Windows.cs} | 36 +- .../Protocols/Interop/SafeHandles.cs | 28 ++ .../Protocols/common/BerConverter.Linux.cs | 28 ++ .../Protocols/common/BerConverter.Windows.cs | 41 ++ .../Protocols/common/BerConverter.cs | 123 +++--- .../Protocols/common/DirectoryControl.cs | 4 +- .../Protocols/ldap/LdapConnection.Linux.cs | 39 ++ .../Protocols/ldap/LdapConnection.Windows.cs | 43 ++ .../Protocols/ldap/LdapConnection.cs | 217 +++++----- .../ldap/LdapPartialResultsProcessor.cs | 2 +- .../ldap/LdapSessionOptions.Linux.cs | 17 + .../ldap/LdapSessionOptions.Windows.cs | 25 ++ .../Protocols/ldap/LdapSessionOptions.cs | 69 ++-- .../Protocols/ldap/Wldap32UnsafeMethods.cs | 376 ------------------ .../tests/AsqRequestControlTests.cs | 27 +- .../tests/BerConverterTests.cs | 70 ++-- .../tests/DirSyncRequestControlTests.cs | 39 +- .../tests/DirectoryServicesProtocolsTests.cs | 9 +- .../tests/DirectoryServicesTestHelpers.cs | 49 +++ .../tests/ExtendedDNControlTests.cs | 8 +- .../tests/LdapConnectionTests.cs | 3 +- .../tests/LdapSessionOptionsTests.cs | 26 ++ .../tests/PageResultRequestControlTests.cs | 27 +- .../tests/QuotaControlTests.cs | 7 +- .../tests/SearchOptionsControlTests.cs | 8 +- .../SecurityDescriptorFlagControlTests.cs | 17 +- .../tests/SortRequestControlTests.cs | 12 +- ...m.DirectoryServices.Protocols.Tests.csproj | 3 +- .../tests/VerifyNameControlTests.cs | 24 +- .../tests/VlvRequestControlTests.cs | 36 +- 43 files changed, 1683 insertions(+), 725 deletions(-) create mode 100644 src/libraries/Common/src/Interop/Interop.Ldap.cs create mode 100644 src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs create mode 100644 src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Wldap32/Interop.Ber.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Wldap32/Interop.Ldap.cs create mode 100644 src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs create mode 100644 src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs create mode 100644 src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Linux.cs create mode 100644 src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Windows.cs create mode 100644 src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/SafeHandles.Linux.cs rename src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/{ldap/SafeHandles.cs => Interop/SafeHandles.Windows.cs} (70%) create mode 100644 src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/SafeHandles.cs create mode 100644 src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.Linux.cs create mode 100644 src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.Windows.cs create mode 100644 src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Linux.cs create mode 100644 src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Windows.cs create mode 100644 src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Linux.cs create mode 100644 src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Windows.cs delete mode 100644 src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/Wldap32UnsafeMethods.cs create mode 100644 src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesTestHelpers.cs diff --git a/src/libraries/Common/src/Interop/Interop.Ldap.cs b/src/libraries/Common/src/Interop/Interop.Ldap.cs new file mode 100644 index 0000000000000..121fae5580ed0 --- /dev/null +++ b/src/libraries/Common/src/Interop/Interop.Ldap.cs @@ -0,0 +1,176 @@ +// 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. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + public const int SEC_WINNT_AUTH_IDENTITY_UNICODE = 0x2; + public const int SEC_WINNT_AUTH_IDENTITY_VERSION = 0x200; + public const string MICROSOFT_KERBEROS_NAME_W = "Kerberos"; +} + +namespace System.DirectoryServices.Protocols +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal class Luid + { + private readonly int _lowPart; + private readonly int _highPart; + + public int LowPart => _lowPart; + public int HighPart => _highPart; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal sealed class SEC_WINNT_AUTH_IDENTITY_EX + { + public int version; + public int length; + public string user; + public int userLength; + public string domain; + public int domainLength; + public string password; + public int passwordLength; + public int flags; + public string packageList; + public int packageListLength; + } + + internal enum BindMethod : uint // Not Supported in Linux + { + LDAP_AUTH_OTHERKIND = 0x86, + LDAP_AUTH_SICILY = LDAP_AUTH_OTHERKIND | 0x0200, + LDAP_AUTH_MSN = LDAP_AUTH_OTHERKIND | 0x0800, + LDAP_AUTH_NTLM = LDAP_AUTH_OTHERKIND | 0x1000, + LDAP_AUTH_DPA = LDAP_AUTH_OTHERKIND | 0x2000, + LDAP_AUTH_NEGOTIATE = LDAP_AUTH_OTHERKIND | 0x0400, + LDAP_AUTH_SSPI = LDAP_AUTH_NEGOTIATE, + LDAP_AUTH_DIGEST = LDAP_AUTH_OTHERKIND | 0x4000, + LDAP_AUTH_EXTERNAL = LDAP_AUTH_OTHERKIND | 0x0020, + LDAP_AUTH_KRBV4 = 0xFF, + LDAP_AUTH_SIMPLE = 0x80 + } + + internal enum LdapOption + { + LDAP_OPT_DESC = 0x01, + LDAP_OPT_DEREF = 0x02, + LDAP_OPT_SIZELIMIT = 0x03, + LDAP_OPT_TIMELIMIT = 0x04, + LDAP_OPT_REFERRALS = 0x08, + LDAP_OPT_RESTART = 0x09, + LDAP_OPT_SSL = 0x0a, // Not Supported in Linux + LDAP_OPT_REFERRAL_HOP_LIMIT = 0x10, // Not Supported in Linux + LDAP_OPT_VERSION = 0x11, + LDAP_OPT_SERVER_CONTROLS = 0x12, // Not Supported in Windows + LDAP_OPT_CLIENT_CONTROLS = 0x13, // Not Supported in Windows + LDAP_OPT_API_FEATURE_INFO = 0x15, + LDAP_OPT_HOST_NAME = 0x30, + LDAP_OPT_ERROR_NUMBER = 0x31, + LDAP_OPT_ERROR_STRING = 0x32, + LDAP_OPT_SERVER_ERROR = 0x33, + LDAP_OPT_SERVER_EXT_ERROR = 0x34, // Not Supported in Linux + LDAP_OPT_HOST_REACHABLE = 0x3E, // Not Supported in Linux + LDAP_OPT_PING_KEEP_ALIVE = 0x36, // Not Supported in Linux + LDAP_OPT_PING_WAIT_TIME = 0x37, // Not Supported in Linux + LDAP_OPT_PING_LIMIT = 0x38, // Not Supported in Linux + LDAP_OPT_DNSDOMAIN_NAME = 0x3B, // Not Supported in Linux + LDAP_OPT_GETDSNAME_FLAGS = 0x3D, // Not Supported in Linux + LDAP_OPT_PROMPT_CREDENTIALS = 0x3F, // Not Supported in Linux + LDAP_OPT_TCP_KEEPALIVE = 0x40, // Not Supported in Linux + LDAP_OPT_FAST_CONCURRENT_BIND = 0x41, // Not Supported in Linux + LDAP_OPT_SEND_TIMEOUT = 0x42, // Not Supported in Linux + LDAP_OPT_REFERRAL_CALLBACK = 0x70, // Not Supported in Linux + LDAP_OPT_CLIENT_CERTIFICATE = 0x80, // Not Supported in Linux + LDAP_OPT_SERVER_CERTIFICATE = 0x81, // Not Supported in Linux + LDAP_OPT_AUTO_RECONNECT = 0x91, // Not Supported in Linux + LDAP_OPT_SSPI_FLAGS = 0x92, + LDAP_OPT_SSL_INFO = 0x93, // Not Supported in Linux + LDAP_OPT_SIGN = 0x95, + LDAP_OPT_ENCRYPT = 0x96, + LDAP_OPT_SASL_METHOD = 0x97, + LDAP_OPT_AREC_EXCLUSIVE = 0x98, // Not Supported in Linux + LDAP_OPT_SECURITY_CONTEXT = 0x99, + LDAP_OPT_ROOTDSE_CACHE = 0x9a // Not Supported in Linux + } + + internal enum ResultAll + { + LDAP_MSG_ALL = 1, + LDAP_MSG_RECEIVED = 2, + LDAP_MSG_POLLINGALL = 3 // Not Supported in Linux + } + + [StructLayout(LayoutKind.Sequential)] + internal sealed class LDAP_TIMEVAL + { + public int tv_sec; + public int tv_usec; + } + + [StructLayout(LayoutKind.Sequential)] + internal sealed class berval + { + public int bv_len = 0; + public IntPtr bv_val = IntPtr.Zero; + + public berval() { } + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal sealed class LdapControl + { + public IntPtr ldctl_oid = IntPtr.Zero; + public berval ldctl_value = null; + public bool ldctl_iscritical = false; + + public LdapControl() { } + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct LdapReferralCallback + { + public int sizeofcallback; + public QUERYFORCONNECTIONInternal query; + public NOTIFYOFNEWCONNECTIONInternal notify; + public DEREFERENCECONNECTIONInternal dereference; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct CRYPTOAPI_BLOB + { + public int cbData; + public IntPtr pbData; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal struct SecPkgContext_IssuerListInfoEx + { + public IntPtr aIssuers; + public int cIssuers; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + internal sealed class LdapMod + { + public int type = 0; + public IntPtr attribute = IntPtr.Zero; + public IntPtr values = IntPtr.Zero; + + ~LdapMod() + { + if (attribute != IntPtr.Zero) + { + Marshal.FreeHGlobal(attribute); + } + + if (values != IntPtr.Zero) + { + Marshal.FreeHGlobal(values); + } + } + } +} diff --git a/src/libraries/Common/src/Interop/Linux/Interop.Libraries.cs b/src/libraries/Common/src/Interop/Linux/Interop.Libraries.cs index 25f0ce0a445e9..e7bc0d31f0d86 100644 --- a/src/libraries/Common/src/Interop/Linux/Interop.Libraries.cs +++ b/src/libraries/Common/src/Interop/Linux/Interop.Libraries.cs @@ -7,6 +7,7 @@ internal static partial class Interop internal static partial class Libraries { internal const string Odbc32 = "libodbc.so.2"; + internal const string OpenLdap = "libldap-2.4.so.2"; internal const string MsQuic = "msquic"; } } diff --git a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs new file mode 100644 index 0000000000000..4a059e35dacdb --- /dev/null +++ b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ber.cs @@ -0,0 +1,52 @@ +// 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. + +using System; +using System.Runtime.InteropServices; +using System.DirectoryServices.Protocols; + +internal static partial class Interop +{ + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_alloc_t", CharSet = CharSet.Ansi)] + public static extern IntPtr ber_alloc(int option); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_init", CharSet = CharSet.Ansi)] + public static extern IntPtr ber_init(berval value); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_free", CharSet = CharSet.Ansi)] + public static extern IntPtr ber_free([In] IntPtr berelement, int option); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_printf", CharSet = CharSet.Ansi)] + public static extern int ber_printf_emptyarg(SafeBerHandle berElement, string format); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_printf", CharSet = CharSet.Ansi)] + public static extern int ber_printf_int(SafeBerHandle berElement, string format, int value); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_printf", CharSet = CharSet.Ansi)] + public static extern int ber_printf_bytearray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_printf", CharSet = CharSet.Ansi)] + public static extern int ber_printf_berarray(SafeBerHandle berElement, string format, IntPtr value); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_flatten", CharSet = CharSet.Ansi)] + public static extern int ber_flatten(SafeBerHandle berElement, ref IntPtr value); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_bvfree", CharSet = CharSet.Ansi)] + public static extern int ber_bvfree(IntPtr value); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_bvecfree", CharSet = CharSet.Ansi)] + public static extern int ber_bvecfree(IntPtr value); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_scanf", CharSet = CharSet.Ansi)] + public static extern int ber_scanf(SafeBerHandle berElement, string format); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_scanf", CharSet = CharSet.Ansi)] + public static extern int ber_scanf_int(SafeBerHandle berElement, string format, ref int value); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_scanf", CharSet = CharSet.Ansi)] + public static extern int ber_scanf_bitstring(SafeBerHandle berElement, string format, ref IntPtr value, ref int bitLength); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ber_scanf", CharSet = CharSet.Ansi)] + public static extern int ber_scanf_ptr(SafeBerHandle berElement, string format, ref IntPtr value); +} diff --git a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs new file mode 100644 index 0000000000000..7925e24a7df96 --- /dev/null +++ b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs @@ -0,0 +1,145 @@ +// 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. + +using System; +using System.Runtime.InteropServices; +using System.DirectoryServices.Protocols; + +internal static partial class Interop +{ + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_initialize", CharSet = CharSet.Ansi, SetLastError = true)] + public static extern int ldap_initialize(out IntPtr ld, string hostname); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_init", CharSet = CharSet.Ansi, SetLastError = true)] + public static extern IntPtr ldap_init(string hostName, int portNumber); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_unbind_ext_s", CharSet = CharSet.Ansi)] + public static extern int ldap_unbind_ext_s(IntPtr ld, ref IntPtr serverctrls, ref IntPtr clientctrls); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_get_dn", CharSet = CharSet.Ansi)] + public static extern IntPtr ldap_get_dn([In] ConnectionHandle ldapHandle, [In] IntPtr result); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_get_option", CharSet = CharSet.Ansi)] + public static extern int ldap_get_option_secInfo([In] ConnectionHandle ldapHandle, [In] LdapOption option, [In, Out] SecurityPackageContextConnectionInformation outValue); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_get_option", CharSet = CharSet.Ansi)] + public static extern int ldap_get_option_sechandle([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref SecurityHandle outValue); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_get_option", CharSet = CharSet.Ansi)] + public static extern int ldap_get_option_int([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref int outValue); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_get_option", CharSet = CharSet.Ansi)] + public static extern int ldap_get_option_ptr([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref IntPtr outValue); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_get_values_len", CharSet = CharSet.Ansi)] + public static extern IntPtr ldap_get_values_len([In] ConnectionHandle ldapHandle, [In] IntPtr result, string name); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_result", SetLastError = true, CharSet = CharSet.Ansi)] + public static extern int ldap_result([In] ConnectionHandle ldapHandle, int messageId, int all, LDAP_TIMEVAL timeout, ref IntPtr Mesage); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_result2error", CharSet = CharSet.Ansi)] + public static extern int ldap_result2error([In] ConnectionHandle ldapHandle, [In] IntPtr result, int freeIt); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_search_ext", CharSet = CharSet.Ansi)] + public static extern int ldap_search([In] ConnectionHandle ldapHandle, string dn, int scope, string filter, IntPtr attributes, bool attributeOnly, IntPtr servercontrol, IntPtr clientcontrol, int timelimit, int sizelimit, ref int messageNumber); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_set_option", CharSet = CharSet.Ansi)] + public static extern int ldap_set_option_clientcert([In] ConnectionHandle ldapHandle, [In] LdapOption option, QUERYCLIENTCERT outValue); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_set_option", CharSet = CharSet.Ansi)] + public static extern int ldap_set_option_servercert([In] ConnectionHandle ldapHandle, [In] LdapOption option, VERIFYSERVERCERT outValue); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_set_option", CharSet = CharSet.Ansi, SetLastError = true)] + public static extern int ldap_set_option_int([In] ConnectionHandle ld, [In] LdapOption option, ref int inValue); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_set_option", CharSet = CharSet.Ansi)] + public static extern int ldap_set_option_ptr([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref IntPtr inValue); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_set_option", CharSet = CharSet.Ansi)] + public static extern int ldap_set_option_referral([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref LdapReferralCallback outValue); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_start_tls_s", CharSet = CharSet.Ansi)] + public static extern int ldap_start_tls(ConnectionHandle ldapHandle, ref int ServerReturnValue, ref IntPtr Message, IntPtr ServerControls, IntPtr ClientControls); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_parse_result", CharSet = CharSet.Ansi)] + public static extern int ldap_parse_result([In] ConnectionHandle ldapHandle, [In] IntPtr result, ref int serverError, ref IntPtr dn, ref IntPtr message, ref IntPtr referral, ref IntPtr control, byte freeIt); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_parse_result", CharSet = CharSet.Ansi)] + public static extern int ldap_parse_result_referral([In] ConnectionHandle ldapHandle, [In] IntPtr result, IntPtr serverError, IntPtr dn, IntPtr message, ref IntPtr referral, IntPtr control, byte freeIt); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_parse_extended_result", CharSet = CharSet.Ansi)] + public static extern int ldap_parse_extended_result([In] ConnectionHandle ldapHandle, [In] IntPtr result, ref IntPtr oid, ref IntPtr data, byte freeIt); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_parse_reference", CharSet = CharSet.Ansi)] + public static extern int ldap_parse_reference([In] ConnectionHandle ldapHandle, [In] IntPtr result, ref IntPtr referrals, IntPtr ServerControls, byte freeIt); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_sasl_bind_s", CharSet = CharSet.Ansi, SetLastError = true)] + public static extern int ldap_sasl_bind_s([In] ConnectionHandle ld, string dn, string mechanism, berval cred, IntPtr servercontrol, IntPtr clientcontrol, ref berval servercredp); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_simple_bind_s", CharSet = CharSet.Ansi, SetLastError = true)] + public static extern int ldap_simple_bind([In] ConnectionHandle ld, string who, string passwd); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_bind_s", CharSet = CharSet.Ansi, SetLastError = true)] + public static extern int ldap_bind_s([In] ConnectionHandle ld, string who, string passwd, int method); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_err2string", CharSet = CharSet.Ansi)] + public static extern IntPtr ldap_err2string(int err); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_extended_operation", CharSet = CharSet.Ansi)] + public static extern int ldap_extended_operation([In] ConnectionHandle ldapHandle, string oid, berval data, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_first_attribute", CharSet = CharSet.Ansi)] + public static extern IntPtr ldap_first_attribute([In] ConnectionHandle ldapHandle, [In] IntPtr result, ref IntPtr address); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_first_entry", CharSet = CharSet.Ansi)] + public static extern IntPtr ldap_first_entry([In] ConnectionHandle ldapHandle, [In] IntPtr result); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_first_reference", CharSet = CharSet.Ansi)] + public static extern IntPtr ldap_first_reference([In] ConnectionHandle ldapHandle, [In] IntPtr result); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_create_sort_control", CharSet = CharSet.Ansi)] + public static extern int ldap_create_sort_control(ConnectionHandle handle, IntPtr keys, byte critical, ref IntPtr control); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_control_free", CharSet = CharSet.Ansi)] + public static extern int ldap_control_free(IntPtr control); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_controls_free", CharSet = CharSet.Ansi)] + public static extern int ldap_controls_free([In] IntPtr value); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_value_free", CharSet = CharSet.Ansi)] + public static extern int ldap_value_free([In] IntPtr value); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_value_free_len", CharSet = CharSet.Ansi)] + public static extern IntPtr ldap_value_free_len([In] IntPtr berelement); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_memfree", CharSet = CharSet.Ansi)] + public static extern void ldap_memfree([In] IntPtr value); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_modify_ext", CharSet = CharSet.Ansi)] + public static extern int ldap_modify([In] ConnectionHandle ldapHandle, string dn, IntPtr attrs, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_next_attribute", CharSet = CharSet.Ansi)] + public static extern IntPtr ldap_next_attribute([In] ConnectionHandle ldapHandle, [In] IntPtr result, [In, Out] IntPtr address); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_next_entry", CharSet = CharSet.Ansi)] + public static extern IntPtr ldap_next_entry([In] ConnectionHandle ldapHandle, [In] IntPtr result); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_next_reference", CharSet = CharSet.Ansi)] + public static extern IntPtr ldap_next_reference([In] ConnectionHandle ldapHandle, [In] IntPtr result); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_abandon", CharSet = CharSet.Ansi)] + public static extern int ldap_abandon([In] ConnectionHandle ldapHandle, [In] int messagId); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_add_ext", CharSet = CharSet.Ansi)] + public static extern int ldap_add([In] ConnectionHandle ldapHandle, string dn, IntPtr attrs, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_delete_ext", CharSet = CharSet.Ansi)] + public static extern int ldap_delete_ext([In] ConnectionHandle ldapHandle, string dn, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_rename", CharSet = CharSet.Ansi)] + public static extern int ldap_rename([In] ConnectionHandle ldapHandle, string dn, string newRdn, string newParentDn, int deleteOldRdn, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); + + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_compare_ext", CharSet = CharSet.Ansi)] + public static extern int ldap_compare([In] ConnectionHandle ldapHandle, string dn, string attributeName, berval binaryValue, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); +} diff --git a/src/libraries/Common/src/Interop/Windows/Interop.Libraries.cs b/src/libraries/Common/src/Interop/Windows/Interop.Libraries.cs index 1c1b3db6a0b76..2672c4cc489e5 100644 --- a/src/libraries/Common/src/Interop/Windows/Interop.Libraries.cs +++ b/src/libraries/Common/src/Interop/Windows/Interop.Libraries.cs @@ -34,6 +34,7 @@ internal static partial class Libraries internal const string WebSocket = "websocket.dll"; internal const string WinHttp = "winhttp.dll"; internal const string WinMM = "winmm.dll"; + internal const string Wldap32 = "wldap32.dll"; internal const string Ws2_32 = "ws2_32.dll"; internal const string Wtsapi32 = "wtsapi32.dll"; internal const string CompressionNative = "clrcompression.dll"; diff --git a/src/libraries/Common/src/Interop/Windows/Wldap32/Interop.Ber.cs b/src/libraries/Common/src/Interop/Windows/Wldap32/Interop.Ber.cs new file mode 100644 index 0000000000000..5f87ea57938b0 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Wldap32/Interop.Ber.cs @@ -0,0 +1,52 @@ +// 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. + +using System; +using System.DirectoryServices.Protocols; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_free", CharSet = CharSet.Unicode)] + public static extern IntPtr ber_free([In] IntPtr berelement, int option); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_alloc_t", CharSet = CharSet.Unicode)] + public static extern IntPtr ber_alloc(int option); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_printf", CharSet = CharSet.Unicode)] + public static extern int ber_printf_emptyarg(SafeBerHandle berElement, string format); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_printf", CharSet = CharSet.Unicode)] + public static extern int ber_printf_int(SafeBerHandle berElement, string format, int value); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_printf", CharSet = CharSet.Unicode)] + public static extern int ber_printf_bytearray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_printf", CharSet = CharSet.Unicode)] + public static extern int ber_printf_berarray(SafeBerHandle berElement, string format, IntPtr value); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_flatten", CharSet = CharSet.Unicode)] + public static extern int ber_flatten(SafeBerHandle berElement, ref IntPtr value); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_init", CharSet = CharSet.Unicode)] + public static extern IntPtr ber_init(berval value); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_scanf", CharSet = CharSet.Unicode)] + public static extern int ber_scanf(SafeBerHandle berElement, string format); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_scanf", CharSet = CharSet.Unicode)] + public static extern int ber_scanf_int(SafeBerHandle berElement, string format, ref int value); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_scanf", CharSet = CharSet.Unicode)] + public static extern int ber_scanf_ptr(SafeBerHandle berElement, string format, ref IntPtr value); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_scanf", CharSet = CharSet.Unicode)] + public static extern int ber_scanf_bitstring(SafeBerHandle berElement, string format, ref IntPtr value, ref int bitLength); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_bvfree", CharSet = CharSet.Unicode)] + public static extern int ber_bvfree(IntPtr value); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_bvecfree", CharSet = CharSet.Unicode)] + public static extern int ber_bvecfree(IntPtr value); +} diff --git a/src/libraries/Common/src/Interop/Windows/Wldap32/Interop.Ldap.cs b/src/libraries/Common/src/Interop/Windows/Wldap32/Interop.Ldap.cs new file mode 100644 index 0000000000000..a73cd89996e2d --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Wldap32/Interop.Ldap.cs @@ -0,0 +1,154 @@ +// 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. + +using System; +using System.DirectoryServices.Protocols; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_bind_sW", CharSet = CharSet.Unicode)] + public static extern int ldap_bind_s([In]ConnectionHandle ldapHandle, string dn, SEC_WINNT_AUTH_IDENTITY_EX credentials, BindMethod method); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_initW", SetLastError = true, CharSet = CharSet.Unicode)] + public static extern IntPtr ldap_init(string hostName, int portNumber); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, EntryPoint = "ldap_connect", CharSet = CharSet.Unicode)] + public static extern int ldap_connect([In] ConnectionHandle ldapHandle, LDAP_TIMEVAL timeout); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, EntryPoint = "ldap_unbind", CharSet = CharSet.Unicode)] + public static extern int ldap_unbind([In] IntPtr ldapHandle); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_get_optionW", CharSet = CharSet.Unicode)] + public static extern int ldap_get_option_int([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref int outValue); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_set_optionW", CharSet = CharSet.Unicode)] + public static extern int ldap_set_option_int([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref int inValue); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_get_optionW", CharSet = CharSet.Unicode)] + public static extern int ldap_get_option_ptr([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref IntPtr outValue); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_set_optionW", CharSet = CharSet.Unicode)] + public static extern int ldap_set_option_ptr([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref IntPtr inValue); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_get_optionW", CharSet = CharSet.Unicode)] + public static extern int ldap_get_option_sechandle([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref SecurityHandle outValue); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_get_optionW", CharSet = CharSet.Unicode)] + public static extern int ldap_get_option_secInfo([In] ConnectionHandle ldapHandle, [In] LdapOption option, [In, Out] SecurityPackageContextConnectionInformation outValue); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_set_optionW", CharSet = CharSet.Unicode)] + public static extern int ldap_set_option_referral([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref LdapReferralCallback outValue); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_set_optionW", CharSet = CharSet.Unicode)] + public static extern int ldap_set_option_clientcert([In] ConnectionHandle ldapHandle, [In] LdapOption option, QUERYCLIENTCERT outValue); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_set_optionW", CharSet = CharSet.Unicode)] + public static extern int ldap_set_option_servercert([In] ConnectionHandle ldapHandle, [In] LdapOption option, VERIFYSERVERCERT outValue); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "LdapGetLastError")] + public static extern int LdapGetLastError(); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "cldap_openW", SetLastError = true, CharSet = CharSet.Unicode)] + public static extern IntPtr cldap_open(string hostName, int portNumber); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_simple_bind_sW", CharSet = CharSet.Unicode)] + public static extern int ldap_simple_bind_s([In] ConnectionHandle ldapHandle, string distinguishedName, string password); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_delete_extW", CharSet = CharSet.Unicode)] + public static extern int ldap_delete_ext([In] ConnectionHandle ldapHandle, string dn, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_result", SetLastError = true, CharSet = CharSet.Unicode)] + public static extern int ldap_result([In] ConnectionHandle ldapHandle, int messageId, int all, LDAP_TIMEVAL timeout, ref IntPtr Mesage); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_parse_resultW", CharSet = CharSet.Unicode)] + public static extern int ldap_parse_result([In] ConnectionHandle ldapHandle, [In] IntPtr result, ref int serverError, ref IntPtr dn, ref IntPtr message, ref IntPtr referral, ref IntPtr control, byte freeIt); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_parse_resultW", CharSet = CharSet.Unicode)] + public static extern int ldap_parse_result_referral([In] ConnectionHandle ldapHandle, [In] IntPtr result, IntPtr serverError, IntPtr dn, IntPtr message, ref IntPtr referral, IntPtr control, byte freeIt); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_memfreeW", CharSet = CharSet.Unicode)] + public static extern void ldap_memfree([In] IntPtr value); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_value_freeW", CharSet = CharSet.Unicode)] + public static extern int ldap_value_free([In] IntPtr value); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_controls_freeW", CharSet = CharSet.Unicode)] + public static extern int ldap_controls_free([In] IntPtr value); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_abandon", CharSet = CharSet.Unicode)] + public static extern int ldap_abandon([In] ConnectionHandle ldapHandle, [In] int messagId); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_start_tls_sW", CharSet = CharSet.Unicode)] + public static extern int ldap_start_tls(ConnectionHandle ldapHandle, ref int ServerReturnValue, ref IntPtr Message, IntPtr ServerControls, IntPtr ClientControls); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_stop_tls_s", CharSet = CharSet.Unicode)] + public static extern byte ldap_stop_tls(ConnectionHandle ldapHandle); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_rename_extW", CharSet = CharSet.Unicode)] + public static extern int ldap_rename([In] ConnectionHandle ldapHandle, string dn, string newRdn, string newParentDn, int deleteOldRdn, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_compare_extW", CharSet = CharSet.Unicode)] + public static extern int ldap_compare([In] ConnectionHandle ldapHandle, string dn, string attributeName, string strValue, berval binaryValue, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_add_extW", CharSet = CharSet.Unicode)] + public static extern int ldap_add([In] ConnectionHandle ldapHandle, string dn, IntPtr attrs, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_modify_extW", CharSet = CharSet.Unicode)] + public static extern int ldap_modify([In] ConnectionHandle ldapHandle, string dn, IntPtr attrs, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_extended_operationW", CharSet = CharSet.Unicode)] + public static extern int ldap_extended_operation([In] ConnectionHandle ldapHandle, string oid, berval data, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_parse_extended_resultW", CharSet = CharSet.Unicode)] + public static extern int ldap_parse_extended_result([In] ConnectionHandle ldapHandle, [In] IntPtr result, ref IntPtr oid, ref IntPtr data, byte freeIt); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_msgfree", CharSet = CharSet.Unicode)] + public static extern int ldap_msgfree([In] IntPtr result); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_search_extW", CharSet = CharSet.Unicode)] + public static extern int ldap_search([In] ConnectionHandle ldapHandle, string dn, int scope, string filter, IntPtr attributes, bool attributeOnly, IntPtr servercontrol, IntPtr clientcontrol, int timelimit, int sizelimit, ref int messageNumber); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_first_entry", CharSet = CharSet.Unicode)] + public static extern IntPtr ldap_first_entry([In] ConnectionHandle ldapHandle, [In] IntPtr result); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_next_entry", CharSet = CharSet.Unicode)] + public static extern IntPtr ldap_next_entry([In] ConnectionHandle ldapHandle, [In] IntPtr result); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_first_reference", CharSet = CharSet.Unicode)] + public static extern IntPtr ldap_first_reference([In] ConnectionHandle ldapHandle, [In] IntPtr result); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_next_reference", CharSet = CharSet.Unicode)] + public static extern IntPtr ldap_next_reference([In] ConnectionHandle ldapHandle, [In] IntPtr result); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_get_dnW", CharSet = CharSet.Unicode)] + public static extern IntPtr ldap_get_dn([In] ConnectionHandle ldapHandle, [In] IntPtr result); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_first_attributeW", CharSet = CharSet.Unicode)] + public static extern IntPtr ldap_first_attribute([In] ConnectionHandle ldapHandle, [In] IntPtr result, ref IntPtr address); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_next_attributeW", CharSet = CharSet.Unicode)] + public static extern IntPtr ldap_next_attribute([In] ConnectionHandle ldapHandle, [In] IntPtr result, [In, Out] IntPtr address); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_get_values_lenW", CharSet = CharSet.Unicode)] + public static extern IntPtr ldap_get_values_len([In] ConnectionHandle ldapHandle, [In] IntPtr result, string name); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_value_free_len", CharSet = CharSet.Unicode)] + public static extern IntPtr ldap_value_free_len([In] IntPtr berelement); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_parse_referenceW", CharSet = CharSet.Unicode)] + public static extern int ldap_parse_reference([In] ConnectionHandle ldapHandle, [In] IntPtr result, ref IntPtr referrals); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_create_sort_controlW", CharSet = CharSet.Unicode)] + public static extern int ldap_create_sort_control(ConnectionHandle handle, IntPtr keys, byte critical, ref IntPtr control); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_control_freeW", CharSet = CharSet.Unicode)] + public static extern int ldap_control_free(IntPtr control); + + [DllImport("Crypt32.dll", EntryPoint = "CertFreeCRLContext", CharSet = CharSet.Unicode)] + public static extern int CertFreeCRLContext(IntPtr certContext); + + [DllImport(Libraries.Wldap32, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_result2error", CharSet = CharSet.Unicode)] + public static extern int ldap_result2error([In] ConnectionHandle ldapHandle, [In] IntPtr result, int freeIt); +} diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj index a1fa96ae4019b..09328b9fb2159 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj +++ b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj @@ -4,7 +4,7 @@ true $(NoWarn);0649;CA1810 true - $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT;_$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Linux;netcoreapp2.0-Linux;$(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT;_$(NetFrameworkCurrent) true @@ -36,8 +36,44 @@ - - + + + Common\Interop\Interop.Ldap.cs + + + + + + + + + + + Common\Interop\Windows\Interop.Libraries.cs + + + Common\Interop\Windows\Wldap32\Interop.Ldap.cs + + + Common\Interop\Windows\Wldap32\Interop.Ber.cs + + + + + + + + + + + Common\Interop\Linux\Interop.Libraries.cs + + + Common\Interop\Linux\OpenLdap\Interop.Ldap.cs + + + Common\Interop\Linux\OpenLdap\Interop.Ber.cs + @@ -63,4 +99,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs new file mode 100644 index 0000000000000..f58a94df52234 --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Linux.cs @@ -0,0 +1,35 @@ +// 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. + +namespace System.DirectoryServices.Protocols +{ + internal static class BerPal + { + internal static void FreeBervalArray(IntPtr ptrResult) => Interop.ber_bvecfree(ptrResult); + + internal static void FreeBerval(IntPtr flattenptr) => Interop.ber_bvfree(flattenptr); + + internal static void FreeBerElement(IntPtr berelement, int option) => Interop.ber_free(berelement, option); + + internal static int FlattenBerElement(SafeBerHandle berElement, ref IntPtr flattenptr) => Interop.ber_flatten(berElement, ref flattenptr); + + internal static int PrintBerArray(SafeBerHandle berElement, string format, IntPtr value) => Interop.ber_printf_berarray(berElement, format, value); + + internal static int PrintByteArray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length) => Interop.ber_printf_bytearray(berElement, format, value, length); + + internal static int PrintEmptyArgument(SafeBerHandle berElement, string format) => Interop.ber_printf_emptyarg(berElement, format); + + internal static int PrintInt(SafeBerHandle berElement, string format, int value) => Interop.ber_printf_int(berElement, format, value); + + internal static int ScanNext(SafeBerHandle berElement, string format) => Interop.ber_scanf(berElement, format); + + internal static int ScanNextBitString(SafeBerHandle berElement, string format, ref IntPtr ptrResult, ref int bitLength) => Interop.ber_scanf_bitstring(berElement, format, ref ptrResult, ref bitLength); + + internal static int ScanNextInt(SafeBerHandle berElement, string format, ref int result) => Interop.ber_scanf_int(berElement, format, ref result); + + internal static int ScanNextPtr(SafeBerHandle berElement, string format, ref IntPtr value) => Interop.ber_scanf_ptr(berElement, format, ref value); + + internal static bool IsBerDecodeError(int errorCode) => errorCode == -1; + } +} diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs new file mode 100644 index 0000000000000..bec5b5a65d5ac --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/BerPal.Windows.cs @@ -0,0 +1,37 @@ +// 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. + +using System.Runtime.InteropServices; + +namespace System.DirectoryServices.Protocols +{ + internal static class BerPal + { + internal static void FreeBervalArray(IntPtr ptrResult) => Interop.ber_bvecfree(ptrResult); + + internal static void FreeBerval(IntPtr flattenptr) => Interop.ber_bvfree(flattenptr); + + internal static void FreeBerElement(IntPtr berelement, int option) => Interop.ber_free(berelement, option); + + internal static int FlattenBerElement(SafeBerHandle berElement, ref IntPtr flattenptr) => Interop.ber_flatten(berElement, ref flattenptr); + + internal static int PrintBerArray(SafeBerHandle berElement, string format, IntPtr value) => Interop.ber_printf_berarray(berElement, format, value); + + internal static int PrintByteArray(SafeBerHandle berElement, string format, HGlobalMemHandle value, int length) => Interop.ber_printf_bytearray(berElement, format, value, length); + + internal static int PrintEmptyArgument(SafeBerHandle berElement, string format) => Interop.ber_printf_emptyarg(berElement, format); + + internal static int PrintInt(SafeBerHandle berElement, string format, int value) => Interop.ber_printf_int(berElement, format, value); + + internal static int ScanNext(SafeBerHandle berElement, string format) => Interop.ber_scanf(berElement, format); + + internal static int ScanNextBitString(SafeBerHandle berElement, string format, ref IntPtr ptrResult, ref int bitLength) => Interop.ber_scanf_bitstring(berElement, format, ref ptrResult, ref bitLength); + + internal static int ScanNextInt(SafeBerHandle berElement, string format, ref int result) => Interop.ber_scanf_int(berElement, format, ref result); + + internal static int ScanNextPtr(SafeBerHandle berElement, string format, ref IntPtr value) => Interop.ber_scanf_ptr(berElement, format, ref value); + + internal static bool IsBerDecodeError(int errorCode) => errorCode != 0; + } +} diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Linux.cs new file mode 100644 index 0000000000000..09ae9c5e12272 --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Linux.cs @@ -0,0 +1,114 @@ +// 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. + +using System.Runtime.InteropServices; + +namespace System.DirectoryServices.Protocols +{ + internal static class LdapPal + { + internal static void CancelDirectoryAsyncOperation(ConnectionHandle ldapHandle, int messagId) => Interop.ldap_abandon(ldapHandle, messagId); + + internal static int AddDirectoryEntry(ConnectionHandle ldapHandle, string dn, IntPtr attrs, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) => + Interop.ldap_add(ldapHandle, dn, attrs, servercontrol, clientcontrol, ref messageNumber); + + internal static int CompareDirectoryEntries(ConnectionHandle ldapHandle, string dn, string attributeName, string strValue, berval binaryValue, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) => + Interop.ldap_compare(ldapHandle, dn, attributeName, binaryValue, servercontrol, clientcontrol, ref messageNumber); + + internal static void FreeDirectoryControl(IntPtr control) => Interop.ldap_control_free(control); + + internal static void FreeDirectoryControls(IntPtr value) => Interop.ldap_controls_free(value); + + internal static int CreateDirectorySortControl(ConnectionHandle handle, IntPtr keys, byte critical, ref IntPtr control) => Interop.ldap_create_sort_control(handle, keys, critical, ref control); + + internal static int DeleteDirectoryEntry(ConnectionHandle ldapHandle, string dn, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) => Interop.ldap_delete_ext(ldapHandle, dn, servercontrol, clientcontrol, ref messageNumber); + + internal static int ExtendedDirectoryOperation(ConnectionHandle ldapHandle, string oid, berval data, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) => + Interop.ldap_extended_operation(ldapHandle, oid, data, servercontrol, clientcontrol, ref messageNumber); + + internal static IntPtr GetFirstAttributeFromEntry(ConnectionHandle ldapHandle, IntPtr result, ref IntPtr address) => Interop.ldap_first_attribute(ldapHandle, result, ref address); + + internal static IntPtr GetFirstEntryFromResult(ConnectionHandle ldapHandle, IntPtr result) => Interop.ldap_first_entry(ldapHandle, result); + + internal static IntPtr GetFirstReferenceFromResult(ConnectionHandle ldapHandle, IntPtr result) => Interop.ldap_first_reference(ldapHandle, result); + + internal static IntPtr GetDistinguishedName(ConnectionHandle ldapHandle, IntPtr result) => Interop.ldap_get_dn(ldapHandle, result); + + internal static int GetLastErrorFromConnection(ConnectionHandle ldapHandle) + { + int result = 0; + Interop.ldap_get_option_int(ldapHandle, LdapOption.LDAP_OPT_ERROR_NUMBER, ref result); + return result; + } + + internal static int GetIntOption(ConnectionHandle ldapHandle, LdapOption option, ref int outValue) => Interop.ldap_get_option_int(ldapHandle, option, ref outValue); + + internal static int GetPtrOption(ConnectionHandle ldapHandle, LdapOption option, ref IntPtr outValue) => Interop.ldap_get_option_ptr(ldapHandle, option, ref outValue); + + internal static int GetSecurityHandleOption(ConnectionHandle ldapHandle, LdapOption option, ref SecurityHandle outValue) => Interop.ldap_get_option_sechandle(ldapHandle, option, ref outValue); + + // This option is not supported on Linux, so it would most likely throw. + internal static int GetSecInfoOption(ConnectionHandle ldapHandle, LdapOption option, SecurityPackageContextConnectionInformation outValue) => Interop.ldap_get_option_secInfo(ldapHandle, option, outValue); + + internal static IntPtr GetValuesFromAttribute(ConnectionHandle ldapHandle, IntPtr result, string name) => Interop.ldap_get_values_len(ldapHandle, result, name); + + internal static void FreeMemory(IntPtr outValue) => Interop.ldap_memfree(outValue); + + internal static int ModifyDirectoryEntry(ConnectionHandle ldapHandle, string dn, IntPtr attrs, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) => + Interop.ldap_modify(ldapHandle, dn, attrs, servercontrol, clientcontrol, ref messageNumber); + + internal static IntPtr GetNextAttributeFromResult(ConnectionHandle ldapHandle, IntPtr result, IntPtr address) => Interop.ldap_next_attribute(ldapHandle, result, address); + + internal static IntPtr GetNextEntryFromResult(ConnectionHandle ldapHandle, IntPtr result) => Interop.ldap_next_entry(ldapHandle, result); + + internal static IntPtr GetNextReferenceFromResult(ConnectionHandle ldapHandle, IntPtr result) => Interop.ldap_next_reference(ldapHandle, result); + + internal static int ParseExtendedResult(ConnectionHandle ldapHandle, IntPtr result, ref IntPtr oid, ref IntPtr data, byte freeIt) => Interop.ldap_parse_extended_result(ldapHandle, result, ref oid, ref data, freeIt); + + internal static int ParseReference(ConnectionHandle ldapHandle, IntPtr result, ref IntPtr referrals) => Interop.ldap_parse_reference(ldapHandle, result, ref referrals, IntPtr.Zero, 0); + + internal static int ParseResult(ConnectionHandle ldapHandle, IntPtr result, ref int serverError, ref IntPtr dn, ref IntPtr message, ref IntPtr referral, ref IntPtr control, byte freeIt) => + Interop.ldap_parse_result(ldapHandle, result, ref serverError, ref dn, ref message, ref referral, ref control, freeIt); + + internal static int ParseResultReferral(ConnectionHandle ldapHandle, IntPtr result, IntPtr serverError, IntPtr dn, IntPtr message, ref IntPtr referral, IntPtr control, byte freeIt) + => Interop.ldap_parse_result_referral(ldapHandle, result, serverError, dn, message, ref referral, control, freeIt); + + internal static int RenameDirectoryEntry(ConnectionHandle ldapHandle, string dn, string newRdn, string newParentDn, int deleteOldRdn, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) => + Interop.ldap_rename(ldapHandle, dn, newRdn, newParentDn, deleteOldRdn, servercontrol, clientcontrol, ref messageNumber); + + internal static int GetResultFromAsyncOperation(ConnectionHandle ldapHandle, int messageId, int all, LDAP_TIMEVAL timeout, ref IntPtr Message) => Interop.ldap_result(ldapHandle, messageId, all, timeout, ref Message); + + internal static int ResultToErrorCode(ConnectionHandle ldapHandle, IntPtr result, int freeIt) => Interop.ldap_result2error(ldapHandle, result, freeIt); + + internal static int SearchDirectory(ConnectionHandle ldapHandle, string dn, int scope, string filter, IntPtr attributes, bool attributeOnly, IntPtr servercontrol, IntPtr clientcontrol, int timelimit, int sizelimit, ref int messageNumber) => + Interop.ldap_search(ldapHandle, dn, scope, filter, attributes, attributeOnly, servercontrol, clientcontrol, timelimit, sizelimit, ref messageNumber); + + // This option is not supported in Linux, so it would most likely throw. + internal static int SetClientCertOption(ConnectionHandle ldapHandle, LdapOption option, QUERYCLIENTCERT outValue) => Interop.ldap_set_option_clientcert(ldapHandle, option, outValue); + + internal static int SetIntOption(ConnectionHandle ld, LdapOption option, ref int inValue) => Interop.ldap_set_option_int(ld, option, ref inValue); + + internal static int SetPtrOption(ConnectionHandle ldapHandle, LdapOption option, ref IntPtr inValue) => Interop.ldap_set_option_ptr(ldapHandle, option, ref inValue); + + internal static int SetReferralOption(ConnectionHandle ldapHandle, LdapOption option, ref LdapReferralCallback outValue) => Interop.ldap_set_option_referral(ldapHandle, option, ref outValue); + + // This option is not supported in Linux, so it would most likely throw. + internal static int SetServerCertOption(ConnectionHandle ldapHandle, LdapOption option, VERIFYSERVERCERT outValue) => Interop.ldap_set_option_servercert(ldapHandle, option, outValue); + + internal static int BindToDirectory(ConnectionHandle ld, string who, string passwd) => Interop.ldap_simple_bind(ld, who, passwd); + + internal static int StartTls(ConnectionHandle ldapHandle, ref int ServerReturnValue, ref IntPtr Message, IntPtr ServerControls, IntPtr ClientControls) => Interop.ldap_start_tls(ldapHandle, ref ServerReturnValue, ref Message, ServerControls, ClientControls); + + // openldap doesn't have a ldap_stop_tls function. Returning true as no-op for Linux. + internal static byte StopTls(ConnectionHandle ldapHandle) => 1; + + internal static void FreeValue(IntPtr referral) => Interop.ldap_value_free(referral); + + internal static void FreeAttributes(IntPtr berelement) => Interop.ldap_value_free_len(berelement); + + internal static string PtrToString(IntPtr requestName) => Marshal.PtrToStringAnsi(requestName); + + internal static IntPtr StringToPtr(string s) => Marshal.StringToHGlobalAnsi(s); + } +} diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Windows.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Windows.cs new file mode 100644 index 0000000000000..8a70be9f14e5e --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Windows.cs @@ -0,0 +1,105 @@ +// 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. + +using System.Runtime.InteropServices; + +namespace System.DirectoryServices.Protocols +{ + internal static class LdapPal + { + internal static void CancelDirectoryAsyncOperation(ConnectionHandle ldapHandle, int messagId) => Interop.ldap_abandon(ldapHandle, messagId); + + internal static int AddDirectoryEntry(ConnectionHandle ldapHandle, string dn, IntPtr attrs, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) => + Interop.ldap_add(ldapHandle, dn, attrs, servercontrol, clientcontrol, ref messageNumber); + + internal static int CompareDirectoryEntries(ConnectionHandle ldapHandle, string dn, string attributeName, string strValue, berval binaryValue, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) => + Interop.ldap_compare(ldapHandle, dn, attributeName, strValue, binaryValue, servercontrol, clientcontrol, ref messageNumber); + + internal static void FreeDirectoryControl(IntPtr control) => Interop.ldap_control_free(control); + + internal static void FreeDirectoryControls(IntPtr value) => Interop.ldap_controls_free(value); + + internal static int CreateDirectorySortControl(ConnectionHandle handle, IntPtr keys, byte critical, ref IntPtr control) => Interop.ldap_create_sort_control(handle, keys, critical, ref control); + + internal static int DeleteDirectoryEntry(ConnectionHandle ldapHandle, string dn, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) => Interop.ldap_delete_ext(ldapHandle, dn, servercontrol, clientcontrol, ref messageNumber); + + internal static int ExtendedDirectoryOperation(ConnectionHandle ldapHandle, string oid, berval data, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) => + Interop.ldap_extended_operation(ldapHandle, oid, data, servercontrol, clientcontrol, ref messageNumber); + + internal static IntPtr GetFirstAttributeFromEntry(ConnectionHandle ldapHandle, IntPtr result, ref IntPtr address) => Interop.ldap_first_attribute(ldapHandle, result, ref address); + + internal static IntPtr GetFirstEntryFromResult(ConnectionHandle ldapHandle, IntPtr result) => Interop.ldap_first_entry(ldapHandle, result); + + internal static IntPtr GetFirstReferenceFromResult(ConnectionHandle ldapHandle, IntPtr result) => Interop.ldap_first_reference(ldapHandle, result); + + internal static IntPtr GetDistinguishedName(ConnectionHandle ldapHandle, IntPtr result) => Interop.ldap_get_dn(ldapHandle, result); + + internal static int GetLastErrorFromConnection(ConnectionHandle ldapHandle) => Interop.LdapGetLastError(); + + internal static int GetIntOption(ConnectionHandle ldapHandle, LdapOption option, ref int outValue) => Interop.ldap_get_option_int(ldapHandle, option, ref outValue); + + internal static int GetPtrOption(ConnectionHandle ldapHandle, LdapOption option, ref IntPtr outValue) => Interop.ldap_get_option_ptr(ldapHandle, option, ref outValue); + + internal static int GetSecurityHandleOption(ConnectionHandle ldapHandle, LdapOption option, ref SecurityHandle outValue) => Interop.ldap_get_option_sechandle(ldapHandle, option, ref outValue); + + internal static int GetSecInfoOption(ConnectionHandle ldapHandle, LdapOption option, SecurityPackageContextConnectionInformation outValue) => Interop.ldap_get_option_secInfo(ldapHandle, option, outValue); + + internal static IntPtr GetValuesFromAttribute(ConnectionHandle ldapHandle, IntPtr result, string name) => Interop.ldap_get_values_len(ldapHandle, result, name); + + internal static void FreeMemory(IntPtr outValue) => Interop.ldap_memfree(outValue); + + internal static int ModifyDirectoryEntry(ConnectionHandle ldapHandle, string dn, IntPtr attrs, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) => + Interop.ldap_modify(ldapHandle, dn, attrs, servercontrol, clientcontrol, ref messageNumber); + + internal static IntPtr GetNextAttributeFromResult(ConnectionHandle ldapHandle, IntPtr result, IntPtr address) => Interop.ldap_next_attribute(ldapHandle, result, address); + + internal static IntPtr GetNextEntryFromResult(ConnectionHandle ldapHandle, IntPtr result) => Interop.ldap_next_entry(ldapHandle, result); + + internal static IntPtr GetNextReferenceFromResult(ConnectionHandle ldapHandle, IntPtr result) => Interop.ldap_next_reference(ldapHandle, result); + + internal static int ParseExtendedResult(ConnectionHandle ldapHandle, IntPtr result, ref IntPtr oid, ref IntPtr data, byte freeIt) => Interop.ldap_parse_extended_result(ldapHandle, result, ref oid, ref data, freeIt); + + internal static int ParseReference(ConnectionHandle ldapHandle, IntPtr result, ref IntPtr referrals) => Interop.ldap_parse_reference(ldapHandle, result, ref referrals); + + internal static int ParseResult(ConnectionHandle ldapHandle, IntPtr result, ref int serverError, ref IntPtr dn, ref IntPtr message, ref IntPtr referral, ref IntPtr control, byte freeIt) => + Interop.ldap_parse_result(ldapHandle, result, ref serverError, ref dn, ref message, ref referral, ref control, freeIt); + + internal static int ParseResultReferral(ConnectionHandle ldapHandle, IntPtr result, IntPtr serverError, IntPtr dn, IntPtr message, ref IntPtr referral, IntPtr control, byte freeIt) + => Interop.ldap_parse_result_referral(ldapHandle, result, serverError, dn, message, ref referral, control, freeIt); + + internal static int RenameDirectoryEntry(ConnectionHandle ldapHandle, string dn, string newRdn, string newParentDn, int deleteOldRdn, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber) => + Interop.ldap_rename(ldapHandle, dn, newRdn, newParentDn, deleteOldRdn, servercontrol, clientcontrol, ref messageNumber); + + internal static int GetResultFromAsyncOperation(ConnectionHandle ldapHandle, int messageId, int all, LDAP_TIMEVAL timeout, ref IntPtr Message) => Interop.ldap_result(ldapHandle, messageId, all, timeout, ref Message); + + internal static int ResultToErrorCode(ConnectionHandle ldapHandle, IntPtr result, int freeIt) => Interop.ldap_result2error(ldapHandle, result, freeIt); + + internal static int SearchDirectory(ConnectionHandle ldapHandle, string dn, int scope, string filter, IntPtr attributes, bool attributeOnly, IntPtr servercontrol, IntPtr clientcontrol, int timelimit, int sizelimit, ref int messageNumber) => + Interop.ldap_search(ldapHandle, dn, scope, filter, attributes, attributeOnly, servercontrol, clientcontrol, timelimit, sizelimit, ref messageNumber); + + internal static int SetClientCertOption(ConnectionHandle ldapHandle, LdapOption option, QUERYCLIENTCERT outValue) => Interop.ldap_set_option_clientcert(ldapHandle, option, outValue); + + internal static int SetIntOption(ConnectionHandle ld, LdapOption option, ref int inValue) => Interop.ldap_set_option_int(ld, option, ref inValue); + + internal static int SetPtrOption(ConnectionHandle ldapHandle, LdapOption option, ref IntPtr inValue) => Interop.ldap_set_option_ptr(ldapHandle, option, ref inValue); + + internal static int SetReferralOption(ConnectionHandle ldapHandle, LdapOption option, ref LdapReferralCallback outValue) => Interop.ldap_set_option_referral(ldapHandle, option, ref outValue); + + internal static int SetServerCertOption(ConnectionHandle ldapHandle, LdapOption option, VERIFYSERVERCERT outValue) => Interop.ldap_set_option_servercert(ldapHandle, option, outValue); + + internal static int BindToDirectory(ConnectionHandle ld, string who, string passwd) => Interop.ldap_simple_bind_s(ld, who, passwd); + + internal static int StartTls(ConnectionHandle ldapHandle, ref int ServerReturnValue, ref IntPtr Message, IntPtr ServerControls, IntPtr ClientControls) => Interop.ldap_start_tls(ldapHandle, ref ServerReturnValue, ref Message, ServerControls, ClientControls); + + internal static byte StopTls(ConnectionHandle ldapHandle) => Interop.ldap_stop_tls(ldapHandle); + + internal static void FreeValue(IntPtr referral) => Interop.ldap_value_free(referral); + + internal static void FreeAttributes(IntPtr berelement) => Interop.ldap_value_free_len(berelement); + + internal static string PtrToString(IntPtr requestName) => Marshal.PtrToStringUni(requestName); + + internal static IntPtr StringToPtr(string s) => Marshal.StringToHGlobalUni(s); + } +} diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/SafeHandles.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/SafeHandles.Linux.cs new file mode 100644 index 0000000000000..8478b4b150430 --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/SafeHandles.Linux.cs @@ -0,0 +1,79 @@ +// 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. + +using Microsoft.Win32.SafeHandles; + +namespace System.DirectoryServices.Protocols +{ + internal sealed class ConnectionHandle : SafeHandleZeroOrMinusOneIsInvalid + { + internal bool _needDispose = false; + + internal ConnectionHandle() + :base(true) + { + Interop.ldap_initialize(out handle, null); + _needDispose = true; + } + + internal ConnectionHandle(IntPtr value, bool disposeHandle) : base(true) + { + _needDispose = disposeHandle; + if (value == IntPtr.Zero) + { + throw new LdapException(SR.LDAP_CONNECT_ERROR); + } + else + { + SetHandle(value); + } + } + + protected override bool ReleaseHandle() + { + if (_needDispose) + { + IntPtr nullPointer = IntPtr.Zero; + Interop.ldap_unbind_ext_s(handle, ref nullPointer, ref nullPointer); + } + + handle = IntPtr.Zero; + return true; + } + } + + internal sealed class SafeBerHandle : SafeHandleZeroOrMinusOneIsInvalid + { + internal SafeBerHandle() : base(true) + { + SetHandle(Interop.ber_alloc(1)); + if (handle == IntPtr.Zero) + { + throw new OutOfMemoryException(); + } + } + + internal SafeBerHandle(berval value) : base(true) + { + // In Linux if bv_val is null ber_init will segFault instead of returning IntPtr.Zero. + // In Linux if bv_len is 0 ber_init returns a valid pointer which will then fail when trying to use it, + // so we fail early by throwing exception if this is the case. + if (value.bv_val == IntPtr.Zero || value.bv_len == 0) + { + throw new BerConversionException(); + } + SetHandle(Interop.ber_init(value)); + if (handle == IntPtr.Zero) + { + throw new BerConversionException(); + } + } + + protected override bool ReleaseHandle() + { + Interop.ber_free(handle, 1); + return true; + } + } +} diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/SafeHandles.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/SafeHandles.Windows.cs similarity index 70% rename from src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/SafeHandles.cs rename to src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/SafeHandles.Windows.cs index 50a49660e34ac..26d3b4992b1bb 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/SafeHandles.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/SafeHandles.Windows.cs @@ -3,25 +3,23 @@ // See the LICENSE file in the project root for more information. using Microsoft.Win32.SafeHandles; -using System.Runtime.InteropServices; -using System.Security; namespace System.DirectoryServices.Protocols { - internal sealed class BerSafeHandle : SafeHandleZeroOrMinusOneIsInvalid + internal sealed class SafeBerHandle : SafeHandleZeroOrMinusOneIsInvalid { - internal BerSafeHandle() : base(true) + internal SafeBerHandle() : base(true) { - SetHandle(Wldap32.ber_alloc(1)); + SetHandle(Interop.ber_alloc(1)); if (handle == IntPtr.Zero) { throw new OutOfMemoryException(); } } - internal BerSafeHandle(berval value) : base(true) + internal SafeBerHandle(berval value) : base(true) { - SetHandle(Wldap32.ber_init(value)); + SetHandle(Interop.ber_init(value)); if (handle == IntPtr.Zero) { throw new BerConversionException(); @@ -30,21 +28,7 @@ internal BerSafeHandle(berval value) : base(true) protected override bool ReleaseHandle() { - Wldap32.ber_free(handle, 1); - return true; - } - } - - internal sealed class HGlobalMemHandle : SafeHandleZeroOrMinusOneIsInvalid - { - internal HGlobalMemHandle(IntPtr value) : base(true) - { - SetHandle(value); - } - - protected override bool ReleaseHandle() - { - Marshal.FreeHGlobal(handle); + Interop.ber_free(handle, 1); return true; } } @@ -55,11 +39,11 @@ internal sealed class ConnectionHandle : SafeHandleZeroOrMinusOneIsInvalid internal ConnectionHandle() : base(true) { - SetHandle(Wldap32.ldap_init(null, 389)); + SetHandle(Interop.ldap_init(null, 389)); if (handle == IntPtr.Zero) { - int error = Wldap32.LdapGetLastError(); + int error = Interop.LdapGetLastError(); if (Utility.IsLdapError((LdapError)error)) { string errorMessage = LdapErrorMappings.MapResultCode(error); @@ -77,7 +61,7 @@ internal ConnectionHandle(IntPtr value, bool disposeHandle) : base(true) _needDispose = disposeHandle; if (value == IntPtr.Zero) { - int error = Wldap32.LdapGetLastError(); + int error = Interop.LdapGetLastError(); if (Utility.IsLdapError((LdapError)error)) { string errorMessage = LdapErrorMappings.MapResultCode(error); @@ -99,7 +83,7 @@ protected override bool ReleaseHandle() { if (_needDispose) { - Wldap32.ldap_unbind(handle); + Interop.ldap_unbind(handle); } handle = IntPtr.Zero; diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/SafeHandles.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/SafeHandles.cs new file mode 100644 index 0000000000000..0904f64bb092c --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/SafeHandles.cs @@ -0,0 +1,28 @@ +// 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. + +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +namespace System.DirectoryServices.Protocols +{ + internal sealed class HGlobalMemHandle : SafeHandleZeroOrMinusOneIsInvalid + { + internal static IntPtr _dummyPointer = new IntPtr(1); + + internal HGlobalMemHandle(IntPtr value) : base(true) + { + SetHandle(value); + } + + protected override bool ReleaseHandle() + { + if (handle != _dummyPointer) + { + Marshal.FreeHGlobal(handle); + } + return true; + } + } +} diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.Linux.cs new file mode 100644 index 0000000000000..2d1b8508cecb1 --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.Linux.cs @@ -0,0 +1,28 @@ +// 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. + +using System.Collections; + +namespace System.DirectoryServices.Protocols +{ + public static partial class BerConverter + { + private static unsafe int DecodeBitStringHelper(ArrayList resultList, SafeBerHandle berElement) + { + // Windows doesn't really decode BitStrings correctly, and wldap32 will internally treat it as 'O' Octet string. + // In order to match behavior, in Linux we will interpret 'B' as 'O' when passing the call to libldap. + + int error = 0; + // return berval + byte[] byteArray = DecodingByteArrayHelper(berElement, 'O', ref error); + if (!BerPal.IsBerDecodeError(error)) + { + // add result to the list + resultList.Add(byteArray); + } + + return error; + } + } +} diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.Windows.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.Windows.cs new file mode 100644 index 0000000000000..88e4f250bc30d --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.Windows.cs @@ -0,0 +1,41 @@ +// 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. + +using System.Collections; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace System.DirectoryServices.Protocols +{ + public static partial class BerConverter + { + private static unsafe int DecodeBitStringHelper(ArrayList resultList, SafeBerHandle berElement) + { + int error; + // return a bitstring and its length + IntPtr ptrResult = IntPtr.Zero; + int length = 0; + error = BerPal.ScanNextBitString(berElement, "B", ref ptrResult, ref length); + + if (!BerPal.IsBerDecodeError(error)) + { + byte[] byteArray = null; + if (ptrResult != IntPtr.Zero) + { + byteArray = new byte[length]; + Marshal.Copy(ptrResult, byteArray, 0, length); + } + resultList.Add(byteArray); + } + else + { + Debug.WriteLine("ber_scanf for format character 'B' failed"); + } + + // no need to free memory as wldap32 returns the original pointer instead of a duplicating memory pointer that + // needs to be freed + return error; + } + } +} diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.cs index 65599433b1a7f..dde428136c77e 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/BerConverter.cs @@ -2,15 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections; using System.Diagnostics; -using System.Globalization; using System.Runtime.InteropServices; -using System.Collections; using System.Text; namespace System.DirectoryServices.Protocols { - public static class BerConverter + public static partial class BerConverter { public static byte[] Encode(string format, params object[] value) { @@ -27,7 +26,7 @@ public static byte[] Encode(string format, params object[] value) Debug.WriteLine("Begin encoding\n"); // allocate the berelement - BerSafeHandle berElement = new BerSafeHandle(); + SafeBerHandle berElement = new SafeBerHandle(); int valueCount = 0; int error = 0; @@ -37,7 +36,7 @@ public static byte[] Encode(string format, params object[] value) if (fmt == '{' || fmt == '}' || fmt == '[' || fmt == ']' || fmt == 'n') { // no argument needed - error = Wldap32.ber_printf_emptyarg(berElement, new string(fmt, 1)); + error = BerPal.PrintEmptyArgument(berElement, new string(fmt, 1)); } else if (fmt == 't' || fmt == 'i' || fmt == 'e') { @@ -56,7 +55,7 @@ public static byte[] Encode(string format, params object[] value) } // one int argument - error = Wldap32.ber_printf_int(berElement, new string(fmt, 1), (int)value[valueCount]); + error = BerPal.PrintInt(berElement, new string(fmt, 1), (int)value[valueCount]); // increase the value count valueCount++; @@ -78,7 +77,7 @@ public static byte[] Encode(string format, params object[] value) } // one int argument - error = Wldap32.ber_printf_int(berElement, new string(fmt, 1), (bool)value[valueCount] ? 1 : 0); + error = BerPal.PrintInt(berElement, new string(fmt, 1), (bool)value[valueCount] ? 1 : 0); // increase the value count valueCount++; @@ -220,7 +219,7 @@ public static byte[] Encode(string format, params object[] value) { // can't use SafeBerval here as CLR creates a SafeBerval which points to a different memory location, but when doing memory // deallocation, wldap has special check. So have to use IntPtr directly here. - error = Wldap32.ber_flatten(berElement, ref flattenptr); + error = BerPal.FlattenBerElement(berElement, ref flattenptr); if (error == -1) { @@ -247,7 +246,7 @@ public static byte[] Encode(string format, params object[] value) finally { if (flattenptr != IntPtr.Zero) - Wldap32.ber_bvfree(flattenptr); + BerPal.FreeBerval(flattenptr); } return encodingResult; @@ -273,7 +272,7 @@ internal static object[] TryDecode(string format, byte[] value, out bool decodeS UTF8Encoding utf8Encoder = new UTF8Encoding(false, true); berval berValue = new berval(); ArrayList resultList = new ArrayList(); - BerSafeHandle berElement = null; + SafeBerHandle berElement = null; object[] decodeResult = null; decodeSucceeded = false; @@ -292,7 +291,7 @@ internal static object[] TryDecode(string format, byte[] value, out bool decodeS try { - berElement = new BerSafeHandle(berValue); + berElement = new SafeBerHandle(berValue); } finally { @@ -307,17 +306,17 @@ internal static object[] TryDecode(string format, byte[] value, out bool decodeS char fmt = format[formatCount]; if (fmt == '{' || fmt == '}' || fmt == '[' || fmt == ']' || fmt == 'n' || fmt == 'x') { - error = Wldap32.ber_scanf(berElement, new string(fmt, 1)); + error = BerPal.ScanNext(berElement, new string(fmt, 1)); - if (error != 0) + if (BerPal.IsBerDecodeError(error)) Debug.WriteLine("ber_scanf for {, }, [, ], n or x failed"); } else if (fmt == 'i' || fmt == 'e' || fmt == 'b') { int result = 0; - error = Wldap32.ber_scanf_int(berElement, new string(fmt, 1), ref result); + error = BerPal.ScanNextInt(berElement, new string(fmt, 1), ref result); - if (error == 0) + if (!BerPal.IsBerDecodeError(error)) { if (fmt == 'b') { @@ -341,7 +340,7 @@ internal static object[] TryDecode(string format, byte[] value, out bool decodeS { // return a string byte[] byteArray = DecodingByteArrayHelper(berElement, 'O', ref error); - if (error == 0) + if (!BerPal.IsBerDecodeError(error)) { string s = null; if (byteArray != null) @@ -354,7 +353,7 @@ internal static object[] TryDecode(string format, byte[] value, out bool decodeS { // return berval byte[] byteArray = DecodingByteArrayHelper(berElement, fmt, ref error); - if (error == 0) + if (!BerPal.IsBerDecodeError(error)) { // add result to the list resultList.Add(byteArray); @@ -362,26 +361,7 @@ internal static object[] TryDecode(string format, byte[] value, out bool decodeS } else if (fmt == 'B') { - // return a bitstring and its length - IntPtr ptrResult = IntPtr.Zero; - int length = 0; - error = Wldap32.ber_scanf_bitstring(berElement, "B", ref ptrResult, ref length); - - if (error == 0) - { - byte[] byteArray = null; - if (ptrResult != IntPtr.Zero) - { - byteArray = new byte[length]; - Marshal.Copy(ptrResult, byteArray, 0, length); - } - resultList.Add(byteArray); - } - else - Debug.WriteLine("ber_scanf for format character 'B' failed"); - - // no need to free memory as wldap32 returns the original pointer instead of a duplicating memory pointer that - // needs to be freed + error = DecodeBitStringHelper(resultList, berElement); } else if (fmt == 'v') { @@ -390,7 +370,7 @@ internal static object[] TryDecode(string format, byte[] value, out bool decodeS string[] stringArray = null; byteArrayresult = DecodingMultiByteArrayHelper(berElement, 'V', ref error); - if (error == 0) + if (!BerPal.IsBerDecodeError(error)) { if (byteArrayresult != null) { @@ -416,7 +396,7 @@ internal static object[] TryDecode(string format, byte[] value, out bool decodeS byte[][] result = null; result = DecodingMultiByteArrayHelper(berElement, fmt, ref error); - if (error == 0) + if (!BerPal.IsBerDecodeError(error)) { resultList.Add(result); } @@ -427,7 +407,7 @@ internal static object[] TryDecode(string format, byte[] value, out bool decodeS throw new ArgumentException(SR.BerConverterUndefineChar); } - if (error != 0) + if (BerPal.IsBerDecodeError(error)) { // decode failed, just return return decodeResult; @@ -444,7 +424,7 @@ internal static object[] TryDecode(string format, byte[] value, out bool decodeS return decodeResult; } - private static int EncodingByteArrayHelper(BerSafeHandle berElement, byte[] tempValue, char fmt) + private static int EncodingByteArrayHelper(SafeBerHandle berElement, byte[] tempValue, char fmt) { int error = 0; @@ -454,18 +434,18 @@ private static int EncodingByteArrayHelper(BerSafeHandle berElement, byte[] temp IntPtr tmp = Marshal.AllocHGlobal(tempValue.Length); Marshal.Copy(tempValue, 0, tmp, tempValue.Length); HGlobalMemHandle memHandle = new HGlobalMemHandle(tmp); - - error = Wldap32.ber_printf_bytearray(berElement, new string(fmt, 1), memHandle, tempValue.Length); + error = BerPal.PrintByteArray(berElement, new string(fmt, 1), memHandle, tempValue.Length); } else { - error = Wldap32.ber_printf_bytearray(berElement, new string(fmt, 1), new HGlobalMemHandle(IntPtr.Zero), 0); + HGlobalMemHandle memHandle = new HGlobalMemHandle(HGlobalMemHandle._dummyPointer); + error = BerPal.PrintByteArray(berElement, new string(fmt, 1), memHandle, 0); } return error; } - private static byte[] DecodingByteArrayHelper(BerSafeHandle berElement, char fmt, ref int error) + private static byte[] DecodingByteArrayHelper(SafeBerHandle berElement, char fmt, ref int error) { error = 0; IntPtr result = IntPtr.Zero; @@ -474,11 +454,11 @@ private static byte[] DecodingByteArrayHelper(BerSafeHandle berElement, char fmt // can't use SafeBerval here as CLR creates a SafeBerval which points to a different memory location, but when doing memory // deallocation, wldap has special check. So have to use IntPtr directly here. - error = Wldap32.ber_scanf_ptr(berElement, new string(fmt, 1), ref result); + error = BerPal.ScanNextPtr(berElement, new string(fmt, 1), ref result); try { - if (error == 0) + if (!BerPal.IsBerDecodeError(error)) { if (result != IntPtr.Zero) { @@ -494,17 +474,17 @@ private static byte[] DecodingByteArrayHelper(BerSafeHandle berElement, char fmt finally { if (result != IntPtr.Zero) - Wldap32.ber_bvfree(result); + BerPal.FreeBerval(result); } return byteArray; } - private static int EncodingMultiByteArrayHelper(BerSafeHandle berElement, byte[][] tempValue, char fmt) + private static int EncodingMultiByteArrayHelper(SafeBerHandle berElement, byte[][] tempValue, char fmt) { IntPtr berValArray = IntPtr.Zero; IntPtr tempPtr = IntPtr.Zero; - SafeBerval[] managedBerVal = null; + berval[] managedBervalArray = null; int error = 0; try @@ -513,31 +493,26 @@ private static int EncodingMultiByteArrayHelper(BerSafeHandle berElement, byte[] { int i = 0; berValArray = Utility.AllocHGlobalIntPtrArray(tempValue.Length + 1); - int structSize = Marshal.SizeOf(typeof(SafeBerval)); - managedBerVal = new SafeBerval[tempValue.Length]; + int structSize = Marshal.SizeOf(typeof(berval)); + managedBervalArray = new berval[tempValue.Length]; for (i = 0; i < tempValue.Length; i++) { byte[] byteArray = tempValue[i]; // construct the managed berval - managedBerVal[i] = new SafeBerval(); + managedBervalArray[i] = new berval(); - if (byteArray == null) - { - managedBerVal[i].bv_len = 0; - managedBerVal[i].bv_val = IntPtr.Zero; - } - else + if (byteArray != null) { - managedBerVal[i].bv_len = byteArray.Length; - managedBerVal[i].bv_val = Marshal.AllocHGlobal(byteArray.Length); - Marshal.Copy(byteArray, 0, managedBerVal[i].bv_val, byteArray.Length); + managedBervalArray[i].bv_len = byteArray.Length; + managedBervalArray[i].bv_val = Marshal.AllocHGlobal(byteArray.Length); + Marshal.Copy(byteArray, 0, managedBervalArray[i].bv_val, byteArray.Length); } // allocate memory for the unmanaged structure IntPtr valPtr = Marshal.AllocHGlobal(structSize); - Marshal.StructureToPtr(managedBerVal[i], valPtr, false); + Marshal.StructureToPtr(managedBervalArray[i], valPtr, false); tempPtr = (IntPtr)((long)berValArray + IntPtr.Size * i); Marshal.WriteIntPtr(tempPtr, valPtr); @@ -547,9 +522,7 @@ private static int EncodingMultiByteArrayHelper(BerSafeHandle berElement, byte[] Marshal.WriteIntPtr(tempPtr, IntPtr.Zero); } - error = Wldap32.ber_printf_berarray(berElement, new string(fmt, 1), berValArray); - - GC.KeepAlive(managedBerVal); + error = BerPal.PrintBerArray(berElement, new string(fmt, 1), berValArray); } finally { @@ -563,12 +536,22 @@ private static int EncodingMultiByteArrayHelper(BerSafeHandle berElement, byte[] } Marshal.FreeHGlobal(berValArray); } + if (managedBervalArray != null) + { + foreach (berval managedBerval in managedBervalArray) + { + if (managedBerval.bv_val != IntPtr.Zero) + { + Marshal.FreeHGlobal(managedBerval.bv_val); + } + } + } } return error; } - private static byte[][] DecodingMultiByteArrayHelper(BerSafeHandle berElement, char fmt, ref int error) + private static byte[][] DecodingMultiByteArrayHelper(SafeBerHandle berElement, char fmt, ref int error) { error = 0; // several berval @@ -580,9 +563,9 @@ private static byte[][] DecodingMultiByteArrayHelper(BerSafeHandle berElement, c try { - error = Wldap32.ber_scanf_ptr(berElement, new string(fmt, 1), ref ptrResult); + error = BerPal.ScanNextPtr(berElement, new string(fmt, 1), ref ptrResult); - if (error == 0) + if (!BerPal.IsBerDecodeError(error)) { if (ptrResult != IntPtr.Zero) { @@ -615,7 +598,7 @@ private static byte[][] DecodingMultiByteArrayHelper(BerSafeHandle berElement, c { if (ptrResult != IntPtr.Zero) { - Wldap32.ber_bvecfree(ptrResult); + BerPal.FreeBervalArray(ptrResult); } } diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/DirectoryControl.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/DirectoryControl.cs index 8a9efa373315d..ca22f76d9d0be 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/DirectoryControl.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/common/DirectoryControl.cs @@ -729,7 +729,7 @@ public override byte[] GetValue() Marshal.WriteIntPtr(tempPtr, IntPtr.Zero); bool critical = IsCritical; - int error = Wldap32.ldap_create_sort_control(UtilityHandle.GetHandle(), memHandle, critical ? (byte)1 : (byte)0, ref control); + int error = LdapPal.CreateDirectorySortControl(UtilityHandle.GetHandle(), memHandle, critical ? (byte)1 : (byte)0, ref control); if (error != 0) { @@ -759,7 +759,7 @@ public override byte[] GetValue() { if (control != IntPtr.Zero) { - Wldap32.ldap_control_free(control); + LdapPal.FreeDirectoryControl(control); } if (memHandle != IntPtr.Zero) diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Linux.cs new file mode 100644 index 0000000000000..405d4f9eb2a54 --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Linux.cs @@ -0,0 +1,39 @@ +// 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. + +using System.Diagnostics; +using System.Net; + +namespace System.DirectoryServices.Protocols +{ + public partial class LdapConnection + { + // Linux doesn't support setting FQDN so we mark the flag as if it is already set so we don't make a call to set it again. + private bool _setFQDNDone = true; + + private void InternalInitConnectionHandle(string hostname) => _ldapHandle = new ConnectionHandle(Interop.ldap_init(hostname, ((LdapDirectoryIdentifier)_directoryIdentifier).PortNumber), _needDispose); + + private int InternalConnectToServer() + { + Debug.Assert(!_ldapHandle.IsInvalid); + // In Linux you don't have to call Connect after calling init. You directly call bind. + return 0; + } + + private int InternalBind(NetworkCredential tempCredential, SEC_WINNT_AUTH_IDENTITY_EX cred, BindMethod method) + { + int error; + if (tempCredential == null && AuthType == AuthType.External) + { + error = Interop.ldap_simple_bind(_ldapHandle, null, null); + } + else + { + error = Interop.ldap_simple_bind(_ldapHandle, cred.user, cred.password); + } + + return error; + } + } +} diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Windows.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Windows.cs new file mode 100644 index 0000000000000..6ae5eb96143f6 --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Windows.cs @@ -0,0 +1,43 @@ +// 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. + +using System.Diagnostics; +using System.Net; + +namespace System.DirectoryServices.Protocols +{ + public partial class LdapConnection + { + private bool _setFQDNDone = false; + + private void InternalInitConnectionHandle(string hostname) + { + LdapDirectoryIdentifier directoryIdentifier = _directoryIdentifier as LdapDirectoryIdentifier; + + // User wants to setup a connectionless session with server. + if (directoryIdentifier.Connectionless) + { + _ldapHandle = new ConnectionHandle(Interop.cldap_open(hostname, directoryIdentifier.PortNumber), _needDispose); + } + else + { + _ldapHandle = new ConnectionHandle(Interop.ldap_init(hostname, directoryIdentifier.PortNumber), _needDispose); + } + } + + private int InternalConnectToServer() + { + // Connect explicitly to the server. + var timeout = new LDAP_TIMEVAL() + { + tv_sec = (int)(_connectionTimeOut.Ticks / TimeSpan.TicksPerSecond) + }; + Debug.Assert(!_ldapHandle.IsInvalid); + return Interop.ldap_connect(_ldapHandle, timeout); + } + + private int InternalBind(NetworkCredential tempCredential, SEC_WINNT_AUTH_IDENTITY_EX cred, BindMethod method) + => tempCredential == null && AuthType == AuthType.External ? Interop.ldap_bind_s(_ldapHandle, null, null, method) : Interop.ldap_bind_s(_ldapHandle, null, cred, method); + } +} diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.cs index eef1bd29f8210..c66383e6d8a97 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.cs @@ -12,6 +12,7 @@ using System.Xml; using System.Threading; using System.Security.Cryptography.X509Certificates; +using System.Diagnostics.CodeAnalysis; namespace System.DirectoryServices.Protocols { @@ -20,7 +21,7 @@ namespace System.DirectoryServices.Protocols [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate bool QUERYCLIENTCERT(IntPtr Connection, IntPtr trusted_CAs, ref IntPtr certificateHandle); - public class LdapConnection : DirectoryConnection, IDisposable + public partial class LdapConnection : DirectoryConnection, IDisposable { internal enum LdapResult { @@ -48,7 +49,6 @@ internal enum LdapResult private static readonly LdapPartialResultsProcessor s_partialResultsProcessor = null; private static readonly ManualResetEvent s_waitHandle = null; private static readonly PartialResultsRetriever s_retriever = null; - private bool _setFQDNDone = false; internal bool _needDispose = true; private bool _connected = false; internal QUERYCLIENTCERT _clientCertificateRoutine = null; @@ -216,15 +216,7 @@ internal void Init() } } - // User wants to setup a connectionless session with server. - if (((LdapDirectoryIdentifier)_directoryIdentifier).Connectionless == true) - { - _ldapHandle = new ConnectionHandle(Wldap32.cldap_open(hostname, ((LdapDirectoryIdentifier)_directoryIdentifier).PortNumber), _needDispose); - } - else - { - _ldapHandle = new ConnectionHandle(Wldap32.ldap_init(hostname, ((LdapDirectoryIdentifier)_directoryIdentifier).PortNumber), _needDispose); - } + InternalInitConnectionHandle(hostname); // Create a WeakReference object with the target of ldapHandle and put it into our handle table. lock (s_objectLock) @@ -303,7 +295,7 @@ public DirectoryResponse SendRequest(DirectoryRequest request, TimeSpan requestT if (error == 0) { // Success code but message is -1, unexpected. - error = Wldap32.LdapGetLastError(); + error = LdapPal.GetLastErrorFromConnection(_ldapHandle); } throw ConstructException(error, operation); @@ -406,7 +398,7 @@ public IAsyncResult BeginSendRequest(DirectoryRequest request, TimeSpan requestT if (error == 0) { // Success code but message is -1, unexpected. - error = Wldap32.LdapGetLastError(); + error = LdapPal.GetLastErrorFromConnection(_ldapHandle); } throw ConstructException(error, operation); @@ -476,7 +468,7 @@ public void Abort(IAsyncResult asyncResult) } // Cancel the request. - Wldap32.ldap_abandon(_ldapHandle, messageId); + LdapPal.CancelDirectoryAsyncOperation(_ldapHandle, messageId); LdapRequestState resultObject = result._resultObject; if (resultObject != null) @@ -634,17 +626,18 @@ private int SendRequestHelper(DirectoryRequest request, ref int messageID) if (request is DeleteRequest) { // It is an delete operation. - error = Wldap32.ldap_delete_ext(_ldapHandle, ((DeleteRequest)request).DistinguishedName, serverControlArray, clientControlArray, ref messageID); + error = LdapPal.DeleteDirectoryEntry(_ldapHandle, ((DeleteRequest)request).DistinguishedName, serverControlArray, clientControlArray, ref messageID); } else if (request is ModifyDNRequest) { // It is a modify dn operation - error = Wldap32.ldap_rename(_ldapHandle, - ((ModifyDNRequest)request).DistinguishedName, - ((ModifyDNRequest)request).NewName, - ((ModifyDNRequest)request).NewParentDistinguishedName, - ((ModifyDNRequest)request).DeleteOldRdn ? 1 : 0, - serverControlArray, clientControlArray, ref messageID); + error = LdapPal.RenameDirectoryEntry( + _ldapHandle, + ((ModifyDNRequest)request).DistinguishedName, + ((ModifyDNRequest)request).NewName, + ((ModifyDNRequest)request).NewParentDistinguishedName, + ((ModifyDNRequest)request).DeleteOldRdn ? 1 : 0, + serverControlArray, clientControlArray, ref messageID); } else if (request is CompareRequest compareRequest) { @@ -680,12 +673,13 @@ private int SendRequestHelper(DirectoryRequest request, ref int messageID) } // It is a compare request. - error = Wldap32.ldap_compare(_ldapHandle, - ((CompareRequest)request).DistinguishedName, - assertion.Name, - stringValue, - berValuePtr, - serverControlArray, clientControlArray, ref messageID); + error = LdapPal.CompareDirectoryEntries( + _ldapHandle, + ((CompareRequest)request).DistinguishedName, + assertion.Name, + stringValue, + berValuePtr, + serverControlArray, clientControlArray, ref messageID); } else if (request is AddRequest || request is ModifyRequest) { @@ -715,17 +709,19 @@ private int SendRequestHelper(DirectoryRequest request, ref int messageID) if (request is AddRequest) { - error = Wldap32.ldap_add(_ldapHandle, - ((AddRequest)request).DistinguishedName, - modArray, - serverControlArray, clientControlArray, ref messageID); + error = LdapPal.AddDirectoryEntry( + _ldapHandle, + ((AddRequest)request).DistinguishedName, + modArray, + serverControlArray, clientControlArray, ref messageID); } else { - error = Wldap32.ldap_modify(_ldapHandle, - ((ModifyRequest)request).DistinguishedName, - modArray, - serverControlArray, clientControlArray, ref messageID); + error = LdapPal.ModifyDirectoryEntry( + _ldapHandle, + ((ModifyRequest)request).DistinguishedName, + modArray, + serverControlArray, clientControlArray, ref messageID); } } else if (request is ExtendedRequest extendedRequest) @@ -744,10 +740,11 @@ private int SendRequestHelper(DirectoryRequest request, ref int messageID) Marshal.Copy(val, 0, berValuePtr.bv_val, val.Length); } - error = Wldap32.ldap_extended_operation(_ldapHandle, - name, - berValuePtr, - serverControlArray, clientControlArray, ref messageID); + error = LdapPal.ExtendedDirectoryOperation( + _ldapHandle, + name, + berValuePtr, + serverControlArray, clientControlArray, ref messageID); } else if (request is SearchRequest searchRequest) { @@ -772,7 +769,7 @@ private int SendRequestHelper(DirectoryRequest request, ref int messageID) int i = 0; for (i = 0; i < attributeCount; i++) { - IntPtr controlPtr = Marshal.StringToHGlobalUni(searchRequest.Attributes[i]); + IntPtr controlPtr = LdapPal.StringToPtr(searchRequest.Attributes[i]); tempPtr = (IntPtr)((long)searchAttributes + IntPtr.Size * i); Marshal.WriteIntPtr(tempPtr, controlPtr); } @@ -793,17 +790,18 @@ private int SendRequestHelper(DirectoryRequest request, ref int messageID) try { - error = Wldap32.ldap_search(_ldapHandle, - searchRequest.DistinguishedName, - searchScope, - searchRequestFilter, - searchAttributes, - searchRequest.TypesOnly, - serverControlArray, - clientControlArray, - searchTimeLimit, - searchRequest.SizeLimit, - ref messageID); + error = LdapPal.SearchDirectory( + _ldapHandle, + searchRequest.DistinguishedName, + searchScope, + searchRequestFilter, + searchAttributes, + searchRequest.TypesOnly, + serverControlArray, + clientControlArray, + searchTimeLimit, + searchRequest.SizeLimit, + ref messageID); } finally { @@ -1006,7 +1004,7 @@ private void Connect() // Set the certificate callback routine here if user adds the certifcate to the certificate collection. if (ClientCertificates.Count != 0) { - int certError = Wldap32.ldap_set_option_clientcert(_ldapHandle, LdapOption.LDAP_OPT_CLIENT_CERTIFICATE, _clientCertificateRoutine); + int certError = LdapPal.SetClientCertOption(_ldapHandle, LdapOption.LDAP_OPT_CLIENT_CERTIFICATE, _clientCertificateRoutine); if (certError != (int)ResultCode.Success) { if (Utility.IsLdapError((LdapError)certError)) @@ -1025,19 +1023,13 @@ private void Connect() // Set the LDAP_OPT_AREC_EXCLUSIVE flag if necessary. if (((LdapDirectoryIdentifier)Directory).FullyQualifiedDnsHostName && !_setFQDNDone) { - SessionOptions.FQDN = true; + SessionOptions.SetFqdnRequired(); _setFQDNDone = true; } - // Connect explicitly to the server. - var timeout = new LDAP_TIMEVAL() - { - tv_sec = (int)(_connectionTimeOut.Ticks / TimeSpan.TicksPerSecond) - }; - Debug.Assert(!_ldapHandle.IsInvalid); - int error = Wldap32.ldap_connect(_ldapHandle, timeout); + int error = InternalConnectToServer(); - // Filed, throw an exception. + // Failed, throw an exception. if (error != (int)ResultCode.Success) { if (Utility.IsLdapError((LdapError)error)) @@ -1106,7 +1098,7 @@ private void BindHelper(NetworkCredential newCredential, bool needSetCredential) int error; if (AuthType == AuthType.Anonymous) { - error = Wldap32.ldap_simple_bind_s(_ldapHandle, null, null); + error = LdapPal.BindToDirectory(_ldapHandle, null, null); } else if (AuthType == AuthType.Basic) { @@ -1118,19 +1110,19 @@ private void BindHelper(NetworkCredential newCredential, bool needSetCredential) } tempDomainName.Append(username); - error = Wldap32.ldap_simple_bind_s(_ldapHandle, tempDomainName.ToString(), password); + error = LdapPal.BindToDirectory(_ldapHandle, tempDomainName.ToString(), password); } else { var cred = new SEC_WINNT_AUTH_IDENTITY_EX() { - version = Wldap32.SEC_WINNT_AUTH_IDENTITY_VERSION, + version = Interop.SEC_WINNT_AUTH_IDENTITY_VERSION, length = Marshal.SizeOf(typeof(SEC_WINNT_AUTH_IDENTITY_EX)), - flags = Wldap32.SEC_WINNT_AUTH_IDENTITY_UNICODE + flags = Interop.SEC_WINNT_AUTH_IDENTITY_UNICODE }; if (AuthType == AuthType.Kerberos) { - cred.packageList = Wldap32.MICROSOFT_KERBEROS_NAME_W; + cred.packageList = Interop.MICROSOFT_KERBEROS_NAME_W; cred.packageListLength = cred.packageList.Length; } @@ -1173,14 +1165,7 @@ private void BindHelper(NetworkCredential newCredential, bool needSetCredential) break; } - if (tempCredential == null && AuthType == AuthType.External) - { - error = Wldap32.ldap_bind_s(_ldapHandle, null, null, method); - } - else - { - error = Wldap32.ldap_bind_s(_ldapHandle, null, cred, method); - } + error = InternalBind(tempCredential, cred, method); } // Failed, throw exception. @@ -1275,7 +1260,7 @@ internal LdapControl[] BuildControlArray(DirectoryControlCollection controls, bo managedControls[i] = new LdapControl() { // Get the control type. - ldctl_oid = Marshal.StringToHGlobalUni(((DirectoryControl)controlList[i]).Type), + ldctl_oid = LdapPal.StringToPtr(((DirectoryControl)controlList[i]).Type), // Get the control cricality. ldctl_iscritical = ((DirectoryControl)controlList[i]).IsCritical @@ -1358,7 +1343,7 @@ internal LdapMod[] BuildAttributes(CollectionBase directoryAttributes, ArrayList attributes[i].type |= LDAP_MOD_BVALUES; // Write the attribute name. - attributes[i].attribute = Marshal.StringToHGlobalUni(modAttribute.Name); + attributes[i].attribute = LdapPal.StringToPtr(modAttribute.Name); // Write the values. int valuesCount = 0; @@ -1451,7 +1436,7 @@ internal DirectoryResponse ConstructResponse(int messageId, LdapOperation operat needAbandon = false; } - int error = Wldap32.ldap_result(_ldapHandle, messageId, (int)resultType, timeout, ref ldapResult); + int error = LdapPal.GetResultFromAsyncOperation(_ldapHandle, messageId, (int)resultType, timeout, ref ldapResult); if (error != -1 && error != 0) { // parsing the result @@ -1499,13 +1484,13 @@ internal DirectoryResponse ConstructResponse(int messageId, LdapOperation operat response = new ExtendedResponse(responseDn, responseControl, (ResultCode)resultError, responseMessage, responseReferral); if (resultError == (int)ResultCode.Success) { - resultError = Wldap32.ldap_parse_extended_result(_ldapHandle, ldapResult, ref requestName, ref requestValue, 0 /*not free it*/); + resultError = LdapPal.ParseExtendedResult(_ldapHandle, ldapResult, ref requestName, ref requestValue, 0 /*not free it*/); if (resultError == 0) { string name = null; if (requestName != IntPtr.Zero) { - name = Marshal.PtrToStringUni(requestName); + name = LdapPal.PtrToString(requestName); } berval val = null; @@ -1542,7 +1527,7 @@ internal DirectoryResponse ConstructResponse(int messageId, LdapOperation operat SearchResultReferenceCollection searchResultReferences = new SearchResultReferenceCollection(); // parsing the resultentry - entryMessage = Wldap32.ldap_first_entry(_ldapHandle, ldapResult); + entryMessage = LdapPal.GetFirstEntryFromResult(_ldapHandle, ldapResult); int entrycount = 0; while (entryMessage != IntPtr.Zero) @@ -1554,11 +1539,11 @@ internal DirectoryResponse ConstructResponse(int messageId, LdapOperation operat } entrycount++; - entryMessage = Wldap32.ldap_next_entry(_ldapHandle, entryMessage); + entryMessage = LdapPal.GetNextEntryFromResult(_ldapHandle, entryMessage); } // Parse the reference. - IntPtr referenceMessage = Wldap32.ldap_first_reference(_ldapHandle, ldapResult); + IntPtr referenceMessage = LdapPal.GetFirstReferenceFromResult(_ldapHandle, ldapResult); while (referenceMessage != IntPtr.Zero) { @@ -1568,7 +1553,7 @@ internal DirectoryResponse ConstructResponse(int messageId, LdapOperation operat searchResultReferences.Add(reference); } - referenceMessage = Wldap32.ldap_next_reference(_ldapHandle, referenceMessage); + referenceMessage = LdapPal.GetNextReferenceFromResult(_ldapHandle, referenceMessage); } ((SearchResponse)response).Entries = searchResultEntries; @@ -1601,17 +1586,17 @@ internal DirectoryResponse ConstructResponse(int messageId, LdapOperation operat { if (requestName != IntPtr.Zero) { - Wldap32.ldap_memfree(requestName); + LdapPal.FreeMemory(requestName); } if (requestValue != IntPtr.Zero) { - Wldap32.ldap_memfree(requestValue); + LdapPal.FreeMemory(requestValue); } if (ldapResult != IntPtr.Zero) { - Wldap32.ldap_msgfree(ldapResult); + LdapPal.FreeMemory(ldapResult); } } } @@ -1634,13 +1619,13 @@ internal DirectoryResponse ConstructResponse(int messageId, LdapOperation operat } else { - error = Wldap32.LdapGetLastError(); + error = LdapPal.GetLastErrorFromConnection(_ldapHandle); } // Abandon the request. if (needAbandon) { - Wldap32.ldap_abandon(_ldapHandle, messageId); + LdapPal.CancelDirectoryAsyncOperation(_ldapHandle, messageId); } } @@ -1657,15 +1642,15 @@ internal unsafe int ConstructParsedResult(IntPtr ldapResult, ref int serverError try { - int resultError = Wldap32.ldap_parse_result(_ldapHandle, ldapResult, ref serverError, ref dn, ref message, ref referral, ref control, 0 /* not free it */); + int resultError = LdapPal.ParseResult(_ldapHandle, ldapResult, ref serverError, ref dn, ref message, ref referral, ref control, 0 /* not free it */); if (resultError == 0) { // Parse the dn. - responseDn = Marshal.PtrToStringUni(dn); + responseDn = LdapPal.PtrToString(dn); // Parse the message. - responseMessage = Marshal.PtrToStringUni(message); + responseMessage = LdapPal.PtrToString(message); // Parse the referral. if (referral != IntPtr.Zero) @@ -1676,7 +1661,7 @@ internal unsafe int ConstructParsedResult(IntPtr ldapResult, ref int serverError var referralList = new ArrayList(); while (singleReferral != null) { - string s = Marshal.PtrToStringUni((IntPtr)singleReferral); + string s = LdapPal.PtrToString((IntPtr)singleReferral); referralList.Add(s); i++; @@ -1718,7 +1703,7 @@ internal unsafe int ConstructParsedResult(IntPtr ldapResult, ref int serverError // we need to take care of one special case, when can't connect to the server, ldap_parse_result fails with local error if (resultError == (int)LdapError.LocalError) { - int tmpResult = Wldap32.ldap_result2error(_ldapHandle, ldapResult, 0 /* not free it */); + int tmpResult = LdapPal.ResultToErrorCode(_ldapHandle, ldapResult, 0 /* not free it */); if (tmpResult != 0) { resultError = tmpResult; @@ -1732,22 +1717,22 @@ internal unsafe int ConstructParsedResult(IntPtr ldapResult, ref int serverError { if (dn != IntPtr.Zero) { - Wldap32.ldap_memfree(dn); + LdapPal.FreeMemory(dn); } if (message != IntPtr.Zero) { - Wldap32.ldap_memfree(message); + LdapPal.FreeMemory(message); } if (referral != IntPtr.Zero) { - Wldap32.ldap_value_free(referral); + LdapPal.FreeValue(referral); } if (control != IntPtr.Zero) { - Wldap32.ldap_controls_free(control); + LdapPal.FreeDirectoryControls(control); } } } @@ -1762,11 +1747,11 @@ internal SearchResultEntry ConstructEntry(IntPtr entryMessage) { // Get the dn. string entryDn = null; - dn = Wldap32.ldap_get_dn(_ldapHandle, entryMessage); + dn = LdapPal.GetDistinguishedName(_ldapHandle, entryMessage); if (dn != IntPtr.Zero) { - entryDn = Marshal.PtrToStringUni(dn); - Wldap32.ldap_memfree(dn); + entryDn = LdapPal.PtrToString(dn); + LdapPal.FreeMemory(dn); dn = IntPtr.Zero; } @@ -1774,7 +1759,7 @@ internal SearchResultEntry ConstructEntry(IntPtr entryMessage) SearchResultAttributeCollection attributes = resultEntry.Attributes; // Get attributes. - attribute = Wldap32.ldap_first_attribute(_ldapHandle, entryMessage, ref address); + attribute = LdapPal.GetFirstAttributeFromEntry(_ldapHandle, entryMessage, ref address); int tempcount = 0; while (attribute != IntPtr.Zero) @@ -1782,14 +1767,14 @@ internal SearchResultEntry ConstructEntry(IntPtr entryMessage) DirectoryAttribute attr = ConstructAttribute(entryMessage, attribute); attributes.Add(attr.Name, attr); - Wldap32.ldap_memfree(attribute); + LdapPal.FreeMemory(attribute); tempcount++; - attribute = Wldap32.ldap_next_attribute(_ldapHandle, entryMessage, address); + attribute = LdapPal.GetNextAttributeFromResult(_ldapHandle, entryMessage, address); } if (address != IntPtr.Zero) { - Wldap32.ber_free(address, 0); + BerPal.FreeBerElement(address, 0); address = IntPtr.Zero; } @@ -1799,17 +1784,17 @@ internal SearchResultEntry ConstructEntry(IntPtr entryMessage) { if (dn != IntPtr.Zero) { - Wldap32.ldap_memfree(dn); + LdapPal.FreeMemory(dn); } if (attribute != IntPtr.Zero) { - Wldap32.ldap_memfree(attribute); + LdapPal.FreeMemory(attribute); } if (address != IntPtr.Zero) { - Wldap32.ber_free(address, 0); + BerPal.FreeBerElement(address, 0); } } } @@ -1821,10 +1806,9 @@ internal DirectoryAttribute ConstructAttribute(IntPtr entryMessage, IntPtr attri _isSearchResult = true }; - string name = Marshal.PtrToStringUni(attributeName); + string name = LdapPal.PtrToString(attributeName); attribute.Name = name; - - IntPtr valuesArray = Wldap32.ldap_get_values_len(_ldapHandle, entryMessage, name); + IntPtr valuesArray = LdapPal.GetValuesFromAttribute(_ldapHandle, entryMessage, name); try { if (valuesArray != IntPtr.Zero) @@ -1852,7 +1836,7 @@ internal DirectoryAttribute ConstructAttribute(IntPtr entryMessage, IntPtr attri { if (valuesArray != IntPtr.Zero) { - Wldap32.ldap_value_free_len(valuesArray); + LdapPal.FreeAttributes(valuesArray); } } @@ -1862,8 +1846,7 @@ internal DirectoryAttribute ConstructAttribute(IntPtr entryMessage, IntPtr attri internal SearchResultReference ConstructReference(IntPtr referenceMessage) { IntPtr referenceArray = IntPtr.Zero; - - int error = Wldap32.ldap_parse_reference(_ldapHandle, referenceMessage, ref referenceArray); + int error = LdapPal.ParseReference(_ldapHandle, referenceMessage, ref referenceArray); try { @@ -1877,14 +1860,14 @@ internal SearchResultReference ConstructReference(IntPtr referenceMessage) tempPtr = Marshal.ReadIntPtr(referenceArray, IntPtr.Size * count); while (tempPtr != IntPtr.Zero) { - string s = Marshal.PtrToStringUni(tempPtr); + string s = LdapPal.PtrToString(tempPtr); referralList.Add(s); count++; tempPtr = Marshal.ReadIntPtr(referenceArray, IntPtr.Size * count); } - Wldap32.ldap_value_free(referenceArray); + LdapPal.FreeValue(referenceArray); referenceArray = IntPtr.Zero; } @@ -1904,7 +1887,7 @@ internal SearchResultReference ConstructReference(IntPtr referenceMessage) { if (referenceArray != IntPtr.Zero) { - Wldap32.ldap_value_free(referenceArray); + LdapPal.FreeValue(referenceArray); } } @@ -1973,7 +1956,7 @@ private DirectoryControl ConstructControl(IntPtr controlPtr) Marshal.PtrToStructure(controlPtr, control); Debug.Assert(control.ldctl_oid != IntPtr.Zero); - string controlType = Marshal.PtrToStringUni(control.ldctl_oid); + string controlType = LdapPal.PtrToString(control.ldctl_oid); byte[] bytes = new byte[control.ldctl_value.bv_len]; Marshal.Copy(control.ldctl_value.bv_val, bytes, 0, control.ldctl_value.bv_len); diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapPartialResultsProcessor.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapPartialResultsProcessor.cs index 0477e494f9f2d..3d6b85838ca01 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapPartialResultsProcessor.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapPartialResultsProcessor.cs @@ -214,7 +214,7 @@ private void GetResultsHelper(LdapPartialAsyncResult asyncResult) asyncResult._resultStatus = ResultsStatus.Done; // Need to abandon this request. - Wldap32.ldap_abandon(connection._ldapHandle, asyncResult._messageID); + LdapPal.CancelDirectoryAsyncOperation(connection._ldapHandle, asyncResult._messageID); } } diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Linux.cs new file mode 100644 index 0000000000000..209aa7447abd8 --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Linux.cs @@ -0,0 +1,17 @@ +// 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. + +namespace System.DirectoryServices.Protocols +{ + public partial class LdapSessionOptions + { + private static void PALCertFreeCRLContext(IntPtr certPtr) { /* No op */ } + + public bool SecureSocketLayer + { + get => throw new PlatformNotSupportedException(); + set => throw new PlatformNotSupportedException(); + } + } +} diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Windows.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Windows.cs new file mode 100644 index 0000000000000..e78154995ea79 --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.Windows.cs @@ -0,0 +1,25 @@ +// 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. + +namespace System.DirectoryServices.Protocols +{ + public partial class LdapSessionOptions + { + private static void PALCertFreeCRLContext(IntPtr certPtr) => Interop.CertFreeCRLContext(certPtr); + + public bool SecureSocketLayer + { + get + { + int outValue = GetIntValueHelper(LdapOption.LDAP_OPT_SSL); + return outValue == 1; + } + set + { + int temp = value ? 1 : 0; + SetIntValueHelper(LdapOption.LDAP_OPT_SSL, temp); + } + } + } +} diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.cs index 2ff8d02bc4eb2..e59d8352ab68e 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapSessionOptions.cs @@ -116,7 +116,7 @@ internal struct SecurityHandle public IntPtr Upper; } - public class LdapSessionOptions + public partial class LdapSessionOptions { private readonly LdapConnection _connection = null; private ReferralCallback _callbackRoutine = new ReferralCallback(); @@ -155,20 +155,6 @@ public ReferralChasingOptions ReferralChasing } } - public bool SecureSocketLayer - { - get - { - int outValue = GetIntValueHelper(LdapOption.LDAP_OPT_SSL); - return outValue == 1; - } - set - { - int temp = value ? 1 : 0; - SetIntValueHelper(LdapOption.LDAP_OPT_SSL, temp); - } - } - public int ReferralHopLimit { get => GetIntValueHelper(LdapOption.LDAP_OPT_REFERRAL_HOP_LIMIT); @@ -319,7 +305,7 @@ public SecurityPackageContextConnectionInformation SslInformation } var secInfo = new SecurityPackageContextConnectionInformation(); - int error = Wldap32.ldap_get_option_secInfo(_connection._ldapHandle, LdapOption.LDAP_OPT_SSL_INFO, secInfo); + int error = LdapPal.GetSecInfoOption(_connection._ldapHandle, LdapOption.LDAP_OPT_SSL_INFO, secInfo); ErrorChecking.CheckAndSetLdapError(error); return secInfo; @@ -337,7 +323,7 @@ public object SecurityContext SecurityHandle tempHandle = default; - int error = Wldap32.ldap_get_option_sechandle(_connection._ldapHandle, LdapOption.LDAP_OPT_SECURITY_CONTEXT, ref tempHandle); + int error = LdapPal.GetSecurityHandleOption(_connection._ldapHandle, LdapOption.LDAP_OPT_SECURITY_CONTEXT, ref tempHandle); ErrorChecking.CheckAndSetLdapError(error); return tempHandle; @@ -489,7 +475,7 @@ public QueryClientCertificateCallback QueryClientCertificate if (value != null) { - int certError = Wldap32.ldap_set_option_clientcert(_connection._ldapHandle, LdapOption.LDAP_OPT_CLIENT_CERTIFICATE, _connection._clientCertificateRoutine); + int certError = LdapPal.SetClientCertOption(_connection._ldapHandle, LdapOption.LDAP_OPT_CLIENT_CERTIFICATE, _connection._clientCertificateRoutine); if (certError != (int)ResultCode.Success) { if (Utility.IsLdapError((LdapError)certError)) @@ -531,7 +517,7 @@ public VerifyServerCertificateCallback VerifyServerCertificate if (value != null) { - int error = Wldap32.ldap_set_option_servercert(_connection._ldapHandle, LdapOption.LDAP_OPT_SERVER_CERTIFICATE, _serverCertificateRoutine); + int error = LdapPal.SetServerCertOption(_connection._ldapHandle, LdapOption.LDAP_OPT_SERVER_CERTIFICATE, _serverCertificateRoutine); ErrorChecking.CheckAndSetLdapError(error); } @@ -547,13 +533,9 @@ internal DereferenceAlias DerefAlias set => SetIntValueHelper(LdapOption.LDAP_OPT_DEREF, (int)value); } - internal bool FQDN + internal void SetFqdnRequired() { - set - { - // set the value to true - SetIntValueHelper(LdapOption.LDAP_OPT_AREC_EXCLUSIVE, 1); - } + SetIntValueHelper(LdapOption.LDAP_OPT_AREC_EXCLUSIVE, 1); } public void FastConcurrentBind() @@ -569,7 +551,7 @@ public void FastConcurrentBind() // Do the fast concurrent bind. int inValue = 1; - int error = Wldap32.ldap_set_option_int(_connection._ldapHandle, LdapOption.LDAP_OPT_FAST_CONCURRENT_BIND, ref inValue); + int error = LdapPal.SetIntOption(_connection._ldapHandle, LdapOption.LDAP_OPT_FAST_CONCURRENT_BIND, ref inValue); ErrorChecking.CheckAndSetLdapError(error); } @@ -629,11 +611,11 @@ public unsafe void StartTransportLayerSecurity(DirectoryControlCollection contro Marshal.WriteIntPtr(tempPtr, IntPtr.Zero); } - int error = Wldap32.ldap_start_tls(_connection._ldapHandle, ref serverError, ref ldapResult, serverControlArray, clientControlArray); + int error = LdapPal.StartTls(_connection._ldapHandle, ref serverError, ref ldapResult, serverControlArray, clientControlArray); if (ldapResult != IntPtr.Zero) { // Parse the referral. - int resultError = Wldap32.ldap_parse_result_referral(_connection._ldapHandle, ldapResult, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref referral, IntPtr.Zero, 0 /* not free it */); + int resultError = LdapPal.ParseResultReferral(_connection._ldapHandle, ldapResult, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref referral, IntPtr.Zero, 0 /* not free it */); if (resultError == 0 && referral != IntPtr.Zero) { char** referralPtr = (char**)referral; @@ -642,7 +624,7 @@ public unsafe void StartTransportLayerSecurity(DirectoryControlCollection contro ArrayList referralList = new ArrayList(); while (singleReferral != null) { - string s = Marshal.PtrToStringUni((IntPtr)singleReferral); + string s = LdapPal.PtrToString((IntPtr)singleReferral); referralList.Add(s); i++; @@ -652,7 +634,7 @@ public unsafe void StartTransportLayerSecurity(DirectoryControlCollection contro // Free heap memory. if (referral != IntPtr.Zero) { - Wldap32.ldap_value_free(referral); + LdapPal.FreeValue(referral); referral = IntPtr.Zero; } @@ -759,7 +741,7 @@ public unsafe void StartTransportLayerSecurity(DirectoryControlCollection contro if (referral != IntPtr.Zero) { - Wldap32.ldap_value_free(referral); + LdapPal.FreeValue(referral); } } } @@ -771,7 +753,7 @@ public void StopTransportLayerSecurity() throw new ObjectDisposedException(GetType().Name); } - byte result = Wldap32.ldap_stop_tls(_connection._ldapHandle); + byte result = LdapPal.StopTls(_connection._ldapHandle); if (result == 0) { throw new TlsOperationException(null, SR.TLSStopFailure); @@ -786,7 +768,7 @@ private int GetIntValueHelper(LdapOption option) } int outValue = 0; - int error = Wldap32.ldap_get_option_int(_connection._ldapHandle, option, ref outValue); + int error = LdapPal.GetIntOption(_connection._ldapHandle, option, ref outValue); ErrorChecking.CheckAndSetLdapError(error); return outValue; @@ -800,7 +782,7 @@ private void SetIntValueHelper(LdapOption option, int value) } int temp = value; - int error = Wldap32.ldap_set_option_int(_connection._ldapHandle, option, ref temp); + int error = LdapPal.SetIntOption(_connection._ldapHandle, option, ref temp); ErrorChecking.CheckAndSetLdapError(error); } @@ -813,18 +795,18 @@ private string GetStringValueHelper(LdapOption option, bool releasePtr) } IntPtr outValue = new IntPtr(0); - int error = Wldap32.ldap_get_option_ptr(_connection._ldapHandle, option, ref outValue); + int error = LdapPal.GetPtrOption(_connection._ldapHandle, option, ref outValue); ErrorChecking.CheckAndSetLdapError(error); string stringValue = null; if (outValue != IntPtr.Zero) { - stringValue = Marshal.PtrToStringUni(outValue); + stringValue = LdapPal.PtrToString(outValue); } if (releasePtr) { - Wldap32.ldap_memfree(outValue); + LdapPal.FreeMemory(outValue); } return stringValue; @@ -840,12 +822,12 @@ private void SetStringValueHelper(LdapOption option, string value) IntPtr inValue = IntPtr.Zero; if (value != null) { - inValue = Marshal.StringToHGlobalUni(value); + inValue = LdapPal.StringToPtr(value); } try { - int error = Wldap32.ldap_set_option_ptr(_connection._ldapHandle, option, ref inValue); + int error = LdapPal.SetPtrOption(_connection._ldapHandle, option, ref inValue); ErrorChecking.CheckAndSetLdapError(error); } finally @@ -866,8 +848,7 @@ private void ProcessCallBackRoutine(ReferralCallback tempCallback) notify = tempCallback.NotifyNewConnection == null ? null : _notifiyDelegate, dereference = tempCallback.DereferenceConnection == null ? null : _dereferenceDelegate }; - - int error = Wldap32.ldap_set_option_referral(_connection._ldapHandle, LdapOption.LDAP_OPT_REFERRAL_CALLBACK, ref value); + int error = LdapPal.SetReferralOption(_connection._ldapHandle, LdapOption.LDAP_OPT_REFERRAL_CALLBACK, ref value); ErrorChecking.CheckAndSetLdapError(error); } @@ -884,7 +865,7 @@ private int ProcessQueryConnection(IntPtr PrimaryConnection, IntPtr ReferralFrom { if (NewDNPtr != IntPtr.Zero) { - NewDN = Marshal.PtrToStringUni(NewDNPtr); + NewDN = LdapPal.PtrToString(NewDNPtr); } var target = new StringBuilder(); @@ -951,7 +932,7 @@ private bool ProcessNotifyConnection(IntPtr primaryConnection, IntPtr referralFr string newDN = null; if (newDNPtr != IntPtr.Zero) { - newDN = Marshal.PtrToStringUni(newDNPtr); + newDN = LdapPal.PtrToString(newDNPtr); } var target = new StringBuilder(); @@ -1099,7 +1080,7 @@ private bool ProcessServerCertificate(IntPtr connection, IntPtr serverCert) } finally { - Wldap32.CertFreeCRLContext(certPtr); + PALCertFreeCRLContext(certPtr); } value = _serverCertificateDelegate(_connection, certificate); diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/Wldap32UnsafeMethods.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/Wldap32UnsafeMethods.cs deleted file mode 100644 index 34605a49366b2..0000000000000 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/Wldap32UnsafeMethods.cs +++ /dev/null @@ -1,376 +0,0 @@ -// 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. - -using System.Runtime.InteropServices; -using System.Security; - -namespace System.DirectoryServices.Protocols -{ - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal class Luid - { - private readonly int _lowPart; - private readonly int _highPart; - - public int LowPart => _lowPart; - public int HighPart => _highPart; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal sealed class SEC_WINNT_AUTH_IDENTITY_EX - { - public int version; - public int length; - public string user; - public int userLength; - public string domain; - public int domainLength; - public string password; - public int passwordLength; - public int flags; - public string packageList; - public int packageListLength; - } - - internal enum BindMethod : uint - { - LDAP_AUTH_OTHERKIND = 0x86, - LDAP_AUTH_SICILY = LDAP_AUTH_OTHERKIND | 0x0200, - LDAP_AUTH_MSN = LDAP_AUTH_OTHERKIND | 0x0800, - LDAP_AUTH_NTLM = LDAP_AUTH_OTHERKIND | 0x1000, - LDAP_AUTH_DPA = LDAP_AUTH_OTHERKIND | 0x2000, - LDAP_AUTH_NEGOTIATE = LDAP_AUTH_OTHERKIND | 0x0400, - LDAP_AUTH_SSPI = LDAP_AUTH_NEGOTIATE, - LDAP_AUTH_DIGEST = LDAP_AUTH_OTHERKIND | 0x4000, - LDAP_AUTH_EXTERNAL = LDAP_AUTH_OTHERKIND | 0x0020 - } - - internal enum LdapOption - { - LDAP_OPT_DESC = 0x01, - LDAP_OPT_DEREF = 0x02, - LDAP_OPT_SIZELIMIT = 0x03, - LDAP_OPT_TIMELIMIT = 0x04, - LDAP_OPT_REFERRALS = 0x08, - LDAP_OPT_RESTART = 0x09, - LDAP_OPT_SSL = 0x0a, - LDAP_OPT_REFERRAL_HOP_LIMIT = 0x10, - LDAP_OPT_VERSION = 0x11, - LDAP_OPT_API_FEATURE_INFO = 0x15, - LDAP_OPT_HOST_NAME = 0x30, - LDAP_OPT_ERROR_NUMBER = 0x31, - LDAP_OPT_ERROR_STRING = 0x32, - LDAP_OPT_SERVER_ERROR = 0x33, - LDAP_OPT_SERVER_EXT_ERROR = 0x34, - LDAP_OPT_HOST_REACHABLE = 0x3E, - LDAP_OPT_PING_KEEP_ALIVE = 0x36, - LDAP_OPT_PING_WAIT_TIME = 0x37, - LDAP_OPT_PING_LIMIT = 0x38, - LDAP_OPT_DNSDOMAIN_NAME = 0x3B, - LDAP_OPT_GETDSNAME_FLAGS = 0x3D, - LDAP_OPT_PROMPT_CREDENTIALS = 0x3F, - LDAP_OPT_TCP_KEEPALIVE = 0x40, - LDAP_OPT_FAST_CONCURRENT_BIND = 0x41, - LDAP_OPT_SEND_TIMEOUT = 0x42, - LDAP_OPT_REFERRAL_CALLBACK = 0x70, - LDAP_OPT_CLIENT_CERTIFICATE = 0x80, - LDAP_OPT_SERVER_CERTIFICATE = 0x81, - LDAP_OPT_AUTO_RECONNECT = 0x91, - LDAP_OPT_SSPI_FLAGS = 0x92, - LDAP_OPT_SSL_INFO = 0x93, - LDAP_OPT_SIGN = 0x95, - LDAP_OPT_ENCRYPT = 0x96, - LDAP_OPT_SASL_METHOD = 0x97, - LDAP_OPT_AREC_EXCLUSIVE = 0x98, - LDAP_OPT_SECURITY_CONTEXT = 0x99, - LDAP_OPT_ROOTDSE_CACHE = 0x9a - } - - internal enum ResultAll - { - LDAP_MSG_ALL = 1, - LDAP_MSG_RECEIVED = 2, - LDAP_MSG_POLLINGALL = 3 - } - - [StructLayout(LayoutKind.Sequential)] - internal sealed class LDAP_TIMEVAL - { - public int tv_sec; - public int tv_usec; - } - - [StructLayout(LayoutKind.Sequential)] - internal sealed class berval - { - public int bv_len = 0; - public IntPtr bv_val = IntPtr.Zero; - - public berval() { } - } - - [StructLayout(LayoutKind.Sequential)] - internal sealed class SafeBerval - { - public int bv_len = 0; - public IntPtr bv_val = IntPtr.Zero; - - ~SafeBerval() - { - if (bv_val != IntPtr.Zero) - { - Marshal.FreeHGlobal(bv_val); - } - } - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal sealed class LdapControl - { - public IntPtr ldctl_oid = IntPtr.Zero; - public berval ldctl_value = null; - public bool ldctl_iscritical = false; - - public LdapControl() { } - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct LdapReferralCallback - { - public int sizeofcallback; - public QUERYFORCONNECTIONInternal query; - public NOTIFYOFNEWCONNECTIONInternal notify; - public DEREFERENCECONNECTIONInternal dereference; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct CRYPTOAPI_BLOB - { - public int cbData; - public IntPtr pbData; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct SecPkgContext_IssuerListInfoEx - { - public IntPtr aIssuers; - public int cIssuers; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal sealed class LdapMod - { - public int type = 0; - public IntPtr attribute = IntPtr.Zero; - public IntPtr values = IntPtr.Zero; - - ~LdapMod() - { - if (attribute != IntPtr.Zero) - { - Marshal.FreeHGlobal(attribute); - } - - if (values != IntPtr.Zero) - { - Marshal.FreeHGlobal(values); - } - } - } - - internal class Wldap32 - { - private const string Wldap32dll = "wldap32.dll"; - - public const int SEC_WINNT_AUTH_IDENTITY_UNICODE = 0x2; - public const int SEC_WINNT_AUTH_IDENTITY_VERSION = 0x200; - public const string MICROSOFT_KERBEROS_NAME_W = "Kerberos"; - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_bind_sW", CharSet = CharSet.Unicode)] - public static extern int ldap_bind_s([In]ConnectionHandle ldapHandle, string dn, SEC_WINNT_AUTH_IDENTITY_EX credentials, BindMethod method); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_initW", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern IntPtr ldap_init(string hostName, int portNumber); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, EntryPoint = "ldap_connect", CharSet = CharSet.Unicode)] - public static extern int ldap_connect([In] ConnectionHandle ldapHandle, LDAP_TIMEVAL timeout); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, EntryPoint = "ldap_unbind", CharSet = CharSet.Unicode)] - public static extern int ldap_unbind([In] IntPtr ldapHandle); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_get_optionW", CharSet = CharSet.Unicode)] - public static extern int ldap_get_option_int([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref int outValue); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_set_optionW", CharSet = CharSet.Unicode)] - public static extern int ldap_set_option_int([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref int inValue); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_get_optionW", CharSet = CharSet.Unicode)] - public static extern int ldap_get_option_ptr([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref IntPtr outValue); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_set_optionW", CharSet = CharSet.Unicode)] - public static extern int ldap_set_option_ptr([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref IntPtr inValue); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_get_optionW", CharSet = CharSet.Unicode)] - public static extern int ldap_get_option_sechandle([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref SecurityHandle outValue); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_get_optionW", CharSet = CharSet.Unicode)] - public static extern int ldap_get_option_secInfo([In] ConnectionHandle ldapHandle, [In] LdapOption option, [In, Out] SecurityPackageContextConnectionInformation outValue); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_set_optionW", CharSet = CharSet.Unicode)] - public static extern int ldap_set_option_referral([In] ConnectionHandle ldapHandle, [In] LdapOption option, ref LdapReferralCallback outValue); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_set_optionW", CharSet = CharSet.Unicode)] - public static extern int ldap_set_option_clientcert([In] ConnectionHandle ldapHandle, [In] LdapOption option, QUERYCLIENTCERT outValue); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_set_optionW", CharSet = CharSet.Unicode)] - public static extern int ldap_set_option_servercert([In] ConnectionHandle ldapHandle, [In] LdapOption option, VERIFYSERVERCERT outValue); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "LdapGetLastError")] - public static extern int LdapGetLastError(); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "cldap_openW", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern IntPtr cldap_open(string hostName, int portNumber); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_simple_bind_sW", CharSet = CharSet.Unicode)] - public static extern int ldap_simple_bind_s([In] ConnectionHandle ldapHandle, string distinguishedName, string password); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_delete_extW", CharSet = CharSet.Unicode)] - public static extern int ldap_delete_ext([In] ConnectionHandle ldapHandle, string dn, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_result", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern int ldap_result([In] ConnectionHandle ldapHandle, int messageId, int all, LDAP_TIMEVAL timeout, ref IntPtr Mesage); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_parse_resultW", CharSet = CharSet.Unicode)] - public static extern int ldap_parse_result([In] ConnectionHandle ldapHandle, [In] IntPtr result, ref int serverError, ref IntPtr dn, ref IntPtr message, ref IntPtr referral, ref IntPtr control, byte freeIt); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_parse_resultW", CharSet = CharSet.Unicode)] - public static extern int ldap_parse_result_referral([In] ConnectionHandle ldapHandle, [In] IntPtr result, IntPtr serverError, IntPtr dn, IntPtr message, ref IntPtr referral, IntPtr control, byte freeIt); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_memfreeW", CharSet = CharSet.Unicode)] - public static extern void ldap_memfree([In] IntPtr value); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_value_freeW", CharSet = CharSet.Unicode)] - public static extern int ldap_value_free([In] IntPtr value); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_controls_freeW", CharSet = CharSet.Unicode)] - public static extern int ldap_controls_free([In] IntPtr value); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_abandon", CharSet = CharSet.Unicode)] - public static extern int ldap_abandon([In] ConnectionHandle ldapHandle, [In] int messagId); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_start_tls_sW", CharSet = CharSet.Unicode)] - public static extern int ldap_start_tls(ConnectionHandle ldapHandle, ref int ServerReturnValue, ref IntPtr Message, IntPtr ServerControls, IntPtr ClientControls); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_stop_tls_s", CharSet = CharSet.Unicode)] - public static extern byte ldap_stop_tls(ConnectionHandle ldapHandle); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_rename_extW", CharSet = CharSet.Unicode)] - public static extern int ldap_rename([In] ConnectionHandle ldapHandle, string dn, string newRdn, string newParentDn, int deleteOldRdn, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_compare_extW", CharSet = CharSet.Unicode)] - public static extern int ldap_compare([In] ConnectionHandle ldapHandle, string dn, string attributeName, string strValue, berval binaryValue, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_add_extW", CharSet = CharSet.Unicode)] - public static extern int ldap_add([In] ConnectionHandle ldapHandle, string dn, IntPtr attrs, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_modify_extW", CharSet = CharSet.Unicode)] - public static extern int ldap_modify([In] ConnectionHandle ldapHandle, string dn, IntPtr attrs, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_extended_operationW", CharSet = CharSet.Unicode)] - public static extern int ldap_extended_operation([In] ConnectionHandle ldapHandle, string oid, berval data, IntPtr servercontrol, IntPtr clientcontrol, ref int messageNumber); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_parse_extended_resultW", CharSet = CharSet.Unicode)] - public static extern int ldap_parse_extended_result([In] ConnectionHandle ldapHandle, [In] IntPtr result, ref IntPtr oid, ref IntPtr data, byte freeIt); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_msgfree", CharSet = CharSet.Unicode)] - public static extern int ldap_msgfree([In] IntPtr result); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_search_extW", CharSet = CharSet.Unicode)] - public static extern int ldap_search([In] ConnectionHandle ldapHandle, string dn, int scope, string filter, IntPtr attributes, bool attributeOnly, IntPtr servercontrol, IntPtr clientcontrol, int timelimit, int sizelimit, ref int messageNumber); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_first_entry", CharSet = CharSet.Unicode)] - public static extern IntPtr ldap_first_entry([In] ConnectionHandle ldapHandle, [In] IntPtr result); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_next_entry", CharSet = CharSet.Unicode)] - public static extern IntPtr ldap_next_entry([In] ConnectionHandle ldapHandle, [In] IntPtr result); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_first_reference", CharSet = CharSet.Unicode)] - public static extern IntPtr ldap_first_reference([In] ConnectionHandle ldapHandle, [In] IntPtr result); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_next_reference", CharSet = CharSet.Unicode)] - public static extern IntPtr ldap_next_reference([In] ConnectionHandle ldapHandle, [In] IntPtr result); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_get_dnW", CharSet = CharSet.Unicode)] - public static extern IntPtr ldap_get_dn([In] ConnectionHandle ldapHandle, [In] IntPtr result); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_first_attributeW", CharSet = CharSet.Unicode)] - public static extern IntPtr ldap_first_attribute([In] ConnectionHandle ldapHandle, [In] IntPtr result, ref IntPtr address); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_next_attributeW", CharSet = CharSet.Unicode)] - public static extern IntPtr ldap_next_attribute([In] ConnectionHandle ldapHandle, [In] IntPtr result, [In, Out] IntPtr address); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_free", CharSet = CharSet.Unicode)] - public static extern IntPtr ber_free([In] IntPtr berelement, int option); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_get_values_lenW", CharSet = CharSet.Unicode)] - public static extern IntPtr ldap_get_values_len([In] ConnectionHandle ldapHandle, [In] IntPtr result, string name); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_value_free_len", CharSet = CharSet.Unicode)] - public static extern IntPtr ldap_value_free_len([In] IntPtr berelement); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_parse_referenceW", CharSet = CharSet.Unicode)] - public static extern int ldap_parse_reference([In] ConnectionHandle ldapHandle, [In] IntPtr result, ref IntPtr referrals); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_alloc_t", CharSet = CharSet.Unicode)] - public static extern IntPtr ber_alloc(int option); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_printf", CharSet = CharSet.Unicode)] - public static extern int ber_printf_emptyarg(BerSafeHandle berElement, string format); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_printf", CharSet = CharSet.Unicode)] - public static extern int ber_printf_int(BerSafeHandle berElement, string format, int value); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_printf", CharSet = CharSet.Unicode)] - public static extern int ber_printf_bytearray(BerSafeHandle berElement, string format, HGlobalMemHandle value, int length); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_printf", CharSet = CharSet.Unicode)] - public static extern int ber_printf_berarray(BerSafeHandle berElement, string format, IntPtr value); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_flatten", CharSet = CharSet.Unicode)] - public static extern int ber_flatten(BerSafeHandle berElement, ref IntPtr value); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_init", CharSet = CharSet.Unicode)] - public static extern IntPtr ber_init(berval value); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_scanf", CharSet = CharSet.Unicode)] - public static extern int ber_scanf(BerSafeHandle berElement, string format); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_scanf", CharSet = CharSet.Unicode)] - public static extern int ber_scanf_int(BerSafeHandle berElement, string format, ref int value); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_scanf", CharSet = CharSet.Unicode)] - public static extern int ber_scanf_ptr(BerSafeHandle berElement, string format, ref IntPtr value); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_scanf", CharSet = CharSet.Unicode)] - public static extern int ber_scanf_bitstring(BerSafeHandle berElement, string format, ref IntPtr value, ref int length); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_bvfree", CharSet = CharSet.Unicode)] - public static extern int ber_bvfree(IntPtr value); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ber_bvecfree", CharSet = CharSet.Unicode)] - public static extern int ber_bvecfree(IntPtr value); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_create_sort_controlW", CharSet = CharSet.Unicode)] - public static extern int ldap_create_sort_control(ConnectionHandle handle, IntPtr keys, byte critical, ref IntPtr control); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_control_freeW", CharSet = CharSet.Unicode)] - public static extern int ldap_control_free(IntPtr control); - - [DllImport("Crypt32.dll", EntryPoint = "CertFreeCRLContext", CharSet = CharSet.Unicode)] - public static extern int CertFreeCRLContext(IntPtr certContext); - - [DllImport(Wldap32dll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ldap_result2error", CharSet = CharSet.Unicode)] - public static extern int ldap_result2error([In] ConnectionHandle ldapHandle, [In] IntPtr result, int freeIt); - } -} diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/AsqRequestControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/AsqRequestControlTests.cs index 4c4f335a7933f..97c70bf4c081c 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/AsqRequestControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/AsqRequestControlTests.cs @@ -2,10 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; +using System.Runtime.InteropServices; using Xunit; namespace System.DirectoryServices.Protocols.Tests { + [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] public class AsqRequestControlTests { [Fact] @@ -17,13 +20,29 @@ public void Ctor_Default() Assert.True(control.ServerSide); Assert.Equal("1.2.840.113556.1.4.1504", control.Type); - Assert.Equal(new byte[] { 48, 132, 0, 0, 0, 2, 4, 0 }, control.GetValue()); + var expected = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 2, 4, 0 } : new byte[] { 48, 2, 4, 0 }; + + Assert.Equal(expected, control.GetValue()); + } + + public static IEnumerable Ctor_String_Test_data() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + yield return new object[] { null, new byte[] { 48, 132, 0, 0, 0, 2, 4, 0 } }; + yield return new object[] { "", new byte[] { 48, 132, 0, 0, 0, 2, 4, 0 } }; + yield return new object[] { "A", new byte[] { 48, 132, 0, 0, 0, 3, 4, 1, 65 } }; + } + else + { + yield return new object[] { null, new byte[] { 48, 2, 4, 0 } }; + yield return new object[] { "", new byte[] { 48, 2, 4, 0 } }; + yield return new object[] { "A", new byte[] { 48, 3, 4, 1, 65 } }; + } } [Theory] - [InlineData(null, new byte[] { 48, 132, 0, 0, 0, 2, 4, 0 })] - [InlineData("", new byte[] { 48, 132, 0, 0, 0, 2, 4, 0 })] - [InlineData("A", new byte[] { 48, 132, 0, 0, 0, 3, 4, 1, 65 })] + [MemberData(nameof(Ctor_String_Test_data))] public void Ctor_String(string attributeName, byte[] expectedValue) { var control = new AsqRequestControl(attributeName); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs index 54f85a9e9783a..a6b301da3829c 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs @@ -3,10 +3,12 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Runtime.InteropServices; using Xunit; namespace System.DirectoryServices.Protocols.Tests { + [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] public class BerConverterTests { public static IEnumerable Encode_TestData() @@ -15,22 +17,28 @@ public static IEnumerable Encode_TestData() yield return new object[] { "", new object[10], new byte[0] }; yield return new object[] { "b", new object[] { true, false, true, false }, new byte[] { 1, 1, 255 } }; - yield return new object[] { "{", new object[] { "a" }, new byte[] { 48, 0, 0, 0, 0, 0 } }; - yield return new object[] { "{}", new object[] { "a" }, new byte[] { 48, 132, 0, 0, 0, 0 } }; - yield return new object[] { "[", new object[] { "a" }, new byte[] { 49, 0, 0, 0, 0, 0 } }; - yield return new object[] { "[]", new object[] { "a" }, new byte[] { 49, 132, 0, 0, 0, 0 } }; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + yield return new object[] { "{", new object[] { "a" }, new byte[] { 48, 0, 0, 0, 0, 0 } }; // This format is not supported by Linux OpenLDAP + } + yield return new object[] { "{}", new object[] { "a" }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 0 } : new byte[] { 48, 0 } }; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + yield return new object[] { "[", new object[] { "a" }, new byte[] { 49, 0, 0, 0, 0, 0 } }; // This format is not supported by Linux OpenLDAP + } + yield return new object[] { "[]", new object[] { "a" }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 49, 132, 0, 0, 0, 0 } : new byte[] { 49, 0 } }; yield return new object[] { "n", new object[] { "a" }, new byte[] { 5, 0 } }; - yield return new object[] { "tetie", new object[] { -1, 0, 1, 2, 3 }, new byte[] { 255, 1, 0, 1, 1, 2, 10, 1, 3 } }; - yield return new object[] { "{tetie}", new object[] { -1, 0, 1, 2, 3 }, new byte[] { 48, 132, 0, 0, 0, 9, 255, 1, 0, 1, 1, 2, 10, 1, 3 } }; + yield return new object[] { "tetie", new object[] { -1, 0, 1, 2, 3 }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 255, 1, 0, 1, 1, 2, 10, 1, 3 } : new byte[] { 10, 1, 0, 1, 1, 2, 10, 1, 3 } }; + yield return new object[] { "{tetie}", new object[] { -1, 0, 1, 2, 3 }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 9, 255, 1, 0, 1, 1, 2, 10, 1, 3 } : new byte[] { 48, 9, 10, 1, 0, 1, 1, 2, 10, 1, 3 } }; yield return new object[] { "bb", new object[] { true, false }, new byte[] { 1, 1, 255, 1, 1, 0 } }; - yield return new object[] { "{bb}", new object[] { true, false }, new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 } }; + yield return new object[] { "{bb}", new object[] { true, false }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 } : new byte[] { 48, 6, 1, 1, 255, 1, 1, 0 } }; yield return new object[] { "ssss", new object[] { null, "", "abc", "\0" }, new byte[] { 4, 0, 4, 0, 4, 3, 97, 98, 99, 4, 1, 0 } }; - yield return new object[] { "oXo", new object[] { null, new byte[] { 0, 1, 2, 255 }, new byte[0] }, new byte[] { 4, 0, 3, 4, 0, 1, 2, 255, 4, 0 } }; + yield return new object[] { "oXo", new object[] { null, new byte[] { 0, 1, 2, 255 }, new byte[0] }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 4, 0, 3, 4, 0, 1, 2, 255, 4, 0 } : new byte[] { 4, 0, 3, 2, 4, 0, 4, 0 } }; yield return new object[] { "vv", new object[] { null, new string[] { "abc", "", null } }, new byte[] { 4, 3, 97, 98, 99, 4, 0, 4, 0 } }; - yield return new object[] { "{vv}", new object[] { null, new string[] { "abc", "", null } }, new byte[] { 48, 132, 0, 0, 0, 9, 4, 3, 97, 98, 99, 4, 0, 4, 0 } }; + yield return new object[] { "{vv}", new object[] { null, new string[] { "abc", "", null } }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 9, 4, 3, 97, 98, 99, 4, 0, 4, 0 } : new byte[] { 48, 9, 4, 3, 97, 98, 99, 4, 0, 4, 0 } }; yield return new object[] { "VVVV", new object[] { null, new byte[][] { new byte[] { 0, 1, 2, 3 }, null }, new byte[][] { new byte[0] }, new byte[0][] }, new byte[] { 4, 4, 0, 1, 2, 3, 4, 0, 4, 0 } }; } @@ -112,10 +120,13 @@ public static IEnumerable Decode_TestData() yield return new object[] { "{bb}", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 }, new object[] { true, false } }; yield return new object[] { "{OO}", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 }, new object[] { new byte[] { 255 }, new byte[] { 0 } } }; yield return new object[] { "{BB}", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 }, new object[] { new byte[] { 255 }, new byte[] { 0 } } }; - yield return new object[] { "{vv}", new byte[] { 48, 132, 0, 0, 0, 9, 4, 3, 97, 98, 99, 4, 0, 4, 0 }, new object[] { null, null } }; - yield return new object[] { "{vv}", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 }, new object[] { new string[] { "\x01" }, null } }; - yield return new object[] { "{VV}", new byte[] { 48, 132, 0, 0, 0, 9, 4, 3, 97, 98, 99, 4, 0, 4, 0 }, new object[] { null, null } }; - yield return new object[] { "{VV}", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 }, new object[] { new byte[][] { new byte[] { 1 } }, null } }; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // vv and VV formats are not supported yet in Linux + { + yield return new object[] { "{vv}", new byte[] { 48, 132, 0, 0, 0, 9, 4, 3, 97, 98, 99, 4, 0, 4, 0 }, new object[] { null, null } }; + yield return new object[] { "{vv}", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 }, new object[] { new string[] { "\x01" }, null } }; + yield return new object[] { "{VV}", new byte[] { 48, 132, 0, 0, 0, 9, 4, 3, 97, 98, 99, 4, 0, 4, 0 }, new object[] { null, null } }; + yield return new object[] { "{VV}", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 }, new object[] { new byte[][] { new byte[] { 1 } }, null } }; + } } [Theory] @@ -139,18 +150,29 @@ public void UnknownFormat_ThrowsArgumentException(string format, byte[] values) AssertExtensions.Throws(null, () => BerConverter.Decode(format, values)); } + public static IEnumerable Decode_Invalid_ThrowsBerConversionException_Data() + { + yield return new object[] { "n", null }; + yield return new object[] { "n", new byte[0] }; + yield return new object[] { "{", new byte[] { 1 } }; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + yield return new object[] { "}", new byte[] { 1 } }; // This is considered a valid case in Linux + } + yield return new object[] { "{}{}{}{}{}{}{}", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 } }; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + yield return new object[] { "aaa", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 } }; + } + yield return new object[] { "iii", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 } }; + yield return new object[] { "eee", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 } }; + yield return new object[] { "bbb", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 } }; + yield return new object[] { "OOO", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 } }; + yield return new object[] { "BBB", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 } }; + } + [Theory] - [InlineData("n", null)] - [InlineData("n", new byte[0])] - [InlineData("{", new byte[] { 1 })] - [InlineData("}", new byte[] { 1 })] - [InlineData("{}{}{}{}{}{}{}", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 })] - [InlineData("aaa", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 })] - [InlineData("iii", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 })] - [InlineData("eee", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 })] - [InlineData("bbb", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 })] - [InlineData("OOO", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 })] - [InlineData("BBB", new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 })] + [MemberData(nameof(Decode_Invalid_ThrowsBerConversionException_Data))] public void Decode_Invalid_ThrowsBerConversionException(string format, byte[] values) { Assert.Throws(() => BerConverter.Decode(format, values)); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/DirSyncRequestControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/DirSyncRequestControlTests.cs index 09f212987f652..8a494282e67f1 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/DirSyncRequestControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/DirSyncRequestControlTests.cs @@ -2,10 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; +using System.Runtime.InteropServices; using Xunit; namespace System.DirectoryServices.Protocols.Tests { + [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] public class DirSyncRequestControlTests { [Fact] @@ -20,13 +23,19 @@ public void Ctor_Default() Assert.True(control.ServerSide); Assert.Equal("1.2.840.113556.1.4.841", control.Type); - Assert.Equal(new byte[] { 48, 132, 0, 0, 0, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 }, control.GetValue()); + var expected = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 } : new byte[] { 48, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 }; + Assert.Equal(expected, control.GetValue()); + } + + public static IEnumerable Ctor_Cookie_Data() + { + yield return new object[] { null, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 } : new byte[] { 48, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 } }; + yield return new object[] { new byte[0], (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 } : new byte[] { 48, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 } }; + yield return new object[] { new byte[] { 97, 98, 99 }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 13, 2, 1, 0, 2, 3, 16, 0, 0, 4, 3, 97, 98, 99 } : new byte[] { 48, 13, 2, 1, 0, 2, 3, 16, 0, 0, 4, 3, 97, 98, 99 } }; } [Theory] - [InlineData(null, new byte[] { 48, 132, 0, 0, 0, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 })] - [InlineData(new byte[0], new byte[] { 48, 132, 0, 0, 0, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 })] - [InlineData(new byte[] { 97, 98, 99 }, new byte[] { 48, 132, 0, 0, 0, 13, 2, 1, 0, 2, 3, 16, 0, 0, 4, 3, 97, 98, 99 })] + [MemberData(nameof(Ctor_Cookie_Data))] public void Ctor_Cookie(byte[] cookie, byte[] expectedValue) { var control = new DirSyncRequestControl(cookie); @@ -41,10 +50,15 @@ public void Ctor_Cookie(byte[] cookie, byte[] expectedValue) Assert.Equal(expectedValue, control.GetValue()); } + public static IEnumerable Ctor_Cookie_Options_Data() + { + yield return new object[] { null, DirectorySynchronizationOptions.None, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 } : new byte[] { 48, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 } }; + yield return new object[] { new byte[0], DirectorySynchronizationOptions.None - 1, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 13, 2, 4, 255, 255, 255, 255, 2, 3, 16, 0, 0, 4, 0 } : new byte[] { 48, 10, 2, 1, 255, 2, 3, 16, 0, 0, 4, 0 } }; + yield return new object[] { new byte[] { 97, 98, 99 }, DirectorySynchronizationOptions.ObjectSecurity, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 13, 2, 1, 1, 2, 3, 16, 0, 0, 4, 3, 97, 98, 99 } : new byte[] { 48, 13, 2, 1, 1, 2, 3, 16, 0, 0, 4, 3, 97, 98, 99 } }; + } + [Theory] - [InlineData(null, DirectorySynchronizationOptions.None, new byte[] { 48, 132, 0, 0, 0, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 })] - [InlineData(new byte[0], DirectorySynchronizationOptions.None - 1, new byte[] { 48, 132, 0, 0, 0, 13, 2, 4, 255, 255, 255, 255, 2, 3, 16, 0, 0, 4, 0 })] - [InlineData(new byte[] { 97, 98, 99 }, DirectorySynchronizationOptions.ObjectSecurity, new byte[] { 48, 132, 0, 0, 0, 13, 2, 1, 1, 2, 3, 16, 0, 0, 4, 3, 97, 98, 99 })] + [MemberData(nameof(Ctor_Cookie_Options_Data))] public void Ctor_Cookie_Options(byte[] cookie, DirectorySynchronizationOptions option, byte[] expectedValue) { var control = new DirSyncRequestControl(cookie, option); @@ -59,10 +73,15 @@ public void Ctor_Cookie_Options(byte[] cookie, DirectorySynchronizationOptions o Assert.Equal(expectedValue, control.GetValue()); } + public static IEnumerable Ctor_Cookie_Options_AttributeCount_Data() + { + yield return new object[] { null, DirectorySynchronizationOptions.None, 1048576, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 } : new byte[] { 48, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 } }; + yield return new object[] { new byte[0], DirectorySynchronizationOptions.None - 1, 0, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 11, 2, 4, 255, 255, 255, 255, 2, 1, 0, 4, 0 } : new byte[] { 48, 8, 2, 1, 255, 2, 1, 0, 4, 0 } }; + yield return new object[] { new byte[] { 97, 98, 99 }, DirectorySynchronizationOptions.ObjectSecurity, 10, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 11, 2, 1, 1, 2, 1, 10, 4, 3, 97, 98, 99 } : new byte[] { 48, 11, 2, 1, 1, 2, 1, 10, 4, 3, 97, 98, 99 } }; + } + [Theory] - [InlineData(null, DirectorySynchronizationOptions.None, 1048576, new byte[] { 48, 132, 0, 0, 0, 10, 2, 1, 0, 2, 3, 16, 0, 0, 4, 0 })] - [InlineData(new byte[0], DirectorySynchronizationOptions.None - 1, 0, new byte[] { 48, 132, 0, 0, 0, 11, 2, 4, 255, 255, 255, 255, 2, 1, 0, 4, 0 })] - [InlineData(new byte[] { 97, 98, 99 }, DirectorySynchronizationOptions.ObjectSecurity, 10, new byte[] { 48, 132, 0, 0, 0, 11, 2, 1, 1, 2, 1, 10, 4, 3, 97, 98, 99 })] + [MemberData(nameof(Ctor_Cookie_Options_AttributeCount_Data))] public void Ctor_Cookie_Options_AttributeCount(byte[] cookie, DirectorySynchronizationOptions option, int attributeCount , byte[] expectedValue) { var control = new DirSyncRequestControl(cookie, option, attributeCount); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesProtocolsTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesProtocolsTests.cs index f520df26b2b4d..af065dfd6a393 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesProtocolsTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesProtocolsTests.cs @@ -2,17 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Runtime.InteropServices; -using System.Collections.Generic; -using System.Collections; +using System.DirectoryServices.Tests; using System.Globalization; using System.Net; using Xunit; -using System.Threading; -using System.DirectoryServices.Tests; -using System.DirectoryServices.Protocols; -namespace System.DirectoryServicesProtocols.Tests +namespace System.DirectoryServices.Protocols.Tests { public partial class DirectoryServicesProtocolsTests { diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesTestHelpers.cs b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesTestHelpers.cs new file mode 100644 index 0000000000000..80ac7ec9c6084 --- /dev/null +++ b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesTestHelpers.cs @@ -0,0 +1,49 @@ +// 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. + +using System.Runtime.InteropServices; +using Xunit; + +[assembly: ActiveIssue("https://github.com/dotnet/runtime/issues/35912", TestRuntimes.Mono)] + +namespace System.DirectoryServices.Protocols.Tests +{ + public static class DirectoryServicesTestHelpers + { + public static bool IsWindowsOrLibLdapIsInstalled => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || IsLibLdapInstalled; + + // Cache the check once we have performed it once + private static bool? _isLibLdapInstalled = null; + + public static bool IsLibLdapInstalled + { + get + { + if (!_isLibLdapInstalled.HasValue) + { + try + { + // Attempt PInvoking into libldap + IntPtr handle = ber_alloc(1); + ber_free(handle, 1); + _isLibLdapInstalled = true; + } + catch (Exception) + { + _isLibLdapInstalled = false; + } + } + return _isLibLdapInstalled.Value; + } + } + + internal const string OpenLdap = "libldap-2.4.so.2"; + + [DllImport(OpenLdap, EntryPoint = "ber_alloc_t", CharSet = CharSet.Ansi)] + internal static extern IntPtr ber_alloc(int option); + + [DllImport(OpenLdap, EntryPoint = "ber_free", CharSet = CharSet.Ansi)] + public static extern IntPtr ber_free([In] IntPtr berelement, int option); + } +} diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/ExtendedDNControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/ExtendedDNControlTests.cs index 7a759afeb07ba..ade556afd0d9f 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/ExtendedDNControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/ExtendedDNControlTests.cs @@ -3,10 +3,12 @@ // See the LICENSE file in the project root for more information. using System.ComponentModel; +using System.Runtime.InteropServices; using Xunit; namespace System.DirectoryServices.Protocols.Tests { + [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] public class ExtendedDNControlTests { [Fact] @@ -18,7 +20,8 @@ public void Ctor_Default() Assert.True(control.ServerSide); Assert.Equal("1.2.840.113556.1.4.529", control.Type); - Assert.Equal(new byte[] { 48, 132, 0, 0, 0, 3, 2, 1, 0 }, control.GetValue()); + var expected = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 3, 2, 1, 0 } : new byte[] { 48, 3, 2, 1, 0 }; + Assert.Equal(expected, control.GetValue()); } [Fact] @@ -30,7 +33,8 @@ public void Ctor_Flag() Assert.True(control.ServerSide); Assert.Equal("1.2.840.113556.1.4.529", control.Type); - Assert.Equal(new byte[] { 48, 132, 0, 0, 0, 3, 2, 1, 1 }, control.GetValue()); + var expected = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 3, 2, 1, 1 } : new byte[] { 48, 3, 2, 1, 1 }; + Assert.Equal(expected, control.GetValue()); } [Theory] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/LdapConnectionTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/LdapConnectionTests.cs index ee262ec1a03c1..c8b8fb0a5be95 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/LdapConnectionTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/LdapConnectionTests.cs @@ -5,13 +5,12 @@ using System.Collections.Generic; using System.ComponentModel; using System.Net; -using System.Net.Sockets; using System.Threading; -using System.Threading.Tasks; using Xunit; namespace System.DirectoryServices.Protocols.Tests { + [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] public class LdapConnectionTests { [Theory] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/LdapSessionOptionsTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/LdapSessionOptionsTests.cs index f8ea1cceea2e4..30abf231c1942 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/LdapSessionOptionsTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/LdapSessionOptionsTests.cs @@ -8,9 +8,11 @@ namespace System.DirectoryServices.Protocols.Tests { + [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] public class LdapSessionOptionsTests { [Theory] + [PlatformSpecific(TestPlatforms.Windows)] [InlineData(ReferralChasingOptions.None)] [InlineData(ReferralChasingOptions.External)] public void ReferralChasing_Set_GetReturnsExpected(ReferralChasingOptions value) @@ -47,6 +49,7 @@ public void ReferralChasing_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Theory] + [PlatformSpecific(TestPlatforms.Windows)] [InlineData(true)] [InlineData(false)] public void SecureSocketLayer_Set_GetReturnsExpected(bool value) @@ -62,6 +65,7 @@ public void SecureSocketLayer_Set_GetReturnsExpected(bool value) } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void SecureSocketLayer_GetSetWhenDisposed_ThrowsObjectDisposedException() { var connection = new LdapConnection("server"); @@ -72,6 +76,7 @@ public void SecureSocketLayer_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void ReferralHopLimit_Set_GetReturnsExpected() { using (var connection = new LdapConnection("server")) @@ -142,6 +147,7 @@ public void ProtocolVersion_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void HostName_Set_GetReturnsExpected() { using (var connection = new LdapConnection("server")) @@ -168,6 +174,7 @@ public void HostName_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void DomainName_Set_GetReturnsExpected() { using (var connection = new LdapConnection("server")) @@ -194,6 +201,7 @@ public void DomainName_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Theory] + [PlatformSpecific(TestPlatforms.Windows)] [InlineData(LocatorFlags.AvoidSelf)] [InlineData(LocatorFlags.None - 1)] public void LocatorFlag_Set_GetReturnsExpected(LocatorFlags value) @@ -219,6 +227,7 @@ public void LocatorFlag_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void HostReachable_Get_ReturnsTrue() { using (var connection = new LdapConnection("server")) @@ -238,6 +247,7 @@ public void HostReachable_GetWhenDisposed_ThrowsObjectDisposedException() } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void PingKeepAliveTimeout_Set_GetReturnsExpected() { using (var connection = new LdapConnection("server")) @@ -272,6 +282,7 @@ public void PingKeepAliveTimeout_GetSetWhenDisposed_ThrowsObjectDisposedExceptio } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void PingLimit_Set_GetReturnsExpected() { using (var connection = new LdapConnection("server")) @@ -304,6 +315,7 @@ public void PingLimit_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void PingWaitTimeout_Set_GetReturnsExpected() { using (var connection = new LdapConnection("server")) @@ -338,6 +350,7 @@ public void PingWaitTimeout_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Theory] + [PlatformSpecific(TestPlatforms.Windows)] [InlineData(true)] [InlineData(false)] public void AutoReconnect_Set_GetReturnsExpected(bool value) @@ -363,6 +376,7 @@ public void AutoReconnect_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Theory] + [PlatformSpecific(TestPlatforms.Windows)] [InlineData(-1)] [InlineData(10)] public void SspiFlag_Set_GetReturnsExpected(int value) @@ -388,6 +402,7 @@ public void SspiFlag_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void SslInformation_GetNotStarted_ThrowsDirectoryOperationException() { using (var connection = new LdapConnection("server")) @@ -407,6 +422,7 @@ public void SslInformation_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void SecurityContext_GetNotStarted_ThrowsDirectoryOperationException() { using (var connection = new LdapConnection("server")) @@ -426,6 +442,7 @@ public void SecurityContext_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Theory] + [PlatformSpecific(TestPlatforms.Windows)] [InlineData(true)] [InlineData(false)] public void Signing_Set_GetReturnsExpected(bool value) @@ -451,6 +468,7 @@ public void Signing_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Theory] + [PlatformSpecific(TestPlatforms.Windows)] [InlineData(true)] [InlineData(false)] public void Sealing_Set_GetReturnsExpected(bool value) @@ -476,6 +494,7 @@ public void Sealing_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void SaslMethod_Set_ThrowsLdapException() { using (var connection = new LdapConnection("server")) @@ -498,6 +517,7 @@ public void SaslMethod_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Theory] + [PlatformSpecific(TestPlatforms.Windows)] [InlineData(true)] [InlineData(false)] public void RootDseCache_Set_GetReturnsExpected(bool value) @@ -523,6 +543,7 @@ public void RootDseCache_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Theory] + [PlatformSpecific(TestPlatforms.Windows)] [InlineData(true)] [InlineData(false)] public void TcpKeepAlive_Set_GetReturnsExpected(bool value) @@ -548,6 +569,7 @@ public void TcpKeepAlive_GetSetWhenDisposed_ThrowsObjectDisposedException() } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void SendTimeout_Set_GetReturnsExpected() { using (var connection = new LdapConnection("server")) @@ -595,6 +617,7 @@ public void ReferralCallback_Get_ReturnsException() } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void ReferralCallback_Set_GetReturnsExpected() { using (var connection = new LdapConnection("server")) @@ -625,6 +648,7 @@ public void ReferralCallback_GetGetSetWhenDisposed_ThrowsObjectDisposedException } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void QueryClientCertificate_Set_GetReturnsExpected() { using (var connection = new LdapConnection("server")) @@ -653,6 +677,7 @@ public void QueryClientCertificate_GetGetSetWhenDisposed_ThrowsObjectDisposedExc } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void VerifyServerCertificate_Set_GetReturnsExpected() { using (var connection = new LdapConnection("server")) @@ -699,6 +724,7 @@ public void StartTransportLayerSecurity_Disposed_ThrowsObjectDisposedException() } [Fact] + [PlatformSpecific(TestPlatforms.Windows)] public void StopTransportLayerSecurity_NotStarted_ThrowsTlsOperationException() { using (var connection = new LdapConnection("server")) diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/PageResultRequestControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/PageResultRequestControlTests.cs index 6ce552719fb78..e629b5327b636 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/PageResultRequestControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/PageResultRequestControlTests.cs @@ -3,12 +3,12 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.ComponentModel; -using System.Security.Principal; +using System.Runtime.InteropServices; using Xunit; namespace System.DirectoryServices.Protocols.Tests { + [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] public class PageResultRequestControlTests { [Fact] @@ -21,12 +21,18 @@ public void Ctor_Default() Assert.Equal(512, control.PageSize); Assert.Equal("1.2.840.113556.1.4.319", control.Type); - Assert.Equal(new byte[] { 48, 132, 0, 0, 0, 6, 2, 2, 2, 0, 4, 0 }, control.GetValue()); + var expected = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 6, 2, 2, 2, 0, 4, 0 } : new byte[] { 48, 6, 2, 2, 2, 0, 4, 0 }; + Assert.Equal(expected, control.GetValue()); + } + + public static IEnumerable Ctor_PageSize_Data() + { + yield return new object[] { 0, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 5, 2, 1, 0, 4, 0 } : new byte[] { 48, 5, 2, 1, 0, 4, 0 } }; + yield return new object[] { 10, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 5, 2, 1, 10, 4, 0 } : new byte[] { 48, 5, 2, 1, 10, 4, 0 } }; } [Theory] - [InlineData(0, new byte[] { 48, 132, 0, 0, 0, 5, 2, 1, 0, 4, 0 })] - [InlineData(10, new byte[] { 48, 132, 0, 0, 0, 5, 2, 1, 10, 4, 0 })] + [MemberData(nameof(Ctor_PageSize_Data))] public void Ctor_PageSize(int pageSize, byte[] expectedValue) { var control = new PageResultRequestControl(pageSize); @@ -45,10 +51,15 @@ public void Ctor_NegativePageSize_ThrowsArgumentException() AssertExtensions.Throws("value", () => new PageResultRequestControl(-1)); } + public static IEnumerable Ctor_Cookie_Data() + { + yield return new object[] { null, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 6, 2, 2, 2, 0, 4, 0 } : new byte[] { 48, 6, 2, 2, 2, 0, 4, 0 } }; + yield return new object[] { new byte[0], (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 6, 2, 2, 2, 0, 4, 0 } : new byte[] { 48, 6, 2, 2, 2, 0, 4, 0 } }; + yield return new object[] { new byte[] { 1, 2, 3, }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 9, 2, 2, 2, 0, 4, 3, 1, 2, 3 } : new byte[] { 48, 9, 2, 2, 2, 0, 4, 3, 1, 2, 3 } }; + } + [Theory] - [InlineData(null, new byte[] { 48, 132, 0, 0, 0, 6, 2, 2, 2, 0, 4, 0 })] - [InlineData(new byte[0], new byte[] { 48, 132, 0, 0, 0, 6, 2, 2, 2, 0, 4, 0 })] - [InlineData(new byte[] { 1, 2, 3, }, new byte[] { 48, 132, 0, 0, 0, 9, 2, 2, 2, 0, 4, 3, 1, 2, 3 })] + [MemberData(nameof(Ctor_Cookie_Data))] public void Ctor_Cookie(byte[] cookie, byte[] expectedValue) { var control = new PageResultRequestControl(cookie); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/QuotaControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/QuotaControlTests.cs index 590da560d8383..300bf8c4874f1 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/QuotaControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/QuotaControlTests.cs @@ -3,12 +3,13 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.ComponentModel; +using System.Runtime.InteropServices; using System.Security.Principal; using Xunit; namespace System.DirectoryServices.Protocols.Tests { + [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] public class QuotaControlTests { [Fact] @@ -20,7 +21,8 @@ public void Ctor_Default() Assert.True(control.ServerSide); Assert.Equal("1.2.840.113556.1.4.1852", control.Type); - Assert.Equal(new byte[] { 48, 132, 0, 0, 0, 2, 4, 0 }, control.GetValue()); + var expected = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 2, 4, 0 } : new byte[] { 48, 2, 4, 0 }; + Assert.Equal(expected, control.GetValue()); } public static IEnumerable Ctor_QuerySid_TestData() @@ -30,6 +32,7 @@ public static IEnumerable Ctor_QuerySid_TestData() } [Theory] + [PlatformSpecific(TestPlatforms.Windows)] //Security Identifiers only work on Windows [MemberData(nameof(Ctor_QuerySid_TestData))] public void Ctor_QuerySid_Test(SecurityIdentifier querySid, byte[] expectedValue) { diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/SearchOptionsControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/SearchOptionsControlTests.cs index fbf5fc0dc87dc..7fd2878537bb8 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/SearchOptionsControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/SearchOptionsControlTests.cs @@ -3,10 +3,12 @@ // See the LICENSE file in the project root for more information. using System.ComponentModel; +using System.Runtime.InteropServices; using Xunit; namespace System.DirectoryServices.Protocols.Tests { + [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] public class SearchOptionsControlTests { [Fact] @@ -18,7 +20,8 @@ public void Ctor_Default() Assert.True(control.ServerSide); Assert.Equal("1.2.840.113556.1.4.1340", control.Type); - Assert.Equal(new byte[] { 48, 132, 0, 0, 0, 3, 2, 1, 1 }, control.GetValue()); + var expected = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 3, 2, 1, 1 } : new byte[] { 48, 3, 2, 1, 1 }; + Assert.Equal(expected, control.GetValue()); } [Fact] @@ -30,7 +33,8 @@ public void Ctor_Flags() Assert.True(control.ServerSide); Assert.Equal("1.2.840.113556.1.4.1340", control.Type); - Assert.Equal(new byte[] { 48, 132, 0, 0, 0, 3, 2, 1, 2 }, control.GetValue()); + var expected = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 3, 2, 1, 2 } : new byte[] { 48, 3, 2, 1, 2 }; + Assert.Equal(expected, control.GetValue()); } [Theory] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/SecurityDescriptorFlagControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/SecurityDescriptorFlagControlTests.cs index 3d0fc4e6d5024..8c7fabf0ed8bb 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/SecurityDescriptorFlagControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/SecurityDescriptorFlagControlTests.cs @@ -2,11 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.ComponentModel; +using System.Collections.Generic; +using System.Runtime.InteropServices; using Xunit; namespace System.DirectoryServices.Protocols.Tests { + [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] public class SecurityDescriptorFlagControlTests { [Fact] @@ -18,12 +20,18 @@ public void Ctor_Default() Assert.True(control.ServerSide); Assert.Equal("1.2.840.113556.1.4.801", control.Type); - Assert.Equal(new byte[] { 48, 132, 0, 0, 0, 3, 2, 1, 0 }, control.GetValue()); + var expected = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 3, 2, 1, 0 } : new byte[] { 48, 3, 2, 1, 0 }; + Assert.Equal(expected, control.GetValue()); + } + + public static IEnumerable Ctor_Flags_Data() + { + yield return new object[] { SecurityMasks.Group, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 3, 2, 1, 2 } : new byte[] { 48, 3, 2, 1, 2 } }; + yield return new object[] { SecurityMasks.None - 1, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 6, 2, 4, 255, 255, 255, 255 } : new byte[] { 48, 3, 2, 1, 255 } }; } [Theory] - [InlineData(SecurityMasks.Group, new byte[] { 48, 132, 0, 0, 0, 3, 2, 1, 2 })] - [InlineData(SecurityMasks.None - 1, new byte[] { 48, 132, 0, 0, 0, 6, 2, 4, 255, 255, 255, 255 })] + [MemberData(nameof(Ctor_Flags_Data))] public void Ctor_Flags(SecurityMasks masks, byte[] expectedValue) { var control = new SecurityDescriptorFlagControl(masks); @@ -31,7 +39,6 @@ public void Ctor_Flags(SecurityMasks masks, byte[] expectedValue) Assert.Equal(masks, control.SecurityMasks); Assert.True(control.ServerSide); Assert.Equal("1.2.840.113556.1.4.801", control.Type); - Assert.Equal(expectedValue, control.GetValue()); } } diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/SortRequestControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/SortRequestControlTests.cs index 24c57e840cf52..197a8f91c9b9c 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/SortRequestControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/SortRequestControlTests.cs @@ -3,10 +3,12 @@ // See the LICENSE file in the project root for more information. using System.Reflection; +using System.Runtime.InteropServices; using Xunit; namespace System.DirectoryServices.Protocols.Tests { + [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] public class SortRequestControlTests { [Theory] @@ -30,13 +32,13 @@ public void Ctor_SortKeys(bool critical) } control.IsCritical = critical; - Assert.Equal(new byte[] - { - 48, 132, 0, 0, 0, 43, 48, 132, 0, 0, 0, 17, 4, 5,110, + var expected = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? + new byte[] { 48, 132, 0, 0, 0, 43, 48, 132, 0, 0, 0, 17, 4, 5,110, 97, 109, 101, 49, 128, 5, 114, 117, 108, 101, 49, 129, 1, 255, 48, 132, 0, 0, 0, 14, 4, 5, 110, 97, 109, 101, - 50, 128, 5, 114, 117, 108, 101, 50 - }, control.GetValue()); + 50, 128, 5, 114, 117, 108, 101, 50} : + new byte[] { 48, 19, 48, 9, 4, 1, 110, 128, 1, 114, 129, 1, 255, 48, 6, 4, 1, 110, 128, 1, 114 }; + Assert.Equal(expected, control.GetValue()); } [Fact] diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/System.DirectoryServices.Protocols.Tests.csproj b/src/libraries/System.DirectoryServices.Protocols/tests/System.DirectoryServices.Protocols.Tests.csproj index 7cf3cdc3988f9..164327720e330 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/System.DirectoryServices.Protocols.Tests.csproj +++ b/src/libraries/System.DirectoryServices.Protocols/tests/System.DirectoryServices.Protocols.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent) @@ -47,6 +47,7 @@ + diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/VerifyNameControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/VerifyNameControlTests.cs index 73db25a571759..93b790224c950 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/VerifyNameControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/VerifyNameControlTests.cs @@ -2,10 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; +using System.Runtime.InteropServices; using Xunit; namespace System.DirectoryServices.Protocols.Tests { + [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] public class VerifyNameControlTests { [Fact] @@ -18,12 +21,18 @@ public void Ctor_Default() Assert.True(control.ServerSide); Assert.Equal("1.2.840.113556.1.4.1338", control.Type); - Assert.Equal(new byte[] { 48, 132, 0, 0, 0, 5, 2, 1, 0, 4, 0 }, control.GetValue()); + var expected = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 5, 2, 1, 0, 4, 0 } : new byte[] { 48, 5, 2, 1, 0, 4, 0 }; + Assert.Equal(expected, control.GetValue()); + } + + public static IEnumerable Ctor_ServerName_Data() + { + yield return new object[] { "", (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 5, 2, 1, 0, 4, 0 } : new byte[] { 48, 5, 2, 1, 0, 4, 0 } }; + yield return new object[] { "S", (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 7, 2, 1, 0, 4, 2, 83, 0 } : new byte[] { 48, 7, 2, 1, 0, 4, 2, 83, 0 } }; } [Theory] - [InlineData("", new byte[] { 48, 132, 0, 0, 0, 5, 2, 1, 0, 4, 0 })] - [InlineData("S", new byte[] { 48, 132, 0, 0, 0, 7, 2, 1, 0, 4, 2, 83, 0 })] + [MemberData(nameof(Ctor_ServerName_Data))] public void Ctor_ServerName(string serverName, byte[] expectedValue) { var control = new VerifyNameControl(serverName); @@ -36,9 +45,14 @@ public void Ctor_ServerName(string serverName, byte[] expectedValue) Assert.Equal(expectedValue, control.GetValue()); } + public static IEnumerable Ctor_ServerName_Flag_Data() + { + yield return new object[] { "", -1, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 8, 2, 4, 255, 255, 255, 255, 4, 0 } : new byte[] { 48, 5, 2, 1, 255, 4, 0 } }; + yield return new object[] { "S", 10, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 7, 2, 1, 10, 4, 2, 83, 0 } : new byte[] { 48, 7, 2, 1, 10, 4, 2, 83, 0 } }; + } + [Theory] - [InlineData("", -1, new byte[] { 48, 132, 0, 0, 0, 8, 2, 4, 255, 255, 255, 255, 4, 0 })] - [InlineData("S", 10, new byte[] { 48, 132, 0, 0, 0, 7, 2, 1, 10, 4, 2, 83, 0 })] + [MemberData(nameof(Ctor_ServerName_Flag_Data))] public void Ctor_ServerName_Flag(string serverName, int flag, byte[] expectedValue) { var control = new VerifyNameControl(serverName, flag); diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/VlvRequestControlTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/VlvRequestControlTests.cs index d2f42a65fd6ce..7d1844b601e05 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/VlvRequestControlTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/VlvRequestControlTests.cs @@ -2,10 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; +using System.Runtime.InteropServices; using Xunit; namespace System.DirectoryServices.Protocols.Tests { + [ConditionalClass(typeof(DirectoryServicesTestHelpers), nameof(DirectoryServicesTestHelpers.IsWindowsOrLibLdapIsInstalled))] public class VlvRequestControlTests { [Fact] @@ -22,12 +25,18 @@ public void Ctor_Default() Assert.True(control.ServerSide); Assert.Equal("2.16.840.1.113730.3.4.9", control.Type); - Assert.Equal(new byte[] { 48, 132, 0, 0, 0, 18, 2, 1, 0, 2, 1, 0, 160, 132, 0, 0, 0, 6, 2, 1, 0, 2, 1, 0 }, control.GetValue()); + var expected = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 18, 2, 1, 0, 2, 1, 0, 160, 132, 0, 0, 0, 6, 2, 1, 0, 2, 1, 0 } : new byte[] { 48, 14, 2, 1, 0, 2, 1, 0, 160, 6, 2, 1, 0, 2, 1, 0 }; + Assert.Equal(expected, control.GetValue()); + } + + public static IEnumerable Ctor_BeforeCount_AfterCount_Offset_Data() + { + yield return new object[] { 0, 0, 0, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 18, 2, 1, 0, 2, 1, 0, 160, 132, 0, 0, 0, 6, 2, 1, 0, 2, 1, 0 } : new byte[] { 48, 14, 2, 1, 0, 2, 1, 0, 160, 6, 2, 1, 0, 2, 1, 0 } }; + yield return new object[] { 10, 10, 10, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 18, 2, 1, 10, 2, 1, 10, 160, 132, 0, 0, 0, 6, 2, 1, 10, 2, 1, 0 } : new byte[] { 48, 14, 2, 1, 10, 2, 1, 10, 160, 6, 2, 1, 10, 2, 1, 0 } }; } [Theory] - [InlineData(0, 0, 0, new byte[] { 48, 132, 0, 0, 0, 18, 2, 1, 0, 2, 1, 0, 160, 132, 0, 0, 0, 6, 2, 1, 0, 2, 1, 0 })] - [InlineData(10, 10, 10, new byte[] { 48, 132, 0, 0, 0, 18, 2, 1, 10, 2, 1, 10, 160, 132, 0, 0, 0, 6, 2, 1, 10, 2, 1, 0 })] + [MemberData(nameof(Ctor_BeforeCount_AfterCount_Offset_Data))] public void Ctor_BeforeCount_AfterCount_Offset(int beforeCount, int afterCount, int offset, byte[] expectedValue) { var control = new VlvRequestControl(beforeCount, afterCount, offset); @@ -44,9 +53,14 @@ public void Ctor_BeforeCount_AfterCount_Offset(int beforeCount, int afterCount, Assert.Equal(expectedValue, control.GetValue()); } + public static IEnumerable Ctor_BeforeCount_AfterCount_StringTarget_Data() + { + yield return new object[] { 0, 0, null, new byte[0], (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 18, 2, 1, 0, 2, 1, 0, 160, 132, 0, 0, 0, 6, 2, 1, 0, 2, 1, 0 } : new byte[] { 48, 14, 2, 1, 0, 2, 1, 0, 160, 6, 2, 1, 0, 2, 1, 0 } }; + yield return new object[] { 10, 10, "abc", new byte[] { 97, 98, 99 }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 11, 2, 1, 10, 2, 1, 10, 129, 3, 97, 98, 99 } : new byte[] { 48, 11, 2, 1, 10, 2, 1, 10, 129, 3, 97, 98, 99 } }; + } + [Theory] - [InlineData(0, 0, null, new byte[0], new byte[] { 48, 132, 0, 0, 0, 18, 2, 1, 0, 2, 1, 0, 160, 132, 0, 0, 0, 6, 2, 1, 0, 2, 1, 0 })] - [InlineData(10, 10, "abc", new byte[] { 97, 98, 99 }, new byte[] { 48, 132, 0, 0, 0, 11, 2, 1, 10, 2, 1, 10, 129, 3, 97, 98, 99 })] + [MemberData(nameof(Ctor_BeforeCount_AfterCount_StringTarget_Data))] public void Ctor_BeforeCount_AfterCount_StringTarget(int beforeCount, int afterCount, string target, byte[] expectedTarget, byte[] expectedValue) { var control = new VlvRequestControl(beforeCount, afterCount, target); @@ -64,9 +78,14 @@ public void Ctor_BeforeCount_AfterCount_StringTarget(int beforeCount, int afterC Assert.Equal(expectedValue, control.GetValue()); } + public static IEnumerable Ctor_BeforeCount_AfterCount_ByteArrayTarget_Data() + { + yield return new object[] { 0, 0, null, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 18, 2, 1, 0, 2, 1, 0, 160, 132, 0, 0, 0, 6, 2, 1, 0, 2, 1, 0 } : new byte[] { 48, 14, 2, 1, 0, 2, 1, 0, 160, 6, 2, 1, 0, 2, 1, 0 } }; + yield return new object[] { 10, 10, new byte[] { 1, 2, 3 }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 11, 2, 1, 10, 2, 1, 10, 129, 3, 1, 2, 3 } : new byte[] { 48, 11, 2, 1, 10, 2, 1, 10, 129, 3, 1, 2, 3 } }; + } + [Theory] - [InlineData(0, 0, null, new byte[] { 48, 132, 0, 0, 0, 18, 2, 1, 0, 2, 1, 0, 160, 132, 0, 0, 0, 6, 2, 1, 0, 2, 1, 0 })] - [InlineData(10, 10, new byte[] { 1, 2, 3 }, new byte[] { 48, 132, 0, 0, 0, 11, 2, 1, 10, 2, 1, 10, 129, 3, 1, 2, 3 })] + [MemberData(nameof(Ctor_BeforeCount_AfterCount_ByteArrayTarget_Data))] public void Ctor_BeforeCount_AfterCount_ByteArrayTarget(int beforeCount, int afterCount, byte[] target, byte[] expectedValue) { var control = new VlvRequestControl(beforeCount, afterCount, target); @@ -128,7 +147,8 @@ public void ContextId_Set_GetReturnsExpected() Assert.NotSame(contextId, control.ContextId); Assert.Equal(contextId, control.ContextId); - Assert.Equal(new byte[] { 48, 132, 0, 0, 0, 23, 2, 1, 0, 2, 1, 0, 160, 132, 0, 0, 0, 6, 2, 1, 0, 2, 1, 0, 4, 3, 1, 2, 3 }, control.GetValue()); + var expected = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 23, 2, 1, 0, 2, 1, 0, 160, 132, 0, 0, 0, 6, 2, 1, 0, 2, 1, 0, 4, 3, 1, 2, 3 } : new byte[] { 48, 19, 2, 1, 0, 2, 1, 0, 160, 6, 2, 1, 0, 2, 1, 0, 4, 3, 1, 2, 3 }; + Assert.Equal(expected, control.GetValue()); } } } From 5f2857a1787a69bc4245cd6d8d456504681a44ab Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Thu, 7 May 2020 22:40:53 +0200 Subject: [PATCH 033/420] Move tfmsuffix file to fix DesignTimeBuild (#35969) --- {src/libraries => eng}/targetframeworksuffix.props | 0 src/libraries/Directory.Build.props | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename {src/libraries => eng}/targetframeworksuffix.props (100%) diff --git a/src/libraries/targetframeworksuffix.props b/eng/targetframeworksuffix.props similarity index 100% rename from src/libraries/targetframeworksuffix.props rename to eng/targetframeworksuffix.props diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index a86add4cad990..1de45d5dd85ac 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -171,7 +171,7 @@ $([MSBuild]::NormalizeDirectory('$(AssemblyBinDirOutputPath)', 'ref')) - + From 9b5805f9dacee96bac80b2ab10e45e02a9369347 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Thu, 7 May 2020 22:43:49 +0200 Subject: [PATCH 034/420] Remove TargetFramework reads in eng/testing (#35954) --- eng/testing/tests.props | 5 ----- eng/testing/tests.targets | 5 +++++ eng/testing/xunit/xunit.console.props | 15 --------------- eng/testing/xunit/xunit.console.targets | 20 +++++++++++++++++--- eng/testing/xunit/xunit.props | 2 -- 5 files changed, 22 insertions(+), 25 deletions(-) delete mode 100644 eng/testing/xunit/xunit.console.props diff --git a/eng/testing/tests.props b/eng/testing/tests.props index cfdcc2b017144..7534dd5bc2a7f 100644 --- a/eng/testing/tests.props +++ b/eng/testing/tests.props @@ -20,11 +20,6 @@ <_withoutCategories Condition="!$(_withCategories.Contains('failing'))">$(_withoutCategories);failing - - - - - + + + + - - true - testResults.xml - - - - - - - diff --git a/eng/testing/xunit/xunit.console.targets b/eng/testing/xunit/xunit.console.targets index 0f41550251d47..2824bd8410780 100644 --- a/eng/testing/xunit/xunit.console.targets +++ b/eng/testing/xunit/xunit.console.targets @@ -1,8 +1,13 @@ + + true + testResults.xml + + <_depsFileArgument Condition="'$(GenerateDependencyFile)' == 'true'">--depsfile $(AssemblyName).deps.json - "$(RunScriptHost)" exec --runtimeconfig $(AssemblyName).runtimeconfig.json $(_depsFileArgument) xunit.console.dll - xunit.console.exe + "$(RunScriptHost)" exec --runtimeconfig $(AssemblyName).runtimeconfig.json $(_depsFileArgument) xunit.console.dll + xunit.console.exe $(RunScriptCommand) $(TargetFileName) $(RunScriptCommand) -xml $(TestResultsName) @@ -14,7 +19,7 @@ $(RunScriptCommand) -method $(XUnitMethodName) $(RunScriptCommand) -class $(XUnitClassName) $(RunScriptCommand) -verbose - $(RunScriptCommand) -noappdomain + $(RunScriptCommand) -noappdomain $(RunScriptCommand)$(_withCategories.Replace(';', ' -trait category=')) @@ -24,6 +29,15 @@ $(RunScriptCommand) $(XUnitOptions) + + + + + - - From 3058899348decccabcf758be6a586c87dc1f0c9a Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Thu, 7 May 2020 13:46:43 -0700 Subject: [PATCH 035/420] improve handling of handshake failure (#35549) * improve handling of handshake failure * more cleanup * remove console reference * add quotes around parameter * enable ServerAsyncAuthenticate_MismatchProtocols_Fails * cleanup ssl2 test * fix http2 * feedback from review * add back two missing empty lines Co-authored-by: Tomas Weinfurt --- .../src/Resources/Strings.resx | 3 + .../src/System.Net.Security.csproj | 1 + .../src/System/Net/Security/SecureChannel.cs | 10 +- .../src/System/Net/Security/SniHelper.cs | 18 +- .../Net/Security/SslStream.Implementation.cs | 86 +++++-- .../System/Net/Security/SslStreamPal.OSX.cs | 3 +- .../src/System/Net/Security/TlsFrameHelper.cs | 235 ++++++++++++++++++ .../ClientAsyncAuthenticateTest.cs | 12 +- .../ClientDefaultEncryptionTest.cs | 2 +- .../ServerAsyncAuthenticateTest.cs | 7 +- .../FunctionalTests/ServerNoEncryptionTest.cs | 2 +- .../tests/FunctionalTests/SslStreamSniTest.cs | 5 +- .../SslStreamSystemDefaultsTest.cs | 6 +- .../System.Net.Security.Tests.csproj | 2 + .../FunctionalTests/TestConfiguration.cs | 4 +- 15 files changed, 328 insertions(+), 68 deletions(-) create mode 100644 src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs diff --git a/src/libraries/System.Net.Security/src/Resources/Strings.resx b/src/libraries/System.Net.Security/src/Resources/Strings.resx index 7270ea80faefd..8af05ebe134c8 100644 --- a/src/libraries/System.Net.Security/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Security/src/Resources/Strings.resx @@ -212,6 +212,9 @@ Authentication failed because the remote party has closed the transport stream. + + Authentication failed because the remote party sent a TLS alert: '{0}'. + Authentication failed on the remote side (the stream might still be available for additional authentication attempts). diff --git a/src/libraries/System.Net.Security/src/System.Net.Security.csproj b/src/libraries/System.Net.Security/src/System.Net.Security.csproj index 868faddb5727a..067df9b00fcf6 100644 --- a/src/libraries/System.Net.Security/src/System.Net.Security.csproj +++ b/src/libraries/System.Net.Security/src/System.Net.Security.csproj @@ -34,6 +34,7 @@ + diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs index 82aab9fe95196..b770ef26fb78a 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs @@ -625,7 +625,7 @@ private bool AcquireClientCredentials(ref byte[]? thumbPrint) // // Acquire Server Side Certificate information and set it on the class. // - private bool AcquireServerCredentials(ref byte[]? thumbPrint, ReadOnlySpan clientHello) + private bool AcquireServerCredentials(ref byte[]? thumbPrint) { if (NetEventSource.IsEnabled) NetEventSource.Enter(this); @@ -639,13 +639,13 @@ private bool AcquireServerCredentials(ref byte[]? thumbPrint, ReadOnlySpan // with .NET Framework), and if neither is set we fall back to using ServerCertificate. if (_sslAuthenticationOptions.ServerCertSelectionDelegate != null) { - string? serverIdentity = SniHelper.GetServerName(clientHello); - localCertificate = _sslAuthenticationOptions.ServerCertSelectionDelegate(serverIdentity); - + localCertificate = _sslAuthenticationOptions.ServerCertSelectionDelegate(_sslAuthenticationOptions.TargetHost); if (localCertificate == null) { throw new AuthenticationException(SR.net_ssl_io_no_server_cert); } + if (NetEventSource.IsEnabled) + NetEventSource.Info(this, "Use delegate selected Cert"); } else if (_sslAuthenticationOptions.CertSelectionDelegate != null) { @@ -784,7 +784,7 @@ private SecurityStatusPal GenerateToken(ReadOnlySpan inputBuffer, ref byte if (_refreshCredentialNeeded) { cachedCreds = _sslAuthenticationOptions.IsServer - ? AcquireServerCredentials(ref thumbPrint, inputBuffer) + ? AcquireServerCredentials(ref thumbPrint) : AcquireClientCredentials(ref thumbPrint); } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SniHelper.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SniHelper.cs index ffbf730e7d971..db682188997e1 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SniHelper.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SniHelper.cs @@ -26,13 +26,13 @@ internal class SniHelper // opaque fragment[SSLPlaintext.length]; // } SSLPlaintext; const int ContentTypeOffset = 0; - const int ProtocolVersionOffset = ContentTypeOffset + sizeof(ContentType); + const int ProtocolVersionOffset = ContentTypeOffset + sizeof(TlsContentType); const int LengthOffset = ProtocolVersionOffset + ProtocolVersionSize; const int HandshakeOffset = LengthOffset + sizeof(ushort); // SSL v2's ContentType has 0x80 bit set. // We do not care about SSL v2 here because it does not support client hello extensions - if (sslPlainText.Length < HandshakeOffset || (ContentType)sslPlainText[ContentTypeOffset] != ContentType.Handshake) + if (sslPlainText.Length < HandshakeOffset || (TlsContentType)sslPlainText[ContentTypeOffset] != TlsContentType.Handshake) { return null; } @@ -62,10 +62,10 @@ internal class SniHelper // } body; // } Handshake; const int HandshakeTypeOffset = 0; - const int ClientHelloLengthOffset = HandshakeTypeOffset + sizeof(HandshakeType); + const int ClientHelloLengthOffset = HandshakeTypeOffset + sizeof(TlsHandshakeType); const int ClientHelloOffset = ClientHelloLengthOffset + UInt24Size; - if (sslHandshake.Length < ClientHelloOffset || (HandshakeType)sslHandshake[HandshakeTypeOffset] != HandshakeType.ClientHello) + if (sslHandshake.Length < ClientHelloOffset || (TlsHandshakeType)sslHandshake[HandshakeTypeOffset] != TlsHandshakeType.ClientHello) { return null; } @@ -363,16 +363,6 @@ private static Encoding CreateEncoding() return Encoding.GetEncoding("utf-8", new EncoderExceptionFallback(), new DecoderExceptionFallback()); } - private enum ContentType : byte - { - Handshake = 0x16 - } - - private enum HandshakeType : byte - { - ClientHello = 0x01 - } - private enum ExtensionType : ushort { ServerName = 0x00 diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs index 600163be36290..d9ff52dfeba8f 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs @@ -34,14 +34,8 @@ private enum Framing // This is set on the first packet to figure out the framing style. private Framing _framing = Framing.Unknown; - // SSL3/TLS protocol frames definitions. - private enum FrameType : byte - { - ChangeCipherSpec = 20, - Alert = 21, - Handshake = 22, - AppData = 23 - } + private TlsAlertDescription _lastAlertDescription; + private TlsFrameHandshakeInfo _lastFrame; private readonly object _handshakeLock = new object(); private volatile TaskCompletionSource? _handshakeWaiter; @@ -274,7 +268,6 @@ private async Task ForceAuthenticationAsync(TIOAdapter adapter, bool { // get ready to receive first frame _handshakeBuffer = new ArrayBuffer(InitialHandshakeBufferSize); - _framing = Framing.Unknown; } while (!handshakeCompleted) @@ -288,6 +281,19 @@ private async Task ForceAuthenticationAsync(TIOAdapter adapter, bool if (message.Failed) { + if (_lastFrame.Header.Type == TlsContentType.Handshake && message.Size == 0) + { + // If we failed without OS sending out alert, inject one here to be consistent across platforms. + byte[] alert = TlsFrameHelper.CreateAlertFrame(_lastFrame.Header.Version, TlsAlertDescription.ProtocolVersion); + await adapter.WriteAsync(alert, 0, alert.Length).ConfigureAwait(false); + } + else if (_lastFrame.Header.Type == TlsContentType.Alert && _lastAlertDescription != TlsAlertDescription.CloseNotify && + message.Status.ErrorCode == SecurityStatusPalErrorCode.IllegalMessage) + { + // Improve generic message and show details if we failed because of TLS Alert. + throw new AuthenticationException(SR.Format(SR.net_auth_tls_alert, _lastAlertDescription.ToString()), message.GetException()); + } + throw new AuthenticationException(SR.net_auth_SSPI, message.GetException()); } else if (message.Status.ErrorCode == SecurityStatusPalErrorCode.OK) @@ -346,17 +352,49 @@ private async ValueTask ReceiveBlobAsync(TIOAdapter a _framing = DetectFraming(_handshakeBuffer.ActiveReadOnlySpan); } - int frameSize = GetFrameSize(_handshakeBuffer.ActiveReadOnlySpan); - if (frameSize < 0) + if (_framing == Framing.BeforeSSL3) + { +#pragma warning disable 0618 + _lastFrame.Header.Version = SslProtocols.Ssl2; +#pragma warning restore 0618 + _lastFrame.Header.Length = GetFrameSize(_handshakeBuffer.ActiveReadOnlySpan); + } + else + { + TlsFrameHelper.TryGetFrameHeader(_handshakeBuffer.ActiveReadOnlySpan, ref _lastFrame.Header); + } + + if (_lastFrame.Header.Length < 0) { throw new IOException(SR.net_frame_read_size); } + // Header length is content only so we must add header size as well. + int frameSize = _lastFrame.Header.Length + TlsFrameHelper.HeaderSize; if (_handshakeBuffer.ActiveLength < frameSize) { await FillHandshakeBufferAsync(adapter, frameSize).ConfigureAwait(false); } + // At this point, we have at least one TLS frame. + if (_lastFrame.Header.Type == TlsContentType.Alert) + { + TlsAlertLevel level = 0; + if (TlsFrameHelper.TryGetAlertInfo(_handshakeBuffer.ActiveReadOnlySpan, ref level, ref _lastAlertDescription)) + { + if (NetEventSource.IsEnabled && _lastAlertDescription != TlsAlertDescription.CloseNotify) NetEventSource.Fail(this, $"Received TLS alert {_lastAlertDescription}"); + } + } + else if (_lastFrame.Header.Type == TlsContentType.Handshake) + { + if (_handshakeBuffer.ActiveReadOnlySpan[TlsFrameHelper.HeaderSize] == (byte)TlsHandshakeType.ClientHello && + _sslAuthenticationOptions!.ServerCertSelectionDelegate != null) + { + // Process SNI from Client Hello message + TlsFrameHelper.TryGetHandshakeInfo(_handshakeBuffer.ActiveReadOnlySpan, ref _lastFrame); + _sslAuthenticationOptions.TargetHost = _lastFrame.TargetName; + } + } return ProcessBlob(frameSize); } @@ -372,23 +410,24 @@ private ProtocolToken ProcessBlob(int frameSize) _handshakeBuffer.Discard(frameSize); // Often more TLS messages fit into same packet. Get as many complete frames as we can. - while (_handshakeBuffer.ActiveLength > SecureChannel.ReadHeaderSize) + while (_handshakeBuffer.ActiveLength > TlsFrameHelper.HeaderSize) { - ReadOnlySpan remainingData = _handshakeBuffer.ActiveReadOnlySpan; - if (remainingData[0] >= (int)FrameType.AppData) + TlsFrameHeader nextHeader = default; + + if (!TlsFrameHelper.TryGetFrameHeader(_handshakeBuffer.ActiveReadOnlySpan, ref nextHeader)) { break; } - frameSize = GetFrameSize(remainingData); - if (_handshakeBuffer.ActiveLength >= frameSize) + frameSize = nextHeader.Length + TlsFrameHelper.HeaderSize; + if (nextHeader.Type == TlsContentType.AppData || frameSize > _handshakeBuffer.ActiveLength) { - chunkSize += frameSize; - _handshakeBuffer.Discard(frameSize); - continue; + // We don't have full frame left or we already have app data which needs to be processed by decrypt. + break; } - break; + chunkSize += frameSize; + _handshakeBuffer.Discard(frameSize); } return _context!.NextMessage(availableData.Slice(0, chunkSize)); @@ -645,7 +684,7 @@ private async ValueTask ReadAsyncInternal(TIOAdapter adapter, M Debug.Assert(_internalBufferCount >= SecureChannel.ReadHeaderSize); // Parse the frame header to determine the payload size (which includes the header size). - int payloadBytes = GetFrameSize(_internalBuffer.AsSpan(_internalOffset)); + int payloadBytes = TlsFrameHelper.GetFrameSize(_internalBuffer.AsSpan(_internalOffset)); if (payloadBytes < 0) { throw new IOException(SR.net_frame_read_size); @@ -913,6 +952,7 @@ private static byte[] EnsureBufferSize(byte[] buffer, int copyCount, int size) Buffer.BlockCopy(saved, 0, buffer, 0, copyCount); } } + return buffer; } @@ -1003,8 +1043,8 @@ private Framing DetectFraming(ReadOnlySpan bytes) } // If the first byte is SSL3 HandShake, then check if we have a SSLv3 Type3 client hello. - if (bytes[0] == (byte)FrameType.Handshake || bytes[0] == (byte)FrameType.AppData - || bytes[0] == (byte)FrameType.Alert) + if (bytes[0] == (byte)TlsContentType.Handshake || bytes[0] == (byte)TlsContentType.AppData + || bytes[0] == (byte)TlsContentType.Alert) { if (bytes.Length < 3) { diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs index b72e549355fdc..3cf26e783a9d0 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs @@ -237,9 +237,8 @@ public static void VerifyPackageInfo() sslContext = new SafeDeleteSslContext((credential as SafeFreeSslCredentials)!, sslAuthenticationOptions); context = sslContext; - if (!string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost)) + if (!string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost) && !sslAuthenticationOptions.IsServer) { - Debug.Assert(!sslAuthenticationOptions.IsServer, "targetName should not be set for server-side handshakes"); Interop.AppleCrypto.SslSetTargetName(sslContext.SslContext, sslAuthenticationOptions.TargetHost); } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs b/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs new file mode 100644 index 0000000000000..ec18be1b8e374 --- /dev/null +++ b/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs @@ -0,0 +1,235 @@ +// 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. + +using System.Diagnostics; +using System.Security.Authentication; + +namespace System.Net.Security +{ + // SSL3/TLS protocol frames definitions. + internal enum TlsContentType : byte + { + ChangeCipherSpec = 20, + Alert = 21, + Handshake = 22, + AppData = 23 + } + + internal enum TlsHandshakeType : byte + { + HelloRequest = 0, + ClientHello = 1, + ServerHello = 2, + NewSessionTicket = 4, + EndOfEarlyData = 5, + EncryptedExtensions = 8, + Certificate = 11, + ServerKeyExchange = 12, + CertificateRequest = 13, + ServerHelloDone = 14, + CertificateVerify = 15, + ClientKeyExchange = 16, + Finished = 20, + KeyEpdate = 24, + MessageHash = 254 + } + + internal enum TlsAlertLevel : byte + { + Warning = 1, + Fatal = 2, + } + + internal enum TlsAlertDescription : byte + { + CloseNotify = 0, // warning + UnexpectedMessage = 10, // error + BadRecordMac = 20, // error + DecryptionFailed = 21, // reserved + RecordOverflow = 22, // error + DecompressionFail = 30, // error + HandshakeFailure = 40, // error + BadCertificate = 42, // warning or error + UnsupportedCert = 43, // warning or error + CertificateRevoked = 44, // warning or error + CertificateExpired = 45, // warning or error + CertificateUnknown = 46, // warning or error + IllegalParameter = 47, // error + UnknownCA = 48, // error + AccessDenied = 49, // error + DecodeError = 50, // error + DecryptError = 51, // error + ExportRestriction = 60, // reserved + ProtocolVersion = 70, // error + InsuffientSecurity = 71, // error + InternalError = 80, // error + UserCanceled = 90, // warning or error + NoRenegotiation = 100, // warning + UnsupportedExt = 110, // error + } + + internal struct TlsFrameHeader + { + public TlsContentType Type; + public SslProtocols Version; + public int Length; + } + + internal struct TlsFrameHandshakeInfo + { + public TlsFrameHeader Header; + public TlsHandshakeType HandshakeType; + public SslProtocols SupportedVersions; + public string? TargetName; + } + + internal class TlsFrameHelper + { + public const int HeaderSize = 5; + + private static byte[] s_protocolMismatch13 = new byte[] { (byte)TlsContentType.Alert, 3, 4, 0, 2, 2, 70 }; + private static byte[] s_protocolMismatch12 = new byte[] { (byte)TlsContentType.Alert, 3, 3, 0, 2, 2, 70 }; + private static byte[] s_protocolMismatch11 = new byte[] { (byte)TlsContentType.Alert, 3, 2, 0, 2, 2, 70 }; + private static byte[] s_protocolMismatch10 = new byte[] { (byte)TlsContentType.Alert, 3, 1, 0, 2, 2, 70 }; + + public static bool TryGetFrameHeader(ReadOnlySpan frame, ref TlsFrameHeader header) + { + bool result = frame.Length > 4; + + if (frame.Length >= 1) + { + header.Type = (TlsContentType)frame[0]; + + if (frame.Length >= 3) + { + // SSLv3, TLS or later + if (frame[1] == 3) + { + if (frame.Length > 4) + { + header.Length = ((frame[3] << 8) | frame[4]); + } + + switch (frame[2]) + { + case 4: + header.Version = SslProtocols.Tls13; + break; + case 3: + header.Version = SslProtocols.Tls12; + break; + case 2: + header.Version = SslProtocols.Tls11; + break; + case 1: + header.Version = SslProtocols.Tls; + break; + case 0: +#pragma warning disable 0618 + header.Version = SslProtocols.Ssl3; +#pragma warning restore 0618 + break; + default: + header.Version = SslProtocols.None; + break; + } + } + else + { + header.Length = -1; + header.Version = SslProtocols.None; + } + } + } + + return result; + } + + // Returns frame size e.g. header + content + public static int GetFrameSize(ReadOnlySpan frame) + { + if (frame.Length < 5 || frame[1] < 3) + { + return - 1; + } + + return ((frame[3] << 8) | frame[4]) + HeaderSize; + } + + public static bool TryGetHandshakeInfo(ReadOnlySpan frame, ref TlsFrameHandshakeInfo info) + { + if (frame.Length < 6 || frame[0] != (byte)TlsContentType.Handshake) + { + return false; + } + + // This will not fail since we have enough data. + bool gotHeader = TryGetFrameHeader(frame, ref info.Header); + Debug.Assert(gotHeader); + + info.SupportedVersions = info.Header.Version; + + info.HandshakeType = (TlsHandshakeType)frame[5]; + + if (info.HandshakeType == TlsHandshakeType.ClientHello) + { + info.TargetName = SniHelper.GetServerName(frame); + } + + return true; + } + + public static bool TryGetAlertInfo(ReadOnlySpan frame, ref TlsAlertLevel level, ref TlsAlertDescription description) + { + if (frame.Length < 7 || frame[0] != (byte)TlsContentType.Alert) + { + return false; + } + + level = (TlsAlertLevel)frame[5]; + description = (TlsAlertDescription)frame[6]; + + return true; + } + + private static byte[] CreateProtocolVersionAlert(SslProtocols version) => + version switch + { + SslProtocols.Tls13 => s_protocolMismatch13, + SslProtocols.Tls12 => s_protocolMismatch12, + SslProtocols.Tls11 => s_protocolMismatch11, + SslProtocols.Tls => s_protocolMismatch10, + _ => Array.Empty(), + }; + + public static byte[] CreateAlertFrame(SslProtocols version, TlsAlertDescription reason) + { + if (reason == TlsAlertDescription.ProtocolVersion) + { + return CreateProtocolVersionAlert(version); + } + else if ((int)version > (int)SslProtocols.Tls) + { + // Create TLS1.2 alert + byte[] buffer = new byte[] { (byte)TlsContentType.Alert, 3, 3, 0, 2, 2, (byte)reason }; + switch (version) + { + case SslProtocols.Tls13: + buffer[2] = 4; + break; + case SslProtocols.Tls11: + buffer[2] = 2; + break; + case SslProtocols.Tls: + buffer[2] = 1; + break; + } + + return buffer; + } + + return Array.Empty(); + } + } +} diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs index 69c96735809da..5c227192f2448 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs @@ -44,11 +44,7 @@ public async Task ClientAsyncAuthenticate_ServerRequireEncryption_ConnectWithEnc public async Task ClientAsyncAuthenticate_ServerNoEncryption_NoConnect() { // Don't use Tls13 since we are trying to use NullEncryption - Type expectedExceptionType = TestConfiguration.SupportsHandshakeAlerts && TestConfiguration.SupportsNullEncryption ? - typeof(AuthenticationException) : - typeof(IOException); - - await Assert.ThrowsAsync(expectedExceptionType, + await Assert.ThrowsAsync( () => ClientAsyncSslHelper( EncryptionPolicy.NoEncryption, SslProtocolSupport.DefaultSslProtocols, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 )); @@ -120,12 +116,12 @@ public static IEnumerable ProtocolMismatchData() yield return new object[] { SslProtocols.Ssl2, SslProtocols.Tls12, typeof(Exception) }; yield return new object[] { SslProtocols.Ssl3, SslProtocols.Tls12, typeof(Exception) }; #pragma warning restore 0618 - yield return new object[] { SslProtocols.Tls, SslProtocols.Tls11, TestConfiguration.SupportsVersionAlerts ? typeof(AuthenticationException) : typeof(IOException) }; - yield return new object[] { SslProtocols.Tls, SslProtocols.Tls12, TestConfiguration.SupportsVersionAlerts ? typeof(AuthenticationException) : typeof(IOException) }; + yield return new object[] { SslProtocols.Tls, SslProtocols.Tls11, typeof(AuthenticationException) }; + yield return new object[] { SslProtocols.Tls, SslProtocols.Tls12, typeof(AuthenticationException) }; yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls, typeof(AuthenticationException) }; yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls, typeof(AuthenticationException) }; yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls11, typeof(AuthenticationException) }; - yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls12, TestConfiguration.SupportsVersionAlerts ? typeof(AuthenticationException) : typeof(IOException) }; + yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls12, typeof(AuthenticationException) }; } #region Helpers diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs index 4a57ca9063161..ed3a2c635e692 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs @@ -84,7 +84,7 @@ public async Task ClientDefaultEncryption_ServerNoEncryption_NoConnect() using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null)) { - await Assert.ThrowsAsync(TestConfiguration.SupportsHandshakeAlerts ? typeof(AuthenticationException) : typeof(IOException), () => + await Assert.ThrowsAsync(() => sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false)); } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs index 5ecb21d630a9a..9bf0afb5b2290 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs @@ -44,7 +44,6 @@ public async Task ServerAsyncAuthenticate_EachSupportedProtocol_Success(SslProto [Theory] [MemberData(nameof(ProtocolMismatchData))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/29642")] public async Task ServerAsyncAuthenticate_MismatchProtocols_Fails( SslProtocols serverProtocol, SslProtocols clientProtocol, @@ -80,10 +79,10 @@ public static IEnumerable ProtocolMismatchData() #pragma warning restore 0618 yield return new object[] { SslProtocols.Tls, SslProtocols.Tls11, typeof(AuthenticationException) }; yield return new object[] { SslProtocols.Tls, SslProtocols.Tls12, typeof(AuthenticationException) }; - yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls, TestConfiguration.SupportsVersionAlerts ? typeof(AuthenticationException) : typeof(TimeoutException) }; + yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls, typeof(AuthenticationException) }; yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls12, typeof(AuthenticationException) }; - yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls, TestConfiguration.SupportsVersionAlerts ? typeof(AuthenticationException) : typeof(TimeoutException) }; - yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls11, TestConfiguration.SupportsVersionAlerts ? typeof(AuthenticationException) : typeof(TimeoutException) }; + yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls, typeof(AuthenticationException) }; + yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls11, typeof(AuthenticationException) }; } #region Helpers diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs index 65efb78767f9c..d062fac791c1d 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs @@ -43,7 +43,7 @@ public async Task ServerNoEncryption_ClientRequireEncryption_NoConnect() using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption)) { - await Assert.ThrowsAsync(TestConfiguration.SupportsHandshakeAlerts ? typeof(AuthenticationException) : typeof(IOException), () => + await Assert.ThrowsAsync(() => sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false)); } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs index a54624100da2a..b98a9ea992bde 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.IO; using System.Net.Test.Common; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; @@ -201,9 +202,7 @@ private static SslServerAuthenticationOptions DefaultServerOptions() private async Task WithVirtualConnection(Func serverClientConnection, RemoteCertificateValidationCallback clientCertValidate) { - VirtualNetwork vn = new VirtualNetwork(); - using (VirtualNetworkStream serverStream = new VirtualNetworkStream(vn, isServer: true), - clientStream = new VirtualNetworkStream(vn, isServer: false)) + (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams(); using (SslStream server = new SslStream(serverStream, leaveInnerStreamOpen: false), client = new SslStream(clientStream, leaveInnerStreamOpen: false, clientCertValidate)) { diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSystemDefaultsTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSystemDefaultsTest.cs index 4943401bc51ee..bc704fae67fda 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSystemDefaultsTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSystemDefaultsTest.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.IO; using System.Net.Http; using System.Net.Test.Common; using System.Security.Cryptography.X509Certificates; @@ -21,10 +22,7 @@ public abstract class SslStreamSystemDefaultTest public SslStreamSystemDefaultTest() { - var network = new VirtualNetwork(); - var clientNet = new VirtualNetworkStream(network, isServer:false); - var serverNet = new VirtualNetworkStream(network, isServer: true); - + (Stream clientNet, Stream serverNet) = TestHelper.GetConnectedTcpStreams(); _clientStream = new SslStream(clientNet, false, ClientCertCallback); _serverStream = new SslStream(serverNet, false, ServerCertCallback); } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj b/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj index 8a245e86d3069..4ad947504b2c1 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj @@ -66,6 +66,8 @@ Link="ProductionCode\Common\System\Threading\Tasks\TaskToApm.cs" /> + diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs index 9769590181342..577d2ce1f58ef 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs @@ -32,9 +32,7 @@ internal static class TestConfiguration public static bool SupportsHandshakeAlerts { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.Windows); } } - public static bool SupportsAlpnAlerts { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && PlatformDetection.OpenSslVersion.CompareTo(new Version(1,1,0)) >= 0); } } - - public static bool SupportsVersionAlerts { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && PlatformDetection.OpenSslVersion.CompareTo(new Version(1,1,0)) >= 0; } } + public static bool SupportsAlpnAlerts { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && PlatformDetection.OpenSslVersion.CompareTo(new Version(1,0,2)) >= 0); } } public static Task WhenAllOrAnyFailedWithTimeout(params Task[] tasks) => tasks.WhenAllOrAnyFailed(PassingTestTimeoutMilliseconds); From 0ec974709e311ef63e7e23ed7c74f1f33762aecc Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Thu, 7 May 2020 13:47:41 -0700 Subject: [PATCH 036/420] add requirement doc for FreeBSD (#35704) * add freebsd requirements * corrections * format * feedback from review * more cleanup Co-authored-by: Tomas Weinfurt --- docs/workflow/README.md | 2 +- .../requirements/freebsd-requirements.md | 69 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 docs/workflow/requirements/freebsd-requirements.md diff --git a/docs/workflow/README.md b/docs/workflow/README.md index 57c10f7a9d472..7a17fecd50eff 100644 --- a/docs/workflow/README.md +++ b/docs/workflow/README.md @@ -10,7 +10,7 @@ The repo can be built for the following platforms, using the provided setup and | x86 | ✔ | | | | | ARM | ✔ | ✔ | | | | ARM64 | ✔ | ✔ | | | -| | [Requirements](requirements/windows-requirements.md) | [Requirements](requirements/linux-requirements.md) | [Requirements](requirements/macos-requirements.md) | +| | [Requirements](requirements/windows-requirements.md) | [Requirements](requirements/linux-requirements.md) | [Requirements](requirements/macos-requirements.md) | [Requirements](requirements/freebsd-requirements.md) Before proceeding further, please click on the link above that matches your machine and ensure you have installed all the prerequisites for the build to work. diff --git a/docs/workflow/requirements/freebsd-requirements.md b/docs/workflow/requirements/freebsd-requirements.md new file mode 100644 index 0000000000000..59b3c64d928f1 --- /dev/null +++ b/docs/workflow/requirements/freebsd-requirements.md @@ -0,0 +1,69 @@ +Requirements to build dotnet/runtime on FreeBSD +===================== + +This guide will walk you through the requirements needed to build dotnet/runtime on FreeBSD. We'll start by showing how to set up your environment from scratch. +Since there is no official build and FreeBSD package, native build on FreeBSD is not trivial. There are generally three options, sorted by ease of use: +- cross-compile on Linux using Docker +- cross-compile on Linux using Toolchain +- build on FreeBSD + + +Environment +=========== + +These instructions were validated for and on FreeBSD 11.3 and 12.1. + +Build using Docker on Linux +--------------------------- + +This is similar to [Linux](linux-requirements.md) instructions. https://github.com/dotnet/dotnet-buildtools-prereqs-docker repro provides images +with all needed prerequisites to build. As the example bellow may become stale, https://github.com/dotnet/versions/blob/master/build-info/docker/image-info.dotnet-dotnet-buildtools-prereqs-docker-master.json offers list of latest Docker tags. + +```sh +TAG=mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-freebsd-11-20200430154008-a84b0d2 +docker run --rm --volume $(pwd):$(pwd) --workdir $(pwd) --env ROOTFS_DIR=/crossrootfs/x64 -ti $TAG ./build.sh -cross -FreeBSD +``` + +Build using Toolchain Setup +--------------------------- +To build FreeBSD images, prerequisites described in [Linux](linux-requirements.md) are needed. Additionally, crossrootfs for FreeBSD needs to be constructed. +In order to successfully build FreeBSD crossrootfs, few more packages needs to be installed. Following example is for Ubuntu 18: +```sh +apt-get install -y libbz2-dev libz-dev liblzma-dev libarchive-dev libbsd-dev +``` +With prerequisites for crossrootfs one can run: +```sh +./eng/common/cross/build-rootfs.sh freebsd11 $(pwd)/rootfs/freebsd +``` +After that, FreeBSD build can be started by running +``` +ROOTFS_DIR=$(pwd)/rootfs/freebsd ./build.sh -cross -os FreeBSD +``` + + +Building on FreeBSD +------------------- + +Building dotnet/runtime depends on several tools to be installed. + +Install the following packages: + +- cmake +- autoconf +- automake +- libtool +- icu +- libunwind +- lttng-ust +- krb5 +- openssl (optional) + +The lines to install all the packages above using package manager. + +```sh +sudo pkg install --yes libunwind icu libinotify lttng-ust krb5 cmake autoconf automake openssl +``` + +Additionally, working dotnet cli with SDK is needed. On other platforms this would be downloaded automatically during build but it is not currently available for FreeBSD. +It needs to be built once on supported platform or obtained via community resources. + From 1d11bd67055f1342f433824a05c5d194ce85ac76 Mon Sep 17 00:00:00 2001 From: "Nikola Milosavljevic (CLR)" Date: Thu, 7 May 2020 14:36:44 -0700 Subject: [PATCH 037/420] Do not package singlefilehost.exe in shared runtime --- .../Microsoft.NETCore.App.SharedFx.sfxproj | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/installer/pkg/projects/netcoreapp/sfx/Microsoft.NETCore.App.SharedFx.sfxproj b/src/installer/pkg/projects/netcoreapp/sfx/Microsoft.NETCore.App.SharedFx.sfxproj index d12d993a3ff61..f1aab81eb8a4b 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/Microsoft.NETCore.App.SharedFx.sfxproj +++ b/src/installer/pkg/projects/netcoreapp/sfx/Microsoft.NETCore.App.SharedFx.sfxproj @@ -45,6 +45,30 @@ + + + + + + + + + + + + + + + + + + 16.7.0-preview-20200429-01 - 1.0.0-prerelease.20255.4 + 1.0.0-prerelease.20256.2 2.4.1 1.2.1 2.0.5 From 43b5d81660045be81910074f3a4d6c0b96b26305 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 7 May 2020 20:02:08 -0400 Subject: [PATCH 041/420] Translate all ObjectDisposedExceptions to SocketExceptions in MultipleConnectAsync.AttemptConnection (#35965) If ObjectDisposedExceptions occurred at unexpected times, we'd return that ObjectDisposedException rather than a SocketException for OperationAborted. Higher-levels would then treat that arbitrary exception as a generic SocketError. So net net, this means that consuming code would get a SocketException for the more generic SocketError.SocketError rather than the more specific SocketError.OperationAborted. --- .../Net/Sockets/MultipleConnectAsync.cs | 40 ++++--------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/MultipleConnectAsync.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/MultipleConnectAsync.cs index e301f6d5f1019..c201d247f9edf 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/MultipleConnectAsync.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/MultipleConnectAsync.cs @@ -230,55 +230,31 @@ private void InternalConnectCallback(object? sender, SocketAsyncEventArgs args) { try { - Socket? attemptSocket; - IPAddress? attemptAddress = GetNextAddress(out attemptSocket); - + IPAddress? attemptAddress = GetNextAddress(out Socket? attemptSocket); if (attemptAddress == null) { return new SocketException((int)SocketError.NoData); } + Debug.Assert(attemptSocket != null); - _internalArgs!.RemoteEndPoint = new IPEndPoint(attemptAddress, _endPoint!.Port); - - return AttemptConnection(attemptSocket!, _internalArgs); - } - catch (Exception e) - { - if (e is ObjectDisposedException) - { - NetEventSource.Fail(this, "unexpected ObjectDisposedException"); - } - return e; - } - } - - private Exception? AttemptConnection(Socket attemptSocket, SocketAsyncEventArgs args) - { - try - { - if (attemptSocket == null) - { - NetEventSource.Fail(null, "attemptSocket is null!"); - } - - bool pending = attemptSocket.ConnectAsync(args); - if (!pending) + SocketAsyncEventArgs args = _internalArgs!; + args.RemoteEndPoint = new IPEndPoint(attemptAddress, _endPoint!.Port); + if (!attemptSocket.ConnectAsync(args)) { InternalConnectCallback(null, args); } + + return null; } catch (ObjectDisposedException) { - // This can happen if the user closes the socket, and is equivalent to a call - // to CancelConnectAsync + // This can happen if the user closes the socket and is equivalent to a call to CancelConnectAsync. return new SocketException((int)SocketError.OperationAborted); } catch (Exception e) { return e; } - - return null; } protected abstract void OnSucceed(); From b48900f3b37e6d68b5d84a3e48f0c5beb602a128 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 7 May 2020 20:02:37 -0400 Subject: [PATCH 042/420] Make HttpResponseMessage.Content non-nullable (#35910) * Make HttpResponseMessage.Content non-nullable * Fix Microsoft.Extensions.Http test --- .../RedactedLogValueIntegrationTest.cs | 16 +++---- .../System.Net.Http/ref/System.Net.Http.cs | 3 +- .../src/System.Net.Http.csproj | 7 +-- .../src/System/Net/Http/EmptyContent.cs | 38 ++++++++++++++++ .../EmptyReadStream.cs | 0 .../HttpBaseStream.cs | 0 .../System/Net/Http/HttpResponseMessage.cs | 6 ++- .../tests/FunctionalTests/HttpClientTest.cs | 5 ++- .../HttpResponseMessageTest.cs | 45 ++++++++++++++++--- .../HttpStress/ClientOperations.cs | 26 +++++------ .../System.Net.Http.Unit.Tests.csproj | 6 +++ 11 files changed, 118 insertions(+), 34 deletions(-) create mode 100644 src/libraries/System.Net.Http/src/System/Net/Http/EmptyContent.cs rename src/libraries/System.Net.Http/src/System/Net/Http/{SocketsHttpHandler => }/EmptyReadStream.cs (100%) rename src/libraries/System.Net.Http/src/System/Net/Http/{SocketsHttpHandler => }/HttpBaseStream.cs (100%) diff --git a/src/libraries/Microsoft.Extensions.Http/tests/Logging/RedactedLogValueIntegrationTest.cs b/src/libraries/Microsoft.Extensions.Http/tests/Logging/RedactedLogValueIntegrationTest.cs index 67ec29684936e..3b3c122b52fa9 100644 --- a/src/libraries/Microsoft.Extensions.Http/tests/Logging/RedactedLogValueIntegrationTest.cs +++ b/src/libraries/Microsoft.Extensions.Http/tests/Logging/RedactedLogValueIntegrationTest.cs @@ -51,7 +51,7 @@ public async Task RedactHeaderValueWithHeaderList_ValueIsRedactedBeforeLogging() m.EventId == LoggingScopeHttpMessageHandler.Log.EventIds.RequestHeader && m.LoggerName == "System.Net.Http.HttpClient.test.LogicalHandler"; })); - Assert.Equal( + Assert.StartsWith( @"Request Headers: Authorization: * Cache-Control: no-cache @@ -63,7 +63,7 @@ public async Task RedactHeaderValueWithHeaderList_ValueIsRedactedBeforeLogging() m.EventId == LoggingHttpMessageHandler.Log.EventIds.RequestHeader && m.LoggerName == "System.Net.Http.HttpClient.test.ClientHandler"; })); - Assert.Equal( + Assert.StartsWith( @"Request Headers: Authorization: * Cache-Control: no-cache @@ -75,7 +75,7 @@ public async Task RedactHeaderValueWithHeaderList_ValueIsRedactedBeforeLogging() m.EventId == LoggingHttpMessageHandler.Log.EventIds.ResponseHeader && m.LoggerName == "System.Net.Http.HttpClient.test.ClientHandler"; })); - Assert.Equal( + Assert.StartsWith( @"Response Headers: X-Sensitive: * Y-Non-Sensitive: innocuous value @@ -87,7 +87,7 @@ public async Task RedactHeaderValueWithHeaderList_ValueIsRedactedBeforeLogging() m.EventId == LoggingScopeHttpMessageHandler.Log.EventIds.ResponseHeader && m.LoggerName == "System.Net.Http.HttpClient.test.LogicalHandler"; })); - Assert.Equal( + Assert.StartsWith( @"Response Headers: X-Sensitive: * Y-Non-Sensitive: innocuous value @@ -132,7 +132,7 @@ public async Task RedactHeaderValueWithPredicate_ValueIsRedactedBeforeLogging() m.EventId == LoggingScopeHttpMessageHandler.Log.EventIds.RequestHeader && m.LoggerName == "System.Net.Http.HttpClient.test.LogicalHandler"; })); - Assert.Equal( + Assert.StartsWith( @"Request Headers: Authorization: * Cache-Control: no-cache @@ -144,7 +144,7 @@ public async Task RedactHeaderValueWithPredicate_ValueIsRedactedBeforeLogging() m.EventId == LoggingHttpMessageHandler.Log.EventIds.RequestHeader && m.LoggerName == "System.Net.Http.HttpClient.test.ClientHandler"; })); - Assert.Equal( + Assert.StartsWith( @"Request Headers: Authorization: * Cache-Control: no-cache @@ -156,7 +156,7 @@ public async Task RedactHeaderValueWithPredicate_ValueIsRedactedBeforeLogging() m.EventId == LoggingHttpMessageHandler.Log.EventIds.ResponseHeader && m.LoggerName == "System.Net.Http.HttpClient.test.ClientHandler"; })); - Assert.Equal( + Assert.StartsWith( @"Response Headers: X-Sensitive: * Y-Non-Sensitive: innocuous value @@ -168,7 +168,7 @@ public async Task RedactHeaderValueWithPredicate_ValueIsRedactedBeforeLogging() m.EventId == LoggingScopeHttpMessageHandler.Log.EventIds.ResponseHeader && m.LoggerName == "System.Net.Http.HttpClient.test.LogicalHandler"; })); - Assert.Equal( + Assert.StartsWith( @"Response Headers: X-Sensitive: * Y-Non-Sensitive: innocuous value diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.cs b/src/libraries/System.Net.Http/ref/System.Net.Http.cs index 0e0752189fe65..3026fa779ab0d 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.cs +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.cs @@ -209,7 +209,8 @@ public partial class HttpResponseMessage : System.IDisposable { public HttpResponseMessage() { } public HttpResponseMessage(System.Net.HttpStatusCode statusCode) { } - public System.Net.Http.HttpContent? Content { get { throw null; } set { } } + [System.Diagnostics.CodeAnalysis.AllowNull] + public System.Net.Http.HttpContent Content { get { throw null; } set { } } public System.Net.Http.Headers.HttpResponseHeaders Headers { get { throw null; } } public bool IsSuccessStatusCode { get { throw null; } } public string? ReasonPhrase { get { throw null; } set { } } diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index 0744c3d731f13..18b529238e6c8 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -1,4 +1,4 @@ - + Library System.Net.Http @@ -18,12 +18,15 @@ + + + @@ -128,7 +131,6 @@ - @@ -142,7 +144,6 @@ - diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/EmptyContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/EmptyContent.cs new file mode 100644 index 0000000000000..728229337c675 --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/EmptyContent.cs @@ -0,0 +1,38 @@ +// 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. + +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Http +{ + /// Provides a zero-length HttpContent implementation. + internal sealed class EmptyContent : HttpContent + { + protected internal override bool TryComputeLength(out long length) + { + length = 0; + return true; + } + + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) => + Task.CompletedTask; + + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) => + cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) : + SerializeToStreamAsync(stream, context); + + protected override Task CreateContentReadStreamAsync() => + Task.FromResult(EmptyReadStream.Instance); + + protected override Task CreateContentReadStreamAsync(CancellationToken cancellationToken) => + cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) : + CreateContentReadStreamAsync(); + + internal override Stream? TryCreateContentReadStream() => EmptyReadStream.Instance; + + internal override bool AllowDuplex => false; + } +} diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/EmptyReadStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/EmptyReadStream.cs similarity index 100% rename from src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/EmptyReadStream.cs rename to src/libraries/System.Net.Http/src/System/Net/Http/EmptyReadStream.cs diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpBaseStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpBaseStream.cs similarity index 100% rename from src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpBaseStream.cs rename to src/libraries/System.Net.Http/src/System/Net/Http/HttpBaseStream.cs diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs index dbe85b55dea63..b0763db9560bb 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; using System.Net.Http.Headers; using System.Text; @@ -39,9 +40,10 @@ public Version Version internal void SetVersionWithoutValidation(Version value) => _version = value; - public HttpContent? Content + [AllowNull] + public HttpContent Content { - get { return _content; } + get { return _content ??= new EmptyContent(); } set { CheckDisposed(); diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs index a297e28766d3a..544f188bd5770 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs @@ -221,7 +221,10 @@ public async Task GetContentAsync_NullResponseContent_ReturnsDefaultValue() { Assert.Same(string.Empty, await client.GetStringAsync(CreateFakeUri())); Assert.Same(Array.Empty(), await client.GetByteArrayAsync(CreateFakeUri())); - Assert.Same(Stream.Null, await client.GetStreamAsync(CreateFakeUri())); + + Stream s = await client.GetStreamAsync(CreateFakeUri()); + Assert.NotNull(s); + Assert.Equal(-1, s.ReadByte()); } } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpResponseMessageTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpResponseMessageTest.cs index fdeeeb065ca23..7c7fafee8d348 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpResponseMessageTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpResponseMessageTest.cs @@ -2,10 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.IO; -using System.Net.Http.Headers; -using System.Threading; using System.Threading.Tasks; using Xunit; @@ -22,7 +19,7 @@ public void Ctor_Default_CorrectDefaults() Assert.Equal(HttpStatusCode.OK, rm.StatusCode); Assert.Equal("OK", rm.ReasonPhrase); Assert.Equal(new Version(1, 1), rm.Version); - Assert.Null(rm.Content); + Assert.NotNull(rm.Content); Assert.Null(rm.RequestMessage); } } @@ -35,7 +32,7 @@ public void Ctor_SpecifiedValues_CorrectValues() Assert.Equal(HttpStatusCode.Accepted, rm.StatusCode); Assert.Equal("Accepted", rm.ReasonPhrase); Assert.Equal(new Version(1, 1), rm.Version); - Assert.Null(rm.Content); + Assert.NotNull(rm.Content); Assert.Null(rm.RequestMessage); } } @@ -232,8 +229,15 @@ public void Content_SetToNull_Accepted() { using (var rm = new HttpResponseMessage()) { + HttpContent c1 = rm.Content; + Assert.Same(c1, rm.Content); + rm.Content = null; - Assert.Null(rm.Content); + + HttpContent c2 = rm.Content; + Assert.Same(c2, rm.Content); + + Assert.NotSame(c1, c2); } } @@ -249,6 +253,35 @@ public void StatusCode_InvalidStatusCodeRange_ThrowsArgumentOutOfRangeException( } } + [Fact] + public async Task DefaultContent_ReadableNotWritable_Success() + { + var resp = new HttpResponseMessage(); + + HttpContent c = resp.Content; + Assert.NotNull(c); + Assert.Same(c, resp.Content); + Assert.NotSame(resp.Content, new HttpResponseMessage().Content); + + Assert.Equal(0, c.Headers.ContentLength); + + Task t = c.ReadAsStreamAsync(); + Assert.Equal(TaskStatus.RanToCompletion, t.Status); + + Stream s = await t; + Assert.NotNull(s); + + Assert.Equal(-1, s.ReadByte()); + Assert.Equal(0, s.Read(new byte[1], 0, 1)); + Assert.Equal(0, await s.ReadAsync(new byte[1], 0, 1)); + Assert.Equal(0, await s.ReadAsync(new Memory(new byte[1]))); + + Assert.Throws(() => s.WriteByte(0)); + Assert.Throws(() => s.Write(new byte[1], 0, 1)); + await Assert.ThrowsAsync(() => s.WriteAsync(new byte[1], 0, 1)); + await Assert.ThrowsAsync(async () => await s.WriteAsync(new ReadOnlyMemory(new byte[1]))); + } + [Fact] public void ToString_DefaultAndNonDefaultInstance_DumpAllFields() { diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/ClientOperations.cs b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/ClientOperations.cs index 2e148dd757e33..8342fed20b694 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/ClientOperations.cs +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/ClientOperations.cs @@ -192,7 +192,7 @@ public static class ClientOperations using HttpResponseMessage m = await ctx.SendAsync(req); ValidateStatusCode(m); - ValidateServerContent(await m.Content!.ReadAsStringAsync(), expectedLength); + ValidateServerContent(await m.Content.ReadAsStringAsync(), expectedLength); }), ("GET Partial", @@ -204,7 +204,7 @@ public static class ClientOperations ValidateStatusCode(m); - using (Stream s = await m.Content!.ReadAsStreamAsync()) + using (Stream s = await m.Content.ReadAsStreamAsync()) { s.ReadByte(); // read single byte from response and throw the rest away } @@ -221,7 +221,7 @@ public static class ClientOperations ValidateStatusCode(res); - await res.Content!.ReadAsStringAsync(); + await res.Content.ReadAsStringAsync(); bool isValidChecksum = ValidateServerChecksum(res.Headers, expectedChecksum); string failureDetails = isValidChecksum ? "server checksum matches client checksum" : "server checksum mismatch"; @@ -273,7 +273,7 @@ public static class ClientOperations using HttpResponseMessage m = await ctx.SendAsync(req); ValidateStatusCode(m); - ValidateContent(expectedResponse, await m.Content!.ReadAsStringAsync(), $"Uri: {uri}"); + ValidateContent(expectedResponse, await m.Content.ReadAsStringAsync(), $"Uri: {uri}"); }), ("GET Aborted", @@ -332,7 +332,7 @@ public static class ClientOperations ValidateStatusCode(m); string checksumMessage = ValidateServerChecksum(m.Headers, checksum) ? "server checksum matches client checksum" : "server checksum mismatch"; - ValidateContent(content, await m.Content!.ReadAsStringAsync(), checksumMessage); + ValidateContent(content, await m.Content.ReadAsStringAsync(), checksumMessage); }), ("POST Multipart Data", @@ -346,7 +346,7 @@ public static class ClientOperations ValidateStatusCode(m); string checksumMessage = ValidateServerChecksum(m.Headers, checksum) ? "server checksum matches client checksum" : "server checksum mismatch"; - ValidateContent(formData.expected, await m.Content!.ReadAsStringAsync(), checksumMessage); + ValidateContent(formData.expected, await m.Content.ReadAsStringAsync(), checksumMessage); }), ("POST Duplex", @@ -359,7 +359,7 @@ public static class ClientOperations using HttpResponseMessage m = await ctx.SendAsync(req, HttpCompletionOption.ResponseHeadersRead); ValidateStatusCode(m); - string response = await m.Content!.ReadAsStringAsync(); + string response = await m.Content.ReadAsStringAsync(); string checksumMessage = ValidateServerChecksum(m.TrailingHeaders, checksum, required: false) ? "server checksum matches client checksum" : "server checksum mismatch"; ValidateContent(content, await m.Content.ReadAsStringAsync(), checksumMessage); @@ -376,7 +376,7 @@ public static class ClientOperations using HttpResponseMessage m = await ctx.SendAsync(req, HttpCompletionOption.ResponseHeadersRead); ValidateStatusCode(m); - string response = await m.Content!.ReadAsStringAsync(); + string response = await m.Content.ReadAsStringAsync(); // trailing headers not supported for all servers, so do not require checksums bool isValidChecksum = ValidateServerChecksum(m.TrailingHeaders, checksum, required: false); @@ -416,7 +416,7 @@ public static class ClientOperations ValidateStatusCode(m); string checksumMessage = ValidateServerChecksum(m.Headers, checksum) ? "server checksum matches client checksum" : "server checksum mismatch"; - ValidateContent(content, await m.Content!.ReadAsStringAsync(), checksumMessage); + ValidateContent(content, await m.Content.ReadAsStringAsync(), checksumMessage); }), ("HEAD", @@ -428,7 +428,7 @@ public static class ClientOperations ValidateStatusCode(m); - if (m.Content!.Headers.ContentLength != expectedLength) + if (m.Content.Headers.ContentLength != expectedLength) { throw new Exception($"Expected {expectedLength}, got {m.Content.Headers.ContentLength}"); } @@ -446,7 +446,7 @@ public static class ClientOperations ValidateStatusCode(m); - string r = await m.Content!.ReadAsStringAsync(); + string r = await m.Content.ReadAsStringAsync(); if (r != "") throw new Exception($"Got unexpected response: {r}"); }), @@ -460,7 +460,7 @@ public static class ClientOperations ValidateStatusCode(m); - string r = await m.Content!.ReadAsStringAsync(); + string r = await m.Content.ReadAsStringAsync(); if (r != "") throw new Exception($"Got unexpected response: {r}"); }), @@ -472,7 +472,7 @@ public static class ClientOperations using HttpResponseMessage m = await ctx.SendAsync(req); ValidateStatusCode(m); - ValidateServerContent(await m.Content!.ReadAsStringAsync(), expectedLength); + ValidateServerContent(await m.Content.ReadAsStringAsync(), expectedLength); }), }; diff --git a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj index c14ef4c1dd220..b4c31ba80fd7b 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj @@ -70,6 +70,8 @@ Link="ProductionCode\Common\System\Threading\Tasks\TaskToApm.cs" /> + + + Date: Thu, 7 May 2020 17:11:28 -0700 Subject: [PATCH 043/420] Compile methods in canon form only (#36011) * Compile methods in canon form only - The previous logic would compile methods that were not in canonical form - These methods would never be used by the runtime, and contributed 70MB to a 170MB composite image - Also fix incorrect intrinsics count value --- .../JitInterface/CorInfoImpl.Intrinsics.cs | 2 +- .../ReadyToRunCodegenNodeFactory.cs | 29 +++++++------------ 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs index a0538e9063fdf..30bc7f772362b 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs @@ -164,7 +164,7 @@ static IntrinsicHashtable InitializeIntrinsicHashtable() table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_GetRawHandle, "AllocatorOf", "System", "Activator"); // If this assert fails, make sure to add the new intrinsics to the table above and update the expected count below. - Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_Count == 55, "Please update intrinsic hash table"); + Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_Count == 56, "Please update intrinsic hash table"); return table; } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs index f6bff77e9dc49..267b946973e75 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs @@ -67,19 +67,20 @@ public void SetMarkingComplete() _markingComplete = true; } - public IMethodNode CompiledMethodNode(MethodDesc method) - { - EcmaModule module = ((EcmaMethod)method.GetTypicalMethodDefinition()).Module; - ModuleToken moduleToken = Resolver.GetModuleTokenForMethod(method, throwIfNotFound: true); + private NodeCache _localMethodCache; - return CreateMethodEntrypointNodeHelper(new MethodWithToken(method, moduleToken, constrainedType: null)); + public MethodWithGCInfo CompiledMethodNode(MethodDesc method) + { + Debug.Assert(CompilationModuleGroup.ContainsMethodBody(method, false)); + Debug.Assert(method == method.GetCanonMethodTarget(CanonicalFormKind.Specific)); + return _localMethodCache.GetOrAdd(method); } private NodeCache _allMethodsOnType; public AllMethodsOnTypeNode AllMethodsOnType(TypeDesc type) { - return _allMethodsOnType.GetOrAdd(type); + return _allMethodsOnType.GetOrAdd(type.ConvertToCanonForm(CanonicalFormKind.Specific)); } private NodeCache _genericReadyToRunHelpersFromDict; @@ -350,7 +351,8 @@ private IMethodNode CreateMethodEntrypoint(TypeAndMethod key) bool isUnboxingStub = key.IsUnboxingStub; bool isInstantiatingStub = key.IsInstantiatingStub; bool isPrecodeImportRequired = key.IsPrecodeImportRequired; - if (CompilationModuleGroup.ContainsMethodBody(method.Method, false)) + MethodDesc compilableMethod = method.Method.GetCanonMethodTarget(CanonicalFormKind.Specific); + if (CompilationModuleGroup.ContainsMethodBody(compilableMethod, false)) { if (isPrecodeImportRequired) { @@ -358,7 +360,7 @@ private IMethodNode CreateMethodEntrypoint(TypeAndMethod key) this, ReadyToRunFixupKind.MethodEntry, method, - CreateMethodEntrypointNodeHelper(method), + CompiledMethodNode(compilableMethod), isUnboxingStub, isInstantiatingStub); } @@ -368,7 +370,7 @@ private IMethodNode CreateMethodEntrypoint(TypeAndMethod key) this, ReadyToRunFixupKind.MethodEntry, method, - CreateMethodEntrypointNodeHelper(method), + CompiledMethodNode(compilableMethod), isUnboxingStub, isInstantiatingStub); } @@ -391,15 +393,6 @@ public IMethodNode MethodEntrypoint(MethodWithToken method, bool isUnboxingStub, return _importMethods.GetOrAdd(key); } - private NodeCache _localMethodCache; - - private MethodWithGCInfo CreateMethodEntrypointNodeHelper(MethodWithToken targetMethod) - { - Debug.Assert(CompilationModuleGroup.ContainsMethodBody(targetMethod.Method, false)); - - return _localMethodCache.GetOrAdd(targetMethod.Method); - } - public IEnumerable EnumerateCompiledMethods() { return EnumerateCompiledMethods(null, CompiledMethodCategory.All); From aaaf9481a457c2b34be0dba889dc0ece8522d9fe Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 7 May 2020 17:30:07 -0700 Subject: [PATCH 044/420] Add staticapphost template entry to signexclusion file (#36043) --- eng/SignCheckExclusionsFile.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/SignCheckExclusionsFile.txt b/eng/SignCheckExclusionsFile.txt index a78ad401525dd..fd2b824540457 100644 --- a/eng/SignCheckExclusionsFile.txt +++ b/eng/SignCheckExclusionsFile.txt @@ -11,3 +11,4 @@ *comhost.dll;;Template, https://github.com/dotnet/core-setup/pull/7549 *apphosttemplateapphostexe.exe;;Template, https://github.com/dotnet/core-setup/pull/7549 *comhosttemplatecomhostdll.dll;;Template, https://github.com/dotnet/core-setup/pull/7549 +*staticapphosttemplateapphostexe.exe;;Template, https://github.com/dotnet/core-setup/pull/7549 From 17cff47fea6f36d68e4388a8b6986ae6cb129279 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 7 May 2020 20:58:18 -0400 Subject: [PATCH 045/420] Remove unnecessary recursive locking from Http2Stream.Complete (#36030) We just asserted we're holding the lock. We don't need to take it again. --- .../System/Net/Http/SocketsHttpHandler/Http2Stream.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs index 2948820a0aab1..6c66a674017b0 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs @@ -329,14 +329,11 @@ private void Complete() _connection.RemoveStream(this); - lock (SyncObject) + CreditWaiter? w = _creditWaiter; + if (w != null) { - CreditWaiter? w = _creditWaiter; - if (w != null) - { - w.Dispose(); - _creditWaiter = null; - } + w.Dispose(); + _creditWaiter = null; } } From 4804b8d9cd8805616c2424b4c698e528a477d9b0 Mon Sep 17 00:00:00 2001 From: Chaojie <42886212+v-chayan@users.noreply.github.com> Date: Fri, 8 May 2020 09:45:21 +0800 Subject: [PATCH 046/420] Delete task code that has been moved to the shared framework SDK in Arcade (#35405) * Delete task code that has been moved to the shared framework SDK in Arcade * Remove RegenerateReadmeTable.cs * Revert "Remove RegenerateReadmeTable.cs" This reverts commit 037f425853e5587da95404f07130e36efd6cb2e3. * BuildFPMToolPreReqs.cs is still needed for packaging Linux_x64 --- .../CopyNupkgAndChangeVersion.cs | 149 ------------- .../CreateFrameworkListFile.cs | 211 ------------------ .../tasks/installer.tasks/ExecWithRetries.cs | 116 ---------- .../GenerateDebRepoUploadJsonFile.cs | 44 ---- .../GenerateJsonObjectString.cs | 145 ------------ .../ProcessSharedFrameworkDeps.cs | 83 ------- .../installer.tasks/RuntimeGraphManager.cs | 65 ------ .../tasks/installer.tasks/RuntimeReference.cs | 63 ------ .../installer.tasks/StabilizeWixFileId.cs | 107 --------- .../ZipFileExtractToDirectory.cs | 86 ------- .../installer.tasks/ZipFileGetEntries.cs | 50 ----- 11 files changed, 1119 deletions(-) delete mode 100644 tools-local/tasks/installer.tasks/CopyNupkgAndChangeVersion.cs delete mode 100644 tools-local/tasks/installer.tasks/CreateFrameworkListFile.cs delete mode 100644 tools-local/tasks/installer.tasks/ExecWithRetries.cs delete mode 100644 tools-local/tasks/installer.tasks/GenerateDebRepoUploadJsonFile.cs delete mode 100644 tools-local/tasks/installer.tasks/GenerateJsonObjectString.cs delete mode 100644 tools-local/tasks/installer.tasks/ProcessSharedFrameworkDeps.cs delete mode 100644 tools-local/tasks/installer.tasks/RuntimeGraphManager.cs delete mode 100644 tools-local/tasks/installer.tasks/RuntimeReference.cs delete mode 100644 tools-local/tasks/installer.tasks/StabilizeWixFileId.cs delete mode 100644 tools-local/tasks/installer.tasks/ZipFileExtractToDirectory.cs delete mode 100644 tools-local/tasks/installer.tasks/ZipFileGetEntries.cs diff --git a/tools-local/tasks/installer.tasks/CopyNupkgAndChangeVersion.cs b/tools-local/tasks/installer.tasks/CopyNupkgAndChangeVersion.cs deleted file mode 100644 index 35f7a42121402..0000000000000 --- a/tools-local/tasks/installer.tasks/CopyNupkgAndChangeVersion.cs +++ /dev/null @@ -1,149 +0,0 @@ -// 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. - -using Microsoft.Build.Framework; -using Newtonsoft.Json.Linq; -using NuGet.Versioning; -using System; -using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Xml.Linq; - -namespace Microsoft.DotNet.Build.Tasks -{ - public class CopyNupkgAndChangeVersion : BuildTask - { - [Required] - public string SourceFile { get; set; } - - [Required] - public string TargetFile { get; set; } - - [Required] - public string OriginalVersion { get; set; } - - [Required] - public string TargetVersion { get; set; } - - public string[] DependencyPackageIdsToChange { get; set; } - - public override bool Execute() - { - Directory.CreateDirectory(Path.GetDirectoryName(TargetFile)); - File.Copy(SourceFile, TargetFile, true); - - using (ZipArchive zip = ZipFile.Open(TargetFile, ZipArchiveMode.Update)) - { - RewriteNuspec(zip); - RewriteRuntimeJson(zip); - } - - return !Log.HasLoggedErrors; - } - - private void RewriteNuspec(ZipArchive zip) - { - foreach (var nuspec in zip.Entries.Where(e => e.FullName.EndsWith(".nuspec"))) - { - Rewrite(nuspec, s => - { - XDocument content = XDocument.Parse(s); - - RewriteNuspecPackageVersion(content); - RewriteNuspecDependencyVersions(content); - - return content.ToString(); - }); - } - } - - private void RewriteRuntimeJson(ZipArchive zip) - { - foreach (var runtimeJson in zip.Entries.Where(e => e.FullName == "runtime.json")) - { - Rewrite(runtimeJson, s => - { - JObject content = JObject.Parse(s); - - RewriteRuntimeJsonVersions(content); - - return content.ToString(); - }); - } - } - - private void RewriteNuspecPackageVersion(XDocument content) - { - XElement versionElement = content - .Element(CreateQualifiedName(content, "package")) - .Element(CreateQualifiedName(content, "metadata")) - .Element(CreateQualifiedName(content, "version")); - - if (versionElement.Value != OriginalVersion) - { - Log.LogError( - $"Original version is '{versionElement.Value}', " + - $"expected '{OriginalVersion}'"); - } - - versionElement.Value = TargetVersion; - } - - private void RewriteNuspecDependencyVersions(XDocument content) - { - foreach (var dependency in content - .Descendants(CreateQualifiedName(content, "dependency")) - .Where(x => - x.Attribute("version").Value == OriginalVersion && - DependencyPackageIdsToChange?.Contains(x.Attribute("id").Value) == true)) - { - dependency.Value = TargetVersion; - } - } - - private void RewriteRuntimeJsonVersions(JObject content) - { - var versionProperties = content - .Descendants() - .OfType() - .Where(p => - p.Value is JValue v && - v.Type == JTokenType.String); - - foreach (var p in versionProperties) - { - var range = VersionRange.Parse(p.Value.Value()); - - if (range.MinVersion.OriginalVersion == OriginalVersion) - { - var newRange = new VersionRange( - NuGetVersion.Parse(TargetVersion), - range.Float); - - p.Value = newRange.ToString(); - } - } - } - - private static XName CreateQualifiedName(XDocument doc, string name) - { - return doc.Root.GetDefaultNamespace().GetName(name); - } - - private static void Rewrite(ZipArchiveEntry entry, Func rewrite) - { - using (var stream = entry.Open()) - using (var reader = new StreamReader(stream)) - using (var writer = new StreamWriter(stream)) - { - var content = rewrite(reader.ReadToEnd()); - - stream.Position = 0; - stream.SetLength(0); - writer.Write(content); - } - } - } -} diff --git a/tools-local/tasks/installer.tasks/CreateFrameworkListFile.cs b/tools-local/tasks/installer.tasks/CreateFrameworkListFile.cs deleted file mode 100644 index 36a3dd59386c0..0000000000000 --- a/tools-local/tasks/installer.tasks/CreateFrameworkListFile.cs +++ /dev/null @@ -1,211 +0,0 @@ -// 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. - -using Microsoft.Build.Framework; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Xml.Linq; - -namespace Microsoft.DotNet.Build.Tasks -{ - public class CreateFrameworkListFile : BuildTask - { - /// - /// Files to extract basic information from and include in the list. - /// - [Required] - public ITaskItem[] Files { get; set; } - - /// - /// A list of assembly names with classification info such as Profile. A - /// Profile="%(Profile)" attribute is included in the framework list for the matching Files - /// item if %(Profile) contains text. - /// - /// If *any* FileClassifications are passed: - /// - /// *Every* file that ends up listed in the framework list must have a matching - /// FileClassification. - /// - /// Additionally, every FileClassification must find exactly one File. - /// - /// This task fails if the conditions aren't met. This ensures the classification doesn't - /// become out of date when the list of files changes. - /// - /// %(Identity): Assembly name (including ".dll"). - /// %(Profile): List of profiles that apply, semicolon-delimited. - /// %(ReferencedByDefault): Empty (default) or "true"/"false". Indicates whether this file - /// should be referenced by default when the SDK uses this framework. - /// - public ITaskItem[] FileClassifications { get; set; } - - [Required] - public string TargetFile { get; set; } - - public string[] TargetFilePrefixes { get; set; } - - /// - /// Extra attributes to place on the root node. - /// - /// %(Identity): Attribute name. - /// %(Value): Attribute value. - /// - public ITaskItem[] RootAttributes { get; set; } - - public override bool Execute() - { - XAttribute[] rootAttributes = RootAttributes - ?.Select(item => new XAttribute(item.ItemSpec, item.GetMetadata("Value"))) - .ToArray(); - - var frameworkManifest = new XElement("FileList", rootAttributes); - - Dictionary fileClassLookup = FileClassifications - ?.ToDictionary( - item => item.ItemSpec, - item => item, - StringComparer.OrdinalIgnoreCase); - - var usedFileClasses = new HashSet(); - - foreach (var f in Files - .Where(IsTargetPathIncluded) - .Select(item => new - { - Item = item, - Filename = Path.GetFileName(item.ItemSpec), - TargetPath = item.GetMetadata("TargetPath"), - AssemblyName = FileUtilities.GetAssemblyName(item.ItemSpec), - FileVersion = FileUtilities.GetFileVersion(item.ItemSpec), - IsNative = item.GetMetadata("IsNative") == "true", - IsSymbolFile = item.GetMetadata("IsSymbolFile") == "true", - IsResourceFile = item.ItemSpec - .EndsWith(".resources.dll", StringComparison.OrdinalIgnoreCase) - }) - .Where(f => - !f.IsSymbolFile && - (f.Filename.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || f.IsNative)) - // Remove duplicate files this task is given. - .GroupBy(f => f.Item.ItemSpec) - .Select(g => g.First()) - // Make order stable between builds. - .OrderBy(f => f.TargetPath, StringComparer.Ordinal) - .ThenBy(f => f.Filename, StringComparer.Ordinal)) - { - string type = "Managed"; - - if (f.IsNative) - { - type = "Native"; - } - else if (f.IsResourceFile) - { - type = "Resources"; - } - - string path = Path.Combine(f.TargetPath, f.Filename).Replace('\\', '/'); - - if (path.StartsWith("runtimes/")) - { - var pathParts = path.Split('/'); - if (pathParts.Length > 1 && pathParts[1].Contains("_")) - { - // This file is a runtime file with a "rid" containing "_". This is assumed - // to mean it's a cross-targeting tool and shouldn't be deployed in a - // self-contained app. Leave it off the list. - continue; - } - } - - var element = new XElement( - "File", - new XAttribute("Type", type), - new XAttribute("Path", path)); - - if (f.IsResourceFile) - { - element.Add( - new XAttribute("Culture", Path.GetFileName(Path.GetDirectoryName(path)))); - } - - if (f.AssemblyName != null) - { - byte[] publicKeyToken = f.AssemblyName.GetPublicKeyToken(); - string publicKeyTokenHex; - - if (publicKeyToken != null) - { - publicKeyTokenHex = BitConverter.ToString(publicKeyToken) - .ToLowerInvariant() - .Replace("-", ""); - } - else - { - Log.LogError($"No public key token found for assembly {f.Item.ItemSpec}"); - publicKeyTokenHex = ""; - } - - element.Add( - new XAttribute("AssemblyName", f.AssemblyName.Name), - new XAttribute("PublicKeyToken", publicKeyTokenHex), - new XAttribute("AssemblyVersion", f.AssemblyName.Version)); - } - else if (!f.IsNative) - { - // This file isn't managed and isn't native. Leave it off the list. - continue; - } - - element.Add(new XAttribute("FileVersion", f.FileVersion)); - - if (fileClassLookup != null) - { - if (fileClassLookup.TryGetValue(f.Filename, out ITaskItem classItem)) - { - string profile = classItem.GetMetadata("Profile"); - - if (!string.IsNullOrEmpty(profile)) - { - element.Add(new XAttribute("Profile", profile)); - } - - string referencedByDefault = classItem.GetMetadata("ReferencedByDefault"); - - if (!string.IsNullOrEmpty(referencedByDefault)) - { - element.Add(new XAttribute("ReferencedByDefault", referencedByDefault)); - } - - usedFileClasses.Add(f.Filename); - } - else - { - Log.LogError($"File matches no classification: {f.Filename}"); - } - } - - frameworkManifest.Add(element); - } - - foreach (var unused in fileClassLookup - ?.Keys.Except(usedFileClasses).OrderBy(p => p) - ?? Enumerable.Empty()) - { - Log.LogError($"Classification matches no files: {unused}"); - } - - Directory.CreateDirectory(Path.GetDirectoryName(TargetFile)); - File.WriteAllText(TargetFile, frameworkManifest.ToString()); - - return !Log.HasLoggedErrors; - } - - private bool IsTargetPathIncluded(ITaskItem item) - { - return TargetFilePrefixes - ?.Any(prefix => item.GetMetadata("TargetPath")?.StartsWith(prefix) == true) ?? true; - } - } -} diff --git a/tools-local/tasks/installer.tasks/ExecWithRetries.cs b/tools-local/tasks/installer.tasks/ExecWithRetries.cs deleted file mode 100644 index 5e57c39f45819..0000000000000 --- a/tools-local/tasks/installer.tasks/ExecWithRetries.cs +++ /dev/null @@ -1,116 +0,0 @@ -// 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. - -// Initially copied from https://github.com/dotnet/buildtools/blob/6736870b84e06b75e7df32bb84d442db1b2afa10/src/Microsoft.DotNet.Build.Tasks/ExecWithRetries.cs - -using Microsoft.Build.Framework; -using Microsoft.Build.Tasks; -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.DotNet.Build.Tasks -{ - /// - /// Run a command and retry if the exit code is not 0. - /// - public class ExecWithRetries : BuildTask - { - [Required] - public string Command { get; set; } - - public string WorkingDirectory { get; set; } - - public bool IgnoreStandardErrorWarningFormat { get; set; } - - public int MaxAttempts { get; set; } = 5; - - /// - /// Base, in seconds, raised to the power of the number of retries so far. - /// - public double RetryDelayBase { get; set; } = 6; - - /// - /// A constant, in seconds, added to (base^retries) to find the delay before retrying. - /// - /// The default is -1 to make the first retry instant, because ((base^0)-1) == 0. - /// - public double RetryDelayConstant { get; set; } = -1; - - /// - /// MSBuild message importance to use when logging stdout messages from the command. Default - /// is "High". - /// - public string StandardOutputImportance { get; set; } - - /// - /// MSBuild message importance to use when logging stderr messages from the command. Default - /// is "High". - /// - public string StandardErrorImportance { get; set; } - - private CancellationTokenSource _cancelTokenSource = new CancellationTokenSource(); - - private Exec _runningExec; - - public void Cancel() - { - _runningExec?.Cancel(); - _cancelTokenSource.Cancel(); - } - - public override bool Execute() - { - for (int i = 0; i < MaxAttempts; i++) - { - _runningExec = new Exec - { - BuildEngine = BuildEngine, - Command = Command, - WorkingDirectory = WorkingDirectory, - IgnoreStandardErrorWarningFormat = IgnoreStandardErrorWarningFormat, - StandardOutputImportance = StandardOutputImportance, - StandardErrorImportance = StandardErrorImportance, - LogStandardErrorAsError = false, - IgnoreExitCode = true - }; - - if (!_runningExec.Execute()) - { - Log.LogError("Child Exec task failed to execute."); - break; - } - - int exitCode = _runningExec.ExitCode; - if (exitCode == 0) - { - return true; - } - - string message = $"Exec FAILED: exit code {exitCode} (attempt {i + 1}/{MaxAttempts})"; - - if (i + 1 == MaxAttempts || _cancelTokenSource.IsCancellationRequested) - { - Log.LogError(message); - break; - } - - TimeSpan delay = TimeSpan.FromSeconds( - Math.Pow(RetryDelayBase, i) + RetryDelayConstant); - - Log.LogMessage(MessageImportance.High, $"{message} -- Retrying after {delay}..."); - - try - { - Task.Delay(delay, _cancelTokenSource.Token).Wait(); - } - catch (AggregateException e) when (e.InnerException is TaskCanceledException) - { - break; - } - } - return false; - } - } -} diff --git a/tools-local/tasks/installer.tasks/GenerateDebRepoUploadJsonFile.cs b/tools-local/tasks/installer.tasks/GenerateDebRepoUploadJsonFile.cs deleted file mode 100644 index 51e373915cb27..0000000000000 --- a/tools-local/tasks/installer.tasks/GenerateDebRepoUploadJsonFile.cs +++ /dev/null @@ -1,44 +0,0 @@ -// 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. - -using Microsoft.Build.Framework; -using System.IO; - - -namespace Microsoft.DotNet.Build.Tasks -{ - public partial class GenerateDebRepoUploadJsonFile : BuildTask - { - private const string _debianRevisionNumber = "1"; - [Required] - public string RepoId { get; set; } - [Required] - public string UploadJsonFilename { get; set; } - [Required] - public string PackageName { get; set; } - [Required] - public string PackageVersion { get; set; } - [Required] - public string UploadUrl { get; set; } - - public override bool Execute() - { - File.Delete(UploadJsonFilename); - - using (var fileStream = File.Create(UploadJsonFilename)) - { - using (StreamWriter sw = new StreamWriter(fileStream)) - { - sw.WriteLine("{"); - sw.WriteLine($" \"name\":\"{PackageName}\","); - sw.WriteLine($" \"version\":\"{PackageVersion}-{_debianRevisionNumber}\","); - sw.WriteLine($" \"repositoryId\":\"{RepoId}\","); - sw.WriteLine($" \"sourceUrl\":\"{UploadUrl}\""); - sw.WriteLine("}"); - } - } - return !Log.HasLoggedErrors; - } - } -} \ No newline at end of file diff --git a/tools-local/tasks/installer.tasks/GenerateJsonObjectString.cs b/tools-local/tasks/installer.tasks/GenerateJsonObjectString.cs deleted file mode 100644 index 558c4b1654eee..0000000000000 --- a/tools-local/tasks/installer.tasks/GenerateJsonObjectString.cs +++ /dev/null @@ -1,145 +0,0 @@ -// 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. - -using Microsoft.Build.Framework; -using System; -using System.IO; -using System.Linq; -using System.Text; - -namespace Microsoft.DotNet.Build.Tasks -{ - public class GenerateJsonObjectString : BuildTask - { - private static readonly string __indent1 = new string(' ', 4); - private static readonly string __indent2 = new string(' ', 8); - - /// - /// Properties to include. If multiple properties have the same name, each property value is - /// included in an array. Only specify one value metadata: the first value is used. - /// - /// %(Identity): Name of the property. - /// %(String): String value of the property. This task adds quotes around it in the JSON. - /// %(Object): Object value of the property. Create this with a nested call to this task. - /// - [Required] - public ITaskItem[] Properties { get; set; } - - /// - /// If set, also write the output JSON string to this file. - /// - public string TargetFile { get; set; } - - [Output] - public string Json { get; set; } - - public override bool Execute() - { - var result = new StringBuilder(); - result.AppendLine("{"); - - bool firstProperty = true; - - foreach (var group in Properties.GroupBy(item => item.ItemSpec)) - { - if (firstProperty) - { - firstProperty = false; - } - else - { - result.AppendLine(","); - } - - result.Append(__indent1); - result.Append("\""); - result.Append(group.Key); - result.Append("\": "); - - if (group.Count() == 1) - { - ITaskItem item = group.First(); - WriteProperty(result, item, __indent1); - } - else - { - result.AppendLine("["); - - bool firstArrayLine = true; - - foreach (ITaskItem item in group) - { - if (firstArrayLine) - { - firstArrayLine = false; - } - else - { - result.AppendLine(","); - } - - result.Append(__indent2); - WriteProperty(result, item, __indent2); - } - - result.AppendLine(); - result.Append(__indent1); - result.Append("]"); - } - } - - result.AppendLine(); - result.AppendLine("}"); - - Json = result.ToString(); - - if (!string.IsNullOrEmpty(TargetFile)) - { - Directory.CreateDirectory(Path.GetDirectoryName(TargetFile)); - File.WriteAllText(TargetFile, Json); - } - - return !Log.HasLoggedErrors; - } - - private void WriteProperty(StringBuilder result, ITaskItem item, string indent) - { - string stringValue = item.GetMetadata("String"); - string objectValue = item.GetMetadata("Object"); - - if (!string.IsNullOrEmpty(stringValue)) - { - result.Append("\""); - result.Append(stringValue); - result.Append("\""); - } - else if (!string.IsNullOrEmpty(objectValue)) - { - bool firstObjectLine = true; - - foreach (var line in objectValue.Split( - new[] {Environment.NewLine}, - StringSplitOptions.RemoveEmptyEntries)) - { - if (firstObjectLine) - { - firstObjectLine = false; - } - else - { - result.AppendLine(); - result.Append(indent); - } - - result.Append(line); - } - } - else - { - Log.LogError($"Item '{item.ItemSpec}' has no String or Object value."); - result.Append("null"); - } - } - } -} diff --git a/tools-local/tasks/installer.tasks/ProcessSharedFrameworkDeps.cs b/tools-local/tasks/installer.tasks/ProcessSharedFrameworkDeps.cs deleted file mode 100644 index 687a8c1448b75..0000000000000 --- a/tools-local/tasks/installer.tasks/ProcessSharedFrameworkDeps.cs +++ /dev/null @@ -1,83 +0,0 @@ -// 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. - -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using Microsoft.Extensions.DependencyModel; -using NuGet.Common; -using NuGet.ProjectModel; -using System; -using System.IO; -using System.Linq; - -namespace Microsoft.DotNet.Build.Tasks -{ - public partial class ProcessSharedFrameworkDeps : Task - { - [Required] - public string AssetsFilePath { get; set; } - - [Required] - public string DepsFilePath { get; set; } - - [Required] - public string[] PackagesToRemove { get; set; } - - [Required] - public string Runtime { get; set; } - - [Required] - public string BuildTasksAssemblyPath { get; set; } - - public override bool Execute() - { - EnsureInitialized(BuildTasksAssemblyPath); - - ExecuteCore(); - - return true; - } - - private void ExecuteCore() - { - DependencyContext context; - using (var depsStream = File.OpenRead(DepsFilePath)) - { - context = new DependencyContextJsonReader().Read(depsStream); - } - - LockFile lockFile = LockFileUtilities.GetLockFile(AssetsFilePath, NullLogger.Instance); - if (lockFile == null) - { - throw new ArgumentException($"Could not load a LockFile at '{AssetsFilePath}'.", nameof(AssetsFilePath)); - } - - var manager = new RuntimeGraphManager(); - var graph = manager.Collect(lockFile); - var expandedGraph = manager.Expand(graph, Runtime); - - var trimmedRuntimeLibraries = context.RuntimeLibraries; - - if (PackagesToRemove != null && PackagesToRemove.Any()) - { - trimmedRuntimeLibraries = RuntimeReference.RemoveReferences(context.RuntimeLibraries, PackagesToRemove); - } - - context = new DependencyContext( - context.Target, - context.CompilationOptions, - context.CompileLibraries, - trimmedRuntimeLibraries, - expandedGraph - ); - - using (var depsStream = File.Create(DepsFilePath)) - { - new DependencyContextWriter().Write(context, depsStream); - } - } - - partial void EnsureInitialized(string buildTasksAssemblyPath); - } -} diff --git a/tools-local/tasks/installer.tasks/RuntimeGraphManager.cs b/tools-local/tasks/installer.tasks/RuntimeGraphManager.cs deleted file mode 100644 index 2bedeef64b844..0000000000000 --- a/tools-local/tasks/installer.tasks/RuntimeGraphManager.cs +++ /dev/null @@ -1,65 +0,0 @@ -// 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. - -using Microsoft.Extensions.DependencyModel; -using NuGet.Packaging; -using NuGet.ProjectModel; -using NuGet.RuntimeModel; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace Microsoft.DotNet.Build.Tasks -{ - internal class RuntimeGraphManager - { - private const string RuntimeJsonFileName = "runtime.json"; - - public RuntimeGraph Collect(LockFile lockFile) - { - string userPackageFolder = lockFile.PackageFolders.FirstOrDefault()?.Path; - var fallBackFolders = lockFile.PackageFolders.Skip(1).Select(f => f.Path); - var packageResolver = new FallbackPackagePathResolver(userPackageFolder, fallBackFolders); - - var graph = RuntimeGraph.Empty; - foreach (var library in lockFile.Libraries) - { - if (string.Equals(library.Type, "package", StringComparison.OrdinalIgnoreCase)) - { - var runtimeJson = library.Files.FirstOrDefault(f => f == RuntimeJsonFileName); - if (runtimeJson != null) - { - var libraryPath = packageResolver.GetPackageDirectory(library.Name, library.Version); - var runtimeJsonFullName = Path.Combine(libraryPath, runtimeJson); - graph = RuntimeGraph.Merge(graph, JsonRuntimeFormat.ReadRuntimeGraph(runtimeJsonFullName)); - } - } - } - return graph; - } - - public IEnumerable Expand(RuntimeGraph runtimeGraph, string runtime) - { - var importers = FindImporters(runtimeGraph, runtime); - foreach (var importer in importers) - { - // ExpandRuntime return runtime itself as first item so we are skiping it - yield return new RuntimeFallbacks(importer, runtimeGraph.ExpandRuntime(importer).Skip(1)); - } - } - - private IEnumerable FindImporters(RuntimeGraph runtimeGraph, string runtime) - { - foreach (var runtimePair in runtimeGraph.Runtimes) - { - var expanded = runtimeGraph.ExpandRuntime(runtimePair.Key); - if (expanded.Contains(runtime)) - { - yield return runtimePair.Key; - } - } - } - } -} diff --git a/tools-local/tasks/installer.tasks/RuntimeReference.cs b/tools-local/tasks/installer.tasks/RuntimeReference.cs deleted file mode 100644 index ead20e864c062..0000000000000 --- a/tools-local/tasks/installer.tasks/RuntimeReference.cs +++ /dev/null @@ -1,63 +0,0 @@ -// 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. - -using Microsoft.Extensions.DependencyModel; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Microsoft.DotNet.Build.Tasks -{ - internal class RuntimeReference - { - public static List RemoveReferences(IReadOnlyList runtimeLibraries, IEnumerable packages) - { - List result = new List(); - - foreach (var runtimeLib in runtimeLibraries) - { - if (string.IsNullOrEmpty(packages.FirstOrDefault(elem => runtimeLib.Name.Equals(elem, StringComparison.OrdinalIgnoreCase)))) - { - List toRemoveDependecy = new List(); - foreach (var dependency in runtimeLib.Dependencies) - { - if (!string.IsNullOrEmpty(packages.FirstOrDefault(elem => dependency.Name.Equals(elem, StringComparison.OrdinalIgnoreCase)))) - { - toRemoveDependecy.Add(dependency); - } - } - - if (toRemoveDependecy.Count > 0) - { - List modifiedDependencies = new List(); - foreach (var dependency in runtimeLib.Dependencies) - { - if (!toRemoveDependecy.Contains(dependency)) - { - modifiedDependencies.Add(dependency); - } - } - - - result.Add(new RuntimeLibrary(runtimeLib.Type, - runtimeLib.Name, - runtimeLib.Version, - runtimeLib.Hash, - runtimeLib.RuntimeAssemblyGroups, - runtimeLib.NativeLibraryGroups, - runtimeLib.ResourceAssemblies, - modifiedDependencies, - runtimeLib.Serviceable)); - - } - else if (string.IsNullOrEmpty(packages.FirstOrDefault(elem => runtimeLib.Name.Equals(elem, StringComparison.OrdinalIgnoreCase)))) - { - result.Add(runtimeLib); - } - } - } - return result; - } - } -} diff --git a/tools-local/tasks/installer.tasks/StabilizeWixFileId.cs b/tools-local/tasks/installer.tasks/StabilizeWixFileId.cs deleted file mode 100644 index 6a76df1df2bd4..0000000000000 --- a/tools-local/tasks/installer.tasks/StabilizeWixFileId.cs +++ /dev/null @@ -1,107 +0,0 @@ -// 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. - -using Microsoft.Build.Framework; -using System; -using System.Diagnostics; -using System.Linq; -using System.Xml.Linq; - -namespace Microsoft.DotNet.Build.Tasks -{ - /// - /// In a WiX source file, replaces the Id of a File with some given string in order to stabilize - /// it. This allows external tooling such as signature validators to rely on a stable identifier - /// for certain files. - /// - public class StabilizeWixFileId : BuildTask - { - /// - /// File to read from. This is expected to be an output from heat.exe. - /// - /// Expected format: - /// - /// - /// - /// - /// - /// - /// - /// ... - /// - [Required] - public string SourceFile { get; set; } - - /// - /// File to write to. May be the same as SourceFile. - /// - [Required] - public string OutputFile { get; set; } - - /// - /// Set of files to stabilize. This matches the end of the "Source" attribute in the WiX - /// source file. If exactly one match isn't found in the WiX source file, this task fails. - /// - /// %(Identity): The file source to replace. - /// %(ReplacementId): The replacement for Id that won't change per-build. - /// - [Required] - public ITaskItem[] FileElementToStabilize { get; set; } - - public override bool Execute() - { - XDocument content = XDocument.Load(SourceFile); - - XNamespace rootNamespace = content.Root.GetDefaultNamespace(); - XName GetQualifiedName(string name) => rootNamespace.GetName(name); - - foreach (var file in FileElementToStabilize) - { - string replacement = file.GetMetadata("ReplacementId"); - - if (string.IsNullOrEmpty(replacement)) - { - Log.LogError($"{nameof(FileElementToStabilize)} {file.ItemSpec} has null/empty ReplacementId metadata."); - continue; - } - - XElement[] matchingFileElements = content.Element(GetQualifiedName("Wix")) - .Elements(GetQualifiedName("Fragment")) - .SelectMany(f => f.Elements(GetQualifiedName("ComponentGroup"))) - .SelectMany(cg => cg.Elements(GetQualifiedName("Component"))) - .SelectMany(c => c.Elements(GetQualifiedName("File"))) - .Where(f => f.Attribute("Source")?.Value - ?.EndsWith(file.ItemSpec, StringComparison.OrdinalIgnoreCase) == true) - .ToArray(); - - if (matchingFileElements.Length != 1) - { - Log.LogError( - $"Expected 1 match for '{file.ItemSpec}', found {matchingFileElements.Length}: " + - string.Join(", ", matchingFileElements.Select(e => e.ToString()))); - - continue; - } - - XAttribute nameAttribute = matchingFileElements[0].Attribute("Id"); - - if (nameAttribute is null) - { - Log.LogError($"Match has no Id attribute: {matchingFileElements[0]}"); - continue; - } - - Log.LogMessage( - $"Setting '{file.ItemSpec}' Id to '{replacement}' for File with Source " + - matchingFileElements[0].Attribute("Source").Value); - - nameAttribute.Value = replacement; - } - - content.Save(OutputFile); - - return !Log.HasLoggedErrors; - } - } -} diff --git a/tools-local/tasks/installer.tasks/ZipFileExtractToDirectory.cs b/tools-local/tasks/installer.tasks/ZipFileExtractToDirectory.cs deleted file mode 100644 index e03a860819ec3..0000000000000 --- a/tools-local/tasks/installer.tasks/ZipFileExtractToDirectory.cs +++ /dev/null @@ -1,86 +0,0 @@ -// 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. - -using Microsoft.Build.Framework; -using System; -using System.IO; -using System.IO.Compression; - -namespace Microsoft.DotNet.Build.Tasks -{ - public sealed class ZipFileExtractToDirectory : BuildTask - { - /// - /// The path to the archive to be extracted. - /// - [Required] - public string SourceArchive { get; set; } - - /// - /// The path of the directory to extract into. - /// - [Required] - public string DestinationDirectory { get; set; } - - /// - /// Indicates if the destination directory should be overwritten if it already exists. - /// - public bool OverwriteDestination { get; set; } - - /// - /// File entries to include in the extraction. Entries are relative - /// paths inside the archive. If null or empty, all files are extracted. - /// - public ITaskItem[] Include { get; set; } - - public override bool Execute() - { - try - { - if (Directory.Exists(DestinationDirectory)) - { - if (OverwriteDestination) - { - Log.LogMessage(MessageImportance.Low, $"'{DestinationDirectory}' already exists, trying to delete before unzipping..."); - Directory.Delete(DestinationDirectory, recursive: true); - } - else - { - Log.LogWarning($"'{DestinationDirectory}' already exists. Did you forget to set '{nameof(OverwriteDestination)}' to true?"); - } - } - - Log.LogMessage(MessageImportance.High, "Decompressing '{0}' into '{1}'...", SourceArchive, DestinationDirectory); - Directory.CreateDirectory(Path.GetDirectoryName(DestinationDirectory)); - - using (ZipArchive archive = ZipFile.OpenRead(SourceArchive)) - { - if (Include?.Length > 0) - { - foreach (ITaskItem entryItem in Include) - { - ZipArchiveEntry entry = archive.GetEntry(entryItem.ItemSpec); - string destinationPath = Path.Combine(DestinationDirectory, entryItem.ItemSpec); - - Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)); - entry.ExtractToFile(destinationPath, overwrite: false); - } - } - else - { - archive.ExtractToDirectory(DestinationDirectory); - } - } - } - catch (Exception e) - { - // We have 2 log calls because we want a nice error message but we also want to capture the callstack in the log. - Log.LogError("An exception has occurred while trying to decompress '{0}' into '{1}'.", SourceArchive, DestinationDirectory); - Log.LogErrorFromException(e, /*show stack=*/ true, /*show detail=*/ true, DestinationDirectory); - return false; - } - return true; - } - } -} diff --git a/tools-local/tasks/installer.tasks/ZipFileGetEntries.cs b/tools-local/tasks/installer.tasks/ZipFileGetEntries.cs deleted file mode 100644 index 56b1e3804e187..0000000000000 --- a/tools-local/tasks/installer.tasks/ZipFileGetEntries.cs +++ /dev/null @@ -1,50 +0,0 @@ -// 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. - -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using System; -using System.IO.Compression; -using System.Linq; - -namespace Microsoft.DotNet.Build.Tasks -{ - public sealed class ZipFileGetEntries : BuildTask - { - /// - /// The path to the archive. - /// - [Required] - public string TargetArchive { get; set; } - - /// - /// Generated items where each ItemSpec is the relative location of a - /// file entry in the zip archive. - /// - [Output] - public ITaskItem[] Entries { get; set; } - - public override bool Execute() - { - try - { - using (ZipArchive archive = ZipFile.OpenRead(TargetArchive)) - { - Entries = archive.Entries - // Escape '%' so encoded '+' in the nupkg stays encoded through MSBuild. - .Select(e => new TaskItem(e.FullName.Replace("%", "%25"))) - .ToArray(); - } - } - catch (Exception e) - { - // We have 2 log calls because we want a nice error message but we also want to capture the callstack in the log. - Log.LogError($"An exception has occurred while trying to read entries from '{TargetArchive}'."); - Log.LogErrorFromException(e, /*show stack=*/ true, /*show detail=*/ true, TargetArchive); - return false; - } - return true; - } - } -} From 16b7db27c98dce5b4d15894db13acd629b8fea62 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 7 May 2020 19:20:23 -0700 Subject: [PATCH 047/420] Add support for ComWrappers-based RCWs to the special native WeakReference support. (#35819) * Add support for ComWrappers-based RCWs to the special native WeakReference support. Rename the WinRT weak reference handle to "native COM weak reference" handle. * Fix line endings. * Fix line endings (try 2). * Revert change to prebuilt idl * Try updating prebuilt again. * Remove accidental duplicate of the test. * PR feedback. * PR Feedback. * React to global ComWrappers changes. * Add back WinRT enum member to prebuilt idl. * Add back old enum member to idl for backcompat. * Change definition of enum member to explicitly assign the same value. * Code cleanup and go down a non-allocating route when possible. * Switch to preemptive mode for the QI call. * Fix contracts * Add a check before calling GetComWeakReference so we only call it when the object has interop info attached. * Apply early check to WeakReference as well. * Make sure we only make one call to PassiveGetSyncBlock instead of 2. * PR Feedback. * ComWrappersNative::GetIdentityForObject can trigger GC since we transition to and from pre-emptive when calling into the external QI. --- .../Runtime/InteropServices/ComWrappers.cs | 9 +- src/coreclr/src/debug/daccess/daccess.cpp | 2 +- src/coreclr/src/debug/daccess/dacdbiimpl.cpp | 8 +- src/coreclr/src/debug/daccess/request.cpp | 4 +- src/coreclr/src/dlls/mscorrc/mscorrc.rc | 2 +- src/coreclr/src/dlls/mscorrc/resource.h | 2 +- src/coreclr/src/gc/gchandletable.cpp | 2 +- src/coreclr/src/gc/gcinterface.h | 8 +- src/coreclr/src/gc/handletable.cpp | 6 +- src/coreclr/src/gc/objecthandle.cpp | 16 +- src/coreclr/src/inc/cordebug.idl | 3 +- src/coreclr/src/pal/prebuilt/inc/cordebug.h | 3 +- src/coreclr/src/vm/appdomain.hpp | 4 +- src/coreclr/src/vm/ecalllist.h | 1 + src/coreclr/src/vm/gchandleutilities.h | 10 +- src/coreclr/src/vm/interoplibinterface.cpp | 115 ++++++++++- src/coreclr/src/vm/interoplibinterface.h | 22 +++ src/coreclr/src/vm/marshalnative.cpp | 2 +- src/coreclr/src/vm/runtimehandles.cpp | 2 +- src/coreclr/src/vm/weakreferencenative.cpp | 186 ++++++++++-------- src/coreclr/tests/src/Interop/CMakeLists.txt | 1 + .../ComWrappers/WeakReference/CMakeLists.txt | 10 + .../WeakReference/WeakReferenceNative.cpp | 124 ++++++++++++ .../WeakReference/WeakReferenceTest.cs | 137 +++++++++++++ .../WeakReference/WeakReferenceTest.csproj | 24 +++ .../tests/src/Interop/common/ComHelpers.h | 6 + 26 files changed, 587 insertions(+), 122 deletions(-) create mode 100644 src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/CMakeLists.txt create mode 100644 src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp create mode 100644 src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs create mode 100644 src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs index 323e60a564801..8c377012666b5 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs @@ -331,8 +331,15 @@ public static void RegisterForTrackerSupport(ComWrappers instance) { throw new InvalidOperationException(SR.InvalidOperation_ResetGlobalComWrappersInstance); } + + SetGlobalInstanceRegisteredForTrackerSupport(); } + + [DllImport(RuntimeHelpers.QCall)] + [SuppressGCTransition] + private static extern void SetGlobalInstanceRegisteredForTrackerSupport(); + /// /// Register a instance to be used as the global instance for marshalling in the runtime. /// @@ -390,4 +397,4 @@ internal static int CallICustomQueryInterface(object customQueryInterfaceMaybe, return (int)customQueryInterface.GetInterface(ref iid, out ppObject); } } -} \ No newline at end of file +} diff --git a/src/coreclr/src/debug/daccess/daccess.cpp b/src/coreclr/src/debug/daccess/daccess.cpp index a05d4f09d0d68..444114587c2ab 100644 --- a/src/coreclr/src/debug/daccess/daccess.cpp +++ b/src/coreclr/src/debug/daccess/daccess.cpp @@ -8252,7 +8252,7 @@ void CALLBACK DacHandleWalker::EnumCallbackSOS(PTR_UNCHECKED_OBJECTREF handle, u if (param->Type == HNDTYPE_DEPENDENT) data.Secondary = GetDependentHandleSecondary(handle.GetAddr()).GetAddr(); #ifdef FEATURE_COMINTEROP - else if (param->Type == HNDTYPE_WEAK_WINRT) + else if (param->Type == HNDTYPE_WEAK_NATIVE_COM) data.Secondary = HndGetHandleExtraInfo(handle.GetAddr()); #endif // FEATURE_COMINTEROP else diff --git a/src/coreclr/src/debug/daccess/dacdbiimpl.cpp b/src/coreclr/src/debug/daccess/dacdbiimpl.cpp index 905698ad4fd71..e3152652fb5f9 100644 --- a/src/coreclr/src/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/src/debug/daccess/dacdbiimpl.cpp @@ -7491,8 +7491,8 @@ UINT32 DacRefWalker::GetHandleWalkerMask() if ((mHandleMask & CorHandleWeakRefCount) || (mHandleMask & CorHandleStrongRefCount)) result |= (1 << HNDTYPE_REFCOUNTED); - if (mHandleMask & CorHandleWeakWinRT) - result |= (1 << HNDTYPE_WEAK_WINRT); + if (mHandleMask & CorHandleWeakNativeCom) + result |= (1 << HNDTYPE_WEAK_NATIVE_COM); #endif // FEATURE_COMINTEROP if (mHandleMask & CorHandleStrongDependent) @@ -7667,8 +7667,8 @@ void CALLBACK DacHandleWalker::EnumCallbackDac(PTR_UNCHECKED_OBJECTREF handle, u data.i64ExtraData = refCnt; break; - case HNDTYPE_WEAK_WINRT: - data.dwType = (DWORD)CorHandleWeakWinRT; + case HNDTYPE_WEAK_NATIVE_COM: + data.dwType = (DWORD)CorHandleWeakNativeCom; break; #endif diff --git a/src/coreclr/src/debug/daccess/request.cpp b/src/coreclr/src/debug/daccess/request.cpp index 2be663ebd77ea..79880ff064e5e 100644 --- a/src/coreclr/src/debug/daccess/request.cpp +++ b/src/coreclr/src/debug/daccess/request.cpp @@ -3253,7 +3253,7 @@ HRESULT ClrDataAccess::GetHandleEnum(ISOSHandleEnum **ppHandleEnum) unsigned int types[] = {HNDTYPE_WEAK_SHORT, HNDTYPE_WEAK_LONG, HNDTYPE_STRONG, HNDTYPE_PINNED, HNDTYPE_VARIABLE, HNDTYPE_DEPENDENT, HNDTYPE_ASYNCPINNED, HNDTYPE_SIZEDREF, #ifdef FEATURE_COMINTEROP - HNDTYPE_REFCOUNTED, HNDTYPE_WEAK_WINRT + HNDTYPE_REFCOUNTED, HNDTYPE_WEAK_NATIVE_COM #endif }; @@ -3291,7 +3291,7 @@ HRESULT ClrDataAccess::GetHandleEnumForGC(unsigned int gen, ISOSHandleEnum **ppH unsigned int types[] = {HNDTYPE_WEAK_SHORT, HNDTYPE_WEAK_LONG, HNDTYPE_STRONG, HNDTYPE_PINNED, HNDTYPE_VARIABLE, HNDTYPE_DEPENDENT, HNDTYPE_ASYNCPINNED, HNDTYPE_SIZEDREF, #ifdef FEATURE_COMINTEROP - HNDTYPE_REFCOUNTED, HNDTYPE_WEAK_WINRT + HNDTYPE_REFCOUNTED, HNDTYPE_WEAK_NATIVE_COM #endif }; diff --git a/src/coreclr/src/dlls/mscorrc/mscorrc.rc b/src/coreclr/src/dlls/mscorrc/mscorrc.rc index 8a7410ef25b2d..4573e20be97ae 100644 --- a/src/coreclr/src/dlls/mscorrc/mscorrc.rc +++ b/src/coreclr/src/dlls/mscorrc/mscorrc.rc @@ -344,7 +344,7 @@ BEGIN IDS_EE_WINRT_NOT_FACTORY_FOR_TYPE "Windows Runtime factory '%1' is not a factory for Windows Runtime type '%2'." IDS_EE_WINRT_INVALID_FACTORY_FOR_TYPE "Windows Runtime type '%1' has a invalid Windows Runtime factory" IDS_EE_CANNOTCAST_NOMARSHAL "The Windows Runtime Object can only be used in the threading context where it was created, because it implements INoMarshal or has MarshalingBehaviorAttribute(MarshalingType.None) set." - IDS_EE_WINRT_WEAKREF_BAD_TYPE "The object resolved by a native IWeakReference has an incompatible type for its managed WeakReference instance.\r\nExpected WeakReference target type: '%1'\r\nNative IWeakReference returned type: '%2'" + IDS_EE_NATIVE_COM_WEAKREF_BAD_TYPE "The object resolved by a native IWeakReference has an incompatible type for its managed WeakReference instance.\r\nExpected WeakReference target type: '%1'\r\nNative IWeakReference returned type: '%2'" #endif // FEATURE_COMINTEROP IDS_EE_INTEROP_CODE_SIZE_COMMENT "Code size" diff --git a/src/coreclr/src/dlls/mscorrc/resource.h b/src/coreclr/src/dlls/mscorrc/resource.h index 342c0570d493b..4011efb748215 100644 --- a/src/coreclr/src/dlls/mscorrc/resource.h +++ b/src/coreclr/src/dlls/mscorrc/resource.h @@ -600,7 +600,7 @@ #ifdef FEATURE_COMINTEROP -#define IDS_EE_WINRT_WEAKREF_BAD_TYPE 0x262e +#define IDS_EE_NATIVE_COM_WEAKREF_BAD_TYPE 0x262e #endif // FEATURE_COMINTEROP #define IDS_EE_BADMARSHAL_TYPE_ANSIBSTR 0x262f diff --git a/src/coreclr/src/gc/gchandletable.cpp b/src/coreclr/src/gc/gchandletable.cpp index b7c4bf2687233..d3f93b457521e 100644 --- a/src/coreclr/src/gc/gchandletable.cpp +++ b/src/coreclr/src/gc/gchandletable.cpp @@ -168,7 +168,7 @@ Object* GCHandleManager::InterlockedCompareExchangeObjectInHandle(OBJECTHANDLE h HandleType GCHandleManager::HandleFetchType(OBJECTHANDLE handle) { uint32_t type = ::HandleFetchType(handle); - assert(type >= HNDTYPE_WEAK_SHORT && type <= HNDTYPE_WEAK_WINRT); + assert(type >= HNDTYPE_WEAK_SHORT && type <= HNDTYPE_WEAK_NATIVE_COM); return static_cast(type); } diff --git a/src/coreclr/src/gc/gcinterface.h b/src/coreclr/src/gc/gcinterface.h index 122106c2ae273..e9bef6a502b45 100644 --- a/src/coreclr/src/gc/gcinterface.h +++ b/src/coreclr/src/gc/gcinterface.h @@ -422,18 +422,18 @@ typedef enum HNDTYPE_SIZEDREF = 8, /* - * WINRT WEAK HANDLES + * NATIVE WEAK HANDLES * - * WinRT weak reference handles hold two different types of weak handles to any + * Native weak reference handles hold two different types of weak handles to any * RCW with an underlying COM object that implements IWeakReferenceSource. The * object reference itself is a short weak handle to the RCW. In addition an * IWeakReference* to the underlying COM object is stored, allowing the handle * to create a new RCW if the existing RCW is collected. This ensures that any - * code holding onto a WinRT weak reference can always access an RCW to the + * code holding onto a native weak reference can always access an RCW to the * underlying COM object as long as it has not been released by all of its strong * references. */ - HNDTYPE_WEAK_WINRT = 9 + HNDTYPE_WEAK_NATIVE_COM = 9 } HandleType; typedef enum diff --git a/src/coreclr/src/gc/handletable.cpp b/src/coreclr/src/gc/handletable.cpp index 898e843419341..1b56c74c791cf 100644 --- a/src/coreclr/src/gc/handletable.cpp +++ b/src/coreclr/src/gc/handletable.cpp @@ -409,10 +409,10 @@ void HndDestroyHandleOfUnknownType(HHANDLETABLE hTable, OBJECTHANDLE handle) _ASSERTE(handle); #ifdef FEATURE_COMINTEROP - // If we're being asked to destroy a WinRT weak handle, that will cause a leak + // If we're being asked to destroy a native COM weak handle, that will cause a leak // of the IWeakReference* that it holds in its extra data. Instead of using this - // API use DestroyWinRTWeakHandle instead. - _ASSERTE(HandleFetchType(handle) != HNDTYPE_WEAK_WINRT); + // API use DestroyNativeComWeakHandle instead. + _ASSERTE(HandleFetchType(handle) != HNDTYPE_WEAK_NATIVE_COM); #endif // FEATURE_COMINTEROP // fetch the type and then free normally diff --git a/src/coreclr/src/gc/objecthandle.cpp b/src/coreclr/src/gc/objecthandle.cpp index 4a4f201ca03bd..e6a5160d7ee54 100644 --- a/src/coreclr/src/gc/objecthandle.cpp +++ b/src/coreclr/src/gc/objecthandle.cpp @@ -426,7 +426,7 @@ void CALLBACK ScanPointerForProfilerAndETW(_UNCHECKED_OBJECTREF *pObjRef, uintpt case HNDTYPE_WEAK_SHORT: case HNDTYPE_WEAK_LONG: #ifdef FEATURE_COMINTEROP - case HNDTYPE_WEAK_WINRT: + case HNDTYPE_WEAK_NATIVE_COM: #endif // FEATURE_COMINTEROP rootFlags |= kEtwGCRootFlagsWeakRef; break; @@ -520,7 +520,7 @@ static const uint32_t s_rgTypeFlags[] = HNDF_EXTRAINFO, // HNDTYPE_DEPENDENT HNDF_NORMAL, // HNDTYPE_ASYNCPINNED HNDF_EXTRAINFO, // HNDTYPE_SIZEDREF - HNDF_EXTRAINFO, // HNDTYPE_WEAK_WINRT + HNDF_EXTRAINFO, // HNDTYPE_WEAK_NATIVE_COM }; int getNumberOfSlots() @@ -1380,7 +1380,7 @@ void Ref_CheckAlive(uint32_t condemned, uint32_t maxgen, uintptr_t lp1) { HNDTYPE_WEAK_SHORT #ifdef FEATURE_COMINTEROP - , HNDTYPE_WEAK_WINRT + , HNDTYPE_WEAK_NATIVE_COM #endif // FEATURE_COMINTEROP }; uint32_t flags = (((ScanContext*) lp1)->concurrent) ? HNDGCF_ASYNC : HNDGCF_NORMAL; @@ -1439,7 +1439,7 @@ void Ref_UpdatePointers(uint32_t condemned, uint32_t maxgen, ScanContext* sc, Re HNDTYPE_REFCOUNTED, #endif // FEATURE_COMINTEROP || FEATURE_REDHAWK #ifdef FEATURE_COMINTEROP - HNDTYPE_WEAK_WINRT, + HNDTYPE_WEAK_NATIVE_COM, #endif // FEATURE_COMINTEROP HNDTYPE_SIZEDREF, }; @@ -1485,7 +1485,7 @@ void Ref_ScanHandlesForProfilerAndETW(uint32_t maxgen, uintptr_t lp1, handle_sca HNDTYPE_REFCOUNTED, #endif // FEATURE_COMINTEROP || FEATURE_REDHAWK #ifdef FEATURE_COMINTEROP - HNDTYPE_WEAK_WINRT, + HNDTYPE_WEAK_NATIVE_COM, #endif // FEATURE_COMINTEROP HNDTYPE_PINNED, // HNDTYPE_VARIABLE, @@ -1631,7 +1631,7 @@ void Ref_AgeHandles(uint32_t condemned, uint32_t maxgen, uintptr_t lp1) HNDTYPE_REFCOUNTED, #endif // FEATURE_COMINTEROP || FEATURE_REDHAWK #ifdef FEATURE_COMINTEROP - HNDTYPE_WEAK_WINRT, + HNDTYPE_WEAK_NATIVE_COM, #endif // FEATURE_COMINTEROP HNDTYPE_ASYNCPINNED, HNDTYPE_SIZEDREF, @@ -1674,7 +1674,7 @@ void Ref_RejuvenateHandles(uint32_t condemned, uint32_t maxgen, uintptr_t lp1) HNDTYPE_REFCOUNTED, #endif // FEATURE_COMINTEROP || FEATURE_REDHAWK #ifdef FEATURE_COMINTEROP - HNDTYPE_WEAK_WINRT, + HNDTYPE_WEAK_NATIVE_COM, #endif // FEATURE_COMINTEROP HNDTYPE_ASYNCPINNED, HNDTYPE_SIZEDREF, @@ -1716,7 +1716,7 @@ void Ref_VerifyHandleTable(uint32_t condemned, uint32_t maxgen, ScanContext* sc) HNDTYPE_REFCOUNTED, #endif // FEATURE_COMINTEROP || FEATURE_REDHAWK #ifdef FEATURE_COMINTEROP - HNDTYPE_WEAK_WINRT, + HNDTYPE_WEAK_NATIVE_COM, #endif // FEATURE_COMINTEROP HNDTYPE_ASYNCPINNED, HNDTYPE_SIZEDREF, diff --git a/src/coreclr/src/inc/cordebug.idl b/src/coreclr/src/inc/cordebug.idl index 87e1458cfc91d..be745368f2bb3 100644 --- a/src/coreclr/src/inc/cordebug.idl +++ b/src/coreclr/src/inc/cordebug.idl @@ -2567,7 +2567,8 @@ typedef enum CorGCReferenceType CorHandleStrongDependent = 1<<6, CorHandleStrongAsyncPinned = 1<<7, CorHandleStrongSizedByref = 1<<8, - CorHandleWeakWinRT = 1<<9, + CorHandleWeakNativeCom = 1<<9, + CorHandleWeakWinRT = CorHandleWeakNativeCom, CorReferenceStack = 0x80000001, CorReferenceFinalizer = 80000002, diff --git a/src/coreclr/src/pal/prebuilt/inc/cordebug.h b/src/coreclr/src/pal/prebuilt/inc/cordebug.h index 96dc9c0eb1926..69c897575113f 100644 --- a/src/coreclr/src/pal/prebuilt/inc/cordebug.h +++ b/src/coreclr/src/pal/prebuilt/inc/cordebug.h @@ -6376,7 +6376,8 @@ enum CorGCReferenceType CorHandleStrongDependent = ( 1 << 6 ) , CorHandleStrongAsyncPinned = ( 1 << 7 ) , CorHandleStrongSizedByref = ( 1 << 8 ) , - CorHandleWeakWinRT = ( 1 << 9 ) , + CorHandleWeakNativeCom = ( 1 << 9 ) , + CorHandleWeakWinRT = CorHandleWeakNativeCom, CorReferenceStack = 0x80000001, CorReferenceFinalizer = 80000002, CorHandleStrongOnly = 0x1e3, diff --git a/src/coreclr/src/vm/appdomain.hpp b/src/coreclr/src/vm/appdomain.hpp index 0ca41f064ee5c..f017b42c73a2a 100644 --- a/src/coreclr/src/vm/appdomain.hpp +++ b/src/coreclr/src/vm/appdomain.hpp @@ -1110,10 +1110,10 @@ class BaseDomain return ::CreateRefcountedHandle(m_handleStore, object); } - OBJECTHANDLE CreateWinRTWeakHandle(OBJECTREF object, IWeakReference* pWinRTWeakReference) + OBJECTHANDLE CreateNativeComWeakHandle(OBJECTREF object, IWeakReference* pComWeakReference) { WRAPPER_NO_CONTRACT; - return ::CreateWinRTWeakHandle(m_handleStore, object, pWinRTWeakReference); + return ::CreateNativeComWeakHandle(m_handleStore, object, pComWeakReference); } #endif // FEATURE_COMINTEROP diff --git a/src/coreclr/src/vm/ecalllist.h b/src/coreclr/src/vm/ecalllist.h index 87aa7b62be5b2..155ae2c516e7c 100644 --- a/src/coreclr/src/vm/ecalllist.h +++ b/src/coreclr/src/vm/ecalllist.h @@ -986,6 +986,7 @@ FCFuncStart(gComWrappersFuncs) QCFuncElement("TryGetOrCreateComInterfaceForObjectInternal", ComWrappersNative::TryGetOrCreateComInterfaceForObject) QCFuncElement("TryGetOrCreateObjectForComInstanceInternal", ComWrappersNative::TryGetOrCreateObjectForComInstance) QCFuncElement("SetGlobalInstanceRegisteredForMarshalling", GlobalComWrappersForMarshalling::SetGlobalInstanceRegisteredForMarshalling) + QCFuncElement("SetGlobalInstanceRegisteredForTrackerSupport", GlobalComWrappersForTrackerSupport::SetGlobalInstanceRegisteredForTrackerSupport) FCFuncEnd() #endif // FEATURE_COMWRAPPERS diff --git a/src/coreclr/src/vm/gchandleutilities.h b/src/coreclr/src/vm/gchandleutilities.h index b875644b853b5..d90a2f0faef09 100644 --- a/src/coreclr/src/vm/gchandleutilities.h +++ b/src/coreclr/src/vm/gchandleutilities.h @@ -201,9 +201,9 @@ inline OBJECTHANDLE CreateGlobalRefcountedHandle(OBJECTREF object) // Special handle creation convenience functions #ifdef FEATURE_COMINTEROP -inline OBJECTHANDLE CreateWinRTWeakHandle(IGCHandleStore* store, OBJECTREF object, IWeakReference* pWinRTWeakReference) +inline OBJECTHANDLE CreateNativeComWeakHandle(IGCHandleStore* store, OBJECTREF object, IWeakReference* pComWeakReference) { - OBJECTHANDLE hnd = store->CreateHandleWithExtraInfo(OBJECTREFToObject(object), HNDTYPE_WEAK_WINRT, (void*)pWinRTWeakReference); + OBJECTHANDLE hnd = store->CreateHandleWithExtraInfo(OBJECTREFToObject(object), HNDTYPE_WEAK_NATIVE_COM, (void*)pComWeakReference); if (!hnd) { COMPlusThrowOM(); @@ -363,7 +363,7 @@ inline void DestroyTypedHandle(OBJECTHANDLE handle) } #ifdef FEATURE_COMINTEROP -inline void DestroyWinRTWeakHandle(OBJECTHANDLE handle) +inline void DestroyNativeComWeakHandle(OBJECTHANDLE handle) { CONTRACTL { @@ -375,7 +375,7 @@ inline void DestroyWinRTWeakHandle(OBJECTHANDLE handle) CONTRACTL_END; // Release the WinRT weak reference if we have one. We're assuming that this will not reenter the - // runtime, since if we are pointing at a managed object, we should not be using HNDTYPE_WEAK_WINRT + // runtime, since if we are pointing at a managed object, we should not be using HNDTYPE_WEAK_NATIVE_COM // but rather HNDTYPE_WEAK_SHORT or HNDTYPE_WEAK_LONG. void* pExtraInfo = GCHandleUtilities::GetGCHandleManager()->GetExtraInfoFromHandle(handle); IWeakReference* pWinRTWeakReference = reinterpret_cast(pExtraInfo); @@ -385,7 +385,7 @@ inline void DestroyWinRTWeakHandle(OBJECTHANDLE handle) } DiagHandleDestroyed(handle); - GCHandleUtilities::GetGCHandleManager()->DestroyHandleOfType(handle, HNDTYPE_WEAK_WINRT); + GCHandleUtilities::GetGCHandleManager()->DestroyHandleOfType(handle, HNDTYPE_WEAK_NATIVE_COM); } #endif diff --git a/src/coreclr/src/vm/interoplibinterface.cpp b/src/coreclr/src/vm/interoplibinterface.cpp index 934e0bbf6fadc..3eaf5ba37f410 100644 --- a/src/coreclr/src/vm/interoplibinterface.cpp +++ b/src/coreclr/src/vm/interoplibinterface.cpp @@ -401,7 +401,8 @@ namespace Volatile ExtObjCxtCache::g_Instance; // Indicator for if a ComWrappers implementation is globally registered - bool g_IsGlobalComWrappersRegistered; + bool g_IsGlobalComWrappersRegisteredForMarshalling; + bool g_IsGlobalComWrappersRegisteredForTrackerSupport; // Defined handle types for the specific object uses. const HandleType InstanceHandleType{ HNDTYPE_STRONG }; @@ -1387,15 +1388,15 @@ void QCALLTYPE GlobalComWrappersForMarshalling::SetGlobalInstanceRegisteredForMa // QCALL contracts are not used here because the managed declaration // uses the SuppressGCTransition attribute - _ASSERTE(!g_IsGlobalComWrappersRegistered); - g_IsGlobalComWrappersRegistered = true; + _ASSERTE(!g_IsGlobalComWrappersRegisteredForMarshalling); + g_IsGlobalComWrappersRegisteredForMarshalling = true; } bool GlobalComWrappersForMarshalling::TryGetOrCreateComInterfaceForObject( _In_ OBJECTREF instance, _Outptr_ void** wrapperRaw) { - if (!g_IsGlobalComWrappersRegistered) + if (!g_IsGlobalComWrappersRegisteredForMarshalling) return false; // Switch to Cooperative mode since object references @@ -1420,7 +1421,7 @@ bool GlobalComWrappersForMarshalling::TryGetOrCreateObjectForComInstance( _In_ INT32 objFromComIPFlags, _Out_ OBJECTREF* objRef) { - if (!g_IsGlobalComWrappersRegistered) + if (!g_IsGlobalComWrappersRegisteredForMarshalling) return false; // Determine the true identity of the object @@ -1452,6 +1453,110 @@ bool GlobalComWrappersForMarshalling::TryGetOrCreateObjectForComInstance( } } +void QCALLTYPE GlobalComWrappersForTrackerSupport::SetGlobalInstanceRegisteredForTrackerSupport() +{ + // QCALL contracts are not used here because the managed declaration + // uses the SuppressGCTransition attribute + + _ASSERTE(!g_IsGlobalComWrappersRegisteredForTrackerSupport); + g_IsGlobalComWrappersRegisteredForTrackerSupport = true; +} + +bool GlobalComWrappersForTrackerSupport::TryGetOrCreateComInterfaceForObject( + _In_ OBJECTREF instance, + _Outptr_ void** wrapperRaw) +{ + CONTRACTL + { + THROWS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + if (!g_IsGlobalComWrappersRegisteredForTrackerSupport) + return false; + + // Passing NULL as the ComWrappers implementation indicates using the globally registered instance + return TryGetOrCreateComInterfaceForObjectInternal( + NULL, + instance, + CreateComInterfaceFlags::CreateComInterfaceFlags_TrackerSupport, + ComWrappersScenario::TrackerSupportGlobalInstance, + wrapperRaw); +} + +bool GlobalComWrappersForTrackerSupport::TryGetOrCreateObjectForComInstance( + _In_ IUnknown* externalComObject, + _Out_ OBJECTREF* objRef) +{ + CONTRACTL + { + THROWS; + MODE_COOPERATIVE; + } + CONTRACTL_END; + + if (!g_IsGlobalComWrappersRegisteredForTrackerSupport) + return false; + + // Determine the true identity of the object + SafeComHolder identity; + { + GCX_PREEMP(); + + HRESULT hr = externalComObject->QueryInterface(IID_IUnknown, &identity); + _ASSERTE(hr == S_OK); + } + + // Passing NULL as the ComWrappers implementation indicates using the globally registered instance + return TryGetOrCreateObjectForComInstanceInternal( + NULL /*comWrappersImpl*/, + identity, + CreateObjectFlags::CreateObjectFlags_TrackerObject, + ComWrappersScenario::TrackerSupportGlobalInstance, + NULL /*wrapperMaybe*/, + objRef); +} + +IUnknown* ComWrappersNative::GetIdentityForObject(_In_ OBJECTREF* objectPROTECTED, _In_ REFIID riid) +{ + CONTRACTL + { + NOTHROW; + GC_TRIGGERS; + MODE_COOPERATIVE; + PRECONDITION(CheckPointer(objectPROTECTED)); + } + CONTRACTL_END; + + ASSERT_PROTECTED(objectPROTECTED); + + SyncBlock* syncBlock = (*objectPROTECTED)->PassiveGetSyncBlock(); + if (syncBlock == nullptr) + { + return nullptr; + } + + InteropSyncBlockInfo* interopInfo = syncBlock->GetInteropInfoNoCreate(); + if (interopInfo == nullptr) + { + return nullptr; + } + + void* context; + if (interopInfo->TryGetExternalComObjectContext(&context)) + { + IUnknown* identity = reinterpret_cast(reinterpret_cast(context)->Identity); + GCX_PREEMP(); + IUnknown* result; + if (SUCCEEDED(identity->QueryInterface(riid, (void**)&result))) + { + return result; + } + } + return nullptr; +} + #endif // FEATURE_COMWRAPPERS void Interop::OnGCStarted(_In_ int nCondemnedGeneration) diff --git a/src/coreclr/src/vm/interoplibinterface.h b/src/coreclr/src/vm/interoplibinterface.h index 6a5884a66075c..3e5abda54cd6a 100644 --- a/src/coreclr/src/vm/interoplibinterface.h +++ b/src/coreclr/src/vm/interoplibinterface.h @@ -37,6 +37,9 @@ class ComWrappersNative public: // COM activation static void MarkWrapperAsComActivated(_In_ IUnknown* wrapperMaybe); + +public: // Unwrapping support + static IUnknown* GetIdentityForObject(_In_ OBJECTREF* objectPROTECTED, _In_ REFIID riid); }; class GlobalComWrappersForMarshalling @@ -58,6 +61,25 @@ class GlobalComWrappersForMarshalling _Out_ OBJECTREF* objRef); }; + +class GlobalComWrappersForTrackerSupport +{ +public: + // Native QCall for the ComWrappers managed type to indicate a global instance + // is registered for tracker support. This should be set if the private static member + // representing the global instance for tracker support on ComWrappers is non-null. + static void QCALLTYPE SetGlobalInstanceRegisteredForTrackerSupport(); + +public: // Functions operating on a registered global instance for tracker support + static bool TryGetOrCreateComInterfaceForObject( + _In_ OBJECTREF instance, + _Outptr_ void** wrapperRaw); + + static bool TryGetOrCreateObjectForComInstance( + _In_ IUnknown* externalComObject, + _Out_ OBJECTREF* objRef); +}; + #endif // FEATURE_COMWRAPPERS class Interop diff --git a/src/coreclr/src/vm/marshalnative.cpp b/src/coreclr/src/vm/marshalnative.cpp index 2e068019c2ab2..75c1e514420f1 100644 --- a/src/coreclr/src/vm/marshalnative.cpp +++ b/src/coreclr/src/vm/marshalnative.cpp @@ -558,7 +558,7 @@ FCIMPL2(LPVOID, MarshalNative::GCHandleInternalAlloc, Object *obj, int type) OBJECTREF objRef(obj); - assert(type >= HNDTYPE_WEAK_SHORT && type <= HNDTYPE_WEAK_WINRT); + assert(type >= HNDTYPE_WEAK_SHORT && type <= HNDTYPE_WEAK_NATIVE_COM); if (CORProfilerTrackGC()) { diff --git a/src/coreclr/src/vm/runtimehandles.cpp b/src/coreclr/src/vm/runtimehandles.cpp index a16bc1a1c2aaa..82c793bf3f7af 100644 --- a/src/coreclr/src/vm/runtimehandles.cpp +++ b/src/coreclr/src/vm/runtimehandles.cpp @@ -1110,7 +1110,7 @@ PVOID QCALLTYPE RuntimeTypeHandle::GetGCHandle(QCall::TypeHandle pTypeHandle, IN GCX_COOP(); TypeHandle th = pTypeHandle.AsTypeHandle(); - assert(handleType >= HNDTYPE_WEAK_SHORT && handleType <= HNDTYPE_WEAK_WINRT); + assert(handleType >= HNDTYPE_WEAK_SHORT && handleType <= HNDTYPE_WEAK_NATIVE_COM); objHandle = AppDomain::GetCurrentDomain()->CreateTypedHandle(NULL, static_cast(handleType)); th.GetLoaderAllocator()->RegisterHandleForCleanup(objHandle); diff --git a/src/coreclr/src/vm/weakreferencenative.cpp b/src/coreclr/src/vm/weakreferencenative.cpp index b1dc825494f35..2cdb83ce9b81e 100644 --- a/src/coreclr/src/vm/weakreferencenative.cpp +++ b/src/coreclr/src/vm/weakreferencenative.cpp @@ -16,6 +16,7 @@ #include "typestring.h" #include "typeparse.h" #include "threadsuspend.h" +#include "interoplibinterface.h" //************************************************************************ @@ -34,7 +35,7 @@ const LPVOID specialWeakReferenceHandles[3] = { 0, 0, 0 }; // // A WeakReference instance can hold one of three types of handles - short or long weak handles, -// or a WinRT weak reference handle. The WinRT weak reference handle has the extra capability +// or a native COM weak reference handle. The native COM weak reference handle has the extra capability // of recreating an RCW for a COM object which is still alive even though the previous RCW had // been collected. In order to differentiate this type of handle from the standard weak handles, // the bottom bit is stolen. @@ -50,23 +51,23 @@ const LPVOID specialWeakReferenceHandles[3] = { 0, 0, 0 }; // The following functions are to set, test, and unset that bit before the handle is used. // -// Determine if an object handle is a WinRT weak reference handle -bool IsWinRTWeakReferenceHandle(OBJECTHANDLE handle) +// Determine if an object handle is a native COM weak reference handle +bool IsNativeComWeakReferenceHandle(OBJECTHANDLE handle) { STATIC_CONTRACT_LEAF; return (reinterpret_cast(handle) & 0x1) != 0x0; } -// Mark an object handle as being a WinRT weak reference handle -OBJECTHANDLE SetWinRTWeakReferenceHandle(OBJECTHANDLE handle) +// Mark an object handle as being a native COM weak reference handle +OBJECTHANDLE SetNativeComWeakReferenceHandle(OBJECTHANDLE handle) { STATIC_CONTRACT_LEAF; - _ASSERTE(!IsWinRTWeakReferenceHandle(handle)); + _ASSERTE(!IsNativeComWeakReferenceHandle(handle)); return reinterpret_cast(reinterpret_cast(handle) | 0x1); } -// Get the object handle value even if the object is a WinRT weak reference +// Get the object handle value even if the object is a native COM weak reference OBJECTHANDLE GetHandleValue(OBJECTHANDLE handle) { STATIC_CONTRACT_LEAF; @@ -102,17 +103,17 @@ struct WeakHandleSpinLockHolder #ifdef FEATURE_COMINTEROP -// Get a WinRT weak reference for the object underlying an RCW if applicable. If the incoming object cannot -// use a WinRT weak reference, nullptr is returned. Otherwise, an AddRef-ed IWeakReference* for the COM +// Get a native COM weak reference for the object underlying an RCW if applicable. If the incoming object cannot +// use a native COM weak reference, nullptr is returned. Otherwise, an AddRef-ed IWeakReference* for the COM // object underlying the RCW is returned. // -// In order to qualify to be used with a HNDTYPE_WEAK_WINRT, the incoming object must: +// In order to qualify to be used with a HNDTYPE_WEAK_NATIVE_COM, the incoming object must: // * be an RCW // * respond to a QI for IWeakReferenceSource // * succeed when asked for an IWeakReference* // // Note that *pObject should be GC protected on the way into this method -IWeakReference* GetWinRTWeakReference(OBJECTREF* pObject) +IWeakReference* GetComWeakReference(OBJECTREF* pObject) { CONTRACTL { @@ -132,21 +133,24 @@ IWeakReference* GetWinRTWeakReference(OBJECTREF* pObject) MethodTable* pMT = (*pObject)->GetMethodTable(); - // If the object is not an RCW, then we do not want to use a WinRT weak reference to it - if (!pMT->IsComObjectType()) - { - return nullptr; - } + SafeComHolder pWeakReferenceSource(nullptr); - // If the object is a managed type deriving from a COM type, then we also do not want to use a WinRT + // If the object is not an RCW, then we do not want to use a native COM weak reference to it + // If the object is a managed type deriving from a COM type, then we also do not want to use a native COM // weak reference to it. (Otherwise, we'll wind up resolving IWeakReference-s back into the CLR // when we don't want to have reentrancy). - if (pMT != g_pBaseCOMObject && pMT->IsExtensibleRCW()) + if (pMT->IsComObjectType() + && (pMT == g_pBaseCOMObject || !pMT->IsExtensibleRCW())) { - return nullptr; + pWeakReferenceSource = reinterpret_cast(GetComIPFromObjectRef(pObject, IID_IWeakReferenceSource, false /* throwIfNoComIP */)); + } +#ifdef FEATURE_COMWRAPPERS + else + { + pWeakReferenceSource = reinterpret_cast(ComWrappersNative::GetIdentityForObject(pObject, IID_IWeakReferenceSource)); } +#endif - SafeComHolder pWeakReferenceSource(reinterpret_cast(GetComIPFromObjectRef(pObject, IID_IWeakReferenceSource, false /* throwIfNoComIP */))); if (pWeakReferenceSource == nullptr) { return nullptr; @@ -162,17 +166,17 @@ IWeakReference* GetWinRTWeakReference(OBJECTREF* pObject) return pWeakReference.Extract(); } -// Given an object handle that stores a WinRT weak reference, attempt to create an RCW -// and store it back in the handle, returning the RCW. If the underlying WinRT object +// Given an object handle that stores a native COM weak reference, attempt to create an RCW +// and store it back in the handle, returning the RCW. If the underlying native COM object // is not alive, then the result is NULL. // // In order to create a new RCW, we must: -// * Have an m_handle of HNDTYPE_WEAK_WINRT (ie the bottom bit of m_handle is set) +// * Have an m_handle of HNDTYPE_WEAK_NATIVE_COM (ie the bottom bit of m_handle is set) // * Have stored an IWeakReference* in the handle extra info when setting up the handle -// (see GetWinRTWeakReference) +// (see GetComWeakReference) // * The IWeakReference* must respond to a Resolve request for IID_IInspectable // * -NOINLINE Object* LoadWinRTWeakReferenceTarget(WEAKREFERENCEREF weakReference, TypeHandle targetType, LPVOID __me) +NOINLINE Object* LoadComWeakReferenceTarget(WEAKREFERENCEREF weakReference, TypeHandle targetType, LPVOID __me) { CONTRACTL { @@ -200,14 +204,14 @@ NOINLINE Object* LoadWinRTWeakReferenceTarget(WEAKREFERENCEREF weakReference, Ty // // Since we're acquiring and releasing the lock multiple times, we need to check the handle state each time we // reacquire the lock to make sure that another thread hasn't reassigned the target of the handle or finalized it - SafeComHolder pWinRTWeakReference = nullptr; + SafeComHolder pComWeakReference = nullptr; { WeakHandleSpinLockHolder handle(AcquireWeakHandleSpinLock(gc.weakReference), &gc.weakReference); GCX_NOTRIGGER(); // Make sure that while we were not holding the spin lock, another thread did not change the target of // this weak reference. Only fetch the IWeakReference* if we still have a valid handle holding a NULL object - // and the handle is still a HNDTYPE_WEAK_WINRT type handle. + // and the handle is still a HNDTYPE_WEAK_NATIVE_COM type handle. if ((handle.Handle != NULL) && !IS_SPECIAL_HANDLE(handle.Handle)) { if (*(Object **)(handle.Handle) != NULL) @@ -217,22 +221,22 @@ NOINLINE Object* LoadWinRTWeakReferenceTarget(WEAKREFERENCEREF weakReference, Ty // weak reference is targeting. gc.target = ObjectToOBJECTREF(*(Object **)(handle.Handle)); } - else if(IsWinRTWeakReferenceHandle(handle.RawHandle)) + else if(IsNativeComWeakReferenceHandle(handle.RawHandle)) { - _ASSERTE(GCHandleUtilities::GetGCHandleManager()->HandleFetchType(handle.Handle) == HNDTYPE_WEAK_WINRT); + _ASSERTE(GCHandleUtilities::GetGCHandleManager()->HandleFetchType(handle.Handle) == HNDTYPE_WEAK_NATIVE_COM); // Retrieve the associated IWeakReference* for this weak reference. Add a reference to it while we release // the spin lock so that another thread doesn't release it out from underneath us. // - // Setting pWinRTWeakReference will claim that it triggers a GC, however that's not true in this case because + // Setting pComWeakReference will claim that it triggers a GC, however that's not true in this case because // it's always set to NULL here and there's nothing for it to release. - _ASSERTE(pWinRTWeakReference.IsNull()); + _ASSERTE(pComWeakReference.IsNull()); CONTRACT_VIOLATION(GCViolation); IGCHandleManager *mgr = GCHandleUtilities::GetGCHandleManager(); - pWinRTWeakReference = reinterpret_cast(mgr->GetExtraInfoFromHandle(handle.Handle)); - if (!pWinRTWeakReference.IsNull()) + pComWeakReference = reinterpret_cast(mgr->GetExtraInfoFromHandle(handle.Handle)); + if (!pComWeakReference.IsNull()) { - pWinRTWeakReference->AddRef(); + pComWeakReference->AddRef(); } } } @@ -242,16 +246,16 @@ NOINLINE Object* LoadWinRTWeakReferenceTarget(WEAKREFERENCEREF weakReference, Ty // identity of the underlying COM object (assuming that object is still alive). This work is done without holding the // spin lock since it will call out to arbitrary code and as such we need to switch to preemptive mode. SafeComHolder pTargetIdentity = nullptr; - if (pWinRTWeakReference != nullptr) + if (pComWeakReference != nullptr) { _ASSERTE(gc.target == NULL); GCX_PREEMP(); - // Using the IWeakReference*, get ahold of the target WinRT object's IInspectable*. If this resolve fails, then we - // assume that the underlying WinRT object is no longer alive, and thus we cannot create a new RCW for it. + // Using the IWeakReference*, get ahold of the target native COM object's IInspectable*. If this resolve fails, then we + // assume that the underlying native COM object is no longer alive, and thus we cannot create a new RCW for it. SafeComHolderPreemp pTarget = nullptr; - if (SUCCEEDED(pWinRTWeakReference->Resolve(IID_IInspectable, &pTarget))) + if (SUCCEEDED(pComWeakReference->Resolve(IID_IInspectable, &pTarget))) { if (!pTarget.IsNull()) { @@ -264,7 +268,11 @@ NOINLINE Object* LoadWinRTWeakReferenceTarget(WEAKREFERENCEREF weakReference, Ty // If we were able to get an IUnkown identity for the object, then we can find or create an associated RCW for it. if (!pTargetIdentity.IsNull()) { - GetObjectRefFromComIP(&gc.rcw, pTargetIdentity); + // Try the global COM wrappers first before falling back to the built-in system. + if (!GlobalComWrappersForTrackerSupport::TryGetOrCreateObjectForComInstance(pTargetIdentity, &gc.rcw)) + { + GetObjectRefFromComIP(&gc.rcw, pTargetIdentity); + } } // If we were able to get an RCW, then we need to reacquire the spin lock and store the RCW in the handle. Note that @@ -272,7 +280,7 @@ NOINLINE Object* LoadWinRTWeakReferenceTarget(WEAKREFERENCEREF weakReference, Ty // building the RCW. In that case, we will defer to the hadle that the other thread set, and let the RCW die. if (gc.rcw != NULL) { - // Make sure the type we got back from the WinRT object is compatible with the type the managed + // Make sure the type we got back from the native COM object is compatible with the type the managed // weak reference expects. (For instance, in the WeakReference case, the returned type // had better be compatible with T). TypeHandle rcwType(gc.rcw->GetMethodTable()); @@ -284,7 +292,7 @@ NOINLINE Object* LoadWinRTWeakReferenceTarget(WEAKREFERENCEREF weakReference, Ty SString resolvedTypeName; TypeString::AppendType(resolvedTypeName, rcwType, TypeString::FormatNamespace | TypeString::FormatFullInst | TypeString::FormatAssembly); - COMPlusThrow(kInvalidCastException, IDS_EE_WINRT_WEAKREF_BAD_TYPE, weakReferenceTypeName.GetUnicode(), resolvedTypeName.GetUnicode()); + COMPlusThrow(kInvalidCastException, IDS_EE_NATIVE_COM_WEAKREF_BAD_TYPE, weakReferenceTypeName.GetUnicode(), resolvedTypeName.GetUnicode()); } WeakHandleSpinLockHolder handle(AcquireWeakHandleSpinLock(gc.weakReference), &gc.weakReference); @@ -420,12 +428,21 @@ FCIMPL3(void, WeakReferenceNative::Create, WeakReferenceObject * pThisUNSAFE, Ob // Create the handle. #ifdef FEATURE_COMINTEROP - IWeakReference* pRawWinRTWeakReference = GetWinRTWeakReference(&gc.pTarget); - if (pRawWinRTWeakReference != nullptr) + IWeakReference* pRawComWeakReference = nullptr; + if (gc.pTarget != NULL) { - SafeComHolder pWinRTWeakReferenceHolder(pRawWinRTWeakReference); - gc.pThis->m_Handle = SetWinRTWeakReferenceHandle(GetAppDomain()->CreateWinRTWeakHandle(gc.pTarget, pWinRTWeakReferenceHolder)); - pWinRTWeakReferenceHolder.SuppressRelease(); + SyncBlock* pSyncBlock = gc.pTarget->PassiveGetSyncBlock(); + if (pSyncBlock != nullptr && pSyncBlock->GetInteropInfoNoCreate() != nullptr) + { + pRawComWeakReference = GetComWeakReference(&gc.pTarget); + } + } + + if (pRawComWeakReference != nullptr) + { + SafeComHolder pComWeakReferenceHolder(pRawComWeakReference); + gc.pThis->m_Handle = SetNativeComWeakReferenceHandle(GetAppDomain()->CreateNativeComWeakHandle(gc.pTarget, pComWeakReferenceHolder)); + pComWeakReferenceHolder.SuppressRelease(); } else #endif // FEATURE_COMINTEROP @@ -463,12 +480,21 @@ FCIMPL3(void, WeakReferenceOfTNative::Create, WeakReferenceObject * pThisUNSAFE, // Create the handle. #ifdef FEATURE_COMINTEROP - IWeakReference* pRawWinRTWeakReference = GetWinRTWeakReference(&gc.pTarget); - if (pRawWinRTWeakReference != nullptr) + IWeakReference* pRawComWeakReference = nullptr; + if (gc.pTarget != NULL) + { + SyncBlock* pSyncBlock = gc.pTarget->PassiveGetSyncBlock(); + if (pSyncBlock != nullptr && pSyncBlock->GetInteropInfoNoCreate() != nullptr) + { + pRawComWeakReference = GetComWeakReference(&gc.pTarget); + } + } + + if (pRawComWeakReference != nullptr) { - SafeComHolder pWinRTWeakReferenceHolder(pRawWinRTWeakReference); - gc.pThis->m_Handle = SetWinRTWeakReferenceHandle(GetAppDomain()->CreateWinRTWeakHandle(gc.pTarget, pWinRTWeakReferenceHolder)); - pWinRTWeakReferenceHolder.SuppressRelease(); + SafeComHolder pComWeakReferenceHolder(pRawComWeakReference); + gc.pThis->m_Handle = SetNativeComWeakReferenceHandle(GetAppDomain()->CreateNativeComWeakHandle(gc.pTarget, pComWeakReferenceHolder)); + pComWeakReferenceHolder.SuppressRelease(); } else #endif // FEATURE_COMINTEROP @@ -499,7 +525,7 @@ void FinalizeWeakReference(Object * obj) // The suspension state of the runtime must be prevented from changing while in this function in order for this to be safe. OBJECTHANDLE handle = ThreadSuspend::SysIsSuspended() ? pThis->m_Handle.LoadWithoutBarrier() : AcquireWeakHandleSpinLock(pThis); OBJECTHANDLE handleToDestroy = NULL; - bool isWeakWinRTHandle = false; + bool isWeakNativeComHandle = false; // Check for not yet constructed or already finalized handle if ((handle != NULL) && !IS_SPECIAL_HANDLE(handle)) @@ -509,8 +535,8 @@ void FinalizeWeakReference(Object * obj) // Cache the old handle value HandleType handleType = GCHandleUtilities::GetGCHandleManager()->HandleFetchType(handleToDestroy); #ifdef FEATURE_COMINTEROP - _ASSERTE(handleType == HNDTYPE_WEAK_LONG || handleType == HNDTYPE_WEAK_SHORT || handleType == HNDTYPE_WEAK_WINRT); - isWeakWinRTHandle = handleType == HNDTYPE_WEAK_WINRT; + _ASSERTE(handleType == HNDTYPE_WEAK_LONG || handleType == HNDTYPE_WEAK_SHORT || handleType == HNDTYPE_WEAK_NATIVE_COM); + isWeakNativeComHandle = handleType == HNDTYPE_WEAK_NATIVE_COM; #else // !FEATURE_COMINTEROP _ASSERTE(handleType == HNDTYPE_WEAK_LONG || handleType == HNDTYPE_WEAK_SHORT); #endif // FEATURE_COMINTEROP @@ -528,9 +554,9 @@ void FinalizeWeakReference(Object * obj) if (handleToDestroy != NULL) { #ifdef FEATURE_COMINTEROP - if (isWeakWinRTHandle) + if (isWeakNativeComHandle) { - DestroyWinRTWeakHandle(handleToDestroy); + DestroyNativeComWeakHandle(handleToDestroy); } else #endif // FEATURE_COMINTEROP @@ -645,14 +671,14 @@ FCIMPL1(Object *, WeakReferenceNative::GetTarget, WeakReferenceObject * pThisUNS OBJECTREF pTarget = GetWeakReferenceTarget(pThis); #ifdef FEATURE_COMINTEROP - // If we found an object, or we're not a WinRT weak reference, then we're done. Othewrise - // we can try to create a new RCW to the underlying WinRT object if it's still alive. - if (pTarget != NULL || !IsWinRTWeakReferenceHandle(pThis->m_Handle)) + // If we found an object, or we're not a native COM weak reference, then we're done. Othewrise + // we can try to create a new RCW to the underlying native COM object if it's still alive. + if (pTarget != NULL || !IsNativeComWeakReferenceHandle(pThis->m_Handle)) { FC_GC_POLL_AND_RETURN_OBJREF(pTarget); } - FC_INNER_RETURN(Object*, LoadWinRTWeakReferenceTarget(pThis, g_pObjectClass, GetEEFuncEntryPointMacro(WeakReferenceNative::GetTarget))); + FC_INNER_RETURN(Object*, LoadComWeakReferenceTarget(pThis, g_pObjectClass, GetEEFuncEntryPointMacro(WeakReferenceNative::GetTarget))); #else // !FEATURE_COMINTEROP FC_GC_POLL_AND_RETURN_OBJREF(pTarget); #endif // FEATURE_COMINTEROP @@ -673,14 +699,14 @@ FCIMPL1(Object *, WeakReferenceOfTNative::GetTarget, WeakReferenceObject * pThis #ifdef FEATURE_COMINTEROP - // If we found an object, or we're not a WinRT weak reference, then we're done. Othewrise - // we can try to create a new RCW to the underlying WinRT object if it's still alive. - if (pTarget != NULL || !IsWinRTWeakReferenceHandle(pThis->m_Handle)) + // If we found an object, or we're not a native COM weak reference, then we're done. Othewrise + // we can try to create a new RCW to the underlying native COM object if it's still alive. + if (pTarget != NULL || !IsNativeComWeakReferenceHandle(pThis->m_Handle)) { FC_GC_POLL_AND_RETURN_OBJREF(pTarget); } - FC_INNER_RETURN(Object*, LoadWinRTWeakReferenceTarget(pThis, pThis->GetMethodTable()->GetInstantiation()[0], GetEEFuncEntryPointMacro(WeakReferenceOfTNative::GetTarget))); + FC_INNER_RETURN(Object*, LoadComWeakReferenceTarget(pThis, pThis->GetMethodTable()->GetInstantiation()[0], GetEEFuncEntryPointMacro(WeakReferenceOfTNative::GetTarget))); #else // !FEATURE_COMINTEROP FC_GC_POLL_AND_RETURN_OBJREF(pTarget); #endif // FEATURE_COMINTEROP @@ -711,7 +737,7 @@ FCIMPLEND #include -// Slow path helper for setting the target of a weak reference. This code is used if a WinRT weak reference might +// Slow path helper for setting the target of a weak reference. This code is used if a native COM weak reference might // be required. NOINLINE void SetWeakReferenceTarget(WEAKREFERENCEREF weakReference, OBJECTREF target, LPVOID __me) { @@ -721,7 +747,7 @@ NOINLINE void SetWeakReferenceTarget(WEAKREFERENCEREF weakReference, OBJECTREF t HELPER_METHOD_FRAME_BEGIN_ATTRIB_2(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, target, weakReference); #ifdef FEATURE_COMINTEROP - SafeComHolder pTargetWeakReference(GetWinRTWeakReference(&target)); + SafeComHolder pTargetWeakReference(GetComWeakReference(&target)); #endif // FEATURE_COMINTEROP @@ -735,30 +761,30 @@ NOINLINE void SetWeakReferenceTarget(WEAKREFERENCEREF weakReference, OBJECTREF t // Existing target is a GC object, new target is a GC object: // * Just store the new object in the handle // - // Existing target is WinRT, new target is WinRT: + // Existing target is native COM weak reference, new target is native COM weak reference: // * Release the existing IWeakReference* // * Store the new IWeakReference* // * Store the new object in the handle // - // Existing target is WinRT, new target is GC: + // Existing target is native COM weak reference, new target is GC: // * Release the existing IWeakReference* // * Store null to the IWeakReference* field // * Store the new object in the handle // - // Existing target is GC, new target is WinRT: + // Existing target is GC, new target is native COM weak reference: // * Destroy the existing handle - // * Allocate a new WinRT weak handle for the new target + // * Allocate a new native COM weak handle for the new target // - if (IsWinRTWeakReferenceHandle(handle.RawHandle)) + if (IsNativeComWeakReferenceHandle(handle.RawHandle)) { - // If the existing reference is a WinRT weak reference, we need to release its IWeakReference pointer + // If the existing reference is a native COM weak reference, we need to release its IWeakReference pointer // and update it with the new weak reference pointer. If the incoming object is not an RCW that can // use IWeakReference, then pTargetWeakReference will be null. Therefore, no matter what the incoming // object type is, we can unconditionally store pTargetWeakReference to the object handle's extra data. IGCHandleManager *mgr = GCHandleUtilities::GetGCHandleManager(); IWeakReference* pExistingWeakReference = reinterpret_cast(mgr->GetExtraInfoFromHandle(handle.Handle)); - mgr->SetExtraInfoForHandle(handle.Handle, HNDTYPE_WEAK_WINRT, reinterpret_cast(pTargetWeakReference.GetValue())); + mgr->SetExtraInfoForHandle(handle.Handle, HNDTYPE_WEAK_NATIVE_COM, reinterpret_cast(pTargetWeakReference.GetValue())); StoreObjectInHandle(handle.Handle, target); if (pExistingWeakReference != nullptr) @@ -768,15 +794,15 @@ NOINLINE void SetWeakReferenceTarget(WEAKREFERENCEREF weakReference, OBJECTREF t } else if (pTargetWeakReference != nullptr) { - // The existing handle is not a WinRT weak reference, but we need to store the new object in - // a WinRT weak reference. Therefore we need to destroy the old handle and create a new WinRT + // The existing handle is not a native COM weak reference, but we need to store the new object in + // a native COM weak reference. Therefore we need to destroy the old handle and create a new native COM // handle. The new handle needs to be allocated first to prevent the weak reference from holding // a destroyed handle if we fail to allocate the new one. - _ASSERTE(!IsWinRTWeakReferenceHandle(handle.RawHandle)); + _ASSERTE(!IsNativeComWeakReferenceHandle(handle.RawHandle)); OBJECTHANDLE previousHandle = handle.RawHandle; - handle.Handle = GetAppDomain()->CreateWinRTWeakHandle(target, pTargetWeakReference); - handle.RawHandle = SetWinRTWeakReferenceHandle(handle.Handle); + handle.Handle = GetAppDomain()->CreateNativeComWeakHandle(target, pTargetWeakReference); + handle.RawHandle = SetNativeComWeakReferenceHandle(handle.Handle); DestroyTypedHandle(previousHandle); } @@ -822,7 +848,7 @@ FCIMPL2(void, WeakReferenceNative::SetTarget, WeakReferenceObject * pThisUNSAFE, // If the existing handle is a GC weak handle and the new target is not an RCW, then // we can avoid setting up a helper method frame and just reset the handle directly. - if (!IsWinRTWeakReferenceHandle(handle)) + if (!IsNativeComWeakReferenceHandle(handle)) { if (pTarget == NULL || !pTarget->GetMethodTable()->IsComObjectType()) { @@ -875,7 +901,7 @@ FCIMPL2(void, WeakReferenceOfTNative::SetTarget, WeakReferenceObject * pThisUNSA // If the existing handle is a GC weak handle and the new target is not an RCW, then // we can avoid setting up a helper method frame and just reset the handle directly. - if (!IsWinRTWeakReferenceHandle(handle)) + if (!IsNativeComWeakReferenceHandle(handle)) { if (pTarget == NULL || !pTarget->GetMethodTable()->IsComObjectType()) { diff --git a/src/coreclr/tests/src/Interop/CMakeLists.txt b/src/coreclr/tests/src/Interop/CMakeLists.txt index 8a39e97624f93..778d9ab3bded8 100644 --- a/src/coreclr/tests/src/Interop/CMakeLists.txt +++ b/src/coreclr/tests/src/Interop/CMakeLists.txt @@ -81,6 +81,7 @@ if(CLR_CMAKE_TARGET_WIN32) add_subdirectory(COM/NativeClients/Dispatch) add_subdirectory(COM/NativeClients/Events) add_subdirectory(COM/ComWrappers/MockReferenceTrackerRuntime) + add_subdirectory(COM/ComWrappers/WeakReference) add_subdirectory(WinRT/NativeComponent) # IJW isn't supported on ARM64 diff --git a/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/CMakeLists.txt b/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/CMakeLists.txt new file mode 100644 index 0000000000000..8166db2186574 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/CMakeLists.txt @@ -0,0 +1,10 @@ +project (WeakReferenceNative) +include_directories( ${INC_PLATFORM_DIR} ) +set(SOURCES WeakReferenceNative.cpp) + +# add the shared library +add_library (WeakReferenceNative SHARED ${SOURCES}) +target_link_libraries(WeakReferenceNative ${LINK_LIBRARIES_ADDITIONAL}) + +# add the install targets +install (TARGETS WeakReferenceNative DESTINATION bin) diff --git a/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp b/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp new file mode 100644 index 0000000000000..5617b11767981 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceNative.cpp @@ -0,0 +1,124 @@ +// 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. + +#include +#include +#include +#include + +namespace +{ + struct WeakReference : public IWeakReference, public UnknownImpl + { + IInspectable* _reference; + std::atomic _strongRefCount; + + WeakReference(IInspectable* reference, ULONG strongRefCount) + : _reference(reference), + _strongRefCount(strongRefCount) + {} + + ULONG AddStrongRef() + { + assert(_strongRefCount > 0); + return (++_strongRefCount); + } + + ULONG ReleaseStrongRef() + { + assert(_strongRefCount > 0); + return --_strongRefCount; + } + + STDMETHOD(Resolve)(REFIID riid, IInspectable** ppvObject) + { + if (_strongRefCount > 0) + { + void* pObject; + HRESULT hr = _reference->QueryInterface(riid, &pObject); + *ppvObject = reinterpret_cast(pObject); + return hr; + } + return E_NOINTERFACE; + } + + STDMETHOD(QueryInterface)( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject) + { + return DoQueryInterface(riid, ppvObject, static_cast(this)); + } + + DEFINE_REF_COUNTING() + }; + + struct WeakReferencableObject : public IWeakReferenceSource, public IInspectable, public UnknownImpl + { + ComSmartPtr _weakReference; + STDMETHOD(GetWeakReference)(_COM_Outptr_ IWeakReference** ppWeakReference) + { + if (!_weakReference) + { + ULONG refCount = UnknownImpl::GetRefCount(); + _weakReference = new WeakReference(this, refCount); + } + _weakReference->AddRef(); + *ppWeakReference = _weakReference; + return S_OK; + } + + STDMETHOD(GetRuntimeClassName)(HSTRING* pRuntimeClassName) + { + return E_NOTIMPL; + } + + STDMETHOD(GetIids)( + ULONG *iidCount, + IID **iids) + { + return E_NOTIMPL; + } + + STDMETHOD(GetTrustLevel)(TrustLevel *trustLevel) + { + *trustLevel = FullTrust; + return S_OK; + } + + STDMETHOD(QueryInterface)( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject) + { + HRESULT hr = DoQueryInterface(riid, ppvObject, static_cast(this), static_cast(this), static_cast(this)); + if (SUCCEEDED(hr) && _weakReference) + { + _weakReference->AddStrongRef(); + } + return hr; + } + STDMETHOD_(ULONG, AddRef)(void) + { + if (_weakReference) + { + return _weakReference->AddStrongRef(); + } + return UnknownImpl::DoAddRef(); + } + STDMETHOD_(ULONG, Release)(void) + { + if (_weakReference) + { + ULONG c = _weakReference->ReleaseStrongRef(); + if (c == 0) + delete this; + return c; + } + return UnknownImpl::DoRelease(); + } + }; +} +extern "C" DLL_EXPORT WeakReferencableObject* STDMETHODCALLTYPE CreateWeakReferencableObject() +{ + return new WeakReferencableObject(); +} diff --git a/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs b/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs new file mode 100644 index 0000000000000..acde6f6415802 --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs @@ -0,0 +1,137 @@ +// 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. + +namespace ComWrappersTests +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + using TestLibrary; + + static class WeakReferenceNative + { + [DllImport(nameof(WeakReferenceNative))] + public static extern IntPtr CreateWeakReferencableObject(); + } + + public struct VtblPtr + { + public IntPtr Vtbl; + } + + public class WeakReferencableWrapper + { + private struct Vtbl + { + public IntPtr QueryInterface; + public _AddRef AddRef; + public _Release Release; + } + + private delegate int _AddRef(IntPtr This); + private delegate int _Release(IntPtr This); + + private readonly IntPtr instance; + private readonly Vtbl vtable; + + public WeakReferencableWrapper(IntPtr instance) + { + var inst = Marshal.PtrToStructure(instance); + this.vtable = Marshal.PtrToStructure(inst.Vtbl); + this.instance = instance; + } + + ~WeakReferencableWrapper() + { + if (this.instance != IntPtr.Zero) + { + this.vtable.Release(this.instance); + } + } + } + + class Program + { + class TestComWrappers : ComWrappers + { + protected unsafe override ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) + { + count = 0; + return null; + } + + protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flag) + { + return new WeakReferencableWrapper(externalComObject); + } + + protected override void ReleaseObjects(IEnumerable objects) + { + } + + public static readonly ComWrappers Instance = new TestComWrappers(); + } + + static void ValidateNativeWeakReference() + { + Console.WriteLine($"Running {nameof(ValidateNativeWeakReference)}..."); + + static (WeakReference, IntPtr) GetWeakReference() + { + var cw = new TestComWrappers(); + + IntPtr objRaw = WeakReferenceNative.CreateWeakReferencableObject(); + + var obj = (WeakReferencableWrapper)cw.GetOrCreateObjectForComInstance(objRaw, CreateObjectFlags.None); + + // The returned WeakReferencableWrapper from ComWrappers takes ownership + // of the ref returned from CreateWeakReferencableObject. + // Call Marshal.AddRef to ensure that objRaw owns a reference. + Marshal.AddRef(objRaw); + + return (new WeakReference(obj), objRaw); + } + + static bool CheckIfWeakReferenceIsAlive(WeakReference wr) + { + return wr.TryGetTarget(out _); + } + + var (weakRef, nativeRef) = GetWeakReference(); + GC.Collect(); + GC.WaitForPendingFinalizers(); + // A weak reference to an RCW wrapping an IWeakReference should stay alive even after the RCW dies + Assert.IsTrue(CheckIfWeakReferenceIsAlive(weakRef)); + + // Release the last native reference. + Marshal.Release(nativeRef); + + GC.Collect(); + GC.WaitForPendingFinalizers(); + + // After all native references die and the RCW is collected, the weak reference should be dead and stay dead. + Assert.IsFalse(CheckIfWeakReferenceIsAlive(weakRef)); + + } + + static int Main(string[] doNotUse) + { + try + { + ComWrappers.RegisterForTrackerSupport(TestComWrappers.Instance); + ValidateNativeWeakReference(); + } + catch (Exception e) + { + Console.WriteLine($"Test Failure: {e}"); + return 101; + } + + return 100; + } + } +} + diff --git a/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj b/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj new file mode 100644 index 0000000000000..edcc33106ebde --- /dev/null +++ b/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj @@ -0,0 +1,24 @@ + + + Exe + + true + + true + true + true + + + + + + + + + + 1 + + + + + diff --git a/src/coreclr/tests/src/Interop/common/ComHelpers.h b/src/coreclr/tests/src/Interop/common/ComHelpers.h index c90ff7a773a2e..673f19063647d 100644 --- a/src/coreclr/tests/src/Interop/common/ComHelpers.h +++ b/src/coreclr/tests/src/Interop/common/ComHelpers.h @@ -105,6 +105,12 @@ class UnknownImpl return c; } +protected: + ULONG GetRefCount() + { + return _refCount; + } + private: std::atomic _refCount = 1; }; From 30119554b2be144ceff06a41326345975dd178f9 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 7 May 2020 20:19:20 -0700 Subject: [PATCH 048/420] Revert "Build an apphost with hostfxr and hostpolicy linked in (#35368)" (#36076) This reverts commit f6e5219b13f4bb9d6c1c9f80fd6ca6c594c6c7f8. --- eng/SignCheckExclusionsFile.txt | 1 - eng/Signing.props | 2 +- eng/native/functions.cmake | 8 +- .../coreclr}/generateexportedsymbols.awk | 0 .../coreclr}/generateversionscript.awk | 0 src/installer/corehost/cli/CMakeLists.txt | 4 +- .../corehost/cli/apphost/CMakeLists.txt | 48 ++++++++- .../cli/apphost/standalone/CMakeLists.txt | 54 ---------- .../apphost/standalone/hostfxr_resolver_t.cpp | 61 ------------ .../cli/apphost/static/CMakeLists.txt | 63 ------------ .../cli/apphost/static/hostfxr_resolver_t.cpp | 63 ------------ .../apphost/static/hostpolicy_resolver.cpp | 59 ----------- .../corehost/cli/dotnet/CMakeLists.txt | 4 - src/installer/corehost/cli/exe.cmake | 3 - src/installer/corehost/cli/fxr/CMakeLists.txt | 45 ++++++++- src/installer/corehost/cli/fxr/fx_muxer.cpp | 40 +++----- .../{standalone => }/hostpolicy_resolver.cpp | 3 - .../corehost/cli/fxr/hostpolicy_resolver.h | 6 +- .../cli/fxr/standalone/CMakeLists.txt | 65 ------------ .../corehost/cli/fxr/standalone/hostfxr.def | 21 ---- .../fxr/standalone/hostfxr_unixexports.src | 20 ---- .../corehost/cli/fxr/static/CMakeLists.txt | 45 --------- .../corehost/cli/hostpolicy/CMakeLists.txt | 46 ++++++++- .../cli/hostpolicy/standalone/CMakeLists.txt | 59 ----------- .../cli/hostpolicy/standalone/hostpolicy.def | 12 --- .../standalone/hostpolicy_unixexports.src | 11 --- .../cli/hostpolicy/static/CMakeLists.txt | 47 --------- src/installer/corehost/cli/lib_static.cmake | 6 +- src/installer/corehost/corehost.cpp | 60 +++++++----- src/installer/corehost/hostfxr_resolver_t.h | 40 -------- ...s_NT.Microsoft.NETCore.DotNetAppHost.props | 1 - .../pkg/Microsoft.NETCore.App.Host.pkgproj | 3 +- .../TestProjects/StaticHostApp/Program.cs | 16 --- .../StaticHostApp/StaticHostApp.csproj | 13 --- .../AppHost.Bundle.Tests/StaticHost.cs | 98 ------------------- 35 files changed, 191 insertions(+), 836 deletions(-) rename {eng/native => src/coreclr}/generateexportedsymbols.awk (100%) rename {eng/native => src/coreclr}/generateversionscript.awk (100%) delete mode 100644 src/installer/corehost/cli/apphost/standalone/CMakeLists.txt delete mode 100644 src/installer/corehost/cli/apphost/standalone/hostfxr_resolver_t.cpp delete mode 100644 src/installer/corehost/cli/apphost/static/CMakeLists.txt delete mode 100644 src/installer/corehost/cli/apphost/static/hostfxr_resolver_t.cpp delete mode 100644 src/installer/corehost/cli/apphost/static/hostpolicy_resolver.cpp rename src/installer/corehost/cli/fxr/{standalone => }/hostpolicy_resolver.cpp (97%) delete mode 100644 src/installer/corehost/cli/fxr/standalone/CMakeLists.txt delete mode 100644 src/installer/corehost/cli/fxr/standalone/hostfxr.def delete mode 100644 src/installer/corehost/cli/fxr/standalone/hostfxr_unixexports.src delete mode 100644 src/installer/corehost/cli/fxr/static/CMakeLists.txt delete mode 100644 src/installer/corehost/cli/hostpolicy/standalone/CMakeLists.txt delete mode 100644 src/installer/corehost/cli/hostpolicy/standalone/hostpolicy.def delete mode 100644 src/installer/corehost/cli/hostpolicy/standalone/hostpolicy_unixexports.src delete mode 100644 src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt delete mode 100644 src/installer/corehost/hostfxr_resolver_t.h delete mode 100644 src/installer/test/Assets/TestProjects/StaticHostApp/Program.cs delete mode 100644 src/installer/test/Assets/TestProjects/StaticHostApp/StaticHostApp.csproj delete mode 100644 src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/StaticHost.cs diff --git a/eng/SignCheckExclusionsFile.txt b/eng/SignCheckExclusionsFile.txt index fd2b824540457..a63e461d075f0 100644 --- a/eng/SignCheckExclusionsFile.txt +++ b/eng/SignCheckExclusionsFile.txt @@ -7,7 +7,6 @@ ;; and SCD apps. If they are signed, the file that the SDK produces has an invalid signature and ;; can't be signed again. More info at https://github.com/dotnet/core-setup/pull/7549. *apphost.exe;;Template, https://github.com/dotnet/core-setup/pull/7549 -*singlefilehost.exe;;Template, https://github.com/dotnet/core-setup/pull/7549 *comhost.dll;;Template, https://github.com/dotnet/core-setup/pull/7549 *apphosttemplateapphostexe.exe;;Template, https://github.com/dotnet/core-setup/pull/7549 *comhosttemplatecomhostdll.dll;;Template, https://github.com/dotnet/core-setup/pull/7549 diff --git a/eng/Signing.props b/eng/Signing.props index 5ceb96ac54bf9..05f2a8bcb3957 100644 --- a/eng/Signing.props +++ b/eng/Signing.props @@ -24,7 +24,7 @@ - + diff --git a/eng/native/functions.cmake b/eng/native/functions.cmake index 49b0064499eb4..060cff8987e35 100644 --- a/eng/native/functions.cmake +++ b/eng/native/functions.cmake @@ -175,8 +175,8 @@ function(generate_exports_file) add_custom_command( OUTPUT ${outputFilename} - COMMAND ${AWK} -f ${CLR_ENG_NATIVE_DIR}/${AWK_SCRIPT} ${INPUT_LIST} >${outputFilename} - DEPENDS ${INPUT_LIST} ${CLR_ENG_NATIVE_DIR}/${AWK_SCRIPT} + COMMAND ${AWK} -f ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT} ${INPUT_LIST} >${outputFilename} + DEPENDS ${INPUT_LIST} ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT} COMMENT "Generating exports file ${outputFilename}" ) set_source_files_properties(${outputFilename} @@ -196,8 +196,8 @@ function(generate_exports_file_prefix inputFilename outputFilename prefix) add_custom_command( OUTPUT ${outputFilename} - COMMAND ${AWK} -f ${CLR_ENG_NATIVE_DIR}/${AWK_SCRIPT} ${AWK_VARS} ${inputFilename} >${outputFilename} - DEPENDS ${inputFilename} ${CLR_ENG_NATIVE_DIR}/${AWK_SCRIPT} + COMMAND ${AWK} -f ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT} ${AWK_VARS} ${inputFilename} >${outputFilename} + DEPENDS ${inputFilename} ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT} COMMENT "Generating exports file ${outputFilename}" ) set_source_files_properties(${outputFilename} diff --git a/eng/native/generateexportedsymbols.awk b/src/coreclr/generateexportedsymbols.awk similarity index 100% rename from eng/native/generateexportedsymbols.awk rename to src/coreclr/generateexportedsymbols.awk diff --git a/eng/native/generateversionscript.awk b/src/coreclr/generateversionscript.awk similarity index 100% rename from eng/native/generateversionscript.awk rename to src/coreclr/generateversionscript.awk diff --git a/src/installer/corehost/cli/CMakeLists.txt b/src/installer/corehost/cli/CMakeLists.txt index 3c1bdb1f2f0ec..15ce0fa117721 100644 --- a/src/installer/corehost/cli/CMakeLists.txt +++ b/src/installer/corehost/cli/CMakeLists.txt @@ -1,10 +1,10 @@ add_subdirectory(hostcommon) add_subdirectory(apphost) add_subdirectory(dotnet) -add_subdirectory(nethost) -add_subdirectory(test_fx_ver) add_subdirectory(fxr) add_subdirectory(hostpolicy) +add_subdirectory(nethost) +add_subdirectory(test_fx_ver) add_subdirectory(test) diff --git a/src/installer/corehost/cli/apphost/CMakeLists.txt b/src/installer/corehost/cli/apphost/CMakeLists.txt index ec7e8e3e2ce4b..ba01e32ec47c7 100644 --- a/src/installer/corehost/cli/apphost/CMakeLists.txt +++ b/src/installer/corehost/cli/apphost/CMakeLists.txt @@ -2,5 +2,49 @@ # The .NET Foundation licenses this file to you under the MIT license. # See the LICENSE file in the project root for more information. -add_subdirectory(static) -add_subdirectory(standalone) +project(apphost) +set(DOTNET_PROJECT_NAME "apphost") + +# Add RPATH to the apphost binary that allows using local copies of shared libraries +# dotnet core depends on for special scenarios when system wide installation of such +# dependencies is not possible for some reason. +# This cannot be enabled for MacOS (Darwin) since its RPATH works in a different way, +# doesn't apply to libraries loaded via dlopen and most importantly, it is not transitive. +if (NOT CLR_CMAKE_TARGET_OSX) + set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) + set(CMAKE_INSTALL_RPATH "\$ORIGIN/netcoredeps") +endif() + +set(SKIP_VERSIONING 1) + +set(SOURCES + ./bundle_marker.cpp +) + +set(HEADERS + ./bundle_marker.h +) + +if(CLR_CMAKE_TARGET_WIN32) + list(APPEND SOURCES + apphost.windows.cpp) + + list(APPEND HEADERS + apphost.windows.h) +endif() + +include(../exe.cmake) + +add_definitions(-DFEATURE_APPHOST=1) + +# Disable manifest generation into the file .exe on Windows +if(CLR_CMAKE_TARGET_WIN32) + set_property(TARGET ${PROJECT_NAME} PROPERTY + LINK_FLAGS "/MANIFEST:NO" + ) +endif() + +# Specify non-default Windows libs to be used for Arm/Arm64 builds +if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64)) + target_link_libraries(apphost Advapi32.lib shell32.lib) +endif() diff --git a/src/installer/corehost/cli/apphost/standalone/CMakeLists.txt b/src/installer/corehost/cli/apphost/standalone/CMakeLists.txt deleted file mode 100644 index 60d9a103b12fb..0000000000000 --- a/src/installer/corehost/cli/apphost/standalone/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ -# 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. - -project(apphost) -set(DOTNET_PROJECT_NAME "apphost") - -# Add RPATH to the apphost binary that allows using local copies of shared libraries -# dotnet core depends on for special scenarios when system wide installation of such -# dependencies is not possible for some reason. -# This cannot be enabled for MacOS (Darwin) since its RPATH works in a different way, -# doesn't apply to libraries loaded via dlopen and most importantly, it is not transitive. -if (NOT CLR_CMAKE_TARGET_OSX) - set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) - set(CMAKE_INSTALL_RPATH "\$ORIGIN/netcoredeps") -endif() - -set(SKIP_VERSIONING 1) - -include_directories(..) - -set(SOURCES - ../bundle_marker.cpp - ./hostfxr_resolver_t.cpp -) - -set(HEADERS - ../bundle_marker.h - ../../../hostfxr_resolver_t.h -) - -if(CLR_CMAKE_TARGET_WIN32) - list(APPEND SOURCES - ../apphost.windows.cpp) - - list(APPEND HEADERS - ../apphost.windows.h) -endif() - -include(../../exe.cmake) - -add_definitions(-DFEATURE_APPHOST=1) - -# Disable manifest generation into the file .exe on Windows -if(CLR_CMAKE_TARGET_WIN32) - set_property(TARGET ${PROJECT_NAME} PROPERTY - LINK_FLAGS "/MANIFEST:NO" - ) -endif() - -# Specify non-default Windows libs to be used for Arm/Arm64 builds -if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64)) - target_link_libraries(apphost Advapi32.lib shell32.lib) -endif() diff --git a/src/installer/corehost/cli/apphost/standalone/hostfxr_resolver_t.cpp b/src/installer/corehost/cli/apphost/standalone/hostfxr_resolver_t.cpp deleted file mode 100644 index 4f3c3888428c5..0000000000000 --- a/src/installer/corehost/cli/apphost/standalone/hostfxr_resolver_t.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// 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. - -#include - -#include "pal.h" -#include "fxr_resolver.h" -#include "trace.h" -#include "hostfxr_resolver_t.h" - -hostfxr_main_bundle_startupinfo_fn hostfxr_resolver_t::resolve_main_bundle_startupinfo() -{ - assert(m_hostfxr_dll != nullptr); - return reinterpret_cast(pal::get_symbol(m_hostfxr_dll, "hostfxr_main_bundle_startupinfo")); -} - -hostfxr_set_error_writer_fn hostfxr_resolver_t::resolve_set_error_writer() -{ - assert(m_hostfxr_dll != nullptr); - return reinterpret_cast(pal::get_symbol(m_hostfxr_dll, "hostfxr_set_error_writer")); -} - -hostfxr_main_startupinfo_fn hostfxr_resolver_t::resolve_main_startupinfo() -{ - assert(m_hostfxr_dll != nullptr); - return reinterpret_cast(pal::get_symbol(m_hostfxr_dll, "hostfxr_main_startupinfo")); -} - -hostfxr_main_fn hostfxr_resolver_t::resolve_main_v1() -{ - assert(m_hostfxr_dll != nullptr); - return reinterpret_cast(pal::get_symbol(m_hostfxr_dll, "hostfxr_main")); -} - -hostfxr_resolver_t::hostfxr_resolver_t(const pal::string_t& app_root) -{ - if (!fxr_resolver::try_get_path(app_root, &m_dotnet_root, &m_fxr_path)) - { - m_status_code = StatusCode::CoreHostLibMissingFailure; - } - else if (pal::load_library(&m_fxr_path, &m_hostfxr_dll)) - { - m_status_code = StatusCode::Success; - } - else - { - trace::error(_X("The library %s was found, but loading it from %s failed"), LIBFXR_NAME, m_fxr_path.c_str()); - trace::error(_X(" - Installing .NET prerequisites might help resolve this problem.")); - trace::error(_X(" %s"), DOTNET_CORE_INSTALL_PREREQUISITES_URL); - m_status_code = StatusCode::CoreHostLibLoadFailure; - } -} - -hostfxr_resolver_t::~hostfxr_resolver_t() -{ - if (m_hostfxr_dll != nullptr) - { - pal::unload_library(m_hostfxr_dll); - } -} diff --git a/src/installer/corehost/cli/apphost/static/CMakeLists.txt b/src/installer/corehost/cli/apphost/static/CMakeLists.txt deleted file mode 100644 index 967aebb24133a..0000000000000 --- a/src/installer/corehost/cli/apphost/static/CMakeLists.txt +++ /dev/null @@ -1,63 +0,0 @@ -# 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. - -project(singlefilehost) -set(DOTNET_PROJECT_NAME "singlefilehost") - -# Add RPATH to the apphost binary that allows using local copies of shared libraries -# dotnet core depends on for special scenarios when system wide installation of such -# dependencies is not possible for some reason. -# This cannot be enabled for MacOS (Darwin) since its RPATH works in a different way, -# doesn't apply to libraries loaded via dlopen and most importantly, it is not transitive. -if (NOT CLR_CMAKE_TARGET_OSX) - set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) - set(CMAKE_INSTALL_RPATH "\$ORIGIN/netcoredeps") -endif() - -set(SKIP_VERSIONING 1) - -include_directories(..) -include_directories(../../json) - -set(SOURCES - ../bundle_marker.cpp - ./hostfxr_resolver_t.cpp - ./hostpolicy_resolver.cpp -) - -set(HEADERS - ../bundle_marker.h - ../../../hostfxr_resolver_t.h -) - -if(CLR_CMAKE_TARGET_WIN32) - list(APPEND SOURCES - ../apphost.windows.cpp) - - list(APPEND HEADERS - ../apphost.windows.h) -endif() - -include(../../exe.cmake) - -add_definitions(-DFEATURE_APPHOST=1) -add_definitions(-DFEATURE_STATIC_HOST=1) - -# Disable manifest generation into the file .exe on Windows -if(CLR_CMAKE_TARGET_WIN32) - set_property(TARGET ${PROJECT_NAME} PROPERTY - LINK_FLAGS "/MANIFEST:NO" - ) -endif() - -# Specify non-default Windows libs to be used for Arm/Arm64 builds -if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64)) - target_link_libraries(singlefilehost Advapi32.lib shell32.lib) -endif() - -target_link_libraries(singlefilehost - libhostfxr_static - libhostpolicy_static - libhostcommon -) diff --git a/src/installer/corehost/cli/apphost/static/hostfxr_resolver_t.cpp b/src/installer/corehost/cli/apphost/static/hostfxr_resolver_t.cpp deleted file mode 100644 index 2c7e2b87a5f6d..0000000000000 --- a/src/installer/corehost/cli/apphost/static/hostfxr_resolver_t.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// 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. - -#include -#include "trace.h" -#include "hostfxr.h" -#include "hostfxr_resolver_t.h" - -extern "C" -{ - int HOSTFXR_CALLTYPE hostfxr_main_bundle_startupinfo(const int argc, const pal::char_t* argv[], const pal::char_t* host_path, const pal::char_t* dotnet_root, const pal::char_t* app_path, int64_t bundle_header_offset); - int HOSTFXR_CALLTYPE hostfxr_main_startupinfo(const int argc, const pal::char_t* argv[], const pal::char_t* host_path, const pal::char_t* dotnet_root, const pal::char_t* app_path); - int HOSTFXR_CALLTYPE hostfxr_main(const int argc, const pal::char_t* argv[]); - hostfxr_error_writer_fn HOSTFXR_CALLTYPE hostfxr_set_error_writer(hostfxr_error_writer_fn error_writer); -} - -hostfxr_main_bundle_startupinfo_fn hostfxr_resolver_t::resolve_main_bundle_startupinfo() -{ - assert(m_hostfxr_dll == nullptr); - return hostfxr_main_bundle_startupinfo; -} - -hostfxr_set_error_writer_fn hostfxr_resolver_t::resolve_set_error_writer() -{ - assert(m_hostfxr_dll == nullptr); - return hostfxr_set_error_writer; -} - -hostfxr_main_startupinfo_fn hostfxr_resolver_t::resolve_main_startupinfo() -{ - assert(m_hostfxr_dll == nullptr); - return hostfxr_main_startupinfo; -} - -hostfxr_main_fn hostfxr_resolver_t::resolve_main_v1() -{ - assert(m_hostfxr_dll == nullptr); - assert(!"This function should not be called in a static host"); - return nullptr; -} - -hostfxr_resolver_t::hostfxr_resolver_t(const pal::string_t& app_root) -{ - if (app_root.length() == 0) - { - trace::info(_X("Application root path is empty. This shouldn't happen")); - m_status_code = StatusCode::CoreHostLibMissingFailure; - } - else - { - trace::info(_X("Using internal fxr")); - - m_dotnet_root.assign(app_root); - m_fxr_path.assign(app_root); - - m_status_code = StatusCode::Success; - } -} - -hostfxr_resolver_t::~hostfxr_resolver_t() -{ -} diff --git a/src/installer/corehost/cli/apphost/static/hostpolicy_resolver.cpp b/src/installer/corehost/cli/apphost/static/hostpolicy_resolver.cpp deleted file mode 100644 index 0b2a35639a2e1..0000000000000 --- a/src/installer/corehost/cli/apphost/static/hostpolicy_resolver.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// 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. - -#include -#include -#include -#include "hostpolicy_resolver.h" -#include -#include - -extern "C" -{ - int HOSTPOLICY_CALLTYPE corehost_load(const host_interface_t* init); - int HOSTPOLICY_CALLTYPE corehost_unload(); - corehost_error_writer_fn HOSTPOLICY_CALLTYPE corehost_set_error_writer(corehost_error_writer_fn error_writer); - int HOSTPOLICY_CALLTYPE corehost_initialize(const corehost_initialize_request_t *init_request, int32_t options, /*out*/ corehost_context_contract *context_contract); - int HOSTPOLICY_CALLTYPE corehost_main(const int argc, const pal::char_t* argv[]); - int HOSTPOLICY_CALLTYPE corehost_main_with_output_buffer(const int argc, const pal::char_t* argv[], pal::char_t buffer[], int32_t buffer_size, int32_t* required_buffer_size); -} - -int hostpolicy_resolver::load( - const pal::string_t& lib_dir, - pal::dll_t* dll, - hostpolicy_contract_t &hostpolicy_contract) -{ - static hostpolicy_contract_t contract; - - trace::info(_X("Using internal hostpolicy")); - - contract.load = corehost_load; - contract.unload = corehost_unload; - contract.set_error_writer = corehost_set_error_writer; - contract.initialize = corehost_initialize; - contract.corehost_main = corehost_main; - contract.corehost_main_with_output_buffer = corehost_main_with_output_buffer; - - hostpolicy_contract = contract; - *dll = nullptr; - - return StatusCode::Success; -} - -bool hostpolicy_resolver::try_get_dir( - host_mode_t mode, - const pal::string_t& dotnet_root, - const fx_definition_vector_t& fx_definitions, - const pal::string_t& app_candidate, - const pal::string_t& specified_deps_file, - const std::vector& probe_realpaths, - pal::string_t* impl_dir) -{ - // static apphost is not supposed to be used in a framework-dependent app - assert(!get_app(fx_definitions).get_runtime_config().get_is_framework_dependent()); - assert(mode == host_mode_t::apphost); - - impl_dir->assign(dotnet_root); - return true; -} diff --git a/src/installer/corehost/cli/dotnet/CMakeLists.txt b/src/installer/corehost/cli/dotnet/CMakeLists.txt index 798ae4030ea0a..4527986acfe3c 100644 --- a/src/installer/corehost/cli/dotnet/CMakeLists.txt +++ b/src/installer/corehost/cli/dotnet/CMakeLists.txt @@ -10,8 +10,4 @@ if(CLR_CMAKE_TARGET_WIN32) dotnet.manifest) endif() -list(APPEND SOURCES - ../apphost/standalone/hostfxr_resolver_t.cpp -) - include(../exe.cmake) diff --git a/src/installer/corehost/cli/exe.cmake b/src/installer/corehost/cli/exe.cmake index 3acc130174aa3..c9295d5c65f77 100644 --- a/src/installer/corehost/cli/exe.cmake +++ b/src/installer/corehost/cli/exe.cmake @@ -18,9 +18,6 @@ list(APPEND SOURCES ${CMAKE_CURRENT_LIST_DIR}/fxr_resolver.cpp ${CMAKE_CURRENT_LIST_DIR}/../corehost.cpp ) -list(APPEND HEADERS - ${CMAKE_CURRENT_LIST_DIR}/../hostfxr_resolver_t.h -) add_executable(${DOTNET_PROJECT_NAME} ${SOURCES} ${RESOURCES}) diff --git a/src/installer/corehost/cli/fxr/CMakeLists.txt b/src/installer/corehost/cli/fxr/CMakeLists.txt index ec7e8e3e2ce4b..216ecbf076bb7 100644 --- a/src/installer/corehost/cli/fxr/CMakeLists.txt +++ b/src/installer/corehost/cli/fxr/CMakeLists.txt @@ -2,5 +2,46 @@ # The .NET Foundation licenses this file to you under the MIT license. # See the LICENSE file in the project root for more information. -add_subdirectory(static) -add_subdirectory(standalone) +project(hostfxr) + +set(DOTNET_PROJECT_NAME "hostfxr") + +# Include directories +include_directories(../json) + +# CMake does not recommend using globbing since it messes with the freshness checks +set(SOURCES + ./command_line.cpp + ./corehost_init.cpp + ./hostfxr.cpp + ./fx_muxer.cpp + ./fx_resolver.cpp + ./fx_resolver.messages.cpp + ./framework_info.cpp + ./host_context.cpp + ./hostpolicy_resolver.cpp + ./sdk_info.cpp + ./sdk_resolver.cpp +) + +set(HEADERS + ../corehost_context_contract.h + ../hostpolicy.h + ../fx_definition.h + ../fx_reference.h + ../roll_fwd_on_no_candidate_fx_option.h + ./command_line.h + ./corehost_init.h + ./fx_muxer.h + ./fx_resolver.h + ./framework_info.h + ./host_context.h + ./hostpolicy_resolver.h + ./sdk_info.h + ./sdk_resolver.h +) + +include(../lib.cmake) + +install_with_stripped_symbols(hostfxr TARGETS corehost) +target_link_libraries(hostfxr libhostcommon) diff --git a/src/installer/corehost/cli/fxr/fx_muxer.cpp b/src/installer/corehost/cli/fxr/fx_muxer.cpp index f41e9095ef064..31c8c17797807 100644 --- a/src/installer/corehost/cli/fxr/fx_muxer.cpp +++ b/src/installer/corehost/cli/fxr/fx_muxer.cpp @@ -66,11 +66,16 @@ namespace } } +template int load_hostpolicy( const pal::string_t& lib_dir, pal::dll_t* h_host, - hostpolicy_contract_t& hostpolicy_contract) + hostpolicy_contract_t &hostpolicy_contract, + const char *main_entry_symbol, + T* main_fn) { + assert(main_entry_symbol != nullptr && main_fn != nullptr); + int rc = hostpolicy_resolver::load(lib_dir, h_host, hostpolicy_contract); if (rc != StatusCode::Success) { @@ -78,6 +83,11 @@ int load_hostpolicy( return rc; } + // Obtain entrypoint symbol + *main_fn = reinterpret_cast(pal::get_symbol(*h_host, main_entry_symbol)); + if (*main_fn == nullptr) + return StatusCode::CoreHostEntryPointFailure; + return StatusCode::Success; } @@ -104,18 +114,7 @@ static int execute_app( hostpolicy_contract_t hostpolicy_contract{}; corehost_main_fn host_main = nullptr; - int code = load_hostpolicy(impl_dll_dir, &hostpolicy_dll, hostpolicy_contract); - - // Obtain entrypoint symbol - if (code == StatusCode::Success) - { - host_main = hostpolicy_contract.corehost_main; - if (host_main == nullptr) - { - code = StatusCode::CoreHostEntryPointFailure; - } - } - + int code = load_hostpolicy(impl_dll_dir, &hostpolicy_dll, hostpolicy_contract, "corehost_main", &host_main); if (code != StatusCode::Success) { handle_initialize_failure_or_abort(); @@ -165,18 +164,7 @@ static int execute_host_command( hostpolicy_contract_t hostpolicy_contract{}; corehost_main_with_output_buffer_fn host_main = nullptr; - int code = load_hostpolicy(impl_dll_dir, &hostpolicy_dll, hostpolicy_contract); - - // Obtain entrypoint symbol - if (code == StatusCode::Success) - { - host_main = hostpolicy_contract.corehost_main_with_output_buffer; - if (host_main == nullptr) - { - code = StatusCode::CoreHostEntryPointFailure; - } - } - + int code = load_hostpolicy(impl_dll_dir, &hostpolicy_dll, hostpolicy_contract, "corehost_main_with_output_buffer", &host_main); if (code != StatusCode::Success) return code; @@ -483,7 +471,7 @@ namespace if (!hostpolicy_resolver::try_get_dir(mode, host_info.dotnet_root, fx_definitions, app_candidate, deps_file, probe_realpaths, &hostpolicy_dir)) { - return StatusCode::CoreHostLibMissingFailure; + return CoreHostLibMissingFailure; } init.reset(new corehost_init_t(host_command, host_info, deps_file, additional_deps_serialized, probe_realpaths, mode, fx_definitions)); diff --git a/src/installer/corehost/cli/fxr/standalone/hostpolicy_resolver.cpp b/src/installer/corehost/cli/fxr/hostpolicy_resolver.cpp similarity index 97% rename from src/installer/corehost/cli/fxr/standalone/hostpolicy_resolver.cpp rename to src/installer/corehost/cli/fxr/hostpolicy_resolver.cpp index 67881d207944f..de3291fecc5b5 100644 --- a/src/installer/corehost/cli/fxr/standalone/hostpolicy_resolver.cpp +++ b/src/installer/corehost/cli/fxr/hostpolicy_resolver.cpp @@ -198,9 +198,6 @@ int hostpolicy_resolver::load( g_hostpolicy_contract.set_error_writer = reinterpret_cast(pal::get_symbol(g_hostpolicy, "corehost_set_error_writer")); g_hostpolicy_contract.initialize = reinterpret_cast(pal::get_symbol(g_hostpolicy, "corehost_initialize")); - g_hostpolicy_contract.corehost_main = reinterpret_cast(pal::get_symbol(g_hostpolicy, "corehost_main")); - g_hostpolicy_contract.corehost_main_with_output_buffer = reinterpret_cast(pal::get_symbol(g_hostpolicy, "corehost_main_with_output_buffer")); - // It's possible to not have corehost_set_error_writer and corehost_initialize. These were // introduced in 3.0, so 2.0 hostpolicy would not have the exports. In this case, we will // not propagate the error writer and errors will still be reported to stderr. Callers are diff --git a/src/installer/corehost/cli/fxr/hostpolicy_resolver.h b/src/installer/corehost/cli/fxr/hostpolicy_resolver.h index 35128327b7bca..4348a53c778e0 100644 --- a/src/installer/corehost/cli/fxr/hostpolicy_resolver.h +++ b/src/installer/corehost/cli/fxr/hostpolicy_resolver.h @@ -20,10 +20,6 @@ struct hostpolicy_contract_t // 3.0+ contracts corehost_set_error_writer_fn set_error_writer; corehost_initialize_fn initialize; - - // 5.0+ contracts - corehost_main_fn corehost_main; - corehost_main_with_output_buffer_fn corehost_main_with_output_buffer; }; namespace hostpolicy_resolver @@ -42,4 +38,4 @@ namespace hostpolicy_resolver pal::string_t* impl_dir); }; -#endif // __HOSTPOLICY_RESOLVER_H__ +#endif // __HOSTPOLICY_RESOLVER_H__ \ No newline at end of file diff --git a/src/installer/corehost/cli/fxr/standalone/CMakeLists.txt b/src/installer/corehost/cli/fxr/standalone/CMakeLists.txt deleted file mode 100644 index 0a2ea92174b6f..0000000000000 --- a/src/installer/corehost/cli/fxr/standalone/CMakeLists.txt +++ /dev/null @@ -1,65 +0,0 @@ -# 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. - -project(hostfxr) - -set(DOTNET_PROJECT_NAME "hostfxr") - -# Include directories -include_directories(../../json) -include_directories(../../fxr) - -# CMake does not recommend using globbing since it messes with the freshness checks -set(SOURCES - ./hostpolicy_resolver.cpp -) - -set(HEADERS - ../command_line.h - ../corehost_init.h - ../fx_muxer.h - ../fx_resolver.h - ../framework_info.h - ../host_context.h - ../sdk_info.h - ../sdk_resolver.h - ../hostpolicy_resolver.h -) - -if(CLR_CMAKE_TARGET_WIN32) - list(APPEND SOURCES - hostfxr.def) -else(CLR_CMAKE_TARGET_WIN32) - set(DEF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/hostfxr_unixexports.src) - set(EXPORTS_FILE ${CMAKE_CURRENT_BINARY_DIR}/hostfxr.exports) - generate_exports_file(${DEF_SOURCES} ${EXPORTS_FILE}) - - if(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) - # Add linker exports file option - set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE}) - endif(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) - - if(CLR_CMAKE_HOST_OSX) - # Add linker exports file option - set(EXPORTS_LINKER_OPTION -Wl,-exported_symbols_list,${EXPORTS_FILE}) - endif(CLR_CMAKE_HOST_OSX) - - if(CLR_CMAKE_HOST_SUNOS) - # Add linker exports file option - set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) - endif(CLR_CMAKE_HOST_SUNOS) -endif(CLR_CMAKE_TARGET_WIN32) - -include(../../lib.cmake) - -if(CLR_CMAKE_HOST_UNIX) - add_custom_target(hostfxr_exports DEPENDS ${EXPORTS_FILE}) - add_dependencies(hostfxr hostfxr_exports) - - set_property(TARGET hostfxr APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION}) - set_property(TARGET hostfxr APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE}) -endif(CLR_CMAKE_HOST_UNIX) - -install_with_stripped_symbols(hostfxr TARGETS corehost) -target_link_libraries(hostfxr libhostcommon libhostfxr_static) diff --git a/src/installer/corehost/cli/fxr/standalone/hostfxr.def b/src/installer/corehost/cli/fxr/standalone/hostfxr.def deleted file mode 100644 index c86139a7fb58b..0000000000000 --- a/src/installer/corehost/cli/fxr/standalone/hostfxr.def +++ /dev/null @@ -1,21 +0,0 @@ -; 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. - -EXPORTS - hostfxr_main_bundle_startupinfo - hostfxr_main_startupinfo - hostfxr_main - hostfxr_resolve_sdk - hostfxr_resolve_sdk2 - hostfxr_get_available_sdks - hostfxr_get_native_search_directories - hostfxr_set_error_writer - hostfxr_initialize_for_dotnet_command_line - hostfxr_initialize_for_runtime_config - hostfxr_run_app - hostfxr_get_runtime_delegate - hostfxr_get_runtime_property_value - hostfxr_set_runtime_property_value - hostfxr_get_runtime_properties - hostfxr_close diff --git a/src/installer/corehost/cli/fxr/standalone/hostfxr_unixexports.src b/src/installer/corehost/cli/fxr/standalone/hostfxr_unixexports.src deleted file mode 100644 index fcf85d027fa64..0000000000000 --- a/src/installer/corehost/cli/fxr/standalone/hostfxr_unixexports.src +++ /dev/null @@ -1,20 +0,0 @@ -; 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. - -hostfxr_main_bundle_startupinfo -hostfxr_main_startupinfo -hostfxr_main -hostfxr_resolve_sdk -hostfxr_resolve_sdk2 -hostfxr_get_available_sdks -hostfxr_get_native_search_directories -hostfxr_set_error_writer -hostfxr_initialize_for_dotnet_command_line -hostfxr_initialize_for_runtime_config -hostfxr_run_app -hostfxr_get_runtime_delegate -hostfxr_get_runtime_property_value -hostfxr_set_runtime_property_value -hostfxr_get_runtime_properties -hostfxr_close diff --git a/src/installer/corehost/cli/fxr/static/CMakeLists.txt b/src/installer/corehost/cli/fxr/static/CMakeLists.txt deleted file mode 100644 index 16c0951c5b21b..0000000000000 --- a/src/installer/corehost/cli/fxr/static/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -# 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. - -project(hostfxr_static) - -set(DOTNET_PROJECT_NAME "hostfxr_static") - -# Include directories -include_directories(../../json) -include_directories(../../fxr) - -# CMake does not recommend using globbing since it messes with the freshness checks -set(SOURCES - ../command_line.cpp - ../corehost_init.cpp - ../hostfxr.cpp - ../fx_muxer.cpp - ../fx_resolver.cpp - ../fx_resolver.messages.cpp - ../framework_info.cpp - ../host_context.cpp - ../sdk_info.cpp - ../sdk_resolver.cpp -) - -set(HEADERS - ../../corehost_context_contract.h - ../../hostpolicy.h - ../../fx_definition.h - ../../fx_reference.h - ../../roll_fwd_on_no_candidate_fx_option.h - ../command_line.h - ../corehost_init.h - ../fx_muxer.h - ../fx_resolver.h - ../framework_info.h - ../host_context.h - ../sdk_info.h - ../sdk_resolver.h -) - -set(SKIP_VERSIONING 1) -set(BUILD_OBJECT_LIBRARY 1) -include(../../lib_static.cmake) diff --git a/src/installer/corehost/cli/hostpolicy/CMakeLists.txt b/src/installer/corehost/cli/hostpolicy/CMakeLists.txt index ec7e8e3e2ce4b..ca2c78fa27951 100644 --- a/src/installer/corehost/cli/hostpolicy/CMakeLists.txt +++ b/src/installer/corehost/cli/hostpolicy/CMakeLists.txt @@ -2,5 +2,47 @@ # The .NET Foundation licenses this file to you under the MIT license. # See the LICENSE file in the project root for more information. -add_subdirectory(static) -add_subdirectory(standalone) +project(hostpolicy) + +set(DOTNET_PROJECT_NAME "hostpolicy") + +# Include directories +include_directories(../fxr) +include_directories(../json) + +# CMake does not recommend using globbing since it messes with the freshness checks +set(SOURCES + ./args.cpp + ./breadcrumbs.cpp + ./coreclr.cpp + ./deps_resolver.cpp + ./hostpolicy_context.cpp + ./hostpolicy.cpp + ./hostpolicy_init.cpp + ../bundle/dir_utils.cpp + ../bundle/extractor.cpp + ../bundle/file_entry.cpp + ../bundle/manifest.cpp + ../bundle/runner.cpp +) + +set(HEADERS + ./args.h + ./breadcrumbs.h + ./coreclr.h + ../corehost_context_contract.h + ./deps_resolver.h + ./hostpolicy_context.h + ../hostpolicy.h + ./hostpolicy_init.h + ../bundle/dir_utils.h + ../bundle/extractor.h + ../bundle/file_entry.h + ../bundle/manifest.h + ../bundle/runner.h +) + +include(../lib.cmake) + +install_with_stripped_symbols(hostpolicy TARGETS corehost) +target_link_libraries(hostpolicy libhostcommon) diff --git a/src/installer/corehost/cli/hostpolicy/standalone/CMakeLists.txt b/src/installer/corehost/cli/hostpolicy/standalone/CMakeLists.txt deleted file mode 100644 index d6631543f81b5..0000000000000 --- a/src/installer/corehost/cli/hostpolicy/standalone/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ -# 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. - -project(hostpolicy) - -set(DOTNET_PROJECT_NAME "hostpolicy") - -# CMake does not recommend using globbing since it messes with the freshness checks - -# Can't call add_library() without source files. Create an empty .c file, -# then link with the static library just recently built. -if (NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/empty.cpp") - file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/empty.cpp" "") -endif () - -set(SOURCES - ${CMAKE_CURRENT_BINARY_DIR}/empty.cpp -) - -set(HEADERS -) - -if(CLR_CMAKE_TARGET_WIN32) - list(APPEND SOURCES - hostpolicy.def) -else(CLR_CMAKE_TARGET_WIN32) - set(DEF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/hostpolicy_unixexports.src) - set(EXPORTS_FILE ${CMAKE_CURRENT_BINARY_DIR}/hostpolicy.exports) - generate_exports_file(${DEF_SOURCES} ${EXPORTS_FILE}) - - if(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) - # Add linker exports file option - set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE}) - endif(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) - - if(CLR_CMAKE_HOST_OSX) - # Add linker exports file option - set(EXPORTS_LINKER_OPTION -Wl,-exported_symbols_list,${EXPORTS_FILE}) - endif(CLR_CMAKE_HOST_OSX) - - if(CLR_CMAKE_HOST_SUNOS) - # Add linker exports file option - set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) - endif(CLR_CMAKE_HOST_SUNOS) -endif(CLR_CMAKE_TARGET_WIN32) - -include(../../lib.cmake) - -if(CLR_CMAKE_HOST_UNIX) - add_custom_target(hostpolicy_exports DEPENDS ${EXPORTS_FILE}) - add_dependencies(hostpolicy hostpolicy_exports) - - set_property(TARGET hostpolicy APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION}) - set_property(TARGET hostpolicy APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE}) -endif(CLR_CMAKE_HOST_UNIX) - -install_with_stripped_symbols(hostpolicy TARGETS corehost) -target_link_libraries(hostpolicy libhostcommon libhostpolicy_static) diff --git a/src/installer/corehost/cli/hostpolicy/standalone/hostpolicy.def b/src/installer/corehost/cli/hostpolicy/standalone/hostpolicy.def deleted file mode 100644 index af03ab9dca68d..0000000000000 --- a/src/installer/corehost/cli/hostpolicy/standalone/hostpolicy.def +++ /dev/null @@ -1,12 +0,0 @@ -; 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. - -EXPORTS - corehost_initialize - corehost_load - corehost_main - corehost_main_with_output_buffer - corehost_resolve_component_dependencies - corehost_set_error_writer - corehost_unload diff --git a/src/installer/corehost/cli/hostpolicy/standalone/hostpolicy_unixexports.src b/src/installer/corehost/cli/hostpolicy/standalone/hostpolicy_unixexports.src deleted file mode 100644 index 98f3e616e9499..0000000000000 --- a/src/installer/corehost/cli/hostpolicy/standalone/hostpolicy_unixexports.src +++ /dev/null @@ -1,11 +0,0 @@ -; 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. - -corehost_initialize -corehost_load -corehost_main -corehost_main_with_output_buffer -corehost_resolve_component_dependencies -corehost_set_error_writer -corehost_unload diff --git a/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt b/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt deleted file mode 100644 index 6845e369bdac3..0000000000000 --- a/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -# 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. - -project(hostpolicy_static) - -set(DOTNET_PROJECT_NAME "hostpolicy_static") - -# Include directories -include_directories(../../fxr) -include_directories(../../json) - -# CMake does not recommend using globbing since it messes with the freshness checks -set(SOURCES - ../args.cpp - ../breadcrumbs.cpp - ../coreclr.cpp - ../deps_resolver.cpp - ../hostpolicy_context.cpp - ../hostpolicy.cpp - ../hostpolicy_init.cpp - ../../bundle/dir_utils.cpp - ../../bundle/extractor.cpp - ../../bundle/file_entry.cpp - ../../bundle/manifest.cpp - ../../bundle/runner.cpp -) - -set(HEADERS - ../args.h - ../breadcrumbs.h - ../coreclr.h - ../deps_resolver.h - ../hostpolicy_context.h - ../hostpolicy_init.h - ../../hostpolicy.h - ../../corehost_context_contract.h - ../../bundle/dir_utils.h - ../../bundle/extractor.h - ../../bundle/file_entry.h - ../../bundle/manifest.h - ../../bundle/runner.h -) - -set(SKIP_VERSIONING 1) -set(BUILD_OBJECT_LIBRARY 1) -include(../../lib_static.cmake) diff --git a/src/installer/corehost/cli/lib_static.cmake b/src/installer/corehost/cli/lib_static.cmake index 00204df3ce9f4..8135e9c19e0e0 100644 --- a/src/installer/corehost/cli/lib_static.cmake +++ b/src/installer/corehost/cli/lib_static.cmake @@ -10,11 +10,7 @@ add_definitions(-D_NO_ASYNCRTIMP) add_definitions(-D_NO_PPLXIMP) add_definitions(-DEXPORT_SHARED_API=1) -if (BUILD_OBJECT_LIBRARY) - add_library(lib${DOTNET_PROJECT_NAME} OBJECT ${SOURCES} ${RESOURCES}) -else () - add_library(lib${DOTNET_PROJECT_NAME} STATIC ${SOURCES} ${RESOURCES}) -endif () +add_library(lib${DOTNET_PROJECT_NAME} STATIC ${SOURCES} ${RESOURCES}) set_target_properties(lib${DOTNET_PROJECT_NAME} PROPERTIES MACOSX_RPATH TRUE) set_target_properties(lib${DOTNET_PROJECT_NAME} PROPERTIES PREFIX "") diff --git a/src/installer/corehost/corehost.cpp b/src/installer/corehost/corehost.cpp index 65cfb61f3ac64..55b8ed629827c 100644 --- a/src/installer/corehost/corehost.cpp +++ b/src/installer/corehost/corehost.cpp @@ -9,7 +9,6 @@ #include "fx_ver.h" #include "trace.h" #include "utils.h" -#include "hostfxr_resolver_t.h" #if defined(FEATURE_APPHOST) #include "bundle_marker.h" @@ -177,41 +176,51 @@ int exe_start(const int argc, const pal::char_t* argv[]) app_path.append(_X(".dll")); #endif - hostfxr_resolver_t fxr{app_root}; + pal::string_t dotnet_root; + pal::string_t fxr_path; + if (!fxr_resolver::try_get_path(app_root, &dotnet_root, &fxr_path)) + { + return StatusCode::CoreHostLibMissingFailure; + } - // Obtain the entrypoints. - int rc = fxr.status_code(); - if (rc != StatusCode::Success) + // Load library + pal::dll_t fxr; + if (!pal::load_library(&fxr_path, &fxr)) { - return rc; + trace::error(_X("The library %s was found, but loading it from %s failed"), LIBFXR_NAME, fxr_path.c_str()); + trace::error(_X(" - Installing .NET prerequisites might help resolve this problem.")); + trace::error(_X(" %s"), DOTNET_CORE_INSTALL_PREREQUISITES_URL); + return StatusCode::CoreHostLibLoadFailure; } + // Obtain the entrypoints. + int rc; #if defined(FEATURE_APPHOST) if (bundle_marker_t::is_bundle()) { - auto hostfxr_main_bundle_startupinfo = fxr.resolve_main_bundle_startupinfo(); + hostfxr_main_bundle_startupinfo_fn hostfxr_main_bundle_startupinfo = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_main_bundle_startupinfo")); if (hostfxr_main_bundle_startupinfo != nullptr) { const pal::char_t* host_path_cstr = host_path.c_str(); - const pal::char_t* dotnet_root_cstr = fxr.dotnet_root().empty() ? nullptr : fxr.dotnet_root().c_str(); + const pal::char_t* dotnet_root_cstr = dotnet_root.empty() ? nullptr : dotnet_root.c_str(); const pal::char_t* app_path_cstr = app_path.empty() ? nullptr : app_path.c_str(); int64_t bundle_header_offset = bundle_marker_t::header_offset(); - trace::info(_X("Invoking fx resolver [%s] hostfxr_main_bundle_startupinfo"), fxr.fxr_path().c_str()); + trace::info(_X("Invoking fx resolver [%s] hostfxr_main_bundle_startupinfo"), fxr_path.c_str()); trace::info(_X("Host path: [%s]"), host_path.c_str()); - trace::info(_X("Dotnet path: [%s]"), fxr.dotnet_root().c_str()); + trace::info(_X("Dotnet path: [%s]"), dotnet_root.c_str()); trace::info(_X("App path: [%s]"), app_path.c_str()); trace::info(_X("Bundle Header Offset: [%lx]"), bundle_header_offset); - auto set_error_writer = fxr.resolve_set_error_writer(); - propagate_error_writer_t propagate_error_writer_to_hostfxr(set_error_writer); + hostfxr_set_error_writer_fn set_error_writer_fn = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_set_error_writer")); + propagate_error_writer_t propagate_error_writer_to_hostfxr(set_error_writer_fn); rc = hostfxr_main_bundle_startupinfo(argc, argv, host_path_cstr, dotnet_root_cstr, app_path_cstr, bundle_header_offset); } else { // The host components will be statically linked with the app-host: https://github.com/dotnet/runtime/issues/32823 // Once this work is completed, an outdated hostfxr can only be found for framework-related apps. - trace::error(_X("The required library %s does not support single-file apps."), fxr.fxr_path().c_str()); + trace::error(_X("The required library %s does not support single-file apps."), fxr_path.c_str()); need_newer_framework_error(); rc = StatusCode::FrameworkMissingFailure; } @@ -219,61 +228,60 @@ int exe_start(const int argc, const pal::char_t* argv[]) else #endif // defined(FEATURE_APPHOST) { - auto hostfxr_main_startupinfo = fxr.resolve_main_startupinfo(); + hostfxr_main_startupinfo_fn hostfxr_main_startupinfo = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_main_startupinfo")); if (hostfxr_main_startupinfo != nullptr) { const pal::char_t* host_path_cstr = host_path.c_str(); - const pal::char_t* dotnet_root_cstr = fxr.dotnet_root().empty() ? nullptr : fxr.dotnet_root().c_str(); + const pal::char_t* dotnet_root_cstr = dotnet_root.empty() ? nullptr : dotnet_root.c_str(); const pal::char_t* app_path_cstr = app_path.empty() ? nullptr : app_path.c_str(); - trace::info(_X("Invoking fx resolver [%s] hostfxr_main_startupinfo"), fxr.fxr_path().c_str()); + trace::info(_X("Invoking fx resolver [%s] hostfxr_main_startupinfo"), fxr_path.c_str()); trace::info(_X("Host path: [%s]"), host_path.c_str()); - trace::info(_X("Dotnet path: [%s]"), fxr.dotnet_root().c_str()); + trace::info(_X("Dotnet path: [%s]"), dotnet_root.c_str()); trace::info(_X("App path: [%s]"), app_path.c_str()); - auto set_error_writer = fxr.resolve_set_error_writer(); - propagate_error_writer_t propagate_error_writer_to_hostfxr(set_error_writer); + hostfxr_set_error_writer_fn set_error_writer_fn = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_set_error_writer")); + propagate_error_writer_t propagate_error_writer_to_hostfxr(set_error_writer_fn); rc = hostfxr_main_startupinfo(argc, argv, host_path_cstr, dotnet_root_cstr, app_path_cstr); // This check exists to provide an error message for UI apps when running 3.0 apps on 2.0 only hostfxr, which doesn't support error writer redirection. - if (trace::get_error_writer() != nullptr && rc == static_cast(StatusCode::FrameworkMissingFailure) && set_error_writer == nullptr) + if (trace::get_error_writer() != nullptr && rc == static_cast(StatusCode::FrameworkMissingFailure) && !set_error_writer_fn) { need_newer_framework_error(); } } -#if !defined(FEATURE_STATIC_HOST) else { if (requires_hostfxr_startupinfo_interface) { - trace::error(_X("The required library %s does not support relative app dll paths."), fxr.fxr_path().c_str()); + trace::error(_X("The required library %s does not support relative app dll paths."), fxr_path.c_str()); rc = StatusCode::CoreHostEntryPointFailure; } else { - trace::info(_X("Invoking fx resolver [%s] v1"), fxr.fxr_path().c_str()); + trace::info(_X("Invoking fx resolver [%s] v1"), fxr_path.c_str()); // Previous corehost trace messages must be printed before calling trace::setup in hostfxr trace::flush(); // For compat, use the v1 interface. This requires additional file I\O to re-parse parameters and // for apphost, does not support DOTNET_ROOT or dll with different name for exe. - auto main_fn_v1 = fxr.resolve_main_v1(); + hostfxr_main_fn main_fn_v1 = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_main")); if (main_fn_v1 != nullptr) { rc = main_fn_v1(argc, argv); } else { - trace::error(_X("The required library %s does not contain the expected entry point."), fxr.fxr_path().c_str()); + trace::error(_X("The required library %s does not contain the expected entry point."), fxr_path.c_str()); rc = StatusCode::CoreHostEntryPointFailure; } } } -#endif // defined(FEATURE_STATIC_HOST) } + pal::unload_library(fxr); return rc; } diff --git a/src/installer/corehost/hostfxr_resolver_t.h b/src/installer/corehost/hostfxr_resolver_t.h deleted file mode 100644 index 21047b56a3c89..0000000000000 --- a/src/installer/corehost/hostfxr_resolver_t.h +++ /dev/null @@ -1,40 +0,0 @@ -// 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. - -#ifndef __HOSTFXR_RESOLVER_T_H__ -#define __HOSTFXR_RESOLVER_T_H__ - -#include "hostfxr.h" -#include "pal.h" -#include "error_codes.h" - -class hostfxr_resolver_t -{ - public: - hostfxr_resolver_t(const pal::string_t& app_root); - ~hostfxr_resolver_t(); - - StatusCode status_code() const { return m_status_code; } - - const pal::string_t& host_path() const { return m_host_path; } - const pal::string_t& dotnet_root() const { return m_dotnet_root; } - const pal::string_t& fxr_path() const { return m_fxr_path; } - - hostfxr_main_bundle_startupinfo_fn resolve_main_bundle_startupinfo(); - hostfxr_set_error_writer_fn resolve_set_error_writer(); - hostfxr_main_startupinfo_fn resolve_main_startupinfo(); - hostfxr_main_fn resolve_main_v1(); - - private: - pal::dll_t m_hostfxr_dll{nullptr}; - - pal::string_t m_host_path; - pal::string_t m_dotnet_root; - pal::string_t m_fxr_path; - - bool m_requires_startupinfo_iface{false}; - StatusCode m_status_code; -}; - -#endif // __HOSTFXR_RESOLVER_T_H__ diff --git a/src/installer/pkg/projects/Microsoft.NETCore.DotNetAppHost/runtime.Windows_NT.Microsoft.NETCore.DotNetAppHost.props b/src/installer/pkg/projects/Microsoft.NETCore.DotNetAppHost/runtime.Windows_NT.Microsoft.NETCore.DotNetAppHost.props index 6d52e1984f8ce..c74da91a0f25c 100644 --- a/src/installer/pkg/projects/Microsoft.NETCore.DotNetAppHost/runtime.Windows_NT.Microsoft.NETCore.DotNetAppHost.props +++ b/src/installer/pkg/projects/Microsoft.NETCore.DotNetAppHost/runtime.Windows_NT.Microsoft.NETCore.DotNetAppHost.props @@ -2,7 +2,6 @@ - diff --git a/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Host.pkgproj b/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Host.pkgproj index 8daa78d3ec711..10915e8d504d4 100644 --- a/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Host.pkgproj +++ b/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Host.pkgproj @@ -15,7 +15,6 @@ --> - @@ -30,4 +29,4 @@ true - + \ No newline at end of file diff --git a/src/installer/test/Assets/TestProjects/StaticHostApp/Program.cs b/src/installer/test/Assets/TestProjects/StaticHostApp/Program.cs deleted file mode 100644 index c631d81d54048..0000000000000 --- a/src/installer/test/Assets/TestProjects/StaticHostApp/Program.cs +++ /dev/null @@ -1,16 +0,0 @@ -// 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. - -using System; - -namespace StaticHostApp -{ - public static class Program - { - public static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - } - } -} diff --git a/src/installer/test/Assets/TestProjects/StaticHostApp/StaticHostApp.csproj b/src/installer/test/Assets/TestProjects/StaticHostApp/StaticHostApp.csproj deleted file mode 100644 index eff31e8532b40..0000000000000 --- a/src/installer/test/Assets/TestProjects/StaticHostApp/StaticHostApp.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - $(NETCoreAppFramework) - Exe - $(TestTargetRid) - $(MNAVersion) - - - - - - diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/StaticHost.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/StaticHost.cs deleted file mode 100644 index 78b5c9449fe1b..0000000000000 --- a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/StaticHost.cs +++ /dev/null @@ -1,98 +0,0 @@ -// 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. - -using BundleTests.Helpers; -using Microsoft.DotNet.Cli.Build.Framework; -using Microsoft.DotNet.CoreSetup.Test; -using Microsoft.NET.HostModel.AppHost; -using Microsoft.NET.HostModel.Bundle; -using System; -using System.IO; -using System.Threading; -using Xunit; - -namespace AppHost.Bundle.Tests -{ - public class StaticHost : IClassFixture - { - private SharedTestState sharedTestState; - - public StaticHost(SharedTestState fixture) - { - sharedTestState = fixture; - } - - // This helper is used in lieu of SDK support for publishing apps using the singlefilehost. - // It replaces the apphost with singlefilehost, and along with appropriate app.dll updates in the host. - // For now, we leave behind the hostpolicy and hostfxr DLLs in the publish directory, because - // removing them requires deps.json update. - void ReplaceApphostWithStaticHost(TestProjectFixture fixture) - { - var staticHost = Path.Combine(fixture.RepoDirProvider.HostArtifacts, - RuntimeInformationExtensions.GetExeFileNameForCurrentPlatform("singlefilehost")); - HostWriter.CreateAppHost(staticHost, - BundleHelper.GetHostPath(fixture), - BundleHelper.GetAppPath(fixture)); - - } - - [Fact] - private void Can_Run_App_With_StatiHost() - { - var fixture = sharedTestState.TestFixture.Copy(); - var appExe = BundleHelper.GetHostPath(fixture); - - ReplaceApphostWithStaticHost(fixture); - - Command.Create(appExe) - .CaptureStdErr() - .CaptureStdOut() - .Execute() - .Should() - .Pass() - .And - .HaveStdOutContaining("Hello World"); - } - - [Fact] - private void Can_Run_SingleFile_App_With_StatiHost() - { - var fixture = sharedTestState.TestFixture.Copy(); - - ReplaceApphostWithStaticHost(fixture); - - string singleFile = BundleHelper.BundleApp(fixture); - - Command.Create(singleFile) - .CaptureStdErr() - .CaptureStdOut() - .Execute() - .Should() - .Pass() - .And - .HaveStdOutContaining("Hello World"); - } - - public class SharedTestState : IDisposable - { - public TestProjectFixture TestFixture { get; set; } - public RepoDirectoriesProvider RepoDirectories { get; set; } - - public SharedTestState() - { - RepoDirectories = new RepoDirectoriesProvider(); - TestFixture = new TestProjectFixture("StaticHostApp", RepoDirectories); - TestFixture - .EnsureRestoredForRid(TestFixture.CurrentRid, RepoDirectories.CorehostPackages) - .PublishProject(runtime: TestFixture.CurrentRid, - outputDirectory: BundleHelper.GetPublishPath(TestFixture)); - } - - public void Dispose() - { - TestFixture.Dispose(); - } - } - } -} From 93344266685c75ebcd293f171b3033432909a60a Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 7 May 2020 20:52:10 -0700 Subject: [PATCH 049/420] Disable Microsoft.Extensions.Caching.Memory.Tests on Mono (#36083) --- .../tests/AssemblyAttributes.cs | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/libraries/Microsoft.Extensions.Caching.Memory/tests/AssemblyAttributes.cs diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/AssemblyAttributes.cs b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/AssemblyAttributes.cs new file mode 100644 index 0000000000000..82c60ec93e309 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/AssemblyAttributes.cs @@ -0,0 +1,7 @@ +// 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. + +using Xunit; + +[assembly: ActiveIssue("https://github.com/dotnet/runtime/issues/35970", TestRuntimes.Mono)] From 2973724e9eeda9d675cf1ea2d8de1d93f68bbc7a Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 7 May 2020 22:10:50 -0700 Subject: [PATCH 050/420] Disable NonDisposedSocket_SafeHandlesCollected in AnyUnix (#36099) --- .../tests/FunctionalTests/DisposedSocketTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisposedSocketTests.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisposedSocketTests.cs index 21e4750d4744b..ee81d7cdf81ac 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisposedSocketTests.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisposedSocketTests.cs @@ -751,7 +751,7 @@ public void EndAccept_Throws_ObjectDisposed() [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsPreciseGcSupported))] [InlineData(false)] [InlineData(true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/35846", TestPlatforms.Linux)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/35846", TestPlatforms.AnyUnix)] public async Task NonDisposedSocket_SafeHandlesCollected(bool clientAsync) { List handles = await CreateHandlesAsync(clientAsync); From 83712dffda33b2b2d26ce13650ecf54f29a34116 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 7 May 2020 22:32:10 -0700 Subject: [PATCH 051/420] Optimize BitOperations.PopCount() with arm64 intrinsics (#35636) * Intrinsicy BitOperations.PopCount() for arm64 Co-authored-by: Tanner Gooding --- .../src/System/Numerics/BitOperations.cs | 22 +++++++++++++++++++ .../Runtime/Intrinsics/Intrinsics.Shims.cs | 20 +++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs index c8356a0c9eb01..fe457200e960d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs @@ -4,6 +4,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; @@ -243,6 +244,19 @@ public static int PopCount(uint value) return (int)Popcnt.PopCount(value); } + if (AdvSimd.Arm64.IsSupported) + { + // PopCount works on vector so convert input value to vector first. + + // Vector64.CreateScalar(uint) generates suboptimal code by storing and + // loading the result to memory. + // See https://github.com/dotnet/runtime/issues/35976 for details. + // Hence use Vector64.Create(ulong) to create Vector64 and operate on that. + Vector64 input = Vector64.Create((ulong)value); + Vector64 aggregated = AdvSimd.Arm64.AddAcross(AdvSimd.PopCount(input.AsByte())); + return AdvSimd.Extract(aggregated, 0); + } + return SoftwareFallback(value); static int SoftwareFallback(uint value) @@ -274,6 +288,14 @@ public static int PopCount(ulong value) return (int)Popcnt.X64.PopCount(value); } + if (AdvSimd.Arm64.IsSupported) + { + // PopCount works on vector so convert input value to vector first. + Vector64 input = Vector64.Create(value); + Vector64 aggregated = AdvSimd.Arm64.AddAcross(AdvSimd.PopCount(input.AsByte())); + return AdvSimd.Extract(aggregated, 0); + } + #if TARGET_32BIT return PopCount((uint)value) // lo + PopCount((uint)(value >> 32)); // hi diff --git a/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs b/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs index 91059ddbeb3a5..e1654081c7766 100644 --- a/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs +++ b/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs @@ -4,6 +4,16 @@ namespace System.Runtime.Intrinsics { + internal static class Vector64 + { + public static Vector64 Create(ulong value) => throw new PlatformNotSupportedException(); + public static Vector64 AsByte(this Vector64 vector) where T : struct => throw new PlatformNotSupportedException(); + } + internal readonly struct Vector64 + where T : struct + { + } + internal static class Vector128 { public static Vector128 Create(short value) => throw new PlatformNotSupportedException(); @@ -130,4 +140,14 @@ public abstract class Arm64 public static int LeadingZeroCount(uint value) => throw new PlatformNotSupportedException(); public static uint ReverseElementBits(uint value) => throw new PlatformNotSupportedException(); } + + internal abstract class AdvSimd : ArmBase + { + public new abstract class Arm64 : ArmBase.Arm64 + { + public static Vector64 AddAcross(Vector64 value) => throw new PlatformNotSupportedException(); + } + public static byte Extract(Vector64 vector, byte index) => throw new PlatformNotSupportedException(); + public static Vector64 PopCount(Vector64 value) => throw new PlatformNotSupportedException(); + } } From 63aee4501b5696df889107f3656581cd0ce7c09c Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 7 May 2020 22:50:10 -0700 Subject: [PATCH 052/420] Disable BerConverterTest in arm64 (#36088) * Disable BerConverterTest in arm64 * Disable just for failing format --- .../tests/BerConverterTests.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs index a6b301da3829c..30836ff3d2aab 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using Microsoft.DotNet.XUnitExtensions; using System.Collections.Generic; using System.Runtime.InteropServices; using Xunit; @@ -42,10 +43,15 @@ public static IEnumerable Encode_TestData() yield return new object[] { "VVVV", new object[] { null, new byte[][] { new byte[] { 0, 1, 2, 3 }, null }, new byte[][] { new byte[0] }, new byte[0][] }, new byte[] { 4, 4, 0, 1, 2, 3, 4, 0, 4, 0 } }; } - [Theory] + [ConditionalTheory] [MemberData(nameof(Encode_TestData))] public void Encode_Objects_ReturnsExpected(string format, object[] values, byte[] expected) { + if (PlatformDetection.IsArm64Process && format.Contains("tetie")) + { + throw new SkipTestException("Active issue: https://github.com/dotnet/runtime/issues/36087"); + } + AssertExtensions.Equal(expected, BerConverter.Encode(format, values)); } From 451c8c25ecb01ab7c613c42361d88513a1836847 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 7 May 2020 23:41:20 -0700 Subject: [PATCH 053/420] Mix installer build configurations in PRs as all are Debug now (#36081) --- eng/pipelines/runtime.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index ab7e22e025a76..d937c2b97f162 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -513,7 +513,7 @@ jobs: - template: /eng/pipelines/installer/installer-matrix.yml parameters: - buildConfig: ${{ variables.debugOnPrReleaseOnRolling }} + buildConfig: Release platforms: - OSX_x64 - Linux_x64 @@ -527,7 +527,7 @@ jobs: - template: /eng/pipelines/installer/installer-matrix.yml parameters: - buildConfig: ${{ variables.debugOnPrReleaseOnRolling }} + buildConfig: Release runtimeFlavor: mono platforms: - Android_x64 From da6a5f9f9747cdb39d82ea4586127cc5631fec67 Mon Sep 17 00:00:00 2001 From: Mitchell Hwang Date: Fri, 8 May 2020 04:34:09 -0400 Subject: [PATCH 054/420] Migrating libraries props into both iOS and Android test runner workflow (#35535) This PR targets "Migrate existing props and targets into the libraries test build flow" in #35123. The changes are primarily simplifying hard-coded paths to the `lib-runtime-packs` `native` and `lib` sub-directories by extending runtime pack path properties. Co-authored-by: Mitchell Hwang --- eng/testing/tests.targets | 30 ++++++++++++++--------------- src/libraries/Directory.Build.props | 5 +++-- src/mono/mono.proj | 1 - 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/eng/testing/tests.targets b/eng/testing/tests.targets index 86e035b0a4a1e..5b10d0f72f31a 100644 --- a/eng/testing/tests.targets +++ b/eng/testing/tests.targets @@ -107,7 +107,6 @@ AssemblyFile="$(ArtifactsObjDir)mono\AndroidAppBuilder\$(HostArch)\$(Configuration)\AndroidAppBuilder.dll" /> - $(ArtifactsDir)bin\lib-runtime-packs\runtimes\android-$(TargetArchitecture) $(OutDir)\Bundle $(RepoRoot)\src\mono\msbuild\AndroidTestRunner\bin arm64-v8a @@ -122,17 +121,17 @@ - - + + - - + + - + @@ -151,7 +150,7 @@ @@ -169,7 +168,6 @@ AssemblyFile="$(ArtifactsObjDir)mono\AppleAppBuilder\$(HostArch)\$(Configuration)\AppleAppBuilder.dll" /> - $(ArtifactsDir)bin\lib-runtime-packs\runtimes\ios-$(TargetArchitecture) $(OutDir)\Bundle $(RepoRoot)\src\mono\msbuild\AppleTestRunner\bin @@ -180,14 +178,14 @@ - - + + - + - + @@ -199,15 +197,15 @@ diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index 1de45d5dd85ac..f358b94b2a5ae 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -273,8 +273,9 @@ $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'testhost', '$(BuildSettings)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'lib-runtime-packs')) - $([MSBuild]::NormalizeDirectory('$(NETCoreAppRuntimePackPath)', 'runtimes', '$(PackageRID)', 'lib', '$(NETCoreAppFramework)')) - $([MSBuild]::NormalizeDirectory('$(NETCoreAppRuntimePackPath)', 'runtimes', '$(PackageRID)', 'native')) + $([MSBuild]::NormalizeDirectory('$(NETCoreAppRuntimePackPath)', 'runtimes', '$(PackageRID)')) + $([MSBuild]::NormalizeDirectory('$(NETCoreAppRuntimePackRIDPath)' 'lib', '$(NETCoreAppFramework)')) + $([MSBuild]::NormalizeDirectory('$(NETCoreAppRuntimePackRIDPath)', 'native')) runtimes/$(PackageRID) $(ArtifactsObjDir)version.txt diff --git a/src/mono/mono.proj b/src/mono/mono.proj index dce9417cfff83..52f22a06b9b58 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -926,7 +926,6 @@ - Date: Fri, 8 May 2020 05:36:09 -0400 Subject: [PATCH 055/420] [interp] Fix memory overwrite during pinvoke r4 parameter passing. (#35835) Fixes https://github.com/mono/mono/issues/19684. Co-authored-by: vargaz --- src/mono/mono/mini/aot-runtime-wasm.c | 6 ------ src/mono/mono/mini/interp/interp.c | 13 +------------ 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/mono/mono/mini/aot-runtime-wasm.c b/src/mono/mono/mini/aot-runtime-wasm.c index ccc5a26510c93..8f26a725abde7 100644 --- a/src/mono/mono/mini/aot-runtime-wasm.c +++ b/src/mono/mono/mini/aot-runtime-wasm.c @@ -63,13 +63,7 @@ type_to_c (MonoType *t) } } -#if TARGET_SIZEOF_VOID_P == 4 -#define FIDX(x) ((x) * 2) -#else #define FIDX(x) (x) -#endif - - typedef union { gint64 l; diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index d2e388df90741..f51fb3d7aa0aa 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -1290,16 +1290,9 @@ static InterpMethodArguments* build_args_from_sig (MonoMethodSignature *sig, Int break; #endif case MONO_TYPE_R4: -#if SIZEOF_VOID_P == 8 case MONO_TYPE_R8: -#endif margs->flen++; break; -#if SIZEOF_VOID_P == 4 - case MONO_TYPE_R8: - margs->flen += 2; - break; -#endif default: g_error ("build_args_from_sig: not implemented yet (1): 0x%x\n", ptype); } @@ -1384,11 +1377,7 @@ static InterpMethodArguments* build_args_from_sig (MonoMethodSignature *sig, Int #if DEBUG_INTERP g_print ("build_args_from_sig: margs->fargs [%d]: %p (%f) (frame @ %d)\n", int_f, margs->fargs [int_f], margs->fargs [int_f], i); #endif -#if SIZEOF_VOID_P == 4 - int_f += 2; -#else - int_f++; -#endif + int_f ++; break; default: g_error ("build_args_from_sig: not implemented yet (2): 0x%x\n", ptype); From 741e9054d25adc8a93fd2695b0848adcecaaffb0 Mon Sep 17 00:00:00 2001 From: Mitchell Hwang Date: Fri, 8 May 2020 08:56:03 -0400 Subject: [PATCH 056/420] Migrating Apple and Android AppBuilder and TestRunner binaries to Artifacts/Bin (#35909) This PR is a part of #35123. This PR achieves two things: 1. Migrates Apple and Android AppBuilder and TestRunner binaries to `/artifacts/bin` 2. Add property paths for Apple and Android AppBuilder and TestRunner projects and binaries After changes, when building `./build.sh -os iOS -subset Mono+Libs+Libs.Tests`, binary files are no longer produced in `/src/mono/msbuild/`. Instead, they can be found in `/artifacts/bin/` --- eng/testing/tests.props | 7 +++++++ eng/testing/tests.targets | 6 ++---- src/mono/Directory.Build.props | 8 ++++++++ src/mono/mono.proj | 8 ++++---- .../msbuild/AndroidAppBuilder/AndroidAppBuilder.csproj | 2 +- .../msbuild/AndroidTestRunner/AndroidTestRunner.csproj | 2 +- src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj | 2 +- src/mono/msbuild/AppleTestRunner/AppleTestRunner.csproj | 2 +- src/mono/netcore/sample/Android/Program.csproj | 7 ++++--- src/mono/netcore/sample/iOS/Program.csproj | 7 ++++--- 10 files changed, 33 insertions(+), 18 deletions(-) diff --git a/eng/testing/tests.props b/eng/testing/tests.props index 7534dd5bc2a7f..be2962cded046 100644 --- a/eng/testing/tests.props +++ b/eng/testing/tests.props @@ -20,6 +20,13 @@ <_withoutCategories Condition="!$(_withCategories.Contains('failing'))">$(_withoutCategories);failing + + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleTestRunner')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidTestRunner')) + + + AssemblyFile="$(AndroidAppBuilder)\$(HostArch)\$(Configuration)\AndroidAppBuilder.dll" /> $(OutDir)\Bundle - $(RepoRoot)\src\mono\msbuild\AndroidTestRunner\bin arm64-v8a armeabi x86_64 @@ -165,11 +164,10 @@ + AssemblyFile="$(AppleAppBuilder)\$(HostArch)\$(Configuration)\AppleAppBuilder.dll" /> $(OutDir)\Bundle - $(RepoRoot)\src\mono\msbuild\AppleTestRunner\bin + + $([MSBuild]::NormalizeDirectory('$(MonoProjectRoot)', 'msbuild', 'AppleAppBuilder')) + $([MSBuild]::NormalizeDirectory('$(MonoProjectRoot)', 'msbuild', 'AppleTestRunner')) + $([MSBuild]::NormalizeDirectory('$(MonoProjectRoot)', 'msbuild', 'AndroidAppBuilder')) + $([MSBuild]::NormalizeDirectory('$(MonoProjectRoot)', 'msbuild', 'AndroidTestRunner')) + diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 52f22a06b9b58..c6c35c2adcb22 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -927,19 +927,19 @@ - - - - diff --git a/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.csproj b/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.csproj index d0ced747eb0be..81ac0dede8395 100644 --- a/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.csproj +++ b/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.csproj @@ -1,7 +1,7 @@ Library - bin + $(AndroidAppBuilder) $(NetCoreAppCurrent) enable true diff --git a/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.csproj b/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.csproj index 8c6e2429f6ee2..75396c49b0f7b 100644 --- a/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.csproj +++ b/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.csproj @@ -1,7 +1,7 @@ Exe - bin + $(AndroidTestRunner) $(NetCoreAppCurrent) enable diff --git a/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj b/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj index dd703fd583a9a..a9ad9fca464b5 100644 --- a/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj +++ b/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj @@ -1,7 +1,7 @@ Library - bin + $(AppleAppBuilder) $(NetCoreAppCurrent) enable true diff --git a/src/mono/msbuild/AppleTestRunner/AppleTestRunner.csproj b/src/mono/msbuild/AppleTestRunner/AppleTestRunner.csproj index 8c6e2429f6ee2..45cccc572889e 100644 --- a/src/mono/msbuild/AppleTestRunner/AppleTestRunner.csproj +++ b/src/mono/msbuild/AppleTestRunner/AppleTestRunner.csproj @@ -1,7 +1,7 @@ Exe - bin + $(AppleTestRunner) $(NetCoreAppCurrent) enable diff --git a/src/mono/netcore/sample/Android/Program.csproj b/src/mono/netcore/sample/Android/Program.csproj index 51a153db7cbe2..065f601c4032e 100644 --- a/src/mono/netcore/sample/Android/Program.csproj +++ b/src/mono/netcore/sample/Android/Program.csproj @@ -6,15 +6,16 @@ x64 $(ArtifactsDir)bin\lib-runtime-packs\runtimes\android-$(TargetArchitecture) $(MSBuildThisFileDirectory)\bin\bundle + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder')) - + + AssemblyFile="$(AndroidAppBuilder)\$(HostArch)\$(Configuration)\AndroidAppBuilder.dll" /> diff --git a/src/mono/netcore/sample/iOS/Program.csproj b/src/mono/netcore/sample/iOS/Program.csproj index 908aad01ea612..ddc14fb0bb531 100644 --- a/src/mono/netcore/sample/iOS/Program.csproj +++ b/src/mono/netcore/sample/iOS/Program.csproj @@ -7,15 +7,16 @@ $(ArtifactsDir)bin\lib-runtime-packs\runtimes\ios-$(TargetArchitecture) $(ArtifactsDir)bin\mono\iOS.$(TargetArchitecture).$(Configuration) $(MSBuildThisFileDirectory)\bin\bundle + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder')) - + + AssemblyFile="$(AppleAppBuilder)\$(HostArch)\$(Configuration)\AppleAppBuilder.dll" /> From 3b68eb3b1edc5a0ed0f4758668937fe4de17c431 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Fri, 8 May 2020 06:21:56 -0700 Subject: [PATCH 057/420] disable sslv2 tests for now (#36102) Co-authored-by: Tomas Weinfurt --- .../tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs | 2 ++ .../tests/FunctionalTests/ClientAsyncAuthenticateTest.cs | 1 + 2 files changed, 3 insertions(+) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs index b264aa6bc6c5d..06133d3398bc3 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs @@ -113,6 +113,7 @@ public static IEnumerable GetAsync_AllowedSSLVersion_Succeeds_MemberDa [Theory] [MemberData(nameof(GetAsync_AllowedSSLVersion_Succeeds_MemberData))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/36100", TestPlatforms.Windows)] public async Task GetAsync_AllowedSSLVersion_Succeeds(SslProtocols acceptedProtocol, bool requestOnlyThisProtocol) { using (HttpClientHandler handler = CreateHttpClientHandler()) @@ -250,6 +251,7 @@ public async Task GetAsync_NoSpecifiedProtocol_DefaultsToTls12() [InlineData(SslProtocols.Tls11 | SslProtocols.Tls12, SslProtocols.Tls)] // Skip this on WinHttpHandler. [InlineData(SslProtocols.Tls12, SslProtocols.Tls11)] [InlineData(SslProtocols.Tls, SslProtocols.Tls12)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/36100", TestPlatforms.Windows)] public async Task GetAsync_AllowedClientSslVersionDiffersFromServer_ThrowsException( SslProtocols allowedClientProtocols, SslProtocols acceptedServerProtocols) { diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs index 5c227192f2448..3a8bf3bd8b53a 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs @@ -59,6 +59,7 @@ public async Task ClientAsyncAuthenticate_EachSupportedProtocol_Success(SslProto [Fact] [PlatformSpecific(TestPlatforms.Windows)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/36100")] public async Task ClientAsyncAuthenticate_Ssl2WithSelf_Success() { // Test Ssl2 against itself. This is a standalone test as even on versions where Windows supports Ssl2, From 2e1bc9d765a783df63ea274c929406111b4bc54c Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Fri, 8 May 2020 16:28:25 +0200 Subject: [PATCH 058/420] Remove MinHandles and OutstandingHandles logic from SocketAsyncEngine (#36019) * remove MinHandles logic from SocketAsyncEngine (always use Round-robin) * remove _outstandingHandles * add Debug.Assert to make sure that we always succeed in adding a new context to the dcitionary * remove duplicated Debug.Assert (checked few lines above) --- .../Net/Sockets/SocketAsyncEngine.Unix.cs | 50 ++----------------- 1 file changed, 5 insertions(+), 45 deletions(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs index badf27e85d358..053cc4fcb6f77 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Unix.cs @@ -122,8 +122,6 @@ private static int GetEngineCount() // private static readonly IntPtr MaxHandles = IntPtr.Size == 4 ? (IntPtr)int.MaxValue : (IntPtr)long.MaxValue; #endif - private static readonly IntPtr MinHandlesForAdditionalEngine = s_maxEngineCount == 1 ? MaxHandles : (IntPtr)32; - // // Sentinel handle value to identify events from the "shutdown pipe," used to signal an event loop to stop // processing events. @@ -136,12 +134,6 @@ private static int GetEngineCount() // private IntPtr _nextHandle; - // - // Count of handles that have been allocated for this event port, but not yet freed. - // Must be accessed under s_lock. - // - private IntPtr _outstandingHandles; - // // Maps handle values to SocketAsyncContext instances. // @@ -165,16 +157,6 @@ private static int GetEngineCount() // private bool IsFull { get { return _nextHandle == MaxHandles; } } - // True if we've don't have sufficient active sockets to allow allocating a new engine. - private bool HasLowNumberOfSockets - { - get - { - return IntPtr.Size == 4 ? _outstandingHandles.ToInt32() < MinHandlesForAdditionalEngine.ToInt32() : - _outstandingHandles.ToInt64() < MinHandlesForAdditionalEngine.ToInt64(); - } - } - // // Allocates a new {SocketAsyncEngine, handle} pair. // @@ -185,21 +167,7 @@ private static void AllocateToken(SocketAsyncContext context, out SocketAsyncEng engine = s_currentEngines[s_allocateFromEngine]; if (engine == null) { - // We minimize the number of engines on applications that have a low number of concurrent sockets. - for (int i = 0; i < s_allocateFromEngine; i++) - { - var previousEngine = s_currentEngines[i]; - if (previousEngine == null || previousEngine.HasLowNumberOfSockets) - { - s_allocateFromEngine = i; - engine = previousEngine; - break; - } - } - if (engine == null) - { - s_currentEngines[s_allocateFromEngine] = engine = new SocketAsyncEngine(); - } + s_currentEngines[s_allocateFromEngine] = engine = new SocketAsyncEngine(); } handle = engine.AllocateHandle(context); @@ -211,10 +179,7 @@ private static void AllocateToken(SocketAsyncContext context, out SocketAsyncEng } // Round-robin to the next engine once we have sufficient sockets on this one. - if (!engine.HasLowNumberOfSockets) - { - s_allocateFromEngine = (s_allocateFromEngine + 1) % s_maxEngineCount; - } + s_allocateFromEngine = (s_allocateFromEngine + 1) % s_maxEngineCount; } } @@ -225,12 +190,10 @@ private IntPtr AllocateHandle(SocketAsyncContext context) IntPtr handle = _nextHandle; Debug.Assert(handle != ShutdownHandle, "ShutdownHandle must not be added to the dictionary"); - _handleToContextMap.TryAdd(handle, new SocketAsyncContextWrapper(context)); - + bool added = _handleToContextMap.TryAdd(handle, new SocketAsyncContextWrapper(context)); + Debug.Assert(added, "Add should always succeed"); _nextHandle = IntPtr.Add(_nextHandle, 1); - _outstandingHandles = IntPtr.Add(_outstandingHandles, 1); - Debug.Assert(handle != ShutdownHandle, $"Expected handle != ShutdownHandle: {handle}"); return handle; } @@ -244,14 +207,11 @@ private void FreeHandle(IntPtr handle) { if (_handleToContextMap.TryRemove(handle, out _)) { - _outstandingHandles = IntPtr.Subtract(_outstandingHandles, 1); - Debug.Assert(_outstandingHandles.ToInt64() >= 0, $"Unexpected _outstandingHandles: {_outstandingHandles}"); - // // If we've allocated all possible handles for this instance, and freed them all, then // we don't need the event loop any more, and can reclaim resources. // - if (IsFull && _outstandingHandles == IntPtr.Zero) + if (IsFull && _handleToContextMap.IsEmpty) { shutdownNeeded = true; } From 59d6c6cf43eb7113adb06b89842b38e5bb2682c9 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Fri, 8 May 2020 10:44:14 -0400 Subject: [PATCH 059/420] [interp] Add x86 support (#35966) This mainly consists of a trampoline that is used when calling from interp into native code, as well as the call convention logic that initializes the CallContext structure (which is passed to the trampoline). On other platforms we also have a single trampoline used when entering interpreter code. That trampoline works in a similar way and its purpose is to avoid compilation of all possible interp entry signatures, which is problematic on full aot scenarios. Given the interp x86 support is currently provided for android, we can avoid using that trampoline for now and use the per signature jit compiled interp_in_wrappers instead. The few disabled interp tests are the same as on amd64. We only support pinvoke into cdecl functions. Co-authored-by: BrzVlad --- src/mono/mono/metadata/object-offsets.h | 8 ++ src/mono/mono/mini/exceptions-x86.c | 12 +++ src/mono/mono/mini/interp/interp-internals.h | 6 +- src/mono/mono/mini/interp/transform.c | 6 ++ src/mono/mono/mini/mini-x86.c | 106 +++++++++++++++++++ src/mono/mono/mini/mini-x86.h | 15 +++ src/mono/mono/mini/tramp-x86.c | 89 ++++++++++++++++ src/mono/mono/tests/Makefile.am | 8 ++ 8 files changed, 249 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/object-offsets.h b/src/mono/mono/metadata/object-offsets.h index 9a36613866d77..82f901714646e 100644 --- a/src/mono/mono/metadata/object-offsets.h +++ b/src/mono/mono/metadata/object-offsets.h @@ -298,6 +298,14 @@ DECL_OFFSET(CallContext, stack_size) DECL_OFFSET(CallContext, stack) #endif +#if defined(TARGET_X86) +DECL_OFFSET(CallContext, eax) +DECL_OFFSET(CallContext, edx) +DECL_OFFSET(CallContext, fret) +DECL_OFFSET(CallContext, stack_size) +DECL_OFFSET(CallContext, stack) +#endif + #if defined(TARGET_X86) DECL_OFFSET(GSharedVtCallInfo, stack_usage) DECL_OFFSET(GSharedVtCallInfo, vret_slot) diff --git a/src/mono/mono/mini/exceptions-x86.c b/src/mono/mono/mini/exceptions-x86.c index 22e54bc9258a5..d8f6f769a1c51 100644 --- a/src/mono/mono/mini/exceptions-x86.c +++ b/src/mono/mono/mini/exceptions-x86.c @@ -1242,3 +1242,15 @@ mono_arch_setup_resume_sighandler_ctx (MonoContext *ctx, gpointer func) MONO_CONTEXT_SET_IP (ctx, func); } + +void +mono_arch_undo_ip_adjustment (MonoContext *ctx) +{ + ctx->eip++; +} + +void +mono_arch_do_ip_adjustment (MonoContext *ctx) +{ + ctx->eip--; +} diff --git a/src/mono/mono/mini/interp/interp-internals.h b/src/mono/mono/mini/interp/interp-internals.h index b335170438670..049de513fcd5f 100644 --- a/src/mono/mono/mini/interp/interp-internals.h +++ b/src/mono/mono/mini/interp/interp-internals.h @@ -181,7 +181,11 @@ typedef struct _StackFragment StackFragment; struct _StackFragment { guint8 *pos, *end; struct _StackFragment *next; - double data [1]; +#if SIZEOF_VOID_P == 4 + /* Align data field to MINT_VT_ALIGNMENT */ + gint32 pad; +#endif + double data [MONO_ZERO_LEN_ARRAY]; }; typedef struct { diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index c9bf7a6b28c78..4554273a0357c 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -2482,6 +2482,12 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target td->last_ins->data [0] = get_data_item_index (td, (void *)csignature); } else if (calli) { td->last_ins->data [0] = get_data_item_index (td, (void *)csignature); +#ifdef TARGET_X86 + /* Windows not tested/supported yet */ + if (td->last_ins->opcode == MINT_CALLI_NAT) + g_assertf (csignature->call_convention == MONO_CALL_DEFAULT || csignature->call_convention == MONO_CALL_C, "Interpreter supports only cdecl pinvoke on x86"); +#endif + if (op != -1) { td->last_ins->data[1] = op; if (td->last_ins->opcode == MINT_CALLI_NAT_FAST) diff --git a/src/mono/mono/mini/mini-x86.c b/src/mono/mono/mini/mini-x86.c index 464dc5d969d61..9bfa7beafeced 100644 --- a/src/mono/mono/mini/mini-x86.c +++ b/src/mono/mono/mini/mini-x86.c @@ -567,6 +567,112 @@ static gboolean storage_in_ireg (ArgStorage storage) return (storage == ArgInIReg || storage == ArgValuetypeInReg); } +static int +arg_need_temp (ArgInfo *ainfo) +{ + /* + * We always fetch the double value from the fpstack. In that case, we + * need to have a separate tmp that is the double value casted to float + */ + if (ainfo->storage == ArgOnFloatFpStack) + return sizeof (float); + return 0; +} + +static gpointer +arg_get_storage (CallContext *ccontext, ArgInfo *ainfo) +{ + switch (ainfo->storage) { + case ArgOnStack: + return ccontext->stack + ainfo->offset; + case ArgOnDoubleFpStack: + return &ccontext->fret; + case ArgInIReg: + /* If pair, the storage is for EDX:EAX */ + return &ccontext->eax; + default: + g_error ("Arg storage type not yet supported"); + } +} + +static void +arg_get_val (CallContext *ccontext, ArgInfo *ainfo, gpointer dest) +{ + g_assert (ainfo->storage == ArgOnFloatFpStack); + + *(float*) dest = (float)ccontext->fret; +} + +void +mono_arch_set_native_call_context_args (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig) +{ + CallInfo *cinfo = get_call_info (NULL, sig); + MonoEECallbacks *interp_cb = mini_get_interp_callbacks (); + gpointer storage; + ArgInfo *ainfo; + + memset (ccontext, 0, sizeof (CallContext)); + + ccontext->stack_size = ALIGN_TO (cinfo->stack_usage, MONO_ARCH_FRAME_ALIGNMENT); + if (ccontext->stack_size) + ccontext->stack = (guint8*)g_calloc (1, ccontext->stack_size); + + if (sig->ret->type != MONO_TYPE_VOID) { + ainfo = &cinfo->ret; + if (ainfo->storage == ArgOnStack) { + /* This is a value type return. The pointer to vt storage is pushed as first argument */ + g_assert (ainfo->offset == 0); + g_assert (ainfo->nslots == 1); + storage = interp_cb->frame_arg_to_storage ((MonoInterpFrameHandle)frame, sig, -1); + *(host_mgreg_t*)ccontext->stack = (host_mgreg_t)storage; + } + } + + g_assert (!sig->hasthis); + + for (int i = 0; i < sig->param_count; i++) { + ainfo = &cinfo->args [i]; + + storage = arg_get_storage (ccontext, ainfo); + + interp_cb->frame_arg_to_data ((MonoInterpFrameHandle)frame, sig, i, storage); + } + + g_free (cinfo); +} + +void +mono_arch_get_native_call_context_ret (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig) +{ + const MonoEECallbacks *interp_cb; + CallInfo *cinfo; + ArgInfo *ainfo; + gpointer storage; + + /* No return value */ + if (sig->ret->type == MONO_TYPE_VOID) + return; + + interp_cb = mini_get_interp_callbacks (); + cinfo = get_call_info (NULL, sig); + ainfo = &cinfo->ret; + + /* Check if return value was stored directly at address passed in reg */ + if (cinfo->ret.storage != ArgOnStack) { + int temp_size = arg_need_temp (ainfo); + + if (temp_size) { + storage = alloca (temp_size); + arg_get_val (ccontext, ainfo, storage); + } else { + storage = arg_get_storage (ccontext, ainfo); + } + interp_cb->data_to_frame_arg ((MonoInterpFrameHandle)frame, sig, -1, storage); + } + + g_free (cinfo); +} + /* * mono_arch_get_argument_info: * @csig: a method signature diff --git a/src/mono/mono/mini/mini-x86.h b/src/mono/mono/mini/mini-x86.h index 6791b57074e9f..6d44cb5f2bf18 100644 --- a/src/mono/mono/mini/mini-x86.h +++ b/src/mono/mono/mini/mini-x86.h @@ -204,6 +204,10 @@ typedef struct { #define MONO_ARCH_HAVE_GET_TRAMPOLINES 1 #define MONO_ARCH_HAVE_GENERAL_RGCTX_LAZY_FETCH_TRAMPOLINE 1 +#define MONO_ARCH_INTERPRETER_SUPPORTED 1 +#define MONO_ARCH_HAVE_INTERP_NATIVE_TO_MANAGED 1 +#define MONO_ARCH_HAVE_INTERP_PINVOKE_TRAMP 1 + #define MONO_ARCH_HAVE_CMOV_OPS 1 #ifdef MONO_ARCH_SIMD_INTRINSICS @@ -332,6 +336,17 @@ struct CallInfo { ArgInfo args [1]; }; +typedef struct { + /* EAX:EDX */ + host_mgreg_t eax; + host_mgreg_t edx; + /* Floating point return value read from the top of x86 fpstack */ + double fret; + /* Stack usage, used for passing params on stack */ + guint32 stack_size; + guint8 *stack; +} CallContext; + guint32 mono_x86_get_this_arg_offset (MonoMethodSignature *sig); diff --git a/src/mono/mono/mini/tramp-x86.c b/src/mono/mono/mini/tramp-x86.c index 196a3bf9ad818..10900c8113d71 100644 --- a/src/mono/mono/mini/tramp-x86.c +++ b/src/mono/mono/mini/tramp-x86.c @@ -719,3 +719,92 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo return buf; } + +gpointer +mono_arch_get_interp_to_native_trampoline (MonoTrampInfo **info) +{ +#ifndef DISABLE_INTERPRETER + guint8 *start = NULL, *code; + guint8 *label_start_copy, *label_exit_copy; + MonoJumpInfo *ji = NULL; + GSList *unwind_ops = NULL; + int buf_len; + int ccontext_offset, target_offset; + + buf_len = 512; + start = code = (guint8 *) mono_global_codeman_reserve (buf_len); + + x86_push_reg (code, X86_EBP); + /* args are on the stack, above saved EBP and pushed return EIP */ + target_offset = 2 * sizeof (target_mgreg_t); + ccontext_offset = target_offset + sizeof (target_mgreg_t); + x86_mov_reg_reg (code, X86_EBP, X86_ESP); + + /* Save some used regs and align stack to 16 bytes */ + x86_push_reg (code, X86_EDI); + x86_push_reg (code, X86_ESI); + + /* load pointer to CallContext* into ESI */ + x86_mov_reg_membase (code, X86_ESI, X86_EBP, ccontext_offset, sizeof (target_mgreg_t)); + + /* allocate the stack space necessary for the call */ + x86_mov_reg_membase (code, X86_ECX, X86_ESI, MONO_STRUCT_OFFSET (CallContext, stack_size), sizeof (target_mgreg_t)); + x86_alu_reg_reg (code, X86_SUB, X86_ESP, X86_ECX); + + /* copy stack from the CallContext, ESI = source, EDI = dest, ECX bytes to copy */ + x86_mov_reg_membase (code, X86_ESI, X86_ESI, MONO_STRUCT_OFFSET (CallContext, stack), sizeof (target_mgreg_t)); + x86_mov_reg_reg (code, X86_EDI, X86_ESP); + + label_start_copy = code; + x86_test_reg_reg (code, X86_ECX, X86_ECX); + label_exit_copy = code; + x86_branch8 (code, X86_CC_Z, 0, FALSE); + x86_mov_reg_membase (code, X86_EDX, X86_ESI, 0, sizeof (target_mgreg_t)); + x86_mov_membase_reg (code, X86_EDI, 0, X86_EDX, sizeof (target_mgreg_t)); + x86_alu_reg_imm (code, X86_ADD, X86_EDI, sizeof (target_mgreg_t)); + x86_alu_reg_imm (code, X86_ADD, X86_ESI, sizeof (target_mgreg_t)); + x86_alu_reg_imm (code, X86_SUB, X86_ECX, sizeof (target_mgreg_t)); + x86_jump_code (code, label_start_copy); + x86_patch (label_exit_copy, code); + + /* load target addr */ + x86_mov_reg_membase (code, X86_EAX, X86_EBP, target_offset, sizeof (target_mgreg_t)); + + /* call into native function */ + x86_call_reg (code, X86_EAX); + + /* Save return values into CallContext* */ + x86_mov_reg_membase (code, X86_ESI, X86_EBP, ccontext_offset, sizeof (target_mgreg_t)); + x86_mov_membase_reg (code, X86_ESI, MONO_STRUCT_OFFSET (CallContext, eax), X86_EAX, sizeof (target_mgreg_t)); + x86_mov_membase_reg (code, X86_ESI, MONO_STRUCT_OFFSET (CallContext, edx), X86_EDX, sizeof (target_mgreg_t)); + + /* + * We always pop ST0, even if we don't have return value. We seem to get away with + * this because fpstack is either empty or has one fp return value on top and the cpu + * doesn't trap if we read top of empty stack. + */ + x86_fst_membase (code, X86_ESI, MONO_STRUCT_OFFSET (CallContext, fret), TRUE, TRUE); + + /* restore ESI, EDI which were saved below rbp */ + x86_mov_reg_membase (code, X86_EDI, X86_EBP, - sizeof (target_mgreg_t), sizeof (target_mgreg_t)); + x86_mov_reg_membase (code, X86_ESI, X86_EBP, - 2 * sizeof (target_mgreg_t), sizeof (target_mgreg_t)); + x86_mov_reg_reg (code, X86_ESP, X86_EBP); + + x86_pop_reg (code, X86_EBP); + + x86_ret (code); + + g_assertf ((code - start) <= buf_len, "%d %d", (int)(code - start), buf_len); + + mono_arch_flush_icache (start, code - start); + MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_HELPER, NULL)); + + if (info) + *info = mono_tramp_info_create ("interp_to_native_trampoline", start, code - start, ji, unwind_ops); + + return start; +#else + g_assert_not_reached (); + return NULL; +#endif /* DISABLE_INTERPRETER */ +} diff --git a/src/mono/mono/tests/Makefile.am b/src/mono/mono/tests/Makefile.am index 566388ce2e457..ffdf85a2c7ff1 100755 --- a/src/mono/mono/tests/Makefile.am +++ b/src/mono/mono/tests/Makefile.am @@ -2034,6 +2034,14 @@ INTERP_DISABLED_TESTS += \ pinvoke3.exe endif +if X86 +INTERP_DISABLED_TESTS += \ + bug-60862.exe \ + cominterop.exe \ + dim-diamondshape.exe \ + pinvoke3.exe +endif + TESTS_CS=$(filter-out $(DISABLED_TESTS),$(TESTS_CS_SRC:.cs=.exe)) TESTS_IL=$(filter-out $(DISABLED_TESTS),$(TESTS_IL_SRC:.il=.exe)) TESTS_BENCH=$(filter-out $(DISABLED_TESTS),$(TESTS_BENCH_SRC:.cs=.exe)) From 57408d0d892544c52bddcde3dd8aa3190edf53a9 Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Fri, 8 May 2020 07:58:10 -0700 Subject: [PATCH 060/420] Struct Improvements (#35544) * Struct Improvements - If we have a struct with a single field we can reference it as the full size of the struct. - Eliminate old code for an integer zero RHS with a SIMD12 LHS, and unify the codegen for zero-init for SIMD8 and SIMD12 (between block init and assignment of SIMD init of 0) --- src/coreclr/src/jit/codegenarm64.cpp | 41 ++++++++++++++++++++---- src/coreclr/src/jit/codegenlinear.cpp | 2 +- src/coreclr/src/jit/codegenxarch.cpp | 11 ------- src/coreclr/src/jit/gentree.h | 20 ++++++++++++ src/coreclr/src/jit/lowerarmarch.cpp | 14 +++++--- src/coreclr/src/jit/lowerxarch.cpp | 17 +++++++--- src/coreclr/src/jit/lsrabuild.cpp | 15 ++++++++- src/coreclr/src/jit/morph.cpp | 3 +- src/coreclr/src/jit/simdcodegenxarch.cpp | 21 +++++++++--- 9 files changed, 110 insertions(+), 34 deletions(-) diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index 26c7411b71e13..c3f7c07bbfcf8 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -1953,17 +1953,31 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree) genConsumeRegs(data); regNumber dataReg = REG_NA; - if (data->isContainedIntOrIImmed()) + if (data->isContained()) { // This is only possible for a zero-init. - assert(data->IsIntegralConst(0)); + assert(data->IsIntegralConst(0) || data->IsSIMDZero()); if (varTypeIsSIMD(targetType)) { - assert(targetType == TYP_SIMD16); - assert(targetReg != REG_NA); - emit->emitIns_R_I(INS_movi, EA_16BYTE, targetReg, 0x00, INS_OPTS_16B); - genProduceReg(tree); + if (targetReg != REG_NA) + { + emit->emitIns_R_I(INS_movi, emitActualTypeSize(targetType), targetReg, 0x00, INS_OPTS_16B); + genProduceReg(tree); + } + else + { + if (targetType == TYP_SIMD16) + { + GetEmitter()->emitIns_S_S_R_R(INS_stp, EA_8BYTE, EA_8BYTE, REG_ZR, REG_ZR, varNum, 0); + } + else + { + assert(targetType == TYP_SIMD8); + GetEmitter()->emitIns_S_R(INS_str, EA_8BYTE, REG_ZR, varNum, 0); + } + genUpdateLife(tree); + } return; } @@ -5019,7 +5033,20 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode) } GenTree* op1 = treeNode->AsOp()->gtOp1; - assert(!op1->isContained()); + + if (op1->isContained()) + { + // This is only possible for a zero-init. + assert(op1->IsIntegralConst(0) || op1->IsSIMDZero()); + + // store lower 8 bytes + GetEmitter()->emitIns_S_R(ins_Store(TYP_DOUBLE), EA_8BYTE, REG_ZR, varNum, offs); + + // Store upper 4 bytes + GetEmitter()->emitIns_S_R(ins_Store(TYP_FLOAT), EA_4BYTE, REG_ZR, varNum, offs + 8); + + return; + } regNumber operandReg = genConsumeReg(op1); // Need an addtional integer register to extract upper 4 bytes from data. diff --git a/src/coreclr/src/jit/codegenlinear.cpp b/src/coreclr/src/jit/codegenlinear.cpp index e3973ba565119..a1e90ee040ed7 100644 --- a/src/coreclr/src/jit/codegenlinear.cpp +++ b/src/coreclr/src/jit/codegenlinear.cpp @@ -1447,7 +1447,7 @@ void CodeGen::genConsumeRegs(GenTree* tree) #ifdef FEATURE_SIMD // (In)Equality operation that produces bool result, when compared // against Vector zero, marks its Vector Zero operand as contained. - assert(tree->OperIsLeaf() || tree->IsIntegralConstVector(0)); + assert(tree->OperIsLeaf() || tree->IsSIMDZero()); #else assert(tree->OperIsLeaf()); #endif diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index 2070291a20808..3323b0566f7fa 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -4676,17 +4676,6 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree) genStoreLclTypeSIMD12(tree); return; } - - // TODO-CQ: It would be better to simply contain the zero, rather than - // generating zero into a register. - if (varTypeIsSIMD(targetType) && (targetReg != REG_NA) && op1->IsCnsIntOrI()) - { - // This is only possible for a zero-init. - noway_assert(op1->IsIntegralConst(0)); - genSIMDZero(targetType, varDsc->lvBaseType, targetReg); - genProduceReg(tree); - return; - } #endif // FEATURE_SIMD genConsumeRegs(op1); diff --git a/src/coreclr/src/jit/gentree.h b/src/coreclr/src/jit/gentree.h index 12645fb12d219..efee04b7ee178 100644 --- a/src/coreclr/src/jit/gentree.h +++ b/src/coreclr/src/jit/gentree.h @@ -1646,6 +1646,7 @@ struct GenTree inline bool IsFPZero(); inline bool IsIntegralConst(ssize_t constVal); inline bool IsIntegralConstVector(ssize_t constVal); + inline bool IsSIMDZero(); inline bool IsBoxedValue(); @@ -6770,6 +6771,25 @@ inline bool GenTree::IsIntegralConstVector(ssize_t constVal) return false; } +//------------------------------------------------------------------- +// IsSIMDZero: returns true if this this is a SIMD vector +// with all its elements equal to zero. +// +// Returns: +// True if this represents an integral const SIMD vector. +// +inline bool GenTree::IsSIMDZero() +{ +#ifdef FEATURE_SIMD + if ((gtOper == GT_SIMD) && (AsSIMD()->gtSIMDIntrinsicID == SIMDIntrinsicInit)) + { + return (gtGetOp1()->IsIntegralConst(0) || gtGetOp1()->IsFPZero()); + } +#endif + + return false; +} + inline bool GenTree::IsBoxedValue() { assert(gtOper != GT_BOX || AsBox()->BoxOp() != nullptr); diff --git a/src/coreclr/src/jit/lowerarmarch.cpp b/src/coreclr/src/jit/lowerarmarch.cpp index 6f3cbda1f55a9..87639a0fdfd8f 100644 --- a/src/coreclr/src/jit/lowerarmarch.cpp +++ b/src/coreclr/src/jit/lowerarmarch.cpp @@ -730,13 +730,20 @@ void Lowering::ContainCheckStoreLoc(GenTreeLclVarCommon* storeLoc) return; } } + + const LclVarDsc* varDsc = comp->lvaGetDesc(storeLoc); + #ifdef FEATURE_SIMD if (varTypeIsSIMD(storeLoc)) { - if (op1->IsIntegralConst(0)) + // If this is a store to memory, we can initialize a zero vector in memory from REG_ZR. + if ((op1->IsIntegralConst(0) || op1->IsSIMDZero()) && varDsc->lvDoNotEnregister) { - // For an InitBlk we want op1 to be contained MakeSrcContained(storeLoc, op1); + if (op1->IsSIMDZero()) + { + MakeSrcContained(op1, op1->gtGetOp1()); + } } return; } @@ -745,8 +752,7 @@ void Lowering::ContainCheckStoreLoc(GenTreeLclVarCommon* storeLoc) // If the source is a containable immediate, make it contained, unless it is // an int-size or larger store of zero to memory, because we can generate smaller code // by zeroing a register and then storing it. - const LclVarDsc* varDsc = comp->lvaGetDesc(storeLoc); - var_types type = varDsc->GetRegisterType(storeLoc); + var_types type = varDsc->GetRegisterType(storeLoc); if (IsContainableImmed(storeLoc, op1) && (!op1->IsIntegralConst(0) || varTypeIsSmall(type))) { MakeSrcContained(storeLoc, op1); diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index ad0426bbb620d..dc5ed420cf19f 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -1990,14 +1990,22 @@ void Lowering::ContainCheckStoreLoc(GenTreeLclVarCommon* storeLoc) return; } } + + const LclVarDsc* varDsc = comp->lvaGetDesc(storeLoc); + #ifdef FEATURE_SIMD if (varTypeIsSIMD(storeLoc)) { - if (op1->IsCnsIntOrI()) + assert(!op1->IsCnsIntOrI()); + if (storeLoc->TypeIs(TYP_SIMD12) && op1->IsSIMDZero() && varDsc->lvDoNotEnregister) { - // For an InitBlk we want op1 to be contained; otherwise we want it to - // be evaluated into an xmm register. + // For a SIMD12 store we can zero from integer registers more easily. MakeSrcContained(storeLoc, op1); + GenTree* constNode = op1->gtGetOp1(); + assert(constNode->OperIsConst()); + constNode->ClearContained(); + constNode->gtType = TYP_INT; + constNode->SetOper(GT_CNS_INT); } return; } @@ -2006,8 +2014,7 @@ void Lowering::ContainCheckStoreLoc(GenTreeLclVarCommon* storeLoc) // If the source is a containable immediate, make it contained, unless it is // an int-size or larger store of zero to memory, because we can generate smaller code // by zeroing a register and then storing it. - const LclVarDsc* varDsc = comp->lvaGetDesc(storeLoc); - var_types type = varDsc->GetRegisterType(storeLoc); + var_types type = varDsc->GetRegisterType(storeLoc); if (IsContainableImmed(storeLoc, op1) && (!op1->IsIntegralConst(0) || varTypeIsSmall(type))) { MakeSrcContained(storeLoc, op1); diff --git a/src/coreclr/src/jit/lsrabuild.cpp b/src/coreclr/src/jit/lsrabuild.cpp index 7a41dd28e713a..0e578987e9e49 100644 --- a/src/coreclr/src/jit/lsrabuild.cpp +++ b/src/coreclr/src/jit/lsrabuild.cpp @@ -3113,7 +3113,20 @@ int LinearScan::BuildStoreLoc(GenTreeLclVarCommon* storeLoc) #endif // !TARGET_64BIT else if (op1->isContained()) { - srcCount = 0; +#ifdef TARGET_XARCH + if (varTypeIsSIMD(storeLoc)) + { + // This is the zero-init case, and we need a register to hold the zero. + // (On Arm64 we can just store REG_ZR.) + assert(op1->IsSIMDZero()); + singleUseRef = BuildUse(op1->gtGetOp1()); + srcCount = 1; + } + else +#endif + { + srcCount = 0; + } } else { diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index fdff5b7298d6d..fc64cf09877f9 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -17431,7 +17431,8 @@ void Compiler::fgMorphLocalField(GenTree* tree, GenTree* parent) var_types treeType = tree->TypeGet(); var_types fieldType = fldVarDsc->TypeGet(); - if (fldOffset != BAD_VAR_NUM && (genTypeSize(fieldType) == genTypeSize(treeType))) + if (fldOffset != BAD_VAR_NUM && + ((genTypeSize(fieldType) == genTypeSize(treeType)) || (varDsc->lvFieldCnt == 1))) { // There is an existing sub-field we can use. tree->AsLclFld()->SetLclNum(fieldLclIndex); diff --git a/src/coreclr/src/jit/simdcodegenxarch.cpp b/src/coreclr/src/jit/simdcodegenxarch.cpp index 8ca69e35be37a..b777d1da4eeed 100644 --- a/src/coreclr/src/jit/simdcodegenxarch.cpp +++ b/src/coreclr/src/jit/simdcodegenxarch.cpp @@ -2973,13 +2973,26 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode) offs = treeNode->AsLclFld()->GetLclOffs(); } - GenTree* op1 = treeNode->AsOp()->gtOp1; + regNumber tmpReg = treeNode->GetSingleTempReg(); + GenTree* op1 = treeNode->AsOp()->gtOp1; + if (op1->isContained()) + { + // This is only possible for a zero-init. + assert(op1->IsIntegralConst(0) || op1->IsSIMDZero()); + genSIMDZero(TYP_SIMD16, op1->AsSIMD()->gtSIMDBaseType, tmpReg); + + // store lower 8 bytes + GetEmitter()->emitIns_S_R(ins_Store(TYP_DOUBLE), EA_8BYTE, tmpReg, varNum, offs); + + // Store upper 4 bytes + GetEmitter()->emitIns_S_R(ins_Store(TYP_FLOAT), EA_4BYTE, tmpReg, varNum, offs + 8); + + return; + } + assert(!op1->isContained()); regNumber operandReg = genConsumeReg(op1); - // Need an addtional Xmm register to extract upper 4 bytes from data. - regNumber tmpReg = treeNode->GetSingleTempReg(); - // store lower 8 bytes GetEmitter()->emitIns_S_R(ins_Store(TYP_DOUBLE), EA_8BYTE, operandReg, varNum, offs); From eb7198f5ac7e05643972c818c43d073857baf024 Mon Sep 17 00:00:00 2001 From: Nikiforov Alexey Date: Fri, 8 May 2020 18:29:14 +0300 Subject: [PATCH 061/420] remove unused locals: System.Private.DataContractSerialization (#35958) --- .../Runtime/Serialization/ReflectionXmlFormatReader.cs | 2 +- .../src/System/Runtime/Serialization/SchemaExporter.cs | 2 +- .../System/Runtime/Serialization/XmlFormatReaderGenerator.cs | 2 +- .../src/System/Xml/XmlBufferReader.cs | 5 ++--- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ReflectionXmlFormatReader.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ReflectionXmlFormatReader.cs index 6c10360268146..3f9c5dc1e84f3 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ReflectionXmlFormatReader.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ReflectionXmlFormatReader.cs @@ -55,7 +55,7 @@ protected override void ReflectionReadMembers(XmlReaderDelegator xmlReader, XmlO context.IncrementItemCount(memberCount); int memberIndex = -1; int firstRequiredMember; - bool[] requiredMembers = GetRequiredMembers(classContract, out firstRequiredMember); + _ = GetRequiredMembers(classContract, out firstRequiredMember); bool hasRequiredMembers = (firstRequiredMember < memberCount); int requiredIndex = hasRequiredMembers ? firstRequiredMember : -1; DataMember[] members = new DataMember[memberCount]; diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs index f610d58635d4d..b5de0afbeb763 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs @@ -450,7 +450,7 @@ private void ExportISerializableDataContract(ClassDataContract dataContract, Xml XmlElement isValueTypeElement = null; if (dataContract.BaseContract != null) { - XmlSchemaComplexContentExtension extension = CreateTypeContent(type, dataContract.BaseContract.StableName, schema); + _ = CreateTypeContent(type, dataContract.BaseContract.StableName, schema); } else { diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlFormatReaderGenerator.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlFormatReaderGenerator.cs index 8eb7f8ee8f6f3..bd5f5d8e3b6c4 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlFormatReaderGenerator.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlFormatReaderGenerator.cs @@ -119,7 +119,7 @@ public XmlFormatClassReaderDelegate GenerateClassReader(ClassDataContract classC ReadClass(classContract); } - bool isFactoryType = InvokeFactoryMethod(classContract, objectId); + _ = InvokeFactoryMethod(classContract, objectId); if (Globals.TypeOfIDeserializationCallback.IsAssignableFrom(classContract.UnderlyingType)) { _ilg.Call(_objectLocal, XmlFormatGeneratorStatics.OnDeserializationMethod, null); diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs index 64dbb9a7b9f40..24920b8c2af61 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs @@ -491,7 +491,7 @@ public TimeSpan ReadTimeSpan() public Guid ReadGuid() { int offset; - byte[] buffer = GetBuffer(ValueHandleLength.Guid, out offset); + _ = GetBuffer(ValueHandleLength.Guid, out offset); Guid guid = GetGuid(offset); Advance(ValueHandleLength.Guid); return guid; @@ -500,7 +500,7 @@ public Guid ReadGuid() public string ReadUTF8String(int length) { int offset; - byte[] buffer = GetBuffer(length, out offset); + _ = GetBuffer(length, out offset); char[] chars = GetCharBuffer(length); int charCount = GetChars(offset, length, chars); string value = new string(chars, 0, charCount); @@ -844,7 +844,6 @@ public bool IsWhitespaceUTF8(int offset, int length) public bool IsWhitespaceUnicode(int offset, int length) { - byte[] buffer = _buffer; for (int i = 0; i < length; i += sizeof(char)) { char ch = (char)GetInt16(offset + i); From 4d163760ce8f878c0a6ab8d8592338910824aee9 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Fri, 8 May 2020 09:09:12 -0700 Subject: [PATCH 062/420] Optimize Vector128 and Vector256.Create methods (#35857) * Updating Vector128.Create(T value) to be intrinsic * Updating Vector128.Create(T, ..., T) to be intrinsic * Updating Vector256.Create(T) and Vector256.Create(T, ..., T) to be intrinsic * Applying formatting patch * Adding additional comments explaining how the Vector128.Create and Vector256.Create calls are lowered * Add an assert that argCnt is as expected for LowerHWIntrinsicCreate * Applying formatting patch * Use unsigned rather than signed types in LowerHWIntrinsicCreate * Have HWIntrinsicInfo::lookupId take the number of arguments into account * Adjusting Vector128.Create(T, ..., T) to not be recursive on ARM64 * Fixing MyICJI::allocMem in superpmi to respect certain CorJitAllocMemFlag * Avoid an implicit downcast --- .../ToolBox/superpmi/superpmi/icorjitinfo.cpp | 49 +- src/coreclr/src/jit/emit.cpp | 7 +- src/coreclr/src/jit/emitxarch.cpp | 3 +- src/coreclr/src/jit/hwintrinsic.cpp | 24 +- src/coreclr/src/jit/hwintrinsic.h | 9 +- src/coreclr/src/jit/hwintrinsiclistxarch.h | 2 + src/coreclr/src/jit/hwintrinsicxarch.cpp | 65 + src/coreclr/src/jit/importer.cpp | 5 +- src/coreclr/src/jit/lower.h | 1 + src/coreclr/src/jit/lowerxarch.cpp | 1228 ++++++++++++++++- .../System/Runtime/Intrinsics/Vector128.cs | 415 +----- .../System/Runtime/Intrinsics/Vector256.cs | 178 +-- 12 files changed, 1491 insertions(+), 495 deletions(-) diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp index 1591f347cbe90..24bc4415e586e 100644 --- a/src/coreclr/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -1578,6 +1578,18 @@ bool MyICJI::runWithErrorTrap(void (*function)(void*), void* param) return RunWithErrorTrap(function, param); } +// Ideally we'd just use the copies of this in standardmacros.h +// however, superpmi is missing various other dependencies as well +static size_t ALIGN_UP_SPMI(size_t val, size_t alignment) +{ + return (val + (alignment - 1)) & ~(alignment - 1); +} + +static void* ALIGN_UP_SPMI(void* val, size_t alignment) +{ + return (void*)ALIGN_UP_SPMI((size_t)val, alignment); +} + // get a block of memory for the code, readonly data, and read-write data void MyICJI::allocMem(ULONG hotCodeSize, /* IN */ ULONG coldCodeSize, /* IN */ @@ -1590,13 +1602,46 @@ void MyICJI::allocMem(ULONG hotCodeSize, /* IN */ ) { jitInstance->mc->cr->AddCall("allocMem"); - // TODO-Cleanup: investigate if we need to check roDataBlock as well. Could hot block size be ever 0? + + // TODO-Cleanup: Could hot block size be ever 0? *hotCodeBlock = jitInstance->mc->cr->allocateMemory(hotCodeSize); + if (coldCodeSize > 0) *coldCodeBlock = jitInstance->mc->cr->allocateMemory(coldCodeSize); else *coldCodeBlock = nullptr; - *roDataBlock = jitInstance->mc->cr->allocateMemory(roDataSize); + + if (roDataSize > 0) + { + size_t roDataAlignment = sizeof(void*); + size_t roDataAlignedSize = static_cast(roDataSize); + + if ((flag & CORJIT_ALLOCMEM_FLG_RODATA_32BYTE_ALIGN) != 0) + { + roDataAlignment = 32; + } + else if ((flag & CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN) != 0) + { + roDataAlignment = 16; + } + else if (roDataSize >= 8) + { + roDataAlignment = 8; + } + + // We need to round the roDataSize up to the alignment size and then + // overallocate by at most alignment - sizeof(void*) to ensure that + // we can offset roDataBlock to be an aligned address and that the + // allocation contains at least the originally requested size after + + roDataAlignedSize = ALIGN_UP_SPMI(roDataAlignedSize, roDataAlignment); + roDataAlignedSize = roDataAlignedSize + (roDataAlignment - sizeof(void*)); + *roDataBlock = jitInstance->mc->cr->allocateMemory(roDataAlignedSize); + *roDataBlock = ALIGN_UP_SPMI(*roDataBlock, roDataAlignment); + } + else + *roDataBlock = nullptr; + jitInstance->mc->cr->recAllocMem(hotCodeSize, coldCodeSize, roDataSize, xcptnsCount, flag, hotCodeBlock, coldCodeBlock, roDataBlock); } diff --git a/src/coreclr/src/jit/emit.cpp b/src/coreclr/src/jit/emit.cpp index f0fd875006c97..8b9c2c7e21fe8 100644 --- a/src/coreclr/src/jit/emit.cpp +++ b/src/coreclr/src/jit/emit.cpp @@ -5339,10 +5339,11 @@ UNATIVE_OFFSET emitter::emitDataGenBeg(UNATIVE_OFFSET size, bool align) { // Data can have any size but since alignment is deduced from the size there's no // way to have a larger data size (e.g. 128) and request 4/8/16 byte alignment. - // 32 bytes (and more) alignment requires VM support (see ICorJitInfo::allocMem). - assert(size <= 16); + // As such, we restrict data above 16 bytes to be a multiple of 16 and assume 16-byte + // alignment. Alignment greater than 16 requires VM support (see ICorJitInfo::allocMem). + assert((size <= 16) || ((size % 16) == 0)); - if (size == 16) + if (size >= 16) { emitConsDsc.align16 = true; } diff --git a/src/coreclr/src/jit/emitxarch.cpp b/src/coreclr/src/jit/emitxarch.cpp index 269324d9a9d4f..af753945e3d2f 100644 --- a/src/coreclr/src/jit/emitxarch.cpp +++ b/src/coreclr/src/jit/emitxarch.cpp @@ -10765,7 +10765,8 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) } // Check that the offset is properly aligned (i.e. the ddd in [ddd]) - assert((emitChkAlign == false) || (ins == INS_lea) || (((size_t)addr & (byteSize - 1)) == 0)); + assert((emitChkAlign == false) || (ins == INS_lea) || + ((byteSize < 16) && (((size_t)addr & (byteSize - 1)) == 0)) || (((size_t)addr & (16 - 1)) == 0)); } else { diff --git a/src/coreclr/src/jit/hwintrinsic.cpp b/src/coreclr/src/jit/hwintrinsic.cpp index 674b7f9946e0d..8f33c4851771b 100644 --- a/src/coreclr/src/jit/hwintrinsic.cpp +++ b/src/coreclr/src/jit/hwintrinsic.cpp @@ -292,16 +292,19 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleForHWSIMD(var_types simdType, va // lookupId: Gets the NamedIntrinsic for a given method name and InstructionSet // // Arguments: +// comp -- The compiler +// sig -- The signature of the intrinsic // className -- The name of the class associated with the HWIntrinsic to lookup // methodName -- The name of the method associated with the HWIntrinsic to lookup // enclosingClassName -- The name of the enclosing class of X64 classes // // Return Value: // The NamedIntrinsic associated with methodName and isa -NamedIntrinsic HWIntrinsicInfo::lookupId(Compiler* comp, - const char* className, - const char* methodName, - const char* enclosingClassName) +NamedIntrinsic HWIntrinsicInfo::lookupId(Compiler* comp, + CORINFO_SIG_INFO* sig, + const char* className, + const char* methodName, + const char* enclosingClassName) { // TODO-Throughput: replace sequential search by binary search CORINFO_InstructionSet isa = lookupIsa(className, enclosingClassName); @@ -324,14 +327,23 @@ NamedIntrinsic HWIntrinsicInfo::lookupId(Compiler* comp, for (int i = 0; i < (NI_HW_INTRINSIC_END - NI_HW_INTRINSIC_START - 1); i++) { + const HWIntrinsicInfo& intrinsicInfo = hwIntrinsicInfoArray[i]; + if (isa != hwIntrinsicInfoArray[i].isa) { continue; } - if (strcmp(methodName, hwIntrinsicInfoArray[i].name) == 0) + int numArgs = static_cast(intrinsicInfo.numArgs); + + if ((numArgs != -1) && (sig->numArgs != static_cast(intrinsicInfo.numArgs))) + { + continue; + } + + if (strcmp(methodName, intrinsicInfo.name) == 0) { - return hwIntrinsicInfoArray[i].id; + return intrinsicInfo.id; } } diff --git a/src/coreclr/src/jit/hwintrinsic.h b/src/coreclr/src/jit/hwintrinsic.h index b3c00f45d9809..7e5fe7905d454 100644 --- a/src/coreclr/src/jit/hwintrinsic.h +++ b/src/coreclr/src/jit/hwintrinsic.h @@ -258,10 +258,11 @@ struct HWIntrinsicInfo static const HWIntrinsicInfo& lookup(NamedIntrinsic id); - static NamedIntrinsic lookupId(Compiler* comp, - const char* className, - const char* methodName, - const char* enclosingClassName); + static NamedIntrinsic lookupId(Compiler* comp, + CORINFO_SIG_INFO* sig, + const char* className, + const char* methodName, + const char* enclosingClassName); static CORINFO_InstructionSet lookupIsa(const char* className, const char* enclosingClassName); static unsigned lookupSimdSize(Compiler* comp, NamedIntrinsic id, CORINFO_SIG_INFO* sig); diff --git a/src/coreclr/src/jit/hwintrinsiclistxarch.h b/src/coreclr/src/jit/hwintrinsiclistxarch.h index 4be0cdadd809c..db2bacbbb6457 100644 --- a/src/coreclr/src/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/src/jit/hwintrinsiclistxarch.h @@ -43,6 +43,7 @@ HARDWARE_INTRINSIC(Vector128, AsVector2, HARDWARE_INTRINSIC(Vector128, AsVector3, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector128, AsVector4, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector128, AsVector128, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(Vector128, Create, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector128, CreateScalarUnsafe, 16, 1, {INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_movss, INS_movsdsse2}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) // The instruction generated for float/double depends on which ISAs are supported HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, 16, 0, {INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_cmpps, INS_cmppd}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics) @@ -76,6 +77,7 @@ HARDWARE_INTRINSIC(Vector256, AsVector256, HARDWARE_INTRINSIC(Vector256, get_AllBitsSet, 32, 0, {INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_cmpps, INS_cmppd}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector256, get_Count, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector256, get_Zero, 32, 0, {INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(Vector256, Create, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector256, CreateScalarUnsafe, 32, 1, {INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_movss, INS_movsdsse2}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector256, GetElement, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector256, WithElement, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg) diff --git a/src/coreclr/src/jit/hwintrinsicxarch.cpp b/src/coreclr/src/jit/hwintrinsicxarch.cpp index 010cd5fa5063d..1ed4dd7716151 100644 --- a/src/coreclr/src/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/src/jit/hwintrinsicxarch.cpp @@ -521,6 +521,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, { GenTree* retNode = nullptr; GenTree* op1 = nullptr; + GenTree* op2 = nullptr; if (!featureSIMD) { @@ -747,6 +748,70 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_Vector128_Create: + case NI_Vector256_Create: + { +#if defined(TARGET_X86) + if (varTypeIsLong(baseType)) + { + // TODO-XARCH-CQ: It may be beneficial to emit the movq + // instruction, which takes a 64-bit memory address and + // works on 32-bit x86 systems. + break; + } +#endif // TARGET_X86 + + // We shouldn't handle this as an intrinsic if the + // respective ISAs have been disabled by the user. + + if (intrinsic == NI_Vector256_Create) + { + if (!compExactlyDependsOn(InstructionSet_AVX)) + { + break; + } + } + else if (baseType == TYP_FLOAT) + { + if (!compExactlyDependsOn(InstructionSet_SSE)) + { + break; + } + } + else if (!compExactlyDependsOn(InstructionSet_SSE2)) + { + break; + } + + if (sig->numArgs == 1) + { + op1 = impPopStack().val; + retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, baseType, simdSize); + } + else if (sig->numArgs == 2) + { + op2 = impPopStack().val; + op1 = impPopStack().val; + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, baseType, simdSize); + } + else + { + assert(sig->numArgs >= 3); + + GenTreeArgList* tmp = nullptr; + + for (unsigned i = 0; i < sig->numArgs; i++) + { + tmp = gtNewArgList(impPopStack().val); + tmp->gtOp2 = op1; + op1 = tmp; + } + + retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, baseType, simdSize); + } + break; + } + case NI_Vector128_CreateScalarUnsafe: { assert(sig->numArgs == 1); diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index aae168c337883..52501b346e928 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -4504,7 +4504,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) if ((namespaceName[0] == '\0') || (strcmp(namespaceName, platformNamespaceName) == 0)) { - result = HWIntrinsicInfo::lookupId(this, className, methodName, enclosingClassName); + CORINFO_SIG_INFO sig; + info.compCompHnd->getMethodSig(method, &sig); + + result = HWIntrinsicInfo::lookupId(this, &sig, className, methodName, enclosingClassName); } else if (strcmp(methodName, "get_IsSupported") == 0) { diff --git a/src/coreclr/src/jit/lower.h b/src/coreclr/src/jit/lower.h index 9c79ede16869a..2fa26918e30f4 100644 --- a/src/coreclr/src/jit/lower.h +++ b/src/coreclr/src/jit/lower.h @@ -315,6 +315,7 @@ class Lowering final : public Phase #ifdef FEATURE_HW_INTRINSICS void LowerHWIntrinsic(GenTreeHWIntrinsic* node); void LowerHWIntrinsicCC(GenTreeHWIntrinsic* node, NamedIntrinsic newIntrinsicId, GenCondition condition); + void LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node); void LowerFusedMultiplyAdd(GenTreeHWIntrinsic* node); #endif // FEATURE_HW_INTRINSICS diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index dc5ed420cf19f..14672d16aaaac 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -927,8 +927,26 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) node->gtType = TYP_SIMD16; } - switch (node->gtHWIntrinsicId) + NamedIntrinsic intrinsicId = node->gtHWIntrinsicId; + + switch (intrinsicId) { + case NI_Vector128_Create: + case NI_Vector256_Create: + { + // We don't directly support the Vector128.Create or Vector256.Create methods in codegen + // and instead lower them to other intrinsic nodes in LowerHWIntrinsicCreate so we expect + // that the node is modified to either not be a HWIntrinsic node or that it is no longer + // the same intrinsic as when it came in. In the case of Vector256.Create, we may lower + // it into 2x Vector128.Create intrinsics which themselves are also lowered into other + // intrinsics that are not Vector*.Create + + LowerHWIntrinsicCreate(node); + assert(!node->OperIsHWIntrinsic() || (node->gtHWIntrinsicId != intrinsicId)); + LowerNode(node); + return; + } + case NI_SSE2_CompareGreaterThan: { if (node->gtSIMDBaseType != TYP_DOUBLE) @@ -1081,6 +1099,1214 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) ContainCheckHWIntrinsic(node); } + +union VectorConstant { + int8_t i8[32]; + uint8_t u8[32]; + int16_t i16[16]; + uint16_t u16[16]; + int32_t i32[8]; + uint32_t u32[8]; + int64_t i64[4]; + uint64_t u64[4]; + float f32[8]; + double f64[4]; +}; + +//---------------------------------------------------------------------------------------------- +// ProcessArgForHWIntrinsicCreate: Processes an argument for the Lowering::LowerHWIntrinsicCreate method +// +// Arguments: +// arg - The argument to process +// argIdx - The index of the argument being processed +// vecCns - The vector constant being constructed +// baseType - The base type of the vector constant +// +// Returns: +// true if arg was a constant; otherwise, false +static bool HandleArgForHWIntrinsicCreate(GenTree* arg, int argIdx, VectorConstant& vecCns, var_types baseType) +{ + switch (baseType) + { + case TYP_BYTE: + case TYP_UBYTE: + { + if (arg->IsCnsIntOrI()) + { + vecCns.i8[argIdx] = static_cast(arg->AsIntCon()->gtIconVal); + return true; + } + else + { + // We expect the VectorConstant to have been already zeroed + assert(vecCns.i8[argIdx] == 0); + } + break; + } + + case TYP_SHORT: + case TYP_USHORT: + { + if (arg->IsCnsIntOrI()) + { + vecCns.i16[argIdx] = static_cast(arg->AsIntCon()->gtIconVal); + return true; + } + else + { + // We expect the VectorConstant to have been already zeroed + assert(vecCns.i16[argIdx] == 0); + } + break; + } + + case TYP_INT: + case TYP_UINT: + { + if (arg->IsCnsIntOrI()) + { + vecCns.i32[argIdx] = static_cast(arg->AsIntCon()->gtIconVal); + return true; + } + else + { + // We expect the VectorConstant to have been already zeroed + assert(vecCns.i32[argIdx] == 0); + } + break; + } + + case TYP_LONG: + case TYP_ULONG: + { + if (arg->OperIs(GT_CNS_LNG)) + { + vecCns.i64[argIdx] = static_cast(arg->AsLngCon()->gtLconVal); + return true; + } + else + { + // We expect the VectorConstant to have been already zeroed + assert(vecCns.i64[argIdx] == 0); + } + break; + } + + case TYP_FLOAT: + { + if (arg->IsCnsFltOrDbl()) + { + vecCns.f32[argIdx] = static_cast(arg->AsDblCon()->gtDconVal); + return true; + } + else + { + // We expect the VectorConstant to have been already zeroed + // We check against the i32, rather than f32, to account for -0.0 + assert(vecCns.i32[argIdx] == 0); + } + break; + } + + case TYP_DOUBLE: + { + if (arg->IsCnsFltOrDbl()) + { + vecCns.f64[argIdx] = static_cast(arg->AsDblCon()->gtDconVal); + return true; + } + else + { + // We expect the VectorConstant to have been already zeroed + // We check against the i64, rather than f64, to account for -0.0 + assert(vecCns.i64[argIdx] == 0); + } + break; + } + + default: + { + unreached(); + } + } + + return false; +} + +//---------------------------------------------------------------------------------------------- +// Lowering::LowerHWIntrinsicCreate: Lowers a Vector64, Vector128, or Vector256 Create call +// +// Arguments: +// node - The hardware intrinsic node. +// +void Lowering::LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node) +{ + NamedIntrinsic intrinsicId = node->gtHWIntrinsicId; + var_types simdType = node->gtType; + var_types baseType = node->gtSIMDBaseType; + unsigned simdSize = node->gtSIMDSize; + VectorConstant vecCns = {}; + + assert(varTypeIsSIMD(simdType)); + assert(varTypeIsArithmetic(baseType)); + assert(simdSize != 0); + + GenTreeArgList* argList = nullptr; + GenTree* op1 = node->gtGetOp1(); + GenTree* op2 = node->gtGetOp2(); + + // Spare GenTrees to be used for the lowering logic below + // Defined upfront to avoid naming conflicts, etc... + GenTree* idx = nullptr; + GenTree* tmp1 = nullptr; + GenTree* tmp2 = nullptr; + GenTree* tmp3 = nullptr; + + assert(op1 != nullptr); + + unsigned argCnt = 0; + unsigned cnsArgCnt = 0; + + if (op1->OperIsList()) + { + assert(op2 == nullptr); + + for (argList = op1->AsArgList(); argList != nullptr; argList = argList->Rest()) + { + if (HandleArgForHWIntrinsicCreate(argList->Current(), argCnt, vecCns, baseType)) + { + cnsArgCnt += 1; + } + argCnt += 1; + } + } + else + { + if (HandleArgForHWIntrinsicCreate(op1, argCnt, vecCns, baseType)) + { + cnsArgCnt += 1; + } + argCnt += 1; + + if (op2 != nullptr) + { + if (HandleArgForHWIntrinsicCreate(op2, argCnt, vecCns, baseType)) + { + cnsArgCnt += 1; + } + argCnt += 1; + } + else if (cnsArgCnt == 1) + { + // These intrinsics are meant to set the same value to every element + // so we'll just specially handle it here and copy it into the remaining + // indices. + + for (unsigned i = 1; i < simdSize / genTypeSize(baseType); i++) + { + HandleArgForHWIntrinsicCreate(op1, i, vecCns, baseType); + } + } + } + assert((argCnt == 1) || (argCnt == (simdSize / genTypeSize(baseType)))); + + if (argCnt == cnsArgCnt) + { + if (op1->OperIsList()) + { + for (argList = op1->AsArgList(); argList != nullptr; argList = argList->Rest()) + { + BlockRange().Remove(argList->Current()); + } + } + else + { + BlockRange().Remove(op1); + + if (op2 != nullptr) + { + BlockRange().Remove(op2); + } + } + + CORINFO_FIELD_HANDLE hnd = comp->GetEmitter()->emitAnyConst(&vecCns, simdSize, emitDataAlignment::Required); + GenTree* clsVarAddr = new (comp, GT_CLS_VAR_ADDR) GenTreeClsVar(GT_CLS_VAR_ADDR, TYP_I_IMPL, hnd, nullptr); + BlockRange().InsertBefore(node, clsVarAddr); + + node->ChangeOper(GT_IND); + node->gtOp1 = clsVarAddr; + + // TODO-XARCH-CQ: We should be able to modify at least the paths that use Insert to trivially support partial + // vector constants. With this, we can create a constant if say 50% of the inputs are also constant and just + // insert the non-constant values which should still allow some gains. + + return; + } + else if (argCnt == 1) + { + // We have the following (where simd is simd16 or simd32): + // /--* op1 T + // node = * HWINTRINSIC simd T Create + + if (intrinsicId == NI_Vector256_Create) + { + if (comp->compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { + // We will be constructing the following parts: + // /--* op1 T + // tmp1 = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* tmp1 simd16 + // node = * HWINTRINSIC simd32 T BroadcastScalarToVector256 + + // This is roughly the following managed code: + // var tmp1 = Vector128.CreateScalarUnsafe(op1); + // return Avx2.BroadcastScalarToVector256(tmp1); + + tmp1 = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, op1, NI_Vector128_CreateScalarUnsafe, baseType, 16); + BlockRange().InsertAfter(op1, tmp1); + LowerNode(tmp1); + + node->gtOp1 = tmp1; + node->gtOp2 = nullptr; + + node->gtHWIntrinsicId = NI_AVX2_BroadcastScalarToVector256; + return; + } + + assert(comp->compIsaSupportedDebugOnly(InstructionSet_AVX)); + + // We will be constructing the following parts: + // /--* op1 T + // tmp1 = * HWINTRINSIC simd16 T Create + // /--* tmp1 simd16 + // * STORE_LCL_VAR simd16 + // tmp1 = LCL_VAR simd16 + // tmp2 = LCL_VAR simd16 + // /--* tmp2 simd16 + // tmp3 = * HWINTRINSIC simd16 T ToVector256Unsafe + // idx = CNS_INT int 0 + // /--* tmp3 simd32 + // +--* tmp1 simd16 + // +--* idx int + // node = * HWINTRINSIC simd32 T InsertVector128 + + // This is roughly the following managed code: + // var tmp1 = Vector128.Create(op1); + // var tmp2 = tmp1; + // var tmp3 = tmp2.ToVector256Unsafe(); + // return Avx.InsertVector128(tmp3, tmp1, 0x01); + + tmp1 = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, op1, NI_Vector128_Create, baseType, 16); + BlockRange().InsertAfter(op1, tmp1); + LowerNode(tmp1); + + node->gtOp1 = tmp1; + LIR::Use tmp1Use(BlockRange(), &node->gtOp1, node); + ReplaceWithLclVar(tmp1Use); + tmp1 = node->gtOp1; + + tmp2 = comp->gtClone(tmp1); + BlockRange().InsertAfter(tmp1, tmp2); + + tmp3 = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD32, tmp2, NI_Vector128_ToVector256Unsafe, baseType, 16); + BlockRange().InsertAfter(tmp2, tmp3); + LowerNode(tmp3); + + idx = comp->gtNewIconNode(0x01, TYP_INT); + BlockRange().InsertAfter(tmp3, idx); + + node->gtOp1 = comp->gtNewArgList(tmp3, tmp1, idx); + node->gtOp2 = nullptr; + + node->gtHWIntrinsicId = NI_AVX_InsertVector128; + return; + } + + // We will be constructing the following parts: + // /--* op1 T + // tmp1 = * HWINTRINSIC simd16 T CreateScalarUnsafe + // ... + + // This is roughly the following managed code: + // var tmp1 = Vector128.CreateScalarUnsafe(op1); + // ... + + tmp1 = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, op1, NI_Vector128_CreateScalarUnsafe, baseType, 16); + BlockRange().InsertAfter(op1, tmp1); + LowerNode(tmp1); + + if ((baseType != TYP_DOUBLE) && comp->compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { + // We will be constructing the following parts: + // ... + // /--* tmp1 simd16 + // node = * HWINTRINSIC simd16 T BroadcastScalarToVector128 + + // This is roughly the following managed code: + // ... + // return Avx2.BroadcastScalarToVector128(tmp1); + + node->gtOp1 = tmp1; + node->gtOp2 = nullptr; + + node->gtHWIntrinsicId = NI_AVX2_BroadcastScalarToVector128; + return; + } + + switch (baseType) + { + case TYP_BYTE: + case TYP_UBYTE: + { + if (comp->compOpportunisticallyDependsOn(InstructionSet_SSSE3)) + { + // We will be constructing the following parts: + // ... + // tmp2 = HWINTRINSIC simd16 ubyte get_Zero + // /--* tmp1 simd16 + // +--* tmp2 simd16 + // node = * HWINTRINSIC simd16 ubyte Shuffle + + // This is roughly the following managed code: + // ... + // var tmp2 = Vector128.Zero; + // return Ssse3.Shuffle(tmp1, tmp2); + + tmp2 = comp->gtNewSimdHWIntrinsicNode(simdType, NI_Vector128_get_Zero, TYP_UBYTE, simdSize); + BlockRange().InsertAfter(tmp1, tmp2); + LowerNode(tmp2); + + node->gtOp1 = tmp1; + node->gtOp2 = tmp2; + + node->gtHWIntrinsicId = NI_SSSE3_Shuffle; + break; + } + + assert(comp->compIsaSupportedDebugOnly(InstructionSet_SSE2)); + + // We will be constructing the following parts: + // ... + // /--* tmp1 simd16 + // * STORE_LCL_VAR simd16 + // tmp1 = LCL_VAR simd16 + // tmp2 = LCL_VAR simd16 + // /--* tmp1 simd16 + // +--* tmp2 simd16 + // tmp1 = * HWINTRINSIC simd16 ubyte UnpackLow + // ... + + // This is roughly the following managed code: + // ... + // var tmp2 = tmp1; + // tmp1 = Sse2.UnpackLow(tmp1, tmp2); + // ... + + node->gtOp1 = tmp1; + LIR::Use tmp1Use(BlockRange(), &node->gtOp1, node); + ReplaceWithLclVar(tmp1Use); + tmp1 = node->gtOp1; + + tmp2 = comp->gtClone(tmp1); + BlockRange().InsertAfter(tmp1, tmp2); + + tmp1 = comp->gtNewSimdHWIntrinsicNode(simdType, tmp1, tmp2, NI_SSE2_UnpackLow, TYP_UBYTE, simdSize); + BlockRange().InsertAfter(tmp2, tmp1); + LowerNode(tmp1); + + __fallthrough; + } + + case TYP_SHORT: + case TYP_USHORT: + { + // We will be constructing the following parts: + // ... + // /--* tmp1 simd16 + // * STORE_LCL_VAR simd16 + // tmp1 = LCL_VAR simd16 + // tmp2 = LCL_VAR simd16 + // /--* tmp1 simd16 + // +--* tmp2 simd16 + // tmp1 = * HWINTRINSIC simd16 ushort UnpackLow + // ... + + // This is roughly the following managed code: + // ... + // var tmp2 = tmp1; + // tmp1 = Sse2.UnpackLow(tmp1, tmp2); + // ... + + assert(comp->compIsaSupportedDebugOnly(InstructionSet_SSE2)); + + node->gtOp1 = tmp1; + LIR::Use tmp1Use(BlockRange(), &node->gtOp1, node); + ReplaceWithLclVar(tmp1Use); + tmp1 = node->gtOp1; + + tmp2 = comp->gtClone(tmp1); + BlockRange().InsertAfter(tmp1, tmp2); + + tmp1 = comp->gtNewSimdHWIntrinsicNode(simdType, tmp1, tmp2, NI_SSE2_UnpackLow, TYP_USHORT, simdSize); + BlockRange().InsertAfter(tmp2, tmp1); + LowerNode(tmp1); + + __fallthrough; + } + + case TYP_INT: + case TYP_UINT: + { + // We will be constructing the following parts: + // ... + // idx = CNS_INT int 0 + // /--* tmp1 simd16 + // +--* idx int + // node = * HWINTRINSIC simd16 uint Shuffle + + // This is roughly the following managed code: + // ... + // return Sse2.Shuffle(tmp1, 0x00); + + assert(comp->compIsaSupportedDebugOnly(InstructionSet_SSE2)); + + idx = comp->gtNewIconNode(0x00, TYP_INT); + BlockRange().InsertAfter(tmp1, idx); + + node->gtOp1 = tmp1; + node->gtOp2 = idx; + + node->gtHWIntrinsicId = NI_SSE2_Shuffle; + node->gtSIMDBaseType = TYP_UINT; + + break; + } + +#if defined(TARGET_AMD64) + case TYP_LONG: + case TYP_ULONG: + { + // We will be constructing the following parts: + // ... + // /--* tmp1 simd16 + // * STORE_LCL_VAR simd16 + // tmp1 = LCL_VAR simd16 + // tmp2 = LCL_VAR simd16 + // /--* tmp1 simd16 + // +--* tmp2 simd16 + // node = * HWINTRINSIC simd16 ulong UnpackLow + + // This is roughly the following managed code: + // ... + // var tmp2 = tmp1; + // return Sse2.UnpackLow(tmp1, tmp2); + + assert(comp->compIsaSupportedDebugOnly(InstructionSet_SSE2)); + + node->gtOp1 = tmp1; + LIR::Use tmp1Use(BlockRange(), &node->gtOp1, node); + ReplaceWithLclVar(tmp1Use); + tmp1 = node->gtOp1; + + tmp2 = comp->gtClone(tmp1); + BlockRange().InsertAfter(tmp1, tmp2); + + node->gtOp1 = tmp1; + node->gtOp2 = tmp2; + + node->gtHWIntrinsicId = NI_SSE2_UnpackLow; + break; + } +#endif // TARGET_AMD64 + + case TYP_FLOAT: + { + if (comp->compOpportunisticallyDependsOn(InstructionSet_AVX)) + { + // We will be constructing the following parts: + // ... + // idx = CNS_INT int 0 + // /--* tmp1 simd16 + // +--* idx int + // node = * HWINTRINSIC simd16 float Permute + + // This is roughly the following managed code: + // ... + // return Avx.Permute(tmp1, 0x00); + + idx = comp->gtNewIconNode(0x00, TYP_INT); + BlockRange().InsertAfter(tmp1, idx); + + node->gtOp1 = tmp1; + node->gtOp2 = idx; + + node->gtHWIntrinsicId = NI_AVX_Permute; + break; + } + + // We will be constructing the following parts: + // ... + // /--* tmp1 simd16 + // * STORE_LCL_VAR simd16 + // tmp1 = LCL_VAR simd16 + // tmp2 = LCL_VAR simd16 + // idx = CNS_INT int 0 + // /--* tmp1 simd16 + // +--* tmp2 simd16 + // +--* idx int + // node = * HWINTRINSIC simd16 float Shuffle + + // This is roughly the following managed code: + // ... + // var tmp2 = tmp1; + // return Sse.Shuffle(tmp1, tmp2, 0x00); + + assert(comp->compIsaSupportedDebugOnly(InstructionSet_SSE)); + + node->gtOp1 = tmp1; + LIR::Use tmp1Use(BlockRange(), &node->gtOp1, node); + ReplaceWithLclVar(tmp1Use); + tmp1 = node->gtOp1; + + tmp2 = comp->gtClone(tmp1); + BlockRange().InsertAfter(tmp1, tmp2); + + idx = comp->gtNewIconNode(0x00, TYP_INT); + BlockRange().InsertAfter(tmp2, idx); + + node->gtOp1 = comp->gtNewArgList(tmp1, tmp2, idx); + node->gtOp2 = nullptr; + + node->gtHWIntrinsicId = NI_SSE_Shuffle; + break; + } + + case TYP_DOUBLE: + { + if (comp->compOpportunisticallyDependsOn(InstructionSet_SSE3)) + { + // We will be constructing the following parts: + // ... + // /--* tmp1 simd16 + // node = * HWINTRINSIC simd16 double MoveAndDuplicate + + // This is roughly the following managed code: + // ... + // return Sse3.MoveAndDuplicate(tmp1); + + node->gtOp1 = tmp1; + node->gtOp2 = nullptr; + + node->gtHWIntrinsicId = NI_SSE3_MoveAndDuplicate; + break; + } + + assert(comp->compIsaSupportedDebugOnly(InstructionSet_SSE2)); + + // We will be constructing the following parts: + // ... + // /--* tmp1 simd16 + // * STORE_LCL_VAR simd16 + // tmp1 = LCL_VAR simd16 + // tmp2 = LCL_VAR simd16 + // /--* tmp1 simd16 + // +--* tmp2 simd16 + // node = * HWINTRINSIC simd16 float MoveLowToHigh + + // This is roughly the following managed code: + // ... + // var tmp2 = tmp1; + // return Sse.MoveLowToHigh(tmp1, tmp2); + + node->gtOp1 = tmp1; + LIR::Use tmp1Use(BlockRange(), &node->gtOp1, node); + ReplaceWithLclVar(tmp1Use); + tmp1 = node->gtOp1; + + tmp2 = comp->gtClone(tmp1); + BlockRange().InsertAfter(tmp1, tmp2); + + node->gtOp1 = tmp1; + node->gtOp2 = tmp2; + + node->gtHWIntrinsicId = NI_SSE_MoveLowToHigh; + node->gtSIMDBaseType = TYP_FLOAT; + + break; + } + + default: + { + unreached(); + } + } + + return; + } + + // We have the following (where simd is simd16 or simd32): + // /--* op1 T + // +--* ... T + // +--* opN T + // node = * HWINTRINSIC simd T Create + + if (intrinsicId == NI_Vector256_Create) + { + assert(comp->compIsaSupportedDebugOnly(InstructionSet_AVX)); + + // We will be constructing the following parts: + // /--* op1 T + // +--* ... T + // lo = * HWINTRINSIC simd16 T Create + // /--* ... T + // +--* opN T + // hi = * HWINTRINSIC simd16 T Create + // idx = CNS_INT int 1 + // /--* lo simd32 + // +--* hi simd16 + // +--* idx int + // node = * HWINTRINSIC simd32 T InsertVector128 + + // This is roughly the following managed code: + // ... + // var lo = Vector128.Create(op1, ...); + // var hi = Vector128.Create(..., opN); + // return Avx.InsertVector128(lo, hi, 0x01); + + // Each Vector128.Create call gets half the operands. That is: + // lo = Vector128.Create(op1, op2); + // hi = Vector128.Create(op3, op4); + // -or- + // lo = Vector128.Create(op1, ..., op3); + // hi = Vector128.Create(op4, ..., op7); + // -or- + // lo = Vector128.Create(op1, ..., op7); + // hi = Vector128.Create(op8, ..., op15); + // -or- + // lo = Vector128.Create(op1, ..., op15); + // hi = Vector128.Create(op16, ..., op31); + + unsigned halfArgCnt = argCnt / 2; + assert((halfArgCnt * 2) == argCnt); + + argList = op1->AsArgList(); + + for (unsigned i = 0; i < halfArgCnt; i++) + { + op2 = argList; + argList = argList->Rest(); + } + + op2->AsArgList()->gtOp2 = nullptr; + op2 = argList; + + // The above for loop splits the operand count into exactly half. + // Once it exits, op1 will point to op1 and op2 will point to the + // last operand that will be passed to the first Vector128.Create + // We will set its op2 to null, terminating the chain and then + // assign op2 to be argList, which is the first operand that will + // get passed to the second Vector128.Create + + GenTree* lo = nullptr; + GenTree* hi = nullptr; + + if (halfArgCnt == 2) + { + // The Vector256.Create calls that take 4 operands are special + // because the half argument count is 2, which means we can't + // actually use the GT_LIST anymore and need to pass them as + // explicit operands instead. + + argList = op1->AsArgList(); + + tmp1 = argList->Current(); + tmp2 = argList->Rest()->Current(); + + lo = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, tmp1, tmp2, NI_Vector128_Create, baseType, 16); + BlockRange().InsertAfter(tmp2, lo); + LowerNode(lo); + + argList = op2->AsArgList(); + + tmp1 = argList->Current(); + tmp2 = argList->Rest()->Current(); + + hi = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, tmp1, tmp2, NI_Vector128_Create, baseType, 16); + BlockRange().InsertAfter(tmp2, hi); + LowerNode(hi); + } + else + { + // The rest of the Vector256.Create calls take at least 8 operands + // and so the half count is at least 4 and we have to continue + // passing around GT_LIST nodes in op1 with a null op2 + assert(halfArgCnt >= 4); + + tmp1 = op2->AsArgList()->Current(); + + lo = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, op1, NI_Vector128_Create, baseType, 16); + BlockRange().InsertBefore(tmp1, lo); + LowerNode(lo); + + hi = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, op2, NI_Vector128_Create, baseType, 16); + BlockRange().InsertBefore(node, hi); + LowerNode(hi); + } + + idx = comp->gtNewIconNode(0x01, TYP_INT); + BlockRange().InsertAfter(hi, idx); + + node->gtOp1 = comp->gtNewArgList(lo, hi, idx); + node->gtOp2 = nullptr; + + node->gtHWIntrinsicId = NI_AVX_InsertVector128; + return; + } + + if (op1->OperIsList()) + { + argList = op1->AsArgList(); + op1 = argList->Current(); + argList = argList->Rest(); + } + + // We will be constructing the following parts: + // /--* op1 T + // tmp1 = * HWINTRINSIC simd16 T CreateScalarUnsafe + // ... + + // This is roughly the following managed code: + // var tmp1 = Vector128.CreateScalarUnsafe(op1); + // ... + + tmp1 = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, op1, NI_Vector128_CreateScalarUnsafe, baseType, 16); + BlockRange().InsertAfter(op1, tmp1); + LowerNode(tmp1); + + switch (baseType) + { + case TYP_BYTE: + case TYP_UBYTE: + case TYP_SHORT: + case TYP_USHORT: + case TYP_INT: + case TYP_UINT: + { + unsigned N = 0; + GenTree* opN = nullptr; + NamedIntrinsic insIntrinsic = NI_Illegal; + + if ((baseType == TYP_SHORT) || (baseType == TYP_USHORT)) + { + assert(comp->compIsaSupportedDebugOnly(InstructionSet_SSE2)); + insIntrinsic = NI_SSE2_Insert; + } + else if (comp->compOpportunisticallyDependsOn(InstructionSet_SSE41)) + { + insIntrinsic = NI_SSE41_Insert; + } + + if (insIntrinsic != NI_Illegal) + { + for (N = 1; N < argCnt - 1; N++) + { + // We will be constructing the following parts: + // ... + // idx = CNS_INT int N + // /--* tmp1 simd16 + // +--* opN T + // +--* idx int + // tmp1 = * HWINTRINSIC simd16 T Insert + // ... + + // This is roughly the following managed code: + // ... + // tmp1 = Sse?.Insert(tmp1, opN, N); + // ... + + opN = argList->Current(); + + idx = comp->gtNewIconNode(N, TYP_INT); + BlockRange().InsertAfter(opN, idx); + + tmp1 = comp->gtNewSimdHWIntrinsicNode(simdType, tmp1, opN, idx, insIntrinsic, baseType, simdSize); + BlockRange().InsertAfter(idx, tmp1); + LowerNode(tmp1); + + argList = argList->Rest(); + } + + assert(N == (argCnt - 1)); + + // We will be constructing the following parts: + // idx = CNS_INT int N + // /--* tmp1 simd16 + // +--* opN T + // +--* idx int + // node = * HWINTRINSIC simd16 T Insert + + // This is roughly the following managed code: + // ... + // tmp1 = Sse?.Insert(tmp1, opN, N); + // ... + + opN = argList->Current(); + + idx = comp->gtNewIconNode(N, TYP_INT); + BlockRange().InsertAfter(opN, idx); + + node->gtOp1 = comp->gtNewArgList(tmp1, opN, idx); + node->gtOp2 = nullptr; + + node->gtHWIntrinsicId = insIntrinsic; + break; + } + + assert((baseType != TYP_SHORT) && (baseType != TYP_USHORT)); + assert(comp->compIsaSupportedDebugOnly(InstructionSet_SSE2)); + + GenTree* op[16]; + op[0] = tmp1; + + for (N = 1; N < argCnt; N++) + { + opN = argList->Current(); + + op[N] = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, opN, NI_Vector128_CreateScalarUnsafe, baseType, 16); + BlockRange().InsertAfter(opN, op[N]); + LowerNode(op[N]); + + argList = argList->Rest(); + } + assert(argList == nullptr); + + if ((baseType == TYP_BYTE) || (baseType == TYP_UBYTE)) + { + for (N = 0; N < argCnt; N += 4) + { + // We will be constructing the following parts: + // ... + // /--* opN T + // opN = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* opO T + // opO = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* opN simd16 + // +--* opO simd16 + // tmp1 = * HWINTRINSIC simd16 T UnpackLow + // /--* opP T + // opP = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* opQ T + // opQ = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* opP simd16 + // +--* opQ simd16 + // tmp2 = * HWINTRINSIC simd16 T UnpackLow + // /--* tmp1 simd16 + // +--* tmp2 simd16 + // tmp3 = * HWINTRINSIC simd16 T UnpackLow + // ... + + // This is roughly the following managed code: + // ... + // tmp1 = Sse2.UnpackLow(opN, opO); + // tmp2 = Sse2.UnpackLow(opP, opQ); + // tmp3 = Sse2.UnpackLow(tmp1, tmp2); + // ... + + unsigned O = N + 1; + unsigned P = N + 2; + unsigned Q = N + 3; + + tmp1 = + comp->gtNewSimdHWIntrinsicNode(simdType, op[N], op[O], NI_SSE2_UnpackLow, TYP_UBYTE, simdSize); + BlockRange().InsertAfter(op[O], tmp1); + LowerNode(tmp1); + + tmp2 = + comp->gtNewSimdHWIntrinsicNode(simdType, op[P], op[Q], NI_SSE2_UnpackLow, TYP_UBYTE, simdSize); + BlockRange().InsertAfter(op[Q], tmp2); + LowerNode(tmp2); + + tmp3 = + comp->gtNewSimdHWIntrinsicNode(simdType, tmp1, tmp2, NI_SSE2_UnpackLow, TYP_USHORT, simdSize); + BlockRange().InsertAfter(tmp2, tmp3); + LowerNode(tmp3); + + // This caches the result in index 0 through 3, depending on which + // loop iteration this is and allows the rest of the logic to be + // shared with the TYP_INT and TYP_UINT path. + + op[N / 4] = tmp3; + } + } + + // We will be constructing the following parts: + // ... + // /--* opN T + // opN = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* opO T + // opO = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* opN simd16 + // +--* opO simd16 + // tmp1 = * HWINTRINSIC simd16 T UnpackLow + // /--* opP T + // opP = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* opQ T + // opQ = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* opP simd16 + // +--* opQ simd16 + // tmp2 = * HWINTRINSIC simd16 T UnpackLow + // /--* tmp1 simd16 + // +--* tmp2 simd16 + // node = * HWINTRINSIC simd16 T UnpackLow + + // This is roughly the following managed code: + // ... + // tmp1 = Sse2.UnpackLow(opN, opO); + // tmp2 = Sse2.UnpackLow(opP, opQ); + // return Sse2.UnpackLow(tmp1, tmp2); + + tmp1 = comp->gtNewSimdHWIntrinsicNode(simdType, op[0], op[1], NI_SSE2_UnpackLow, TYP_UINT, simdSize); + BlockRange().InsertAfter(op[1], tmp1); + LowerNode(tmp1); + + tmp2 = comp->gtNewSimdHWIntrinsicNode(simdType, op[2], op[3], NI_SSE2_UnpackLow, TYP_UINT, simdSize); + BlockRange().InsertAfter(op[3], tmp2); + LowerNode(tmp2); + + node->gtOp1 = tmp1; + node->gtOp2 = tmp2; + + node->gtHWIntrinsicId = NI_SSE2_UnpackLow; + node->gtSIMDBaseType = TYP_ULONG; + break; + } + +#if defined(TARGET_AMD64) + case TYP_LONG: + case TYP_ULONG: + { + if (comp->compOpportunisticallyDependsOn(InstructionSet_SSE41_X64)) + { + // We will be constructing the following parts: + // ... + // idx = CNS_INT int 1 + // /--* tmp1 simd16 + // +--* op2 T + // +--* idx int + // node = * HWINTRINSIC simd16 T Insert + + // This is roughly the following managed code: + // ... + // return Sse41.X64.Insert(tmp1, op2, 0x01); + + idx = comp->gtNewIconNode(0x01, TYP_INT); + BlockRange().InsertAfter(op2, idx); + + node->gtOp1 = comp->gtNewArgList(tmp1, op2, idx); + node->gtOp2 = nullptr; + + node->gtHWIntrinsicId = NI_SSE41_X64_Insert; + break; + } + + // We will be constructing the following parts: + // ... + // /--* op2 T + // tmp2 = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* tmp1 simd16 + // +--* tmp2 simd16 + // node = * HWINTRINSIC simd16 T UnpackLow + + // This is roughly the following managed code: + // ... + // var tmp2 = Vector128.CreateScalarUnsafe(op2); + // return Sse2.UnpackLow(tmp1, tmp2); + + assert(comp->compIsaSupportedDebugOnly(InstructionSet_SSE2)); + + tmp2 = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, op2, NI_Vector128_CreateScalarUnsafe, baseType, 16); + BlockRange().InsertAfter(op2, tmp2); + LowerNode(tmp2); + + node->gtOp1 = tmp1; + node->gtOp2 = tmp2; + + node->gtHWIntrinsicId = NI_SSE2_UnpackLow; + break; + } +#endif // TARGET_AMD64 + + case TYP_FLOAT: + { + unsigned N = 0; + GenTree* opN = nullptr; + + if (comp->compOpportunisticallyDependsOn(InstructionSet_SSE41)) + { + for (N = 1; N < argCnt - 1; N++) + { + // We will be constructing the following parts: + // ... + // + // /--* opN T + // tmp2 = * HWINTRINSIC simd16 T CreateScalarUnsafe + // idx = CNS_INT int N + // /--* tmp1 simd16 + // +--* opN T + // +--* idx int + // tmp1 = * HWINTRINSIC simd16 T Insert + // ... + + // This is roughly the following managed code: + // ... + // tmp2 = Vector128.CreateScalarUnsafe(opN); + // tmp1 = Sse41.Insert(tmp1, tmp2, N << 4); + // ... + + opN = argList->Current(); + + tmp2 = + comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, opN, NI_Vector128_CreateScalarUnsafe, baseType, 16); + BlockRange().InsertAfter(opN, tmp2); + LowerNode(tmp2); + + idx = comp->gtNewIconNode(N << 4, TYP_INT); + BlockRange().InsertAfter(tmp2, idx); + + tmp1 = + comp->gtNewSimdHWIntrinsicNode(simdType, tmp1, tmp2, idx, NI_SSE41_Insert, baseType, simdSize); + BlockRange().InsertAfter(idx, tmp1); + LowerNode(tmp1); + + argList = argList->Rest(); + } + + // We will be constructing the following parts: + // ... + // + // /--* opN T + // tmp2 = * HWINTRINSIC simd16 T CreateScalarUnsafe + // idx = CNS_INT int N + // /--* tmp1 simd16 + // +--* opN T + // +--* idx int + // node = * HWINTRINSIC simd16 T Insert + + // This is roughly the following managed code: + // ... + // tmp2 = Vector128.CreateScalarUnsafe(opN); + // return Sse41.Insert(tmp1, tmp2, N << 4); + + opN = argList->Current(); + + tmp2 = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, opN, NI_Vector128_CreateScalarUnsafe, baseType, 16); + BlockRange().InsertAfter(opN, tmp2); + LowerNode(tmp2); + + idx = comp->gtNewIconNode((argCnt - 1) << 4, TYP_INT); + BlockRange().InsertAfter(tmp2, idx); + + node->gtOp1 = comp->gtNewArgList(tmp1, tmp2, idx); + node->gtOp2 = nullptr; + + node->gtHWIntrinsicId = NI_SSE41_Insert; + break; + } + + // We will be constructing the following parts: + // ... + // /--* opN T + // opN = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* opO T + // opO = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* opN simd16 + // +--* opO simd16 + // tmp1 = * HWINTRINSIC simd16 T UnpackLow + // /--* opP T + // opP = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* opQ T + // opQ = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* opP simd16 + // +--* opQ simd16 + // tmp2 = * HWINTRINSIC simd16 T UnpackLow + // /--* tmp1 simd16 + // +--* tmp2 simd16 + // node = * HWINTRINSIC simd16 T MoveLowToHigh + + // This is roughly the following managed code: + // ... + // tmp1 = Sse.UnpackLow(opN, opO); + // tmp2 = Sse.UnpackLow(opP, opQ); + // return Sse.MoveLowToHigh(tmp1, tmp2); + + assert(comp->compIsaSupportedDebugOnly(InstructionSet_SSE)); + + GenTree* op[4]; + op[0] = tmp1; + + for (N = 1; N < argCnt; N++) + { + opN = argList->Current(); + + op[N] = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, opN, NI_Vector128_CreateScalarUnsafe, baseType, 16); + BlockRange().InsertAfter(opN, op[N]); + LowerNode(op[N]); + + argList = argList->Rest(); + } + assert(argList == nullptr); + + tmp1 = comp->gtNewSimdHWIntrinsicNode(simdType, op[0], op[1], NI_SSE_UnpackLow, baseType, simdSize); + BlockRange().InsertAfter(op[1], tmp1); + LowerNode(tmp1); + + tmp2 = comp->gtNewSimdHWIntrinsicNode(simdType, op[2], op[3], NI_SSE_UnpackLow, baseType, simdSize); + BlockRange().InsertAfter(op[3], tmp2); + LowerNode(tmp2); + + node->gtOp1 = tmp1; + node->gtOp2 = tmp2; + + node->gtHWIntrinsicId = NI_SSE_MoveLowToHigh; + break; + } + + case TYP_DOUBLE: + { + // We will be constructing the following parts: + // ... + // /--* op2 T + // tmp2 = * HWINTRINSIC simd16 T CreateScalarUnsafe + // /--* tmp1 simd16 + // +--* tmp2 simd16 + // node = * HWINTRINSIC simd16 T MoveLowToHigh + + // This is roughly the following managed code: + // ... + // var tmp2 = Vector128.CreateScalarUnsafe(op2); + // return Sse.MoveLowToHigh(tmp1, tmp2); + + assert(comp->compIsaSupportedDebugOnly(InstructionSet_SSE2)); + + tmp2 = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD16, op2, NI_Vector128_CreateScalarUnsafe, baseType, 16); + BlockRange().InsertAfter(op2, tmp2); + LowerNode(tmp2); + + node->gtOp1 = tmp1; + node->gtOp2 = tmp2; + + node->gtHWIntrinsicId = NI_SSE_MoveLowToHigh; + node->gtSIMDBaseType = TYP_FLOAT; + + break; + } + + default: + { + unreached(); + } + } +} #endif // FEATURE_HW_INTRINSICS //---------------------------------------------------------------------------------------------- diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs index 5d55d00f11b8a..db15743c6dcba 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs @@ -259,31 +259,12 @@ public static Vector AsVector(this Vector128 value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m128i _mm_set1_epi8 /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] [Intrinsic] public static unsafe Vector128 Create(byte value) { - if (Avx2.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - return Avx2.BroadcastScalarToVector128(result); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > - } - - if (Ssse3.IsSupported) - { - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - return Ssse3.Shuffle(result, Vector128.Zero); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > - } - - if (Sse2.IsSupported) - { - // We first unpack as bytes to duplicate value into the lower 2 bytes, then we treat it as a ushort and unpack again to duplicate those - // bits into the lower 2 words, we can finally treat it as a uint and shuffle the lower dword to duplicate value across the entire result - - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - result = Sse2.UnpackLow(result, result); // < v, v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - result = Sse2.UnpackLow(result.AsUInt16(), result.AsUInt16()).AsByte(); // < v, v, v, v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - return Sse2.Shuffle(result.AsUInt32(), 0x00).AsByte(); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -318,23 +299,12 @@ static Vector128 SoftwareFallback(byte value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m128d _mm_set1_pd /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] [Intrinsic] public static unsafe Vector128 Create(double value) { - if (Sse3.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { - Vector128 result = CreateScalarUnsafe(value); // < v, ? > - return Sse3.MoveAndDuplicate(result); // < v, v > - } - - if (Sse2.IsSupported) - { - // Treating the value as a set of singles and emitting MoveLowToHigh is more efficient than dealing with the elements directly as double - // However, we still need to check if Sse2 is supported since CreateScalarUnsafe needs it to for movsd, when value is not already in register - - Vector128 result = CreateScalarUnsafe(value); // < v, ? > - return Sse.MoveLowToHigh(result.AsSingle(), result.AsSingle()).AsDouble(); // < v, v > + return Create(value); } return SoftwareFallback(value); @@ -355,24 +325,12 @@ static Vector128 SoftwareFallback(double value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m128i _mm_set1_epi16 /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] [Intrinsic] public static unsafe Vector128 Create(short value) { - if (Avx2.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ? > - return Avx2.BroadcastScalarToVector128(result); // < v, v, v, v, v, v, v, v > - } - - if (Sse2.IsSupported) - { - // We first unpack as ushort to duplicate value into the lower 2 words, then we can treat it as a uint and shuffle the lower dword to - // duplicate value across the entire result - - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ? > - result = Sse2.UnpackLow(result, result); // < v, v, ?, ?, ?, ?, ?, ? > - return Sse2.Shuffle(result.AsInt32(), 0x00).AsInt16(); // < v, v, v, v, v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -399,20 +357,12 @@ static Vector128 SoftwareFallback(short value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m128i _mm_set1_epi32 /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] [Intrinsic] public static unsafe Vector128 Create(int value) { - if (Avx2.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ? > - return Avx2.BroadcastScalarToVector128(result); // < v, v, v, v > - } - - if (Sse2.IsSupported) - { - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ? > - return Sse2.Shuffle(result, 0x00); // < v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -435,22 +385,12 @@ static Vector128 SoftwareFallback(int value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m128i _mm_set1_epi64x /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] [Intrinsic] public static unsafe Vector128 Create(long value) { - if (Sse2.X64.IsSupported) + if (Sse2.X64.IsSupported || AdvSimd.IsSupported) { - if (Avx2.IsSupported) - { - Vector128 result = CreateScalarUnsafe(value); // < v, ? > - return Avx2.BroadcastScalarToVector128(result); // < v, v > - } - else - { - Vector128 result = CreateScalarUnsafe(value); // < v, ? > - return Sse2.UnpackLow(result, result); // < v, v > - } + return Create(value); } return SoftwareFallback(value); @@ -471,32 +411,13 @@ static Vector128 SoftwareFallback(long value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m128i _mm_set1_epi8 /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [CLSCompliant(false)] [Intrinsic] + [CLSCompliant(false)] public static unsafe Vector128 Create(sbyte value) { - if (Avx2.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - return Avx2.BroadcastScalarToVector128(result); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > - } - - if (Ssse3.IsSupported) - { - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - return Ssse3.Shuffle(result, Vector128.Zero); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > - } - - if (Sse2.IsSupported) - { - // We first unpack as bytes to duplicate value into the lower 2 bytes, then we treat it as a ushort and unpack again to duplicate those - // bits into the lower 2 words, we can finally treat it as a uint and shuffle the lower dword to duplicate value across the entire result - - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - result = Sse2.UnpackLow(result, result); // < v, v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - result = Sse2.UnpackLow(result.AsInt16(), result.AsInt16()).AsSByte(); // < v, v, v, v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - return Sse2.Shuffle(result.AsInt32(), 0x00).AsSByte(); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -531,26 +452,12 @@ static Vector128 SoftwareFallback(sbyte value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m128 _mm_set1_ps /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] [Intrinsic] public static unsafe Vector128 Create(float value) { - if (Avx2.IsSupported) + if (Sse.IsSupported || AdvSimd.IsSupported) { - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ? > - return Avx2.BroadcastScalarToVector128(result); // < v, v, v, v > - } - - if (Avx.IsSupported) - { - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ? > - return Avx.Permute(result, 0x00); // < v, v, v, v > - } - - if (Sse.IsSupported) - { - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ? > - return Sse.Shuffle(result, result, 0x00); // < v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -573,25 +480,13 @@ static Vector128 SoftwareFallback(float value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m128i _mm_set1_epi16 /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [CLSCompliant(false)] [Intrinsic] + [CLSCompliant(false)] public static unsafe Vector128 Create(ushort value) { - if (Avx2.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ? > - return Avx2.BroadcastScalarToVector128(result); // < v, v, v, v, v, v, v, v > - } - - if (Sse2.IsSupported) - { - // We first unpack as ushort to duplicate value into the lower 2 words, then we can treat it as a uint and shuffle the lower dword to - // duplicate value across the entire result - - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ? > - result = Sse2.UnpackLow(result, result); // < v, v, ?, ?, ?, ?, ?, ? > - return Sse2.Shuffle(result.AsUInt32(), 0x00).AsUInt16(); // < v, v, v, v, v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -618,21 +513,13 @@ static Vector128 SoftwareFallback(ushort value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m128i _mm_set1_epi32 /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [CLSCompliant(false)] [Intrinsic] + [CLSCompliant(false)] public static unsafe Vector128 Create(uint value) { - if (Avx2.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ? > - return Avx2.BroadcastScalarToVector128(result); // < v, v, v, v > - } - - if (Sse2.IsSupported) - { - Vector128 result = CreateScalarUnsafe(value); // < v, ?, ?, ? > - return Sse2.Shuffle(result, 0x00); // < v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -655,23 +542,13 @@ static Vector128 SoftwareFallback(uint value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m128i _mm_set1_epi64x /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [CLSCompliant(false)] [Intrinsic] + [CLSCompliant(false)] public static unsafe Vector128 Create(ulong value) { - if (Sse2.X64.IsSupported) + if (Sse2.X64.IsSupported || AdvSimd.IsSupported) { - if (Avx2.IsSupported) - { - Vector128 result = CreateScalarUnsafe(value); // < v, ? > - return Avx2.BroadcastScalarToVector128(result); // < v, v > - } - else - { - Vector128 result = CreateScalarUnsafe(value); // < v, ? > - return Sse2.UnpackLow(result, result); // < v, v > - } + return Create(value); } return SoftwareFallback(value); @@ -707,62 +584,15 @@ static Vector128 SoftwareFallback(ulong value) /// The value that element 15 will be initialized to. /// On x86, this method corresponds to __m128i _mm_setr_epi8 /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector128 Create(byte e0, byte e1, byte e2, byte e3, byte e4, byte e5, byte e6, byte e7, byte e8, byte e9, byte e10, byte e11, byte e12, byte e13, byte e14, byte e15) { - if (Sse41.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); // < 0, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e1, 1); // < 0, 1, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e2, 2); // < 0, 1, 2, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e3, 3); // < 0, 1, 2, 3, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e4, 4); // < 0, 1, 2, 3, 4, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e5, 5); // < 0, 1, 2, 3, 4, 5, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e6, 6); // < 0, 1, 2, 3, 4, 5, 6, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e7, 7); // < 0, 1, 2, 3, 4, 5, 6, 7, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e8, 8); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e9, 9); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e10, 10); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e11, 11); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ??, ??, ??, ?? > - result = Sse41.Insert(result, e12, 12); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ??, ??, ?? > - result = Sse41.Insert(result, e13, 13); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, ??, ?? > - result = Sse41.Insert(result, e14, 14); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ?? > - return Sse41.Insert(result, e15, 15); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 > - } - +#if !TARGET_ARM && !TARGET_ARM64 if (Sse2.IsSupported) { - // We deal with the elements in order, unpacking the ordered pairs of bytes into vectors. We then treat those vectors as ushort and - // unpack them again, then again treating those results as uint, and a final time treating them as ulong. This efficiently gets all - // bytes ordered into the result. - - Vector128 lo16, hi16; - Vector128 lo32, hi32; - Vector128 lo64, hi64; - - lo16 = Sse2.UnpackLow(CreateScalarUnsafe(e0), CreateScalarUnsafe(e1)).AsUInt16(); // < 0, 1, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - hi16 = Sse2.UnpackLow(CreateScalarUnsafe(e2), CreateScalarUnsafe(e3)).AsUInt16(); // < 2, 3, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - lo32 = Sse2.UnpackLow(lo16, hi16).AsUInt32(); // < 0, 1, 2, 3, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - - lo16 = Sse2.UnpackLow(CreateScalarUnsafe(e4), CreateScalarUnsafe(e5)).AsUInt16(); // < 4, 5, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - hi16 = Sse2.UnpackLow(CreateScalarUnsafe(e6), CreateScalarUnsafe(e7)).AsUInt16(); // < 6, 7, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - hi32 = Sse2.UnpackLow(lo16, hi16).AsUInt32(); // < 4, 5, 6, 7, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - - lo64 = Sse2.UnpackLow(lo32, hi32).AsUInt64(); // < 0, 1, 2, 3, 4, 5, 6, 7, ??, ??, ??, ??, ??, ??, ??, ?? > - - lo16 = Sse2.UnpackLow(CreateScalarUnsafe(e8), CreateScalarUnsafe(e9)).AsUInt16(); // < 8, 9, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - hi16 = Sse2.UnpackLow(CreateScalarUnsafe(e10), CreateScalarUnsafe(e11)).AsUInt16(); // < 10, 11, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - lo32 = Sse2.UnpackLow(lo16, hi16).AsUInt32(); // < 8, 9, 10, 11, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - - lo16 = Sse2.UnpackLow(CreateScalarUnsafe(e12), CreateScalarUnsafe(e13)).AsUInt16(); // < 12, 13, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - hi16 = Sse2.UnpackLow(CreateScalarUnsafe(e14), CreateScalarUnsafe(e15)).AsUInt16(); // < 14, 15, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - hi32 = Sse2.UnpackLow(lo16, hi16).AsUInt32(); // < 12, 13, 14, 15, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - - hi64 = Sse2.UnpackLow(lo32, hi32).AsUInt64(); // < 8, 9, 10, 11, 12, 13, 14, 15, ??, ??, ??, ??, ??, ??, ??, ?? > - - return Sse2.UnpackLow(lo64, hi64).AsByte(); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 > + return Create(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); } - +#else if (AdvSimd.IsSupported) { Vector128 result = CreateScalarUnsafe(e0); @@ -782,6 +612,7 @@ public static unsafe Vector128 Create(byte e0, byte e1, byte e2, byte e3, result = AdvSimd.Insert(result, 14, e14); return AdvSimd.Insert(result, 15, e15); } +#endif return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); @@ -816,22 +647,21 @@ static Vector128 SoftwareFallback(byte e0, byte e1, byte e2, byte e3, byte /// The value that element 1 will be initialized to. /// On x86, this method corresponds to __m128d _mm_setr_pd /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector128 Create(double e0, double e1) { +#if !TARGET_ARM && !TARGET_ARM64 if (Sse2.IsSupported) { - // Treating the value as a set of singles and emitting MoveLowToHigh is more efficient than dealing with the elements directly as double - // However, we still need to check if Sse2 is supported since CreateScalarUnsafe needs it to for movsd, when value is not already in register - - return Sse.MoveLowToHigh(CreateScalarUnsafe(e0).AsSingle(), CreateScalarUnsafe(e1).AsSingle()).AsDouble(); + return Create(e0, e1); } - +#else if (AdvSimd.IsSupported) { Vector128 result = CreateScalarUnsafe(e0); return AdvSimd.Insert(result, 1, e1); } +#endif return SoftwareFallback(e0, e1); @@ -858,21 +688,15 @@ static Vector128 SoftwareFallback(double e0, double e1) /// The value that element 7 will be initialized to. /// On x86, this method corresponds to __m128i _mm_setr_epi16 /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector128 Create(short e0, short e1, short e2, short e3, short e4, short e5, short e6, short e7) { +#if !TARGET_ARM && !TARGET_ARM64 if (Sse2.IsSupported) { - Vector128 result = CreateScalarUnsafe(e0); // < 0, ?, ?, ?, ?, ?, ?, ? > - result = Sse2.Insert(result, e1, 1); // < 0, 1, ?, ?, ?, ?, ?, ? > - result = Sse2.Insert(result, e2, 2); // < 0, 1, 2, ?, ?, ?, ?, ? > - result = Sse2.Insert(result, e3, 3); // < 0, 1, 2, 3, ?, ?, ?, ? > - result = Sse2.Insert(result, e4, 4); // < 0, 1, 2, 3, 4, ?, ?, ? > - result = Sse2.Insert(result, e5, 5); // < 0, 1, 2, 3, 4, 5, ?, ? > - result = Sse2.Insert(result, e6, 6); // < 0, 1, 2, 3, 4, 5, 6, ? > - return Sse2.Insert(result, e7, 7); // < 0, 1, 2, 3, 4, 5, 6, 7 > + return Create(e0, e1, e2, e3, e4, e5, e6, e7); } - +#else if (AdvSimd.IsSupported) { Vector128 result = CreateScalarUnsafe(e0); @@ -884,6 +708,7 @@ public static unsafe Vector128 Create(short e0, short e1, short e2, short result = AdvSimd.Insert(result, 6, e6); return AdvSimd.Insert(result, 7, e7); } +#endif return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7); @@ -912,28 +737,15 @@ static Vector128 SoftwareFallback(short e0, short e1, short e2, short e3, /// The value that element 3 will be initialized to. /// On x86, this method corresponds to __m128i _mm_setr_epi32 /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector128 Create(int e0, int e1, int e2, int e3) { - if (Sse41.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); // < 0, ?, ?, ? > - result = Sse41.Insert(result, e1, 1); // < 0, 1, ?, ? > - result = Sse41.Insert(result, e2, 2); // < 0, 1, 2, ? > - return Sse41.Insert(result, e3, 3); // < 0, 1, 2, 3 > - } - +#if !TARGET_ARM && !TARGET_ARM64 if (Sse2.IsSupported) { - // We deal with the elements in order, unpacking the ordered pairs of int into vectors. We then treat those vectors as ulong and - // unpack them again. This efficiently gets all ints ordered into the result. - - Vector128 lo64, hi64; - lo64 = Sse2.UnpackLow(CreateScalarUnsafe(e0), CreateScalarUnsafe(e1)).AsInt64(); // < 0, 1, ?, ? > - hi64 = Sse2.UnpackLow(CreateScalarUnsafe(e2), CreateScalarUnsafe(e3)).AsInt64(); // < 2, 3, ?, ? > - return Sse2.UnpackLow(lo64, hi64).AsInt32(); // < 0, 1, 2, 3 > + return Create(e0, e1, e2, e3); } - +#else if (AdvSimd.IsSupported) { Vector128 result = CreateScalarUnsafe(e0); @@ -941,6 +753,7 @@ public static unsafe Vector128 Create(int e0, int e1, int e2, int e3) result = AdvSimd.Insert(result, 2, e2); return AdvSimd.Insert(result, 3, e3); } +#endif return SoftwareFallback(e0, e1, e2, e3); @@ -963,25 +776,21 @@ static Vector128 SoftwareFallback(int e0, int e1, int e2, int e3) /// The value that element 1 will be initialized to. /// On x86, this method corresponds to __m128i _mm_setr_epi64x /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector128 Create(long e0, long e1) { - if (Sse41.X64.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); // < 0, ? > - return Sse41.X64.Insert(result, e1, 1); // < 0, 1 > - } - +#if !TARGET_ARM && !TARGET_ARM64 if (Sse2.X64.IsSupported) { - return Sse2.UnpackLow(CreateScalarUnsafe(e0), CreateScalarUnsafe(e1)); // < 0, 1 > + return Create(e0, e1); } - +#else if (AdvSimd.IsSupported) { Vector128 result = CreateScalarUnsafe(e0); return AdvSimd.Insert(result, 1, e1); } +#endif return SoftwareFallback(e0, e1); @@ -1016,63 +825,16 @@ static Vector128 SoftwareFallback(long e0, long e1) /// The value that element 15 will be initialized to. /// On x86, this method corresponds to __m128i _mm_setr_epi8 /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector128 Create(sbyte e0, sbyte e1, sbyte e2, sbyte e3, sbyte e4, sbyte e5, sbyte e6, sbyte e7, sbyte e8, sbyte e9, sbyte e10, sbyte e11, sbyte e12, sbyte e13, sbyte e14, sbyte e15) { - if (Sse41.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); // < 0, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e1, 1); // < 0, 1, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e2, 2); // < 0, 1, 2, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e3, 3); // < 0, 1, 2, 3, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e4, 4); // < 0, 1, 2, 3, 4, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e5, 5); // < 0, 1, 2, 3, 4, 5, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e6, 6); // < 0, 1, 2, 3, 4, 5, 6, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e7, 7); // < 0, 1, 2, 3, 4, 5, 6, 7, ??, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e8, 8); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, ??, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e9, 9); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ??, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e10, 10); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ??, ??, ??, ??, ?? > - result = Sse41.Insert(result, e11, 11); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ??, ??, ??, ?? > - result = Sse41.Insert(result, e12, 12); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ??, ??, ?? > - result = Sse41.Insert(result, e13, 13); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, ??, ?? > - result = Sse41.Insert(result, e14, 14); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ?? > - return Sse41.Insert(result, e15, 15); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 > - } - +#if !TARGET_ARM && !TARGET_ARM64 if (Sse2.IsSupported) { - // We deal with the elements in order, unpacking the ordered pairs of bytes into vectors. We then treat those vectors as ushort and - // unpack them again, then again treating those results as uint, and a final time treating them as ulong. This efficiently gets all - // bytes ordered into the result. - - Vector128 lo16, hi16; - Vector128 lo32, hi32; - Vector128 lo64, hi64; - - lo16 = Sse2.UnpackLow(CreateScalarUnsafe(e0), CreateScalarUnsafe(e1)).AsInt16(); // < 0, 1, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - hi16 = Sse2.UnpackLow(CreateScalarUnsafe(e2), CreateScalarUnsafe(e3)).AsInt16(); // < 2, 3, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - lo32 = Sse2.UnpackLow(lo16, hi16).AsInt32(); // < 0, 1, 2, 3, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - - lo16 = Sse2.UnpackLow(CreateScalarUnsafe(e4), CreateScalarUnsafe(e5)).AsInt16(); // < 4, 5, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - hi16 = Sse2.UnpackLow(CreateScalarUnsafe(e6), CreateScalarUnsafe(e7)).AsInt16(); // < 6, 7, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - hi32 = Sse2.UnpackLow(lo16, hi16).AsInt32(); // < 4, 5, 6, 7, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - - lo64 = Sse2.UnpackLow(lo32, hi32).AsInt64(); // < 0, 1, 2, 3, 4, 5, 6, 7, ??, ??, ??, ??, ??, ??, ??, ?? > - - lo16 = Sse2.UnpackLow(CreateScalarUnsafe(e8), CreateScalarUnsafe(e9)).AsInt16(); // < 8, 9, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - hi16 = Sse2.UnpackLow(CreateScalarUnsafe(e10), CreateScalarUnsafe(e11)).AsInt16(); // < 10, 11, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - lo32 = Sse2.UnpackLow(lo16, hi16).AsInt32(); // < 8, 9, 10, 11, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - - lo16 = Sse2.UnpackLow(CreateScalarUnsafe(e12), CreateScalarUnsafe(e13)).AsInt16(); // < 12, 13, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - hi16 = Sse2.UnpackLow(CreateScalarUnsafe(e14), CreateScalarUnsafe(e15)).AsInt16(); // < 14, 15, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - hi32 = Sse2.UnpackLow(lo16, hi16).AsInt32(); // < 12, 13, 14, 15, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ??, ?? > - - hi64 = Sse2.UnpackLow(lo32, hi32).AsInt64(); // < 8, 9, 10, 11, 12, 13, 14, 15, ??, ??, ??, ??, ??, ??, ??, ?? > - - return Sse2.UnpackLow(lo64, hi64).AsSByte(); // < 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 > + return Create(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); } - +#else if (AdvSimd.IsSupported) { Vector128 result = CreateScalarUnsafe(e0); @@ -1092,6 +854,7 @@ public static unsafe Vector128 Create(sbyte e0, sbyte e1, sbyte e2, sbyte result = AdvSimd.Insert(result, 14, e14); return AdvSimd.Insert(result, 15, e15); } +#endif return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); @@ -1128,25 +891,15 @@ static Vector128 SoftwareFallback(sbyte e0, sbyte e1, sbyte e2, sbyte e3, /// The value that element 3 will be initialized to. /// On x86, this method corresponds to __m128 _mm_setr_ps /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector128 Create(float e0, float e1, float e2, float e3) { - if (Sse41.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); // < 0, ?, ?, ? > - result = Sse41.Insert(result, CreateScalarUnsafe(e1), 0x10); // < 0, 1, ?, ? > - result = Sse41.Insert(result, CreateScalarUnsafe(e2), 0x20); // < 0, 1, 2, ? > - return Sse41.Insert(result, CreateScalarUnsafe(e3), 0x30); // < 0, 1, 2, 3 > - } - +#if !TARGET_ARM && !TARGET_ARM64 if (Sse.IsSupported) { - Vector128 lo64, hi64; - lo64 = Sse.UnpackLow(CreateScalarUnsafe(e0), CreateScalarUnsafe(e1)); // < 0, 1, ?, ? > - hi64 = Sse.UnpackLow(CreateScalarUnsafe(e2), CreateScalarUnsafe(e3)); // < 2, 3, ?, ? > - return Sse.MoveLowToHigh(lo64, hi64); // < 0, 1, 2, 3 > + return Create(e0, e1, e2, e3); } - +#else if (AdvSimd.IsSupported) { Vector128 result = CreateScalarUnsafe(e0); @@ -1154,6 +907,7 @@ public static unsafe Vector128 Create(float e0, float e1, float e2, float result = AdvSimd.Insert(result, 2, e2); return AdvSimd.Insert(result, 3, e3); } +#endif return SoftwareFallback(e0, e1, e2, e3); @@ -1182,22 +936,16 @@ static Vector128 SoftwareFallback(float e0, float e1, float e2, float e3) /// The value that element 7 will be initialized to. /// On x86, this method corresponds to __m128i _mm_setr_epi16 /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector128 Create(ushort e0, ushort e1, ushort e2, ushort e3, ushort e4, ushort e5, ushort e6, ushort e7) { +#if !TARGET_ARM && !TARGET_ARM64 if (Sse2.IsSupported) { - Vector128 result = CreateScalarUnsafe(e0); // < 0, ?, ?, ?, ?, ?, ?, ? > - result = Sse2.Insert(result, e1, 1); // < 0, 1, ?, ?, ?, ?, ?, ? > - result = Sse2.Insert(result, e2, 2); // < 0, 1, 2, ?, ?, ?, ?, ? > - result = Sse2.Insert(result, e3, 3); // < 0, 1, 2, 3, ?, ?, ?, ? > - result = Sse2.Insert(result, e4, 4); // < 0, 1, 2, 3, 4, ?, ?, ? > - result = Sse2.Insert(result, e5, 5); // < 0, 1, 2, 3, 4, 5, ?, ? > - result = Sse2.Insert(result, e6, 6); // < 0, 1, 2, 3, 4, 5, 6, ? > - return Sse2.Insert(result, e7, 7); // < 0, 1, 2, 3, 4, 5, 6, 7 > + return Create(e0, e1, e2, e3, e4, e5, e6, e7); } - +#else if (AdvSimd.IsSupported) { Vector128 result = CreateScalarUnsafe(e0); @@ -1209,6 +957,7 @@ public static unsafe Vector128 Create(ushort e0, ushort e1, ushort e2, u result = AdvSimd.Insert(result, 6, e6); return AdvSimd.Insert(result, 7, e7); } +#endif return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7); @@ -1237,29 +986,16 @@ static Vector128 SoftwareFallback(ushort e0, ushort e1, ushort e2, ushor /// The value that element 3 will be initialized to. /// On x86, this method corresponds to __m128i _mm_setr_epi32 /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector128 Create(uint e0, uint e1, uint e2, uint e3) { - if (Sse41.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); // < 0, ?, ?, ? > - result = Sse41.Insert(result, e1, 1); // < 0, 1, ?, ? > - result = Sse41.Insert(result, e2, 2); // < 0, 1, 2, ? > - return Sse41.Insert(result, e3, 3); // < 0, 1, 2, 3 > - } - +#if !TARGET_ARM && !TARGET_ARM64 if (Sse2.IsSupported) { - // We deal with the elements in order, unpacking the ordered pairs of int into vectors. We then treat those vectors as ulong and - // unpack them again. This efficiently gets all ints ordered into the result. - - Vector128 lo64, hi64; - lo64 = Sse2.UnpackLow(CreateScalarUnsafe(e0), CreateScalarUnsafe(e1)).AsUInt64(); // < 0, 1, ?, ? > - hi64 = Sse2.UnpackLow(CreateScalarUnsafe(e2), CreateScalarUnsafe(e3)).AsUInt64(); // < 2, 3, ?, ? > - return Sse2.UnpackLow(lo64, hi64).AsUInt32(); // < 0, 1, 2, 3 > + return Create(e0, e1, e2, e3); } - +#else if (AdvSimd.IsSupported) { Vector128 result = CreateScalarUnsafe(e0); @@ -1267,6 +1003,7 @@ public static unsafe Vector128 Create(uint e0, uint e1, uint e2, uint e3) result = AdvSimd.Insert(result, 2, e2); return AdvSimd.Insert(result, 3, e3); } +#endif return SoftwareFallback(e0, e1, e2, e3); @@ -1289,26 +1026,22 @@ static Vector128 SoftwareFallback(uint e0, uint e1, uint e2, uint e3) /// The value that element 1 will be initialized to. /// On x86, this method corresponds to __m128i _mm_setr_epi64x /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector128 Create(ulong e0, ulong e1) { - if (Sse41.X64.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); // < 0, ? > - return Sse41.X64.Insert(result, e1, 1); // < 0, 1 > - } - +#if !TARGET_ARM && !TARGET_ARM64 if (Sse2.X64.IsSupported) { - return Sse2.UnpackLow(CreateScalarUnsafe(e0), CreateScalarUnsafe(e1)); // < 0, 1 > + return Create(e0, e1); } - +#else if (AdvSimd.IsSupported) { Vector128 result = CreateScalarUnsafe(e0); return AdvSimd.Insert(result, 1, e1); } +#endif return SoftwareFallback(e0, e1); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs index 2a123ab52099c..ae4e95608b033 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs @@ -208,19 +208,12 @@ public static Vector AsVector(this Vector256 value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m256i _mm256_set1_epi8 /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector256 Create(byte value) { - if (Avx2.IsSupported) - { - Vector128 result = Vector128.CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - return Avx2.BroadcastScalarToVector256(result); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > - } - if (Avx.IsSupported) { - Vector128 result = Vector128.Create(value); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - return Avx.InsertVector128(result.ToVector256Unsafe(), result, 1); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -271,19 +264,12 @@ static Vector256 SoftwareFallback(byte value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m256d _mm256_set1_pd /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector256 Create(double value) { - if (Avx2.IsSupported) - { - Vector128 result = Vector128.CreateScalarUnsafe(value); // < v, ?, ?, ? > - return Avx2.BroadcastScalarToVector256(result); // < v, v, v, v > - } - if (Avx.IsSupported) { - Vector128 result = Vector128.Create(value); // < v, v, ?, ? > - return Avx.InsertVector128(result.ToVector256Unsafe(), result, 1); // < v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -306,19 +292,12 @@ static Vector256 SoftwareFallback(double value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m256i _mm256_set1_epi16 /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector256 Create(short value) { - if (Avx2.IsSupported) - { - Vector128 result = Vector128.CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - return Avx2.BroadcastScalarToVector256(result); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > - } - if (Avx.IsSupported) { - Vector128 result = Vector128.Create(value); // < v, v, v, v, v, v, v, v, ?, ?, ?, ?, ?, ?, ?, ? > - return Avx.InsertVector128(result.ToVector256Unsafe(), result, 1); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -353,19 +332,12 @@ static Vector256 SoftwareFallback(short value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m256i _mm256_set1_epi32 /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector256 Create(int value) { - if (Avx2.IsSupported) - { - Vector128 result = Vector128.CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ? > - return Avx2.BroadcastScalarToVector256(result); // < v, v, v, v, v, v, v, v > - } - if (Avx.IsSupported) { - Vector128 result = Vector128.Create(value); // < v, v, v, v, ?, ?, ?, ? > - return Avx.InsertVector128(result.ToVector256Unsafe(), result, 1); // < v, v, v, v, v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -392,21 +364,12 @@ static Vector256 SoftwareFallback(int value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m256i _mm256_set1_epi64x /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector256 Create(long value) { - if (Sse2.X64.IsSupported) + if (Sse2.X64.IsSupported && Avx.IsSupported) { - if (Avx2.IsSupported) - { - Vector128 result = Vector128.CreateScalarUnsafe(value); // < v, ?, ?, ? > - return Avx2.BroadcastScalarToVector256(result); // < v, v, v, v > - } - else if (Avx.IsSupported) - { - Vector128 result = Vector128.Create(value); // < v, v, ?, ? > - return Avx.InsertVector128(result.ToVector256Unsafe(), result, 1); // < v, v, v, v > - } + return Create(value); } return SoftwareFallback(value); @@ -429,20 +392,13 @@ static Vector256 SoftwareFallback(long value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m256i _mm256_set1_epi8 /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector256 Create(sbyte value) { - if (Avx2.IsSupported) - { - Vector128 result = Vector128.CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - return Avx2.BroadcastScalarToVector256(result); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > - } - if (Avx.IsSupported) { - Vector128 result = Vector128.Create(value); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - return Avx.InsertVector128(result.ToVector256Unsafe(), result, 1); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -493,19 +449,12 @@ static Vector256 SoftwareFallback(sbyte value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m256 _mm256_set1_ps /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector256 Create(float value) { - if (Avx2.IsSupported) - { - Vector128 result = Vector128.CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ? > - return Avx2.BroadcastScalarToVector256(result); // < v, v, v, v, v, v, v, v > - } - if (Avx.IsSupported) { - Vector128 result = Vector128.Create(value); // < v, v, v, v, ?, ?, ?, ? > - return Avx.InsertVector128(result.ToVector256Unsafe(), result, 1); // < v, v, v, v, v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -532,20 +481,13 @@ static Vector256 SoftwareFallback(float value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m256i _mm256_set1_epi16 /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector256 Create(ushort value) { - if (Avx2.IsSupported) - { - Vector128 result = Vector128.CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? > - return Avx2.BroadcastScalarToVector256(result); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > - } - if (Avx.IsSupported) { - Vector128 result = Vector128.Create(value); // < v, v, v, v, v, v, v, v, ?, ?, ?, ?, ?, ?, ?, ? > - return Avx.InsertVector128(result.ToVector256Unsafe(), result, 1); // < v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -580,20 +522,13 @@ static Vector256 SoftwareFallback(ushort value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m256i _mm256_set1_epi32 /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector256 Create(uint value) { - if (Avx2.IsSupported) - { - Vector128 result = Vector128.CreateScalarUnsafe(value); // < v, ?, ?, ?, ?, ?, ?, ? > - return Avx2.BroadcastScalarToVector256(result); // < v, v, v, v, v, v, v, v > - } - if (Avx.IsSupported) { - Vector128 result = Vector128.Create(value); // < v, v, v, v, ?, ?, ?, ? > - return Avx.InsertVector128(result.ToVector256Unsafe(), result, 1); // < v, v, v, v, v, v, v, v > + return Create(value); } return SoftwareFallback(value); @@ -620,22 +555,13 @@ static Vector256 SoftwareFallback(uint value) /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m256i _mm256_set1_epi64x /// A new with all elements initialized to . - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector256 Create(ulong value) { - if (Sse2.X64.IsSupported) + if (Sse2.X64.IsSupported && Avx.IsSupported) { - if (Avx2.IsSupported) - { - Vector128 result = Vector128.CreateScalarUnsafe(value); // < v, ?, ?, ? > - return Avx2.BroadcastScalarToVector256(result); // < v, v, v, v > - } - else if (Avx.IsSupported) - { - Vector128 result = Vector128.Create(value); // < v, v, ?, ? > - return Avx.InsertVector128(result.ToVector256Unsafe(), result, 1); // < v, v, v, v > - } + return Create(value); } return SoftwareFallback(value); @@ -689,14 +615,12 @@ static Vector256 SoftwareFallback(ulong value) /// The value that element 31 will be initialized to. /// On x86, this method corresponds to __m256i _mm256_setr_epi8 /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector256 Create(byte e0, byte e1, byte e2, byte e3, byte e4, byte e5, byte e6, byte e7, byte e8, byte e9, byte e10, byte e11, byte e12, byte e13, byte e14, byte e15, byte e16, byte e17, byte e18, byte e19, byte e20, byte e21, byte e22, byte e23, byte e24, byte e25, byte e26, byte e27, byte e28, byte e29, byte e30, byte e31) { if (Avx.IsSupported) { - Vector128 lo128 = Vector128.Create(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); - Vector128 hi128 = Vector128.Create(e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31); - return Create(lo128, hi128); + return Create(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31); } return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31); @@ -750,14 +674,12 @@ static Vector256 SoftwareFallback(byte e0, byte e1, byte e2, byte e3, byte /// The value that element 3 will be initialized to. /// On x86, this method corresponds to __m256d _mm256_setr_pd /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector256 Create(double e0, double e1, double e2, double e3) { if (Avx.IsSupported) { - Vector128 lo128 = Vector128.Create(e0, e1); - Vector128 hi128 = Vector128.Create(e2, e3); - return Create(lo128, hi128); + return Create(e0, e1, e2, e3); } return SoftwareFallback(e0, e1, e2, e3); @@ -795,14 +717,12 @@ static Vector256 SoftwareFallback(double e0, double e1, double e2, doubl /// The value that element 15 will be initialized to. /// On x86, this method corresponds to __m256i _mm256_setr_epi16 /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector256 Create(short e0, short e1, short e2, short e3, short e4, short e5, short e6, short e7, short e8, short e9, short e10, short e11, short e12, short e13, short e14, short e15) { if (Avx.IsSupported) { - Vector128 lo128 = Vector128.Create(e0, e1, e2, e3, e4, e5, e6, e7); - Vector128 hi128 = Vector128.Create(e8, e9, e10, e11, e12, e13, e14, e15); - return Create(lo128, hi128); + return Create(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); } return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); @@ -844,14 +764,12 @@ static Vector256 SoftwareFallback(short e0, short e1, short e2, short e3, /// The value that element 7 will be initialized to. /// On x86, this method corresponds to __m256i _mm256_setr_epi32 /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector256 Create(int e0, int e1, int e2, int e3, int e4, int e5, int e6, int e7) { if (Avx.IsSupported) { - Vector128 lo128 = Vector128.Create(e0, e1, e2, e3); - Vector128 hi128 = Vector128.Create(e4, e5, e6, e7); - return Create(lo128, hi128); + return Create(e0, e1, e2, e3, e4, e5, e6, e7); } return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7); @@ -881,14 +799,12 @@ static Vector256 SoftwareFallback(int e0, int e1, int e2, int e3, int e4, i /// The value that element 3 will be initialized to. /// On x86, this method corresponds to __m256i _mm256_setr_epi64x /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector256 Create(long e0, long e1, long e2, long e3) { if (Sse2.X64.IsSupported && Avx.IsSupported) { - Vector128 lo128 = Vector128.Create(e0, e1); - Vector128 hi128 = Vector128.Create(e2, e3); - return Create(lo128, hi128); + return Create(e0, e1, e2, e3); } return SoftwareFallback(e0, e1, e2, e3); @@ -942,15 +858,13 @@ static Vector256 SoftwareFallback(long e0, long e1, long e2, long e3) /// The value that element 31 will be initialized to. /// On x86, this method corresponds to __m256i _mm256_setr_epi8 /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector256 Create(sbyte e0, sbyte e1, sbyte e2, sbyte e3, sbyte e4, sbyte e5, sbyte e6, sbyte e7, sbyte e8, sbyte e9, sbyte e10, sbyte e11, sbyte e12, sbyte e13, sbyte e14, sbyte e15, sbyte e16, sbyte e17, sbyte e18, sbyte e19, sbyte e20, sbyte e21, sbyte e22, sbyte e23, sbyte e24, sbyte e25, sbyte e26, sbyte e27, sbyte e28, sbyte e29, sbyte e30, sbyte e31) { if (Avx.IsSupported) { - Vector128 lo128 = Vector128.Create(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); - Vector128 hi128 = Vector128.Create(e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31); - return Create(lo128, hi128); + return Create(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31); } return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31); @@ -1008,14 +922,12 @@ static Vector256 SoftwareFallback(sbyte e0, sbyte e1, sbyte e2, sbyte e3, /// The value that element 7 will be initialized to. /// On x86, this method corresponds to __m256 _mm256_setr_ps /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] public static unsafe Vector256 Create(float e0, float e1, float e2, float e3, float e4, float e5, float e6, float e7) { if (Avx.IsSupported) { - Vector128 lo128 = Vector128.Create(e0, e1, e2, e3); - Vector128 hi128 = Vector128.Create(e4, e5, e6, e7); - return Create(lo128, hi128); + return Create(e0, e1, e2, e3, e4, e5, e6, e7); } return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7); @@ -1057,15 +969,13 @@ static Vector256 SoftwareFallback(float e0, float e1, float e2, float e3, /// The value that element 15 will be initialized to. /// On x86, this method corresponds to __m256i _mm256_setr_epi16 /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector256 Create(ushort e0, ushort e1, ushort e2, ushort e3, ushort e4, ushort e5, ushort e6, ushort e7, ushort e8, ushort e9, ushort e10, ushort e11, ushort e12, ushort e13, ushort e14, ushort e15) { if (Avx.IsSupported) { - Vector128 lo128 = Vector128.Create(e0, e1, e2, e3, e4, e5, e6, e7); - Vector128 hi128 = Vector128.Create(e8, e9, e10, e11, e12, e13, e14, e15); - return Create(lo128, hi128); + return Create(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); } return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); @@ -1107,15 +1017,13 @@ static Vector256 SoftwareFallback(ushort e0, ushort e1, ushort e2, ushor /// The value that element 7 will be initialized to. /// On x86, this method corresponds to __m256i _mm256_setr_epi32 /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector256 Create(uint e0, uint e1, uint e2, uint e3, uint e4, uint e5, uint e6, uint e7) { if (Avx.IsSupported) { - Vector128 lo128 = Vector128.Create(e0, e1, e2, e3); - Vector128 hi128 = Vector128.Create(e4, e5, e6, e7); - return Create(lo128, hi128); + return Create(e0, e1, e2, e3, e4, e5, e6, e7); } return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7); @@ -1145,15 +1053,13 @@ static Vector256 SoftwareFallback(uint e0, uint e1, uint e2, uint e3, uint /// The value that element 3 will be initialized to. /// On x86, this method corresponds to __m256i _mm256_setr_epi64x /// A new with each element initialized to corresponding specified value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector256 Create(ulong e0, ulong e1, ulong e2, ulong e3) { if (Sse2.X64.IsSupported && Avx.IsSupported) { - Vector128 lo128 = Vector128.Create(e0, e1); - Vector128 hi128 = Vector128.Create(e2, e3); - return Create(lo128, hi128); + return Create(e0, e1, e2, e3); } return SoftwareFallback(e0, e1, e2, e3); From 0b32ff7e61554feef74551bd4189c4943b9a65d1 Mon Sep 17 00:00:00 2001 From: John Salem Date: Fri, 8 May 2020 09:50:00 -0700 Subject: [PATCH 063/420] Modified PR for reverse diagnostics server (#35850) Remove attempts to do too much cleanup on process shutdown, e.g., don't attempt to close handles or cancel overlapped IO --- .../debug/debug-pal/unix/diagnosticsipc.cpp | 287 +++++++++++-- .../debug/debug-pal/win/diagnosticsipc.cpp | 401 ++++++++++++++++-- src/coreclr/src/debug/inc/diagnosticsipc.h | 93 +++- src/coreclr/src/inc/clrconfigvalues.h | 2 +- src/coreclr/src/inc/corhlprpriv.h | 1 + src/coreclr/src/vm/CMakeLists.txt | 2 + src/coreclr/src/vm/diagnosticserver.cpp | 29 +- src/coreclr/src/vm/diagnosticserver.h | 1 - src/coreclr/src/vm/diagnosticsprotocol.h | 54 +++ src/coreclr/src/vm/ipcstreamfactory.cpp | 206 +++++++++ src/coreclr/src/vm/ipcstreamfactory.h | 103 +++++ .../src/tracing/eventpipe/common/Reverse.cs | 178 ++++++++ .../tracing/eventpipe/common/common.csproj | 1 + .../src/tracing/eventpipe/reverse/reverse.cs | 339 +++++++++++++++ .../tracing/eventpipe/reverse/reverse.csproj | 15 + 15 files changed, 1612 insertions(+), 100 deletions(-) create mode 100644 src/coreclr/src/vm/ipcstreamfactory.cpp create mode 100644 src/coreclr/src/vm/ipcstreamfactory.h create mode 100644 src/coreclr/tests/src/tracing/eventpipe/common/Reverse.cs create mode 100644 src/coreclr/tests/src/tracing/eventpipe/reverse/reverse.cs create mode 100644 src/coreclr/tests/src/tracing/eventpipe/reverse/reverse.csproj diff --git a/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp b/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp index e70f35884f510..046350317cde1 100644 --- a/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp +++ b/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp @@ -12,13 +12,20 @@ #include "diagnosticsipc.h" #include "processdescriptor.h" -IpcStream::DiagnosticsIpc::DiagnosticsIpc(const int serverSocket, sockaddr_un *const pServerAddress) : +#if __GNUC__ + #include +#else + #include +#endif // __GNUC__ + +IpcStream::DiagnosticsIpc::DiagnosticsIpc(const int serverSocket, sockaddr_un *const pServerAddress, ConnectionMode mode) : + mode(mode), _serverSocket(serverSocket), _pServerAddress(new sockaddr_un), - _isClosed(false) + _isClosed(false), + _isListening(false) { _ASSERTE(_pServerAddress != nullptr); - _ASSERTE(_serverSocket != -1); _ASSERTE(pServerAddress != nullptr); if (_pServerAddress == nullptr || pServerAddress == nullptr) @@ -32,24 +39,8 @@ IpcStream::DiagnosticsIpc::~DiagnosticsIpc() delete _pServerAddress; } -IpcStream::DiagnosticsIpc *IpcStream::DiagnosticsIpc::Create(const char *const pIpcName, ErrorCallback callback) +IpcStream::DiagnosticsIpc *IpcStream::DiagnosticsIpc::Create(const char *const pIpcName, ConnectionMode mode, ErrorCallback callback) { -#ifdef __APPLE__ - mode_t prev_mask = umask(~(S_IRUSR | S_IWUSR)); // This will set the default permission bit to 600 -#endif // __APPLE__ - - const int serverSocket = ::socket(AF_UNIX, SOCK_STREAM, 0); - if (serverSocket == -1) - { - if (callback != nullptr) - callback(strerror(errno), errno); -#ifdef __APPLE__ - umask(prev_mask); -#endif // __APPLE__ - _ASSERTE(!"Failed to create diagnostics IPC socket."); - return nullptr; - } - sockaddr_un serverAddress{}; serverAddress.sun_family = AF_UNIX; @@ -71,6 +62,24 @@ IpcStream::DiagnosticsIpc *IpcStream::DiagnosticsIpc::Create(const char *const p "socket"); } + if (mode == ConnectionMode::CLIENT) + return new IpcStream::DiagnosticsIpc(-1, &serverAddress, ConnectionMode::CLIENT); + +#ifdef __APPLE__ + mode_t prev_mask = umask(~(S_IRUSR | S_IWUSR)); // This will set the default permission bit to 600 +#endif // __APPLE__ + + const int serverSocket = ::socket(AF_UNIX, SOCK_STREAM, 0); + if (serverSocket == -1) + { + if (callback != nullptr) + callback(strerror(errno), errno); +#ifdef __APPLE__ + umask(prev_mask); +#endif // __APPLE__ + _ASSERTE(!"Failed to create diagnostics IPC socket."); + return nullptr; + } #ifndef __APPLE__ if (fchmod(serverSocket, S_IRUSR | S_IWUSR) == -1) @@ -99,33 +108,52 @@ IpcStream::DiagnosticsIpc *IpcStream::DiagnosticsIpc::Create(const char *const p return nullptr; } - const int fSuccessfulListen = ::listen(serverSocket, /* backlog */ 255); +#ifdef __APPLE__ + umask(prev_mask); +#endif // __APPLE__ + + return new IpcStream::DiagnosticsIpc(serverSocket, &serverAddress, mode); +} + +bool IpcStream::DiagnosticsIpc::Listen(ErrorCallback callback) +{ + _ASSERTE(mode == ConnectionMode::SERVER); + if (mode != ConnectionMode::SERVER) + { + if (callback != nullptr) + callback("Cannot call Listen on a client connection", -1); + return false; + } + + if (_isListening) + return true; + + const int fSuccessfulListen = ::listen(_serverSocket, /* backlog */ 255); if (fSuccessfulListen == -1) { if (callback != nullptr) callback(strerror(errno), errno); _ASSERTE(fSuccessfulListen != -1); - const int fSuccessUnlink = ::unlink(serverAddress.sun_path); + const int fSuccessUnlink = ::unlink(_pServerAddress->sun_path); _ASSERTE(fSuccessUnlink != -1); - const int fSuccessClose = ::close(serverSocket); + const int fSuccessClose = ::close(_serverSocket); _ASSERTE(fSuccessClose != -1); -#ifdef __APPLE__ - umask(prev_mask); -#endif // __APPLE__ - return nullptr; + return false; + } + else + { + _isListening = true; + return true; } - -#ifdef __APPLE__ - umask(prev_mask); -#endif // __APPLE__ - - return new IpcStream::DiagnosticsIpc(serverSocket, &serverAddress); } -IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) const +IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) { + _ASSERTE(mode == ConnectionMode::SERVER); + _ASSERTE(_isListening); + sockaddr_un from; socklen_t fromlen = sizeof(from); const int clientSocket = ::accept(_serverSocket, (sockaddr *)&from, &fromlen); @@ -136,10 +164,117 @@ IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) const return nullptr; } - return new IpcStream(clientSocket); + return new IpcStream(clientSocket, mode); +} + +IpcStream *IpcStream::DiagnosticsIpc::Connect(ErrorCallback callback) +{ + _ASSERTE(mode == ConnectionMode::CLIENT); + + sockaddr_un clientAddress{}; + clientAddress.sun_family = AF_UNIX; + const int clientSocket = ::socket(AF_UNIX, SOCK_STREAM, 0); + if (clientSocket == -1) + { + if (callback != nullptr) + callback(strerror(errno), errno); + return nullptr; + } + + // We don't expect this to block since this is a Unix Domain Socket. `connect` may block until the + // TCP handshake is complete for TCP/IP sockets, but UDS don't use TCP. `connect` will return even if + // the server hasn't called `accept`. + if (::connect(clientSocket, (struct sockaddr *)_pServerAddress, sizeof(*_pServerAddress)) < 0) + { + if (callback != nullptr) + callback(strerror(errno), errno); + return nullptr; + } + + return new IpcStream(clientSocket, ConnectionMode::CLIENT); } -void IpcStream::DiagnosticsIpc::Close(ErrorCallback callback) +int32_t IpcStream::DiagnosticsIpc::Poll(IpcPollHandle *rgIpcPollHandles, uint32_t nHandles, int32_t timeoutMs, ErrorCallback callback) +{ + // prepare the pollfd structs + pollfd *pollfds = new pollfd[nHandles]; + for (uint32_t i = 0; i < nHandles; i++) + { + rgIpcPollHandles[i].revents = 0; // ignore any values in revents + int fd = -1; + if (rgIpcPollHandles[i].pIpc != nullptr) + { + // SERVER + _ASSERTE(rgIpcPollHandles[i].pIpc->mode == ConnectionMode::SERVER); + fd = rgIpcPollHandles[i].pIpc->_serverSocket; + } + else + { + // CLIENT + _ASSERTE(rgIpcPollHandles[i].pStream != nullptr); + fd = rgIpcPollHandles[i].pStream->_clientSocket; + } + + pollfds[i].fd = fd; + pollfds[i].events = POLLIN; + } + + int retval = poll(pollfds, nHandles, timeoutMs); + + // Check results + if (retval < 0) + { + for (uint32_t i = 0; i < nHandles; i++) + { + if ((pollfds[i].revents & POLLERR) && callback != nullptr) + callback(strerror(errno), errno); + rgIpcPollHandles[i].revents = (uint8_t)PollEvents::ERR; + } + delete[] pollfds; + return -1; + } + else if (retval == 0) + { + // we timed out + delete[] pollfds; + return 0; + } + + for (uint32_t i = 0; i < nHandles; i++) + { + if (pollfds[i].revents != 0) + { + // error check FIRST + if (pollfds[i].revents & POLLHUP) + { + // check for hangup first because a closed socket + // will technically meet the requirements for POLLIN + // i.e., a call to recv/read won't block + rgIpcPollHandles[i].revents = (uint8_t)PollEvents::HANGUP; + delete[] pollfds; + return -1; + } + else if ((pollfds[i].revents & (POLLERR|POLLNVAL))) + { + if (callback != nullptr) + callback("Poll error", (uint32_t)pollfds[i].revents); + rgIpcPollHandles[i].revents = (uint8_t)PollEvents::ERR; + delete[] pollfds; + return -1; + } + else if (pollfds[i].revents & POLLIN) + { + rgIpcPollHandles[i].revents = (uint8_t)PollEvents::SIGNALED; + break; + } + } + } + + delete[] pollfds; + return 1; +} + +void IpcStream::DiagnosticsIpc::Close(bool isShutdown, ErrorCallback callback) { if (_isClosed) return; @@ -147,13 +282,19 @@ void IpcStream::DiagnosticsIpc::Close(ErrorCallback callback) if (_serverSocket != -1) { - if (::close(_serverSocket) == -1) + // only close the socket if not shutting down, let the OS handle it in that case + if (!isShutdown && ::close(_serverSocket) == -1) { if (callback != nullptr) callback(strerror(errno), errno); _ASSERTE(!"Failed to close unix domain socket."); } + // N.B. - it is safe to unlink the unix domain socket file while the server + // is still alive: + // "The usual UNIX close-behind semantics apply; the socket can be unlinked + // at any time and will be finally removed from the file system when the last + // reference to it is closed." - unix(7) man page Unlink(callback); } } @@ -172,6 +313,11 @@ void IpcStream::DiagnosticsIpc::Unlink(ErrorCallback callback) } IpcStream::~IpcStream() +{ + Close(); +} + +void IpcStream::Close(ErrorCallback) { if (_clientSocket != -1) { @@ -179,38 +325,89 @@ IpcStream::~IpcStream() const int fSuccessClose = ::close(_clientSocket); _ASSERTE(fSuccessClose != -1); + _clientSocket = -1; } } -bool IpcStream::Read(void *lpBuffer, const uint32_t nBytesToRead, uint32_t &nBytesRead) const +bool IpcStream::Read(void *lpBuffer, const uint32_t nBytesToRead, uint32_t &nBytesRead, const int32_t timeoutMs) { _ASSERTE(lpBuffer != nullptr); - const ssize_t ssize = ::recv(_clientSocket, lpBuffer, nBytesToRead, 0); - const bool fSuccess = ssize != -1; + if (timeoutMs != InfiniteTimeout) + { + pollfd pfd; + pfd.fd = _clientSocket; + pfd.events = POLLIN; + int retval = poll(&pfd, 1, timeoutMs); + if (retval <= 0 || pfd.revents != POLLIN) + { + // timeout or error + return false; + } + // else fallthrough + } + + uint8_t *lpBufferCursor = (uint8_t*)lpBuffer; + ssize_t currentBytesRead = 0; + ssize_t totalBytesRead = 0; + bool fSuccess = true; + while (fSuccess && nBytesToRead - totalBytesRead > 0) + { + currentBytesRead = ::recv(_clientSocket, lpBufferCursor, nBytesToRead - totalBytesRead, 0); + fSuccess = currentBytesRead != 0; + if (!fSuccess) + break; + totalBytesRead += currentBytesRead; + lpBufferCursor += currentBytesRead; + } if (!fSuccess) { // TODO: Add error handling. } - nBytesRead = static_cast(ssize); + nBytesRead = static_cast(totalBytesRead); return fSuccess; } -bool IpcStream::Write(const void *lpBuffer, const uint32_t nBytesToWrite, uint32_t &nBytesWritten) const +bool IpcStream::Write(const void *lpBuffer, const uint32_t nBytesToWrite, uint32_t &nBytesWritten, const int32_t timeoutMs) { _ASSERTE(lpBuffer != nullptr); - const ssize_t ssize = ::send(_clientSocket, lpBuffer, nBytesToWrite, 0); - const bool fSuccess = ssize != -1; + if (timeoutMs != InfiniteTimeout) + { + pollfd pfd; + pfd.fd = _clientSocket; + pfd.events = POLLOUT; + int retval = poll(&pfd, 1, timeoutMs); + if (retval <= 0 || pfd.revents != POLLOUT) + { + // timeout or error + return false; + } + // else fallthrough + } + + uint8_t *lpBufferCursor = (uint8_t*)lpBuffer; + ssize_t currentBytesWritten = 0; + ssize_t totalBytesWritten = 0; + bool fSuccess = true; + while (fSuccess && nBytesToWrite - totalBytesWritten > 0) + { + currentBytesWritten = ::send(_clientSocket, lpBufferCursor, nBytesToWrite - totalBytesWritten, 0); + fSuccess = currentBytesWritten != -1; + if (!fSuccess) + break; + lpBufferCursor += currentBytesWritten; + totalBytesWritten += currentBytesWritten; + } if (!fSuccess) { // TODO: Add error handling. } - nBytesWritten = static_cast(ssize); + nBytesWritten = static_cast(totalBytesWritten); return fSuccess; } diff --git a/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp b/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp index 36c11857cabe9..f7b41b92fc1e6 100644 --- a/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp +++ b/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp @@ -7,9 +7,14 @@ #include #include "diagnosticsipc.h" -IpcStream::DiagnosticsIpc::DiagnosticsIpc(const char(&namedPipeName)[MaxNamedPipeNameLength]) +#define _ASSERTE assert + +IpcStream::DiagnosticsIpc::DiagnosticsIpc(const char(&namedPipeName)[MaxNamedPipeNameLength], ConnectionMode mode) : + mode(mode), + _isListening(false) { memcpy(_pNamedPipeName, namedPipeName, sizeof(_pNamedPipeName)); + memset(&_oOverlap, 0, sizeof(OVERLAPPED)); } IpcStream::DiagnosticsIpc::~DiagnosticsIpc() @@ -17,7 +22,7 @@ IpcStream::DiagnosticsIpc::~DiagnosticsIpc() Close(); } -IpcStream::DiagnosticsIpc *IpcStream::DiagnosticsIpc::Create(const char *const pIpcName, ErrorCallback callback) +IpcStream::DiagnosticsIpc *IpcStream::DiagnosticsIpc::Create(const char *const pIpcName, ConnectionMode mode, ErrorCallback callback) { char namedPipeName[MaxNamedPipeNameLength]{}; int nCharactersWritten = -1; @@ -43,20 +48,32 @@ IpcStream::DiagnosticsIpc *IpcStream::DiagnosticsIpc::Create(const char *const p { if (callback != nullptr) callback("Failed to generate the named pipe name", nCharactersWritten); - assert(nCharactersWritten != -1); + _ASSERTE(nCharactersWritten != -1); return nullptr; } - return new IpcStream::DiagnosticsIpc(namedPipeName); + return new IpcStream::DiagnosticsIpc(namedPipeName, mode); } -IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) const +bool IpcStream::DiagnosticsIpc::Listen(ErrorCallback callback) { + _ASSERTE(mode == ConnectionMode::SERVER); + if (mode != ConnectionMode::SERVER) + { + if (callback != nullptr) + callback("Cannot call Listen on a client connection", -1); + return false; + } + + if (_isListening) + return true; + const uint32_t nInBufferSize = 16 * 1024; const uint32_t nOutBufferSize = 16 * 1024; - HANDLE hPipe = ::CreateNamedPipeA( + _hPipe = ::CreateNamedPipeA( _pNamedPipeName, // pipe name - PIPE_ACCESS_DUPLEX, // read/write access + PIPE_ACCESS_DUPLEX | // read/write access + FILE_FLAG_OVERLAPPED, // async listening PIPE_TYPE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, // message type pipe, message-read and blocking mode PIPE_UNLIMITED_INSTANCES, // max. instances nOutBufferSize, // output buffer size @@ -64,19 +81,32 @@ IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) const 0, // default client time-out NULL); // default security attribute - if (hPipe == INVALID_HANDLE_VALUE) + if (_hPipe == INVALID_HANDLE_VALUE) { if (callback != nullptr) callback("Failed to create an instance of a named pipe.", ::GetLastError()); - return nullptr; + return false; } - const BOOL fSuccess = ::ConnectNamedPipe(hPipe, NULL) != 0; + HANDLE hOverlapEvent = CreateEvent(NULL, true, false, NULL); + if (hOverlapEvent == NULL) + { + if (callback != nullptr) + callback("Failed to create overlap event", ::GetLastError()); + ::CloseHandle(_hPipe); + _hPipe = INVALID_HANDLE_VALUE; + return false; + } + _oOverlap.hEvent = hOverlapEvent; + + BOOL fSuccess = ::ConnectNamedPipe(_hPipe, &_oOverlap) != 0; if (!fSuccess) { const DWORD errorCode = ::GetLastError(); switch (errorCode) { + case ERROR_IO_PENDING: + // There was a pending connection that can be waited on (will happen in poll) case ERROR_PIPE_CONNECTED: // Occurs when a client connects before the function is called. // In this case, there is a connection between client and @@ -86,46 +116,333 @@ IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) const default: if (callback != nullptr) callback("A client process failed to connect.", errorCode); - ::CloseHandle(hPipe); - return nullptr; + ::CloseHandle(_hPipe); + _hPipe = INVALID_HANDLE_VALUE; + ::CloseHandle(_oOverlap.hEvent); + _oOverlap.hEvent = INVALID_HANDLE_VALUE; + return false; + } + } + + _isListening = true; + return true; +} + +IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) +{ + _ASSERTE(_isListening); + _ASSERTE(mode == ConnectionMode::SERVER); + + DWORD dwDummy = 0; + bool fSuccess = GetOverlappedResult( + _hPipe, // handle + &_oOverlap, // overlapped + &dwDummy, // throw-away dword + true); // wait till event signals + + if (!fSuccess) + { + if (callback != nullptr) + callback("Failed to GetOverlappedResults for NamedPipe server", ::GetLastError()); + return nullptr; + } + + // create new IpcStream using handle and reset the Server object so it can listen again + IpcStream *pStream = new IpcStream(_hPipe, ConnectionMode::SERVER); + + // reset the server + _hPipe = INVALID_HANDLE_VALUE; + _isListening = false; + ::CloseHandle(_oOverlap.hEvent); + memset(&_oOverlap, 0, sizeof(OVERLAPPED)); // clear the overlapped objects state + fSuccess = Listen(callback); + if (!fSuccess) + { + delete pStream; + return nullptr; + } + + return pStream; +} + +IpcStream *IpcStream::DiagnosticsIpc::Connect(ErrorCallback callback) +{ + _ASSERTE(mode == ConnectionMode::CLIENT); + if (mode != ConnectionMode::CLIENT) + { + if (callback != nullptr) + callback("Cannot call connect on a server connection", 0); + return nullptr; + } + + HANDLE hPipe = ::CreateFileA( + _pNamedPipeName, // pipe name + PIPE_ACCESS_DUPLEX, // read/write access + 0, // no sharing + NULL, // default security attributes + OPEN_EXISTING, // opens existing pipe + FILE_FLAG_OVERLAPPED, // Overlapped + NULL); // no template file + + if (hPipe == INVALID_HANDLE_VALUE) + { + if (callback != nullptr) + callback("Failed to connect to named pipe.", ::GetLastError()); + return nullptr; + } + + return new IpcStream(hPipe, mode); +} + +void IpcStream::DiagnosticsIpc::Close(bool isShutdown, ErrorCallback) +{ + // don't attempt cleanup on shutdown and let the OS handle it + if (isShutdown) + return; + + if (_hPipe != INVALID_HANDLE_VALUE) + { + if (mode == DiagnosticsIpc::ConnectionMode::SERVER) + { + const BOOL fSuccessDisconnectNamedPipe = ::DisconnectNamedPipe(_hPipe); + _ASSERTE(fSuccessDisconnectNamedPipe != 0); } + + const BOOL fSuccessCloseHandle = ::CloseHandle(_hPipe); + _ASSERTE(fSuccessCloseHandle != 0); } - return new IpcStream(hPipe); + if (_oOverlap.hEvent != INVALID_HANDLE_VALUE) + { + ::CloseHandle(_oOverlap.hEvent); + } } -void IpcStream::DiagnosticsIpc::Close(ErrorCallback) +IpcStream::IpcStream(HANDLE hPipe, DiagnosticsIpc::ConnectionMode mode) : + _hPipe(hPipe), + _mode(mode) { + memset(&_oOverlap, 0, sizeof(OVERLAPPED)); + _oOverlap.hEvent = CreateEvent(NULL, true, false, NULL); } IpcStream::~IpcStream() +{ + Close(); +} + +void IpcStream::Close(ErrorCallback) { if (_hPipe != INVALID_HANDLE_VALUE) { Flush(); - const BOOL fSuccessDisconnectNamedPipe = ::DisconnectNamedPipe(_hPipe); - assert(fSuccessDisconnectNamedPipe != 0); + if (_mode == DiagnosticsIpc::ConnectionMode::SERVER) + { + const BOOL fSuccessDisconnectNamedPipe = ::DisconnectNamedPipe(_hPipe); + _ASSERTE(fSuccessDisconnectNamedPipe != 0); + } const BOOL fSuccessCloseHandle = ::CloseHandle(_hPipe); - assert(fSuccessCloseHandle != 0); + _ASSERTE(fSuccessCloseHandle != 0); + } + + if (_oOverlap.hEvent != INVALID_HANDLE_VALUE) + { + ::CloseHandle(_oOverlap.hEvent); + } +} + +int32_t IpcStream::DiagnosticsIpc::Poll(IpcPollHandle *rgIpcPollHandles, uint32_t nHandles, int32_t timeoutMs, ErrorCallback callback) +{ + // load up an array of handles + HANDLE *pHandles = new HANDLE[nHandles]; + for (uint32_t i = 0; i < nHandles; i++) + { + rgIpcPollHandles[i].revents = 0; // ignore any inputs on revents + if (rgIpcPollHandles[i].pIpc != nullptr) + { + // SERVER + _ASSERTE(rgIpcPollHandles[i].pIpc->mode == DiagnosticsIpc::ConnectionMode::SERVER); + pHandles[i] = rgIpcPollHandles[i].pIpc->_oOverlap.hEvent; + } + else + { + // CLIENT + bool fSuccess = false; + DWORD dwDummy = 0; + if (!rgIpcPollHandles[i].pStream->_isTestReading) + { + // check for data by doing an asynchronous 0 byte read. + // This will signal if the pipe closes (hangup) or the server + // sends new data + fSuccess = ::ReadFile( + rgIpcPollHandles[i].pStream->_hPipe, // handle + nullptr, // null buffer + 0, // read 0 bytes + &dwDummy, // dummy variable + &rgIpcPollHandles[i].pStream->_oOverlap); // overlap object to use + rgIpcPollHandles[i].pStream->_isTestReading = true; + if (!fSuccess) + { + DWORD error = ::GetLastError(); + switch (error) + { + case ERROR_IO_PENDING: + pHandles[i] = rgIpcPollHandles[i].pStream->_oOverlap.hEvent; + break; + case ERROR_PIPE_NOT_CONNECTED: + // hangup + rgIpcPollHandles[i].revents = (uint8_t)PollEvents::HANGUP; + delete[] pHandles; + return -1; + default: + if (callback != nullptr) + callback("0 byte async read on client connection failed", error); + delete[] pHandles; + return -1; + } + } + } + else + { + pHandles[i] = rgIpcPollHandles[i].pStream->_oOverlap.hEvent; + } + } + } + + // call wait for multiple obj + DWORD dwWait = WaitForMultipleObjects( + nHandles, // count + pHandles, // handles + false, // Don't wait-all + timeoutMs); + + if (dwWait == WAIT_TIMEOUT) + { + // we timed out + delete[] pHandles; + return 0; + } + + if (dwWait == WAIT_FAILED) + { + // we errored + if (callback != nullptr) + callback("WaitForMultipleObjects failed", ::GetLastError()); + delete[] pHandles; + return -1; + } + + // determine which of the streams signaled + DWORD index = dwWait - WAIT_OBJECT_0; + // error check the index + if (index < 0 || index > (nHandles - 1)) + { + // check if we abandoned something + DWORD abandonedIndex = dwWait - WAIT_ABANDONED_0; + if (abandonedIndex > 0 || abandonedIndex < (nHandles - 1)) + { + rgIpcPollHandles[abandonedIndex].revents = (uint8_t)IpcStream::DiagnosticsIpc::PollEvents::HANGUP; + delete[] pHandles; + return -1; + } + else + { + if (callback != nullptr) + callback("WaitForMultipleObjects failed", ::GetLastError()); + delete[] pHandles; + return -1; + } } + + // Set revents depending on what signaled the stream + if (rgIpcPollHandles[index].pIpc == nullptr) + { + // CLIENT + // check if the connection got hung up + DWORD dwDummy = 0; + bool fSuccess = GetOverlappedResult(rgIpcPollHandles[index].pStream->_hPipe, + &rgIpcPollHandles[index].pStream->_oOverlap, + &dwDummy, + true); + rgIpcPollHandles[index].pStream->_isTestReading = false; + if (!fSuccess) + { + DWORD error = ::GetLastError(); + if (error == ERROR_PIPE_NOT_CONNECTED) + rgIpcPollHandles[index].revents = (uint8_t)IpcStream::DiagnosticsIpc::PollEvents::HANGUP; + else + { + if (callback != nullptr) + callback("Client connection error", -1); + rgIpcPollHandles[index].revents = (uint8_t)IpcStream::DiagnosticsIpc::PollEvents::ERR; + delete[] pHandles; + return -1; + } + } + else + { + rgIpcPollHandles[index].revents = (uint8_t)IpcStream::DiagnosticsIpc::PollEvents::SIGNALED; + } + } + else + { + // SERVER + rgIpcPollHandles[index].revents = (uint8_t)IpcStream::DiagnosticsIpc::PollEvents::SIGNALED; + } + + delete[] pHandles; + return 1; } -bool IpcStream::Read(void *lpBuffer, const uint32_t nBytesToRead, uint32_t &nBytesRead) const +bool IpcStream::Read(void *lpBuffer, const uint32_t nBytesToRead, uint32_t &nBytesRead, const int32_t timeoutMs) { - assert(lpBuffer != nullptr); + _ASSERTE(lpBuffer != nullptr); DWORD nNumberOfBytesRead = 0; - const bool fSuccess = ::ReadFile( + LPOVERLAPPED overlap = &_oOverlap; + bool fSuccess = ::ReadFile( _hPipe, // handle to pipe lpBuffer, // buffer to receive data nBytesToRead, // size of buffer &nNumberOfBytesRead, // number of bytes read - NULL) != 0; // not overlapped I/O + overlap) != 0; // overlapped I/O if (!fSuccess) { + if (timeoutMs == InfiniteTimeout) + { + fSuccess = GetOverlappedResult(_hPipe, + overlap, + &nNumberOfBytesRead, + true) != 0; + } + else + { + DWORD dwError = GetLastError(); + if (dwError == ERROR_IO_PENDING) + { + DWORD dwWait = WaitForSingleObject(_oOverlap.hEvent, (DWORD)timeoutMs); + if (dwWait == WAIT_OBJECT_0) + { + // get the result + fSuccess = GetOverlappedResult(_hPipe, + overlap, + &nNumberOfBytesRead, + true) != 0; + } + else + { + // cancel IO and ensure the cancel happened + if (CancelIo(_hPipe)) + { + // check if the async write beat the cancellation + fSuccess = GetOverlappedResult(_hPipe, overlap, &nNumberOfBytesRead, true) != 0; + } + } + } + } // TODO: Add error handling. } @@ -133,20 +450,54 @@ bool IpcStream::Read(void *lpBuffer, const uint32_t nBytesToRead, uint32_t &nByt return fSuccess; } -bool IpcStream::Write(const void *lpBuffer, const uint32_t nBytesToWrite, uint32_t &nBytesWritten) const +bool IpcStream::Write(const void *lpBuffer, const uint32_t nBytesToWrite, uint32_t &nBytesWritten, const int32_t timeoutMs) { - assert(lpBuffer != nullptr); + _ASSERTE(lpBuffer != nullptr); DWORD nNumberOfBytesWritten = 0; - const bool fSuccess = ::WriteFile( + LPOVERLAPPED overlap = &_oOverlap; + bool fSuccess = ::WriteFile( _hPipe, // handle to pipe lpBuffer, // buffer to write from nBytesToWrite, // number of bytes to write &nNumberOfBytesWritten, // number of bytes written - NULL) != 0; // not overlapped I/O + overlap) != 0; // overlapped I/O if (!fSuccess) { + DWORD dwError = GetLastError(); + if (dwError == ERROR_IO_PENDING) + { + if (timeoutMs == InfiniteTimeout) + { + // if we're waiting infinitely, don't bother with extra kernel call + fSuccess = GetOverlappedResult(_hPipe, + overlap, + &nNumberOfBytesWritten, + true) != 0; + } + else + { + DWORD dwWait = WaitForSingleObject(_oOverlap.hEvent, (DWORD)timeoutMs); + if (dwWait == WAIT_OBJECT_0) + { + // get the result + fSuccess = GetOverlappedResult(_hPipe, + overlap, + &nNumberOfBytesWritten, + true) != 0; + } + else + { + // cancel IO and ensure the cancel happened + if (CancelIo(_hPipe)) + { + // check if the async write beat the cancellation + fSuccess = GetOverlappedResult(_hPipe, overlap, &nNumberOfBytesWritten, true) != 0; + } + } + } + } // TODO: Add error handling. } diff --git a/src/coreclr/src/debug/inc/diagnosticsipc.h b/src/coreclr/src/debug/inc/diagnosticsipc.h index eabea6c3ceaea..225299c2b8992 100644 --- a/src/coreclr/src/debug/inc/diagnosticsipc.h +++ b/src/coreclr/src/debug/inc/diagnosticsipc.h @@ -18,24 +18,80 @@ typedef void (*ErrorCallback)(const char *szMessage, uint32_t code); class IpcStream final { public: + static constexpr int32_t InfiniteTimeout = -1; ~IpcStream(); - bool Read(void *lpBuffer, const uint32_t nBytesToRead, uint32_t &nBytesRead) const; - bool Write(const void *lpBuffer, const uint32_t nBytesToWrite, uint32_t &nBytesWritten) const; + bool Read(void *lpBuffer, const uint32_t nBytesToRead, uint32_t &nBytesRead, const int32_t timeoutMs = IpcStream::InfiniteTimeout); + bool Write(const void *lpBuffer, const uint32_t nBytesToWrite, uint32_t &nBytesWritten, const int32_t timeoutMs = IpcStream::InfiniteTimeout); bool Flush() const; + void Close(ErrorCallback callback = nullptr); class DiagnosticsIpc final { public: + enum ConnectionMode + { + CLIENT, + SERVER + }; + + enum class PollEvents : uint8_t + { + TIMEOUT = 0x00, // implies timeout + SIGNALED = 0x01, // ready for use + HANGUP = 0x02, // connection remotely closed + ERR = 0x04 // other error + }; + + // The bookeeping struct used for polling on server and client structs + struct IpcPollHandle + { + // Only one of these will be non-null, treat as a union + DiagnosticsIpc *pIpc; + IpcStream *pStream; + + // contains some set of PollEvents + // will be set by Poll + // Any values here are ignored by Poll + uint8_t revents; + + // a cookie assignable by upstream users for additional bookkeeping + void *pUserData; + }; + + // Poll + // Parameters: + // - IpcPollHandle * rgpIpcPollHandles: Array of IpcPollHandles to poll + // - uint32_t nHandles: The number of handles to poll + // - int32_t timeoutMs: The timeout in milliseconds for the poll (-1 == infinite) + // Returns: + // int32_t: -1 on error, 0 on timeout, >0 on successful poll + // Remarks: + // Check the events returned in revents for each IpcPollHandle to find the signaled handle. + // Signaled DiagnosticsIpcs can call Accept() without blocking. + // Signaled IpcStreams can call Read(...) without blocking. + // The caller is responsible for cleaning up "hung up" connections. + static int32_t Poll(IpcPollHandle *rgIpcPollHandles, uint32_t nHandles, int32_t timeoutMs, ErrorCallback callback = nullptr); + + ConnectionMode mode; + ~DiagnosticsIpc(); - //! Creates an IPC object - static DiagnosticsIpc *Create(const char *const pIpcName, ErrorCallback callback = nullptr); + // Creates an IPC object + static DiagnosticsIpc *Create(const char *const pIpcName, ConnectionMode mode, ErrorCallback callback = nullptr); + + // puts the DiagnosticsIpc into Listening Mode + // Re-entrant safe + bool Listen(ErrorCallback callback = nullptr); + + // produces a connected stream from a server-mode DiagnosticsIpc. Blocks until a connection is available. + IpcStream *Accept(ErrorCallback callback = nullptr); - //! Enables the underlaying IPC implementation to accept connection. - IpcStream *Accept(ErrorCallback callback = nullptr) const; + // Connect to a server and returns a connected stream + IpcStream *Connect(ErrorCallback callback = nullptr); - //! Closes an open IPC. - void Close(ErrorCallback callback = nullptr); + // Closes an open IPC. + // Only attempts minimal cleanup if isShutdown==true, i.e., unlinks Unix Domain Socket on Linux, no-op on Windows + void Close(bool isShutdown = false, ErrorCallback callback = nullptr); private: @@ -44,18 +100,22 @@ class IpcStream final sockaddr_un *const _pServerAddress; bool _isClosed; - DiagnosticsIpc(const int serverSocket, sockaddr_un *const pServerAddress); + DiagnosticsIpc(const int serverSocket, sockaddr_un *const pServerAddress, ConnectionMode mode = ConnectionMode::SERVER); - //! Used to unlink the socket so it can be removed from the filesystem - //! when the last reference to it is closed. + // Used to unlink the socket so it can be removed from the filesystem + // when the last reference to it is closed. void Unlink(ErrorCallback callback = nullptr); #else static const uint32_t MaxNamedPipeNameLength = 256; char _pNamedPipeName[MaxNamedPipeNameLength]; // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createnamedpipea + HANDLE _hPipe = INVALID_HANDLE_VALUE; + OVERLAPPED _oOverlap = {}; - DiagnosticsIpc(const char(&namedPipeName)[MaxNamedPipeNameLength]); + DiagnosticsIpc(const char(&namedPipeName)[MaxNamedPipeNameLength], ConnectionMode mode = ConnectionMode::SERVER); #endif /* TARGET_UNIX */ + bool _isListening; + DiagnosticsIpc() = delete; DiagnosticsIpc(const DiagnosticsIpc &src) = delete; DiagnosticsIpc(DiagnosticsIpc &&src) = delete; @@ -66,12 +126,17 @@ class IpcStream final private: #ifdef TARGET_UNIX int _clientSocket = -1; - IpcStream(int clientSocket) : _clientSocket(clientSocket) {} + IpcStream(int clientSocket, int serverSocket, DiagnosticsIpc::ConnectionMode mode = DiagnosticsIpc::ConnectionMode::SERVER) + : _clientSocket(clientSocket), _mode(mode) {} #else HANDLE _hPipe = INVALID_HANDLE_VALUE; - IpcStream(HANDLE hPipe) : _hPipe(hPipe) {} + OVERLAPPED _oOverlap = {}; + BOOL _isTestReading = false; // used to check whether we are already doing a 0-byte read to test for data + IpcStream(HANDLE hPipe, DiagnosticsIpc::ConnectionMode mode = DiagnosticsIpc::ConnectionMode::SERVER); #endif /* TARGET_UNIX */ + DiagnosticsIpc::ConnectionMode _mode; + IpcStream() = delete; IpcStream(const IpcStream &src) = delete; IpcStream(IpcStream &&src) = delete; diff --git a/src/coreclr/src/inc/clrconfigvalues.h b/src/coreclr/src/inc/clrconfigvalues.h index f4cf1d192905c..bd1b8d18d4958 100644 --- a/src/coreclr/src/inc/clrconfigvalues.h +++ b/src/coreclr/src/inc/clrconfigvalues.h @@ -705,7 +705,7 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeProcNumbers, W("EventPipeProcNumbers" // // Diagnostics Server // -RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_DOTNET_DiagnosticsServerAddress, W("DOTNET_DiagnosticsServerAddress"), "The full path including filename for the OS transport (NamedPipe on Windows; Unix Domain Socket on Linux) to be used by the Diagnostics Server", CLRConfig::DontPrependCOMPlus_); +RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_DOTNET_DiagnosticsMonitorAddress, W("DOTNET_DiagnosticsMonitorAddress"), "NamedPipe path without '\\\\.\\pipe\\' on Windows; Full path of Unix Domain Socket on Linux/Unix. Used for Diagnostics Monitoring Agents.", CLRConfig::DontPrependCOMPlus_); // // LTTng diff --git a/src/coreclr/src/inc/corhlprpriv.h b/src/coreclr/src/inc/corhlprpriv.h index 8fcafd08d93c3..7b9e5f1f88567 100644 --- a/src/coreclr/src/inc/corhlprpriv.h +++ b/src/coreclr/src/inc/corhlprpriv.h @@ -507,6 +507,7 @@ class CQuickArrayList : protected CQuickArray using CQuickArray::AllocNoThrow; using CQuickArray::ReSizeNoThrow; using CQuickArray::MaxSize; + using CQuickArray::Ptr; CQuickArrayList() : m_curSize(0) diff --git a/src/coreclr/src/vm/CMakeLists.txt b/src/coreclr/src/vm/CMakeLists.txt index 67a168993b28c..e11e58d777251 100644 --- a/src/coreclr/src/vm/CMakeLists.txt +++ b/src/coreclr/src/vm/CMakeLists.txt @@ -364,6 +364,7 @@ set(VM_SOURCES_WKS interoputil.cpp interpreter.cpp invokeutil.cpp + ipcstreamfactory.cpp jithelpers.cpp managedmdimport.cpp marshalnative.cpp @@ -483,6 +484,7 @@ set(VM_HEADERS_WKS interpreter.h interpreter.hpp invokeutil.h + ipcstreamfactory.h managedmdimport.hpp marshalnative.h methodtablebuilder.h diff --git a/src/coreclr/src/vm/diagnosticserver.cpp b/src/coreclr/src/vm/diagnosticserver.cpp index 9fbde4a797da9..9879c7b1e35dc 100644 --- a/src/coreclr/src/vm/diagnosticserver.cpp +++ b/src/coreclr/src/vm/diagnosticserver.cpp @@ -4,6 +4,7 @@ #include "common.h" #include "diagnosticserver.h" +#include "ipcstreamfactory.h" #include "eventpipeprotocolhelper.h" #include "dumpdiagnosticprotocolhelper.h" #include "profilerdiagnosticprotocolhelper.h" @@ -19,7 +20,6 @@ #ifdef FEATURE_PERFTRACING -IpcStream::DiagnosticsIpc *DiagnosticServer::s_pIpc = nullptr; Volatile DiagnosticServer::s_shuttingDown(false); DWORD WINAPI DiagnosticServer::DiagnosticsServerThread(LPVOID) @@ -29,11 +29,11 @@ DWORD WINAPI DiagnosticServer::DiagnosticsServerThread(LPVOID) NOTHROW; GC_TRIGGERS; MODE_PREEMPTIVE; - PRECONDITION(s_pIpc != nullptr); + PRECONDITION(IpcStreamFactory::HasActiveConnections()); } CONTRACTL_END; - if (s_pIpc == nullptr) + if (!IpcStreamFactory::HasActiveConnections()) { STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ERROR, "Diagnostics IPC listener was undefined\n"); return 1; @@ -47,8 +47,7 @@ DWORD WINAPI DiagnosticServer::DiagnosticsServerThread(LPVOID) { while (!s_shuttingDown) { - // FIXME: Ideally this would be something like a std::shared_ptr - IpcStream *pStream = s_pIpc->Accept(LoggingCallback); + IpcStream *pStream = IpcStreamFactory::GetNextAvailableStream(LoggingCallback); if (pStream == nullptr) continue; @@ -134,7 +133,7 @@ bool DiagnosticServer::Initialize() }; NewArrayHolder address = nullptr; - CLRConfigStringHolder wAddress = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DOTNET_DiagnosticsServerAddress); + CLRConfigStringHolder wAddress = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DOTNET_DiagnosticsMonitorAddress); int nCharactersWritten = 0; if (wAddress != nullptr) { @@ -145,12 +144,14 @@ bool DiagnosticServer::Initialize() nCharactersWritten = WideCharToMultiByte(CP_UTF8, 0, wAddress, -1, address, nCharactersWritten, NULL, NULL); assert(nCharactersWritten != 0); } + + // Create the client mode connection + fSuccess &= IpcStreamFactory::CreateClient(address, ErrorCallback); } - // TODO: Should we handle/assert that (s_pIpc == nullptr)? - s_pIpc = IpcStream::DiagnosticsIpc::Create(address, ErrorCallback); + fSuccess &= IpcStreamFactory::CreateServer(nullptr, ErrorCallback); - if (s_pIpc != nullptr) + if (IpcStreamFactory::HasActiveConnections()) { #ifdef FEATURE_AUTO_TRACE auto_trace_init(); @@ -161,14 +162,13 @@ bool DiagnosticServer::Initialize() nullptr, // no security attribute 0, // default stack size DiagnosticsServerThread, // thread proc - (LPVOID)s_pIpc, // thread parameter + nullptr, // thread parameter 0, // not suspended &dwThreadId); // returns thread ID if (hServerThread == NULL) { - delete s_pIpc; - s_pIpc = nullptr; + IpcStreamFactory::CloseConnections(); // Failed to create IPC thread. STRESS_LOG1( @@ -213,7 +213,7 @@ bool DiagnosticServer::Shutdown() EX_TRY { - if (s_pIpc != nullptr) + if (IpcStreamFactory::HasActiveConnections()) { auto ErrorCallback = [](const char *szMessage, uint32_t code) { STRESS_LOG2( @@ -223,7 +223,8 @@ bool DiagnosticServer::Shutdown() code, // data1 szMessage); // data2 }; - s_pIpc->Close(ErrorCallback); // This will break the accept waiting for client connection. + + IpcStreamFactory::Shutdown(ErrorCallback); } fSuccess = true; } diff --git a/src/coreclr/src/vm/diagnosticserver.h b/src/coreclr/src/vm/diagnosticserver.h index 393fbda0bd9ae..a5b8f07f7847b 100644 --- a/src/coreclr/src/vm/diagnosticserver.h +++ b/src/coreclr/src/vm/diagnosticserver.h @@ -46,7 +46,6 @@ class DiagnosticServer final static DWORD WINAPI DiagnosticsServerThread(LPVOID lpThreadParameter); private: - static IpcStream::DiagnosticsIpc *s_pIpc; static Volatile s_shuttingDown; }; diff --git a/src/coreclr/src/vm/diagnosticsprotocol.h b/src/coreclr/src/vm/diagnosticsprotocol.h index bbc622a6411a3..e6bd3d4e89a8d 100644 --- a/src/coreclr/src/vm/diagnosticsprotocol.h +++ b/src/coreclr/src/vm/diagnosticsprotocol.h @@ -103,6 +103,60 @@ namespace DiagnosticsIpc const MagicVersion DotnetIpcMagic_V1 = { "DOTNET_IPC_V1" }; + /** + * ==ADVERTISE PROTOCOL== + * Before standard IPC Protocol communication can occur on a client-mode connection + * the runtime must advertise itself over the connection. ALL SUBSEQUENT COMMUNICATION + * IS STANDARD DIAGNOSTICS IPC PROTOCOL COMMUNICATION. + * + * See spec in: dotnet/diagnostics@documentation/design-docs/ipc-spec.md + * + * The flow for Advertise is a one-way burst of 24 bytes consisting of + * 8 bytes - "ADVR_V1\0" (ASCII chars + null byte) + * 16 bytes - random 128 bit number cookie (little-endian) + * 8 bytes - PID (little-endian) + * 2 bytes - unused 2 byte field for futureproofing + */ + + const uint8_t AdvertiseMagic_V1[8] = "ADVR_V1"; + + const uint32_t AdvertiseSize = 34; + + static GUID AdvertiseCookie_V1 = GUID_NULL; + + inline GUID GetAdvertiseCookie_V1() + { + if (AdvertiseCookie_V1 == GUID_NULL) + { + CoCreateGuid(&AdvertiseCookie_V1); + } + + return AdvertiseCookie_V1; + } + + inline bool SendIpcAdvertise_V1(IpcStream *pStream) + { + uint8_t advertiseBuffer[DiagnosticsIpc::AdvertiseSize]; + GUID cookie = GetAdvertiseCookie_V1(); + uint64_t pid = GetCurrentProcessId(); + + uint64_t *buffer = (uint64_t*)advertiseBuffer; + buffer[0] = *(uint64_t*)AdvertiseMagic_V1; + buffer[1] = (((uint64_t)VAL32(cookie.Data1) << 32) | ((uint64_t)VAL16(cookie.Data2) << 16) | VAL16((uint64_t)cookie.Data3)); + buffer[2] = *(uint64_t*)cookie.Data4; + buffer[3] = VAL64(pid); + + // zero out unused field + ((uint16_t*)advertiseBuffer)[16] = VAL16(0); + + uint32_t nBytesWritten = 0; + if (!pStream->Write(advertiseBuffer, sizeof(advertiseBuffer), nBytesWritten, 100 /* ms */)) + return false; + + _ASSERTE(nBytesWritten == sizeof(advertiseBuffer)); + return nBytesWritten == sizeof(advertiseBuffer); + } + const IpcHeader GenericSuccessHeader = { { DotnetIpcMagic_V1 }, diff --git a/src/coreclr/src/vm/ipcstreamfactory.cpp b/src/coreclr/src/vm/ipcstreamfactory.cpp new file mode 100644 index 0000000000000..33d36e93de5ba --- /dev/null +++ b/src/coreclr/src/vm/ipcstreamfactory.cpp @@ -0,0 +1,206 @@ +// 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. + +#include "common.h" +#include "diagnosticsprotocol.h" +#include "ipcstreamfactory.h" + +#ifdef FEATURE_PERFTRACING + +CQuickArrayList IpcStreamFactory::s_rgpConnectionStates = CQuickArrayList(); +Volatile IpcStreamFactory::s_isShutdown = false; + +bool IpcStreamFactory::ClientConnectionState::GetIpcPollHandle(IpcStream::DiagnosticsIpc::IpcPollHandle *pIpcPollHandle, ErrorCallback callback) +{ + if (_pStream == nullptr) + { + // cache is empty, reconnect, e.g., there was a disconnect + IpcStream *pConnection = _pIpc->Connect(callback); + if (pConnection == nullptr) + { + if (callback != nullptr) + callback("Failed to connect to client connection", -1); + return false; + } + if (!DiagnosticsIpc::SendIpcAdvertise_V1(pConnection)) + { + if (callback != nullptr) + callback("Failed to send advertise message", -1); + delete pConnection; + return false; + } + + _pStream = pConnection; + } + *pIpcPollHandle = { nullptr, _pStream, 0, this }; + return true; +} + +IpcStream *IpcStreamFactory::ClientConnectionState::GetConnectedStream(ErrorCallback callback) +{ + IpcStream *pStream = _pStream; + _pStream = nullptr; + return pStream; +} + +void IpcStreamFactory::ClientConnectionState::Reset(ErrorCallback callback) +{ + delete _pStream; + _pStream = nullptr; +} + +bool IpcStreamFactory::ServerConnectionState::GetIpcPollHandle(IpcStream::DiagnosticsIpc::IpcPollHandle *pIpcPollHandle, ErrorCallback callback) +{ + *pIpcPollHandle = { _pIpc, nullptr, 0, this }; + return true; +} + +IpcStream *IpcStreamFactory::ServerConnectionState::GetConnectedStream(ErrorCallback callback) +{ + return _pIpc->Accept(callback); +} + +// noop for server +void IpcStreamFactory::ServerConnectionState::Reset(ErrorCallback) +{ + return; +} + +bool IpcStreamFactory::CreateServer(const char *const pIpcName, ErrorCallback callback) +{ + IpcStream::DiagnosticsIpc *pIpc = IpcStream::DiagnosticsIpc::Create(pIpcName, IpcStream::DiagnosticsIpc::ConnectionMode::SERVER, callback); + if (pIpc != nullptr) + { + if (pIpc->Listen(callback)) + { + s_rgpConnectionStates.Push(new ServerConnectionState(pIpc)); + return true; + } + else + { + delete pIpc; + return false; + } + } + else + { + return false; + } +} + +bool IpcStreamFactory::CreateClient(const char *const pIpcName, ErrorCallback callback) +{ + IpcStream::DiagnosticsIpc *pIpc = IpcStream::DiagnosticsIpc::Create(pIpcName, IpcStream::DiagnosticsIpc::ConnectionMode::CLIENT, callback); + if (pIpc != nullptr) + { + s_rgpConnectionStates.Push(new ClientConnectionState(pIpc)); + return true; + } + else + { + return false; + } +} + +bool IpcStreamFactory::HasActiveConnections() +{ + return !s_isShutdown && s_rgpConnectionStates.Size() > 0; +} + +void IpcStreamFactory::CloseConnections(ErrorCallback callback) +{ + for (uint32_t i = 0; i < (uint32_t)s_rgpConnectionStates.Size(); i++) + s_rgpConnectionStates[i]->Close(callback); +} + +void IpcStreamFactory::Shutdown(ErrorCallback callback) +{ + if (s_isShutdown) + return; + s_isShutdown = true; + for (uint32_t i = 0; i < (uint32_t)s_rgpConnectionStates.Size(); i++) + s_rgpConnectionStates[i]->Close(true, callback); +} + +// helper function for getting timeout +int32_t IpcStreamFactory::GetNextTimeout(int32_t currentTimeoutMs) +{ + if (currentTimeoutMs == s_pollTimeoutInfinite) + { + return s_pollTimeoutMinMs; + } + else + { + return (currentTimeoutMs >= s_pollTimeoutMaxMs) ? + s_pollTimeoutMaxMs : + (int32_t)((float)currentTimeoutMs * s_pollTimeoutFalloffFactor); + } +} + +IpcStream *IpcStreamFactory::GetNextAvailableStream(ErrorCallback callback) +{ + IpcStream *pStream = nullptr; + CQuickArrayList rgIpcPollHandles; + + int32_t pollTimeoutMs = s_pollTimeoutInfinite; + bool fConnectSuccess = true; + uint32_t nPollAttempts = 0; + + while (pStream == nullptr) + { + fConnectSuccess = true; + for (uint32_t i = 0; i < (uint32_t)s_rgpConnectionStates.Size(); i++) + { + IpcStream::DiagnosticsIpc::IpcPollHandle pollHandle = {}; + if (s_rgpConnectionStates[i]->GetIpcPollHandle(&pollHandle, callback)) + { + rgIpcPollHandles.Push(pollHandle); + } + else + { + fConnectSuccess = false; + } + } + + pollTimeoutMs = fConnectSuccess ? + s_pollTimeoutInfinite : + GetNextTimeout(pollTimeoutMs); + + int32_t retval = IpcStream::DiagnosticsIpc::Poll(rgIpcPollHandles.Ptr(), (uint32_t)rgIpcPollHandles.Size(), pollTimeoutMs, callback); + nPollAttempts++; + STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::GetNextAvailableStream - Poll attempt: %d, timeout: %dms.\n", nPollAttempts, pollTimeoutMs); + + if (retval != 0) + { + for (uint32_t i = 0; i < (uint32_t)rgIpcPollHandles.Size(); i++) + { + switch ((IpcStream::DiagnosticsIpc::PollEvents)rgIpcPollHandles[i].revents) + { + case IpcStream::DiagnosticsIpc::PollEvents::HANGUP: + ((ConnectionState*)(rgIpcPollHandles[i].pUserData))->Reset(callback); + STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_INFO10, "IpcStreamFactory::GetNextAvailableStream - Poll attempt: %d, connection hung up.\n", nPollAttempts); + pollTimeoutMs = s_pollTimeoutMinMs; + break; + case IpcStream::DiagnosticsIpc::PollEvents::SIGNALED: + if (pStream == nullptr) // only use first signaled stream; will get others on subsequent calls + pStream = ((ConnectionState*)(rgIpcPollHandles[i].pUserData))->GetConnectedStream(callback); + break; + case IpcStream::DiagnosticsIpc::PollEvents::ERR: + return nullptr; + default: + // TODO: Error handling + break; + } + } + } + + // clear the view + while (rgIpcPollHandles.Size() > 0) + rgIpcPollHandles.Pop(); + } + + return pStream; +} + +#endif // FEATURE_PERFTRACING \ No newline at end of file diff --git a/src/coreclr/src/vm/ipcstreamfactory.h b/src/coreclr/src/vm/ipcstreamfactory.h new file mode 100644 index 0000000000000..04d92bef84628 --- /dev/null +++ b/src/coreclr/src/vm/ipcstreamfactory.h @@ -0,0 +1,103 @@ +// 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. + +#ifndef __IPC_STREAM_FACTORY_H__ +#define __IPC_STREAM_FACTORY_H__ + +#ifdef FEATURE_PERFTRACING + +#include "diagnosticsipc.h" + +class IpcStreamFactory +{ +public: + struct ConnectionState + { + public: + ConnectionState(IpcStream::DiagnosticsIpc *pIpc) : + _pIpc(pIpc), + _pStream(nullptr) + { } + + // returns a pollable handle and performs any preparation required + // e.g., as a side-effect, will connect and advertise on reverse connections + virtual bool GetIpcPollHandle(IpcStream::DiagnosticsIpc::IpcPollHandle *pIpcPollHandle, ErrorCallback callback = nullptr) = 0; + + // Returns the signaled stream in a usable state + virtual IpcStream *GetConnectedStream(ErrorCallback callback = nullptr) = 0; + + // Resets the connection in the event of a hangup + virtual void Reset(ErrorCallback callback = nullptr) = 0; + + // closes the underlying connections + // only performs minimal cleanup if isShutdown==true + void Close(bool isShutdown = false, ErrorCallback callback = nullptr) + { + if (_pIpc != nullptr) + _pIpc->Close(isShutdown, callback); + if (_pStream != nullptr && !isShutdown) + _pStream->Close(callback); + } + + protected: + IpcStream::DiagnosticsIpc *_pIpc; + IpcStream *_pStream; + }; + + struct ClientConnectionState : public ConnectionState + { + ClientConnectionState(IpcStream::DiagnosticsIpc *pIpc) : ConnectionState(pIpc) { } + + // returns a pollable handle and performs any preparation required + bool GetIpcPollHandle(IpcStream::DiagnosticsIpc::IpcPollHandle *pIpcPollHandle, ErrorCallback callback = nullptr) override; + + // Returns the signaled stream in a usable state + IpcStream *GetConnectedStream(ErrorCallback callback = nullptr) override; + + // Resets the connection in the event of a hangup + void Reset(ErrorCallback callback = nullptr) override; + }; + + struct ServerConnectionState : public ConnectionState + { + ServerConnectionState(IpcStream::DiagnosticsIpc *pIpc) : ConnectionState(pIpc) { } + + // returns a pollable handle and performs any preparation required + bool GetIpcPollHandle(IpcStream::DiagnosticsIpc::IpcPollHandle *pIpcPollHandle, ErrorCallback callback = nullptr) override; + + // Returns the signaled stream in a usable state + IpcStream *GetConnectedStream(ErrorCallback callback = nullptr) override; + + // Resets the connection in the event of a hangup + void Reset(ErrorCallback callback = nullptr) override; + }; + + static bool CreateServer(const char *const pIpcName, ErrorCallback = nullptr); + static bool CreateClient(const char *const pIpcName, ErrorCallback = nullptr); + static IpcStream *GetNextAvailableStream(ErrorCallback = nullptr); + static bool HasActiveConnections(); + static void CloseConnections(ErrorCallback callback = nullptr); + static void Shutdown(ErrorCallback callback = nullptr); +private: + static CQuickArrayList s_rgpConnectionStates; + static Volatile s_isShutdown; + + // Polling timeout semantics + // If client connection is opted in + // and connection succeeds => set timeout to infinite + // and connection fails => set timeout to minimum and scale by falloff factor + // else => set timeout to -1 (infinite) + // + // If an agent closes its socket while we're still connected, + // Poll will return and let us know which connection hung up + static int32_t GetNextTimeout(int32_t currentTimeoutMs); + constexpr static float s_pollTimeoutFalloffFactor = 1.25; + constexpr static int32_t s_pollTimeoutInfinite = -1; + constexpr static int32_t s_pollTimeoutMinMs = 10; + constexpr static int32_t s_pollTimeoutMaxMs = 500; +}; + +#endif // FEATURE_PERFTRACING + +#endif // __IPC_STREAM_FACTORY_H__ \ No newline at end of file diff --git a/src/coreclr/tests/src/tracing/eventpipe/common/Reverse.cs b/src/coreclr/tests/src/tracing/eventpipe/common/Reverse.cs new file mode 100644 index 0000000000000..c4f1c9464e609 --- /dev/null +++ b/src/coreclr/tests/src/tracing/eventpipe/common/Reverse.cs @@ -0,0 +1,178 @@ +// 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. + +using System; +using System.IO; +using System.IO.Pipes; +using System.Net.Sockets; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace Tracing.Tests.Common +{ + /** + * ==ADVERTISE PROTOCOL== + * Before standard IPC Protocol communication can occur on a client-mode connection + * the runtime must advertise itself over the connection. ALL SUBSEQUENT COMMUNICATION + * IS STANDARD DIAGNOSTICS IPC PROTOCOL COMMUNICATION. + * + * The flow for Advertise is a one-way burst of 32 bytes consisting of + * 8 bytes - "ADVR_V1\0" (ASCII chars + null byte) + * 16 bytes - CLR Instance Cookie (little-endian) + * 8 bytes - PID (little-endian) + * 2 bytes - unused for futureproofing + */ + + public class IpcAdvertise + { + public static int Size_V1 => 34; + public static byte[] Magic_V1 => System.Text.Encoding.ASCII.GetBytes("ADVR_V1" + '\0'); + public static int MagicSize_V1 => 8; + + public byte[] Magic = Magic_V1; + public UInt64 ProcessId; + public Guid RuntimeInstanceCookie; + public UInt16 Unused; + + /// + /// + /// + /// (pid, clrInstanceId) + public static IpcAdvertise Parse(Stream stream) + { + var binaryReader = new BinaryReader(stream); + var advertise = new IpcAdvertise() + { + Magic = binaryReader.ReadBytes(Magic_V1.Length), + RuntimeInstanceCookie = new Guid(binaryReader.ReadBytes(16)), + ProcessId = binaryReader.ReadUInt64(), + Unused = binaryReader.ReadUInt16() + }; + + for (int i = 0; i < Magic_V1.Length; i++) + if (advertise.Magic[i] != Magic_V1[i]) + throw new Exception("Invalid advertise message from client connection"); + + // FUTURE: switch on incoming magic and change if version ever increments + return advertise; + } + + override public string ToString() + { + return $"{{ Magic={Magic}; ClrInstanceId={RuntimeInstanceCookie}; ProcessId={ProcessId}; Unused={Unused}; }}"; + } + } + public class ReverseServer + { + public static string MakeServerAddress() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return "DOTNET_TRACE_TESTS_" + Path.GetRandomFileName(); + } + else + { + return Path.Combine(Path.GetTempPath(), "DOTNET_TRACE_TESTS_" + Path.GetRandomFileName()); + } + } + + private object _server; // _server ::= socket | NamedPipeServerStream + private Socket _clientSocket; // only used on non-Windows + private string _serverAddress; + + public ReverseServer(string serverAddress, int bufferSize = 16 * 1024) + { + _serverAddress = serverAddress; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + _server = new NamedPipeServerStream( + serverAddress, + PipeDirection.InOut, + NamedPipeServerStream.MaxAllowedServerInstances, + PipeTransmissionMode.Byte, + PipeOptions.None, + bufferSize, + bufferSize); + } + else + { + if (File.Exists(serverAddress)) + File.Delete(serverAddress); + var remoteEP = new UnixDomainSocketEndPoint(serverAddress); + + var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified); + // socket(7) states that SO_RCVBUF has a minimum of 128 and SO_SNDBUF has minimum of 1024 + socket.SendBufferSize = Math.Max(bufferSize, 1024); + socket.ReceiveBufferSize = Math.Max(bufferSize, 128); + socket.Bind(remoteEP); + socket.Listen(255); + socket.LingerState.Enabled = false; + _server = socket; + } + } + + public async Task AcceptAsync() + { + switch (_server) + { + case NamedPipeServerStream serverStream: + await serverStream.WaitForConnectionAsync(); + return serverStream; + case Socket socket: + _clientSocket = await socket.AcceptAsync(); + return new NetworkStream(_clientSocket); + default: + throw new ArgumentException("Invalid server type"); + } + } + + public void Shutdown() + { + switch (_server) + { + case NamedPipeServerStream serverStream: + try + { + serverStream.Disconnect(); + } + catch {} + finally + { + serverStream.Dispose(); + } + break; + case Socket socket: + try + { + socket.Shutdown(SocketShutdown.Both); + } + catch {} + finally + { + _clientSocket?.Close(); + socket.Close(); + socket.Dispose(); + _clientSocket?.Dispose(); + if (File.Exists(_serverAddress)) + File.Delete(_serverAddress); + } + break; + default: + throw new ArgumentException("Invalid server type"); + } + } + + // Creates the server, listens, and closes the server + public static async Task CreateServerAndReceiveAdvertisement(string serverAddress) + { + var server = new ReverseServer(serverAddress); + Logger.logger.Log("Waiting for connection"); + Stream stream = await server.AcceptAsync(); + Logger.logger.Log("Got a connection"); + IpcAdvertise advertise = IpcAdvertise.Parse(stream); + server.Shutdown(); + return advertise; + } + } +} \ No newline at end of file diff --git a/src/coreclr/tests/src/tracing/eventpipe/common/common.csproj b/src/coreclr/tests/src/tracing/eventpipe/common/common.csproj index 0df38b391df23..a0b36c8336dcc 100644 --- a/src/coreclr/tests/src/tracing/eventpipe/common/common.csproj +++ b/src/coreclr/tests/src/tracing/eventpipe/common/common.csproj @@ -9,5 +9,6 @@ + diff --git a/src/coreclr/tests/src/tracing/eventpipe/reverse/reverse.cs b/src/coreclr/tests/src/tracing/eventpipe/reverse/reverse.cs new file mode 100644 index 0000000000000..5fdc7ca11a235 --- /dev/null +++ b/src/coreclr/tests/src/tracing/eventpipe/reverse/reverse.cs @@ -0,0 +1,339 @@ +// 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. + +using System; +using System.Diagnostics.Tracing; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.Diagnostics.Tools.RuntimeClient; +using Tracing.Tests.Common; +using System.Threading; +using System.IO; +using Microsoft.Diagnostics.Tracing; + +namespace Tracing.Tests.ReverseValidation +{ + public class ReverseValidation + { + // The runtime will do an exponential falloff by a factor of 1.25 starting at 10ms with a max of 500ms + // We can time tests out after waiting 30s which should have sufficient attempts + private static int _maxPollTimeMS = 30_000; + + private static async Task WaitTillTimeout(Task task, TimeSpan timeout) + { + using var cts = new CancellationTokenSource(); + var completedTask = await Task.WhenAny(task, Task.Delay(timeout, cts.Token)); + if (completedTask == task) + { + cts.Cancel(); + return await task; + } + else + { + throw new TimeoutException("Task timed out"); + } + } + + public static async Task RunSubprocess(string serverName, Func beforeExecution = null, Func duringExecution = null, Func afterExecution = null) + { + using (var process = new Process()) + { + if (beforeExecution != null) + await beforeExecution(); + + process.StartInfo.UseShellExecute = false; + process.StartInfo.CreateNoWindow = true; + process.StartInfo.Environment.Add("DOTNET_DiagnosticsMonitorAddress", serverName); + process.StartInfo.FileName = Process.GetCurrentProcess().MainModule.FileName; + process.StartInfo.Arguments = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath + " 0"; + Logger.logger.Log($"running sub-process: {process.StartInfo.FileName} {process.StartInfo.Arguments}"); + bool fSuccess = process.Start(); + Logger.logger.Log($"subprocess started: {fSuccess}"); + Logger.logger.Log($"subprocess PID: {process.Id}"); + + while (!EventPipeClient.ListAvailablePorts().Contains(process.Id)) + await Task.Delay(100); + try + { + if (duringExecution != null) + await duringExecution(process.Id); + } + finally + { + process.Kill(); + } + + + if (afterExecution != null) + await afterExecution(); + } + } + + public static async Task TEST_RuntimeIsResilientToServerClosing() + { + string serverName = ReverseServer.MakeServerAddress(); + Logger.logger.Log($"Server name is '{serverName}'"); + await RunSubprocess( + serverName: serverName, + duringExecution: async (_) => + { + var ad1 = await WaitTillTimeout(ReverseServer.CreateServerAndReceiveAdvertisement(serverName), TimeSpan.FromMilliseconds(_maxPollTimeMS)); + Logger.logger.Log(ad1.ToString()); + var ad2 = await WaitTillTimeout(ReverseServer.CreateServerAndReceiveAdvertisement(serverName), TimeSpan.FromMilliseconds(_maxPollTimeMS)); + Logger.logger.Log(ad2.ToString()); + var ad3 = await WaitTillTimeout(ReverseServer.CreateServerAndReceiveAdvertisement(serverName), TimeSpan.FromMilliseconds(_maxPollTimeMS)); + Logger.logger.Log(ad3.ToString()); + var ad4 = await WaitTillTimeout(ReverseServer.CreateServerAndReceiveAdvertisement(serverName), TimeSpan.FromMilliseconds(_maxPollTimeMS)); + Logger.logger.Log(ad4.ToString()); + } + ); + + return true; + } + + public static async Task TEST_RuntimeConnectsToExistingServer() + { + string serverName = ReverseServer.MakeServerAddress(); + Task advertiseTask = ReverseServer.CreateServerAndReceiveAdvertisement(serverName); + Logger.logger.Log($"Server name is `{serverName}`"); + await RunSubprocess( + serverName: serverName, + duringExecution: async (_) => + { + IpcAdvertise advertise = await WaitTillTimeout(advertiseTask, TimeSpan.FromMilliseconds(_maxPollTimeMS)); + Logger.logger.Log(advertise.ToString()); + } + ); + + return true; + } + + + public static async Task TEST_CanConnectServerAndClientAtSameTime() + { + string serverName = ReverseServer.MakeServerAddress(); + Logger.logger.Log($"Server name is '{serverName}'"); + var server = new ReverseServer(serverName); + await RunSubprocess( + serverName: serverName, + duringExecution: async (int pid) => + { + Task reverseTask = Task.Run(async () => + { + Logger.logger.Log($"Waiting for reverse connection"); + Stream reverseStream = await server.AcceptAsync(); + Logger.logger.Log("Got reverse connection"); + IpcAdvertise advertise = IpcAdvertise.Parse(reverseStream); + Logger.logger.Log(advertise.ToString()); + }); + + Task regularTask = Task.Run(async () => + { + var config = new SessionConfiguration( + circularBufferSizeMB: 1000, + format: EventPipeSerializationFormat.NetTrace, + providers: new List { + new Provider("Microsoft-DotNETCore-SampleProfiler") + }); + Logger.logger.Log("Starting EventPipeSession over standard connection"); + using Stream stream = EventPipeClient.CollectTracing(pid, config, out var sessionId); + Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); + using var source = new EventPipeEventSource(stream); + Task readerTask = Task.Run(() => source.Process()); + await Task.Delay(500); + Logger.logger.Log("Stopping EventPipeSession over standard connection"); + EventPipeClient.StopTracing(pid, sessionId); + await readerTask; + Logger.logger.Log("Stopped EventPipeSession over standard connection"); + }); + + await Task.WhenAll(reverseTask, regularTask); + } + ); + + server.Shutdown(); + + return true; + } + + public static async Task TEST_ServerWorksIfClientDoesntAccept() + { + string serverName = ReverseServer.MakeServerAddress(); + Logger.logger.Log($"Server name is '{serverName}'"); + var server = new ReverseServer(serverName); + await RunSubprocess( + serverName: serverName, + duringExecution: async (int pid) => + { + var config = new SessionConfiguration( + circularBufferSizeMB: 10, + format: EventPipeSerializationFormat.NetTrace, + providers: new List { + new Provider("Microsoft-DotNETCore-SampleProfiler") + }); + Logger.logger.Log("Starting EventPipeSession over standard connection"); + using Stream stream = EventPipeClient.CollectTracing(pid, config, out var sessionId); + Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); + using var source = new EventPipeEventSource(stream); + Task readerTask = Task.Run(() => source.Process()); + await Task.Delay(500); + Logger.logger.Log("Stopping EventPipeSession over standard connection"); + EventPipeClient.StopTracing(pid, sessionId); + await readerTask; + Logger.logger.Log("Stopped EventPipeSession over standard connection"); + } + ); + + server.Shutdown(); + + return true; + } + + public static async Task TEST_ServerIsResilientToNoBufferAgent() + { + // N.B. - this test is only testing behavior on Windows since Unix Domain Sockets get their buffer size from the + // system configuration and isn't set here. Tests passing on Windows should indicate it would pass on Unix systems as well. + string serverName = ReverseServer.MakeServerAddress(); + Logger.logger.Log($"Server name is '{serverName}'"); + var server = new ReverseServer(serverName, 0); + await RunSubprocess( + serverName: serverName, + duringExecution: async (int pid) => + { + var config = new SessionConfiguration( + circularBufferSizeMB: 10, + format: EventPipeSerializationFormat.NetTrace, + providers: new List { + new Provider("Microsoft-DotNETCore-SampleProfiler") + }); + Logger.logger.Log("Starting EventPipeSession over standard connection"); + using Stream stream = EventPipeClient.CollectTracing(pid, config, out var sessionId); + Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); + using var source = new EventPipeEventSource(stream); + Task readerTask = Task.Run(() => source.Process()); + await Task.Delay(500); + Logger.logger.Log("Stopping EventPipeSession over standard connection"); + EventPipeClient.StopTracing(pid, sessionId); + await readerTask; + Logger.logger.Log("Stopped EventPipeSession over standard connection"); + } + ); + + server.Shutdown(); + + return true; + } + + public static async Task TEST_ReverseConnectionCanRecycleWhileTracing() + { + string serverName = ReverseServer.MakeServerAddress(); + Logger.logger.Log($"Server name is '{serverName}'"); + await RunSubprocess( + serverName: serverName, + duringExecution: async (int pid) => + { + Task regularTask = Task.Run(async () => + { + var config = new SessionConfiguration( + circularBufferSizeMB: 1000, + format: EventPipeSerializationFormat.NetTrace, + providers: new List { + new Provider("Microsoft-DotNETCore-SampleProfiler") + }); + Logger.logger.Log("Starting EventPipeSession over standard connection"); + using Stream stream = EventPipeClient.CollectTracing(pid, config, out var sessionId); + Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); + using var source = new EventPipeEventSource(stream); + Task readerTask = Task.Run(() => source.Process()); + await Task.Delay(500); + Logger.logger.Log("Stopping EventPipeSession over standard connection"); + EventPipeClient.StopTracing(pid, sessionId); + await readerTask; + Logger.logger.Log("Stopped EventPipeSession over standard connection"); + }); + + Task reverseTask = Task.Run(async () => + { + var ad1 = await WaitTillTimeout(ReverseServer.CreateServerAndReceiveAdvertisement(serverName), TimeSpan.FromMilliseconds(_maxPollTimeMS)); + Logger.logger.Log(ad1.ToString()); + var ad2 = await WaitTillTimeout(ReverseServer.CreateServerAndReceiveAdvertisement(serverName), TimeSpan.FromMilliseconds(_maxPollTimeMS)); + Logger.logger.Log(ad2.ToString()); + var ad3 = await WaitTillTimeout(ReverseServer.CreateServerAndReceiveAdvertisement(serverName), TimeSpan.FromMilliseconds(_maxPollTimeMS)); + Logger.logger.Log(ad3.ToString()); + var ad4 = await WaitTillTimeout(ReverseServer.CreateServerAndReceiveAdvertisement(serverName), TimeSpan.FromMilliseconds(_maxPollTimeMS)); + Logger.logger.Log(ad4.ToString()); + }); + + await Task.WhenAll(reverseTask, regularTask); + } + ); + + return true; + } + + public static async Task TEST_StandardConnectionStillWorksIfReverseConnectionIsBroken() + { + string serverName = ReverseServer.MakeServerAddress(); + Logger.logger.Log($"Server name is '{serverName}'"); + await RunSubprocess( + serverName: serverName, + duringExecution: async (int pid) => + { + var config = new SessionConfiguration( + circularBufferSizeMB: 1000, + format: EventPipeSerializationFormat.NetTrace, + providers: new List { + new Provider("Microsoft-DotNETCore-SampleProfiler") + }); + Logger.logger.Log("Starting EventPipeSession over standard connection"); + using Stream stream = EventPipeClient.CollectTracing(pid, config, out var sessionId); + Logger.logger.Log($"Started EventPipeSession over standard connection with session id: 0x{sessionId:x}"); + using var source = new EventPipeEventSource(stream); + Task readerTask = Task.Run(() => source.Process()); + await Task.Delay(500); + Logger.logger.Log("Stopping EventPipeSession over standard connection"); + EventPipeClient.StopTracing(pid, sessionId); + await readerTask; + Logger.logger.Log("Stopped EventPipeSession over standard connection"); + } + ); + + return true; + } + + public static async Task Main(string[] args) + { + if (args.Length >= 1) + { + await Task.Delay(TimeSpan.FromMinutes(10)); // will be killed in test + return 1; + } + + bool fSuccess = true; + IEnumerable tests = typeof(ReverseValidation).GetMethods().Where(mi => mi.Name.StartsWith("TEST_")); + foreach (var test in tests) + { + Logger.logger.Log($"::== Running test: {test.Name}"); + bool result = true; + try + { + result = await (Task)test.Invoke(null, new object[] {}); + } + catch (Exception e) + { + result = false; + Logger.logger.Log(e.ToString()); + } + fSuccess &= result; + Logger.logger.Log($"Test passed: {result}"); + Logger.logger.Log($""); + + } + return fSuccess ? 100 : -1; + } + } +} \ No newline at end of file diff --git a/src/coreclr/tests/src/tracing/eventpipe/reverse/reverse.csproj b/src/coreclr/tests/src/tracing/eventpipe/reverse/reverse.csproj new file mode 100644 index 0000000000000..2c10c6ed46533 --- /dev/null +++ b/src/coreclr/tests/src/tracing/eventpipe/reverse/reverse.csproj @@ -0,0 +1,15 @@ + + + .NETCoreApp + exe + BuildAndRun + true + 0 + true + true + + + + + + \ No newline at end of file From ab71b6dc8bb01a4eb56e3fce4df017da5a475e2a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 8 May 2020 17:03:48 +0000 Subject: [PATCH 064/420] [master] Update dependencies from 4 repositories (#36111) * Update dependencies from https://github.com/dotnet/arcade build 20200506.5 - Microsoft.DotNet.XUnitExtensions: 5.0.0-beta.20255.6 -> 5.0.0-beta.20256.5 - Microsoft.DotNet.VersionTools.Tasks: 5.0.0-beta.20255.6 -> 5.0.0-beta.20256.5 - Microsoft.DotNet.ApiCompat: 5.0.0-beta.20255.6 -> 5.0.0-beta.20256.5 - Microsoft.DotNet.Arcade.Sdk: 5.0.0-beta.20255.6 -> 5.0.0-beta.20256.5 - Microsoft.DotNet.Build.Tasks.Feed: 5.0.0-beta.20255.6 -> 5.0.0-beta.20256.5 - Microsoft.DotNet.Build.Tasks.Packaging: 5.0.0-beta.20255.6 -> 5.0.0-beta.20256.5 - Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk: 5.0.0-beta.20255.6 -> 5.0.0-beta.20256.5 - Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk: 5.0.0-beta.20255.6 -> 5.0.0-beta.20256.5 - Microsoft.DotNet.CodeAnalysis: 5.0.0-beta.20255.6 -> 5.0.0-beta.20256.5 - Microsoft.DotNet.XUnitConsoleRunner: 2.5.1-beta.20255.6 -> 2.5.1-beta.20256.5 - Microsoft.DotNet.GenAPI: 5.0.0-beta.20255.6 -> 5.0.0-beta.20256.5 - Microsoft.DotNet.Helix.Sdk: 5.0.0-beta.20255.6 -> 5.0.0-beta.20256.5 - Microsoft.DotNet.RemoteExecutor: 5.0.0-beta.20255.6 -> 5.0.0-beta.20256.5 - Microsoft.DotNet.GenFacades: 5.0.0-beta.20255.6 -> 5.0.0-beta.20256.5 * Update dependencies from https://github.com/mono/linker build 20200507.4 - Microsoft.NET.ILLink.Tasks: 5.0.0-preview.3.20256.5 -> 5.0.0-preview.3.20257.4 * Update dependencies from https://github.com/dotnet/runtime-assets build 20200507.1 - System.ComponentModel.TypeConverter.TestData: 5.0.0-beta.20256.1 -> 5.0.0-beta.20257.1 - System.Drawing.Common.TestData: 5.0.0-beta.20256.1 -> 5.0.0-beta.20257.1 - System.IO.Compression.TestData: 5.0.0-beta.20256.1 -> 5.0.0-beta.20257.1 - System.IO.Packaging.TestData: 5.0.0-beta.20256.1 -> 5.0.0-beta.20257.1 - System.Net.TestData: 5.0.0-beta.20256.1 -> 5.0.0-beta.20257.1 - System.Private.Runtime.UnicodeData: 5.0.0-beta.20256.1 -> 5.0.0-beta.20257.1 - System.Security.Cryptography.X509Certificates.TestData: 5.0.0-beta.20256.1 -> 5.0.0-beta.20257.1 - System.Windows.Extensions.TestData: 5.0.0-beta.20256.1 -> 5.0.0-beta.20257.1 * Update dependencies from https://github.com/dotnet/xharness build 20200507.4 - Microsoft.DotNet.XHarness.Tests.Runners: 1.0.0-prerelease.20256.2 -> 1.0.0-prerelease.20257.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 96 +++++++++---------- eng/Versions.props | 40 ++++---- eng/common/CIBuild.cmd | 2 +- eng/common/PSScriptAnalyzerSettings.psd1 | 2 +- eng/common/cibuild.sh | 2 +- eng/common/cross/arm/sources.list.trusty | 2 +- eng/common/cross/arm/sources.list.xenial | 2 +- eng/common/cross/arm64/sources.list.trusty | 2 +- eng/common/cross/arm64/sources.list.xenial | 2 +- eng/common/darc-init.ps1 | 4 +- eng/common/darc-init.sh | 2 +- eng/common/dotnet-install.cmd | 2 +- eng/common/generate-graph-files.ps1 | 2 +- eng/common/init-tools-native.cmd | 2 +- eng/common/msbuild.ps1 | 2 +- eng/common/native/install-cmake-test.sh | 2 +- eng/common/native/install-cmake.sh | 2 +- eng/common/performance/perfhelixpublish.proj | 2 +- eng/common/performance/performance-setup.ps1 | 2 +- eng/common/pipeline-logging-functions.sh | 2 +- eng/common/sdl/NuGet.config | 2 +- eng/common/templates/job/performance.yml | 2 +- .../steps/run-script-ifequalelse.yml | 2 +- global.json | 12 +-- 24 files changed, 96 insertions(+), 96 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3bf47676610c7..d7c8650bf65e4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -6,61 +6,61 @@ - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 981e1a0b0149281a5994ecddfeb5cfcf002f9f1e + 8547938aefa24475a04877285553f0b2663ae249 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization @@ -86,37 +86,37 @@ https://github.com/microsoft/vstest df61f73a1f4608df5ee0957350fbd3e81f924c6b - + https://github.com/dotnet/runtime-assets - dca67e64ede5a701747e9a8e0117c18aaa4f7bca + 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d - + https://github.com/dotnet/runtime-assets - dca67e64ede5a701747e9a8e0117c18aaa4f7bca + 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d - + https://github.com/dotnet/runtime-assets - dca67e64ede5a701747e9a8e0117c18aaa4f7bca + 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d - + https://github.com/dotnet/runtime-assets - dca67e64ede5a701747e9a8e0117c18aaa4f7bca + 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d - + https://github.com/dotnet/runtime-assets - dca67e64ede5a701747e9a8e0117c18aaa4f7bca + 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d - + https://github.com/dotnet/runtime-assets - dca67e64ede5a701747e9a8e0117c18aaa4f7bca + 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d - + https://github.com/dotnet/runtime-assets - dca67e64ede5a701747e9a8e0117c18aaa4f7bca + 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d - + https://github.com/dotnet/runtime-assets - dca67e64ede5a701747e9a8e0117c18aaa4f7bca + 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d https://github.com/dotnet/llvm-project @@ -170,13 +170,13 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - fe2d8f8c2007ecf3789df3d8169d9809111875bb + 6e17588c5e0c1804312d81e98dceeab5eb7f6f1f - + https://github.com/dotnet/xharness - 1bf48d38e217b0edebbd42c2af3e47fb01211c37 + a8346dcc301875ef9cede0500f3736a73dbbc3cf diff --git a/eng/Versions.props b/eng/Versions.props index 38378636e01c5..7febd65b98e5c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -57,16 +57,16 @@ - 5.0.0-beta.20255.6 - 5.0.0-beta.20255.6 - 5.0.0-beta.20255.6 - 5.0.0-beta.20255.6 - 5.0.0-beta.20255.6 - 5.0.0-beta.20255.6 - 2.5.1-beta.20255.6 - 5.0.0-beta.20255.6 - 5.0.0-beta.20255.6 - 5.0.0-beta.20255.6 + 5.0.0-beta.20256.5 + 5.0.0-beta.20256.5 + 5.0.0-beta.20256.5 + 5.0.0-beta.20256.5 + 5.0.0-beta.20256.5 + 5.0.0-beta.20256.5 + 2.5.1-beta.20256.5 + 5.0.0-beta.20256.5 + 5.0.0-beta.20256.5 + 5.0.0-beta.20256.5 5.0.0-preview.4.20202.18 5.0.0-preview.4.20202.18 @@ -80,14 +80,14 @@ 5.0.0-preview.4.20202.18 5.0.0-alpha.1.19563.3 - 5.0.0-beta.20256.1 - 5.0.0-beta.20256.1 - 5.0.0-beta.20256.1 - 5.0.0-beta.20256.1 - 5.0.0-beta.20256.1 - 5.0.0-beta.20256.1 - 5.0.0-beta.20256.1 - 5.0.0-beta.20256.1 + 5.0.0-beta.20257.1 + 5.0.0-beta.20257.1 + 5.0.0-beta.20257.1 + 5.0.0-beta.20257.1 + 5.0.0-beta.20257.1 + 5.0.0-beta.20257.1 + 5.0.0-beta.20257.1 + 5.0.0-beta.20257.1 2.2.0-prerelease.19564.1 @@ -113,7 +113,7 @@ 4.8.0 16.7.0-preview-20200429-01 - 1.0.0-prerelease.20256.2 + 1.0.0-prerelease.20257.4 2.4.1 1.2.1 2.0.5 @@ -122,7 +122,7 @@ 3.1.0-preview-20200129.1 - 5.0.0-preview.3.20256.5 + 5.0.0-preview.3.20257.4 6.0.1-alpha.1.20254.1 6.0.1-alpha.1.20254.1 diff --git a/eng/common/CIBuild.cmd b/eng/common/CIBuild.cmd index ac1f72bf94e05..56c2f25ac22ff 100644 --- a/eng/common/CIBuild.cmd +++ b/eng/common/CIBuild.cmd @@ -1,2 +1,2 @@ @echo off -powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0Build.ps1""" -restore -build -test -sign -pack -publish -ci %*" +powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0Build.ps1""" -restore -build -test -sign -pack -publish -ci %*" \ No newline at end of file diff --git a/eng/common/PSScriptAnalyzerSettings.psd1 b/eng/common/PSScriptAnalyzerSettings.psd1 index fc7eafc265b70..4c1ea7c98ea4d 100644 --- a/eng/common/PSScriptAnalyzerSettings.psd1 +++ b/eng/common/PSScriptAnalyzerSettings.psd1 @@ -8,4 +8,4 @@ 'PSStandardDSCFunctionsInResource', 'PSUseIdenticalMandatoryParametersForDSC', 'PSUseIdenticalParametersForDSC') -} +} \ No newline at end of file diff --git a/eng/common/cibuild.sh b/eng/common/cibuild.sh index 66e3b0ac61c36..1a02c0dec8fd7 100755 --- a/eng/common/cibuild.sh +++ b/eng/common/cibuild.sh @@ -13,4 +13,4 @@ while [[ -h $source ]]; do done scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" -. "$scriptroot/build.sh" --restore --build --test --pack --publish --ci $@ +. "$scriptroot/build.sh" --restore --build --test --pack --publish --ci $@ \ No newline at end of file diff --git a/eng/common/cross/arm/sources.list.trusty b/eng/common/cross/arm/sources.list.trusty index 8aa98a259ff0f..07d8f88d82e87 100644 --- a/eng/common/cross/arm/sources.list.trusty +++ b/eng/common/cross/arm/sources.list.trusty @@ -8,4 +8,4 @@ deb http://ports.ubuntu.com/ubuntu-ports/ trusty-backports main restricted deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-backports main restricted deb http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm/sources.list.xenial b/eng/common/cross/arm/sources.list.xenial index 56fbb36a59f62..eacd86b7df3c1 100644 --- a/eng/common/cross/arm/sources.list.xenial +++ b/eng/common/cross/arm/sources.list.xenial @@ -8,4 +8,4 @@ deb http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm64/sources.list.trusty b/eng/common/cross/arm64/sources.list.trusty index 8aa98a259ff0f..07d8f88d82e87 100644 --- a/eng/common/cross/arm64/sources.list.trusty +++ b/eng/common/cross/arm64/sources.list.trusty @@ -8,4 +8,4 @@ deb http://ports.ubuntu.com/ubuntu-ports/ trusty-backports main restricted deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-backports main restricted deb http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm64/sources.list.xenial b/eng/common/cross/arm64/sources.list.xenial index 56fbb36a59f62..eacd86b7df3c1 100644 --- a/eng/common/cross/arm64/sources.list.xenial +++ b/eng/common/cross/arm64/sources.list.xenial @@ -8,4 +8,4 @@ deb http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse -deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/darc-init.ps1 b/eng/common/darc-init.ps1 index d1b9f5c20ba06..435e7641341b1 100644 --- a/eng/common/darc-init.ps1 +++ b/eng/common/darc-init.ps1 @@ -1,5 +1,5 @@ param ( - $darcVersion = "1.1.0-beta.20255.1", + $darcVersion = $null, $versionEndpoint = 'https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16', $verbosity = 'minimal', $toolpath = $null @@ -44,4 +44,4 @@ catch { Write-Host $_.ScriptStackTrace Write-PipelineTelemetryError -Category 'Darc' -Message $_ ExitWithExitCode 1 -} +} \ No newline at end of file diff --git a/eng/common/darc-init.sh b/eng/common/darc-init.sh index 9e62d08cd3e0c..d981d7bbf38de 100755 --- a/eng/common/darc-init.sh +++ b/eng/common/darc-init.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash source="${BASH_SOURCE[0]}" -darcVersion='1.1.0-beta.20255.1' +darcVersion='' versionEndpoint='https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16' verbosity='minimal' diff --git a/eng/common/dotnet-install.cmd b/eng/common/dotnet-install.cmd index f74c16cc8a892..b1c2642e76f72 100644 --- a/eng/common/dotnet-install.cmd +++ b/eng/common/dotnet-install.cmd @@ -1,2 +1,2 @@ @echo off -powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0dotnet-install.ps1""" %*" +powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0dotnet-install.ps1""" %*" \ No newline at end of file diff --git a/eng/common/generate-graph-files.ps1 b/eng/common/generate-graph-files.ps1 index bc7ad852d56a5..0728b1a8b570d 100644 --- a/eng/common/generate-graph-files.ps1 +++ b/eng/common/generate-graph-files.ps1 @@ -83,4 +83,4 @@ catch { ExitWithExitCode 1 } finally { Pop-Location -} +} \ No newline at end of file diff --git a/eng/common/init-tools-native.cmd b/eng/common/init-tools-native.cmd index 10938a23c5287..438cd548c452c 100644 --- a/eng/common/init-tools-native.cmd +++ b/eng/common/init-tools-native.cmd @@ -1,3 +1,3 @@ @echo off powershell -NoProfile -NoLogo -ExecutionPolicy ByPass -command "& """%~dp0init-tools-native.ps1""" %*" -exit /b %ErrorLevel% +exit /b %ErrorLevel% \ No newline at end of file diff --git a/eng/common/msbuild.ps1 b/eng/common/msbuild.ps1 index b2dceff4ce87d..c6401230002fe 100644 --- a/eng/common/msbuild.ps1 +++ b/eng/common/msbuild.ps1 @@ -23,4 +23,4 @@ catch { ExitWithExitCode 1 } -ExitWithExitCode 0 +ExitWithExitCode 0 \ No newline at end of file diff --git a/eng/common/native/install-cmake-test.sh b/eng/common/native/install-cmake-test.sh index 7d1b7136d8dee..12339a40761d4 100755 --- a/eng/common/native/install-cmake-test.sh +++ b/eng/common/native/install-cmake-test.sh @@ -114,4 +114,4 @@ if [[ $? != 0 ]]; then exit 1 fi -exit 0 +exit 0 \ No newline at end of file diff --git a/eng/common/native/install-cmake.sh b/eng/common/native/install-cmake.sh index aaa3e3818904b..18041be87633e 100755 --- a/eng/common/native/install-cmake.sh +++ b/eng/common/native/install-cmake.sh @@ -114,4 +114,4 @@ if [[ $? != 0 ]]; then exit 1 fi -exit 0 +exit 0 \ No newline at end of file diff --git a/eng/common/performance/perfhelixpublish.proj b/eng/common/performance/perfhelixpublish.proj index f86c3419efa03..cf5941e1b6455 100644 --- a/eng/common/performance/perfhelixpublish.proj +++ b/eng/common/performance/perfhelixpublish.proj @@ -118,4 +118,4 @@ $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name Microsoft.CodeAnalysis.CSharp.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root - + \ No newline at end of file diff --git a/eng/common/performance/performance-setup.ps1 b/eng/common/performance/performance-setup.ps1 index a0703852ee667..f5e6ca688b709 100644 --- a/eng/common/performance/performance-setup.ps1 +++ b/eng/common/performance/performance-setup.ps1 @@ -112,4 +112,4 @@ Write-PipelineSetVariable -Name 'Queue' -Value "$Queue" -IsMultiJobVariable $fal Write-PipelineSetVariable -Name 'HelixSourcePrefix' -Value "$HelixSourcePrefix" -IsMultiJobVariable $false Write-PipelineSetVariable -Name '_BuildConfig' -Value "$Architecture.$Kind.$Framework" -IsMultiJobVariable $false -exit 0 +exit 0 \ No newline at end of file diff --git a/eng/common/pipeline-logging-functions.sh b/eng/common/pipeline-logging-functions.sh index f87f195bb8ceb..33c3f0d8072a4 100755 --- a/eng/common/pipeline-logging-functions.sh +++ b/eng/common/pipeline-logging-functions.sh @@ -176,4 +176,4 @@ function Write-PipelinePrependPath { if [[ "$ci" == true ]]; then echo "##vso[task.prependpath]$prepend_path" fi -} +} \ No newline at end of file diff --git a/eng/common/sdl/NuGet.config b/eng/common/sdl/NuGet.config index a8213a55c4c0a..0c5451c11415f 100644 --- a/eng/common/sdl/NuGet.config +++ b/eng/common/sdl/NuGet.config @@ -1,4 +1,4 @@ - + diff --git a/eng/common/templates/job/performance.yml b/eng/common/templates/job/performance.yml index 53be464a30bcb..f877fd7a89800 100644 --- a/eng/common/templates/job/performance.yml +++ b/eng/common/templates/job/performance.yml @@ -92,4 +92,4 @@ jobs: Creator: $(Creator) WorkItemTimeout: 4:00 # 4 hours WorkItemDirectory: '$(WorkItemDirectory)' # WorkItemDirectory can not be empty, so we send it some docs to keep it happy - CorrelationPayloadDirectory: '$(PayloadDirectory)' # it gets checked out to a folder with shorter path than WorkItemDirectory so we can avoid file name too long exceptions + CorrelationPayloadDirectory: '$(PayloadDirectory)' # it gets checked out to a folder with shorter path than WorkItemDirectory so we can avoid file name too long exceptions \ No newline at end of file diff --git a/eng/common/templates/steps/run-script-ifequalelse.yml b/eng/common/templates/steps/run-script-ifequalelse.yml index 2dcd9d12aaf86..3d1242f5587c8 100644 --- a/eng/common/templates/steps/run-script-ifequalelse.yml +++ b/eng/common/templates/steps/run-script-ifequalelse.yml @@ -30,4 +30,4 @@ steps: name: ${{ parameters.name }} displayName: ${{ parameters.displayName }} env: ${{ parameters.env }} - condition: ${{ parameters.condition }} + condition: ${{ parameters.condition }} \ No newline at end of file diff --git a/global.json b/global.json index 572ecf2b8740e..b2f8615d5d8a8 100644 --- a/global.json +++ b/global.json @@ -1,21 +1,21 @@ { "sdk": { - "version": "5.0.100-preview.5.20228.8", + "version": "5.0.100-preview.5.20251.2", "allowPrerelease": true, "rollForward": "major" }, "tools": { - "dotnet": "5.0.100-preview.5.20228.8" + "dotnet": "5.0.100-preview.5.20251.2" }, "native-tools": { "cmake": "3.14.2", "python3": "3.7.1" }, "msbuild-sdks": { - "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20255.6", - "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20255.6", - "Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.20255.6", - "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20255.6", + "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20256.5", + "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20256.5", + "Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.20256.5", + "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20256.5", "FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0", "Microsoft.NET.Sdk.IL": "5.0.0-preview.4.20202.18", "Microsoft.Build.NoTargets": "1.0.53", From c1aab32df9fc37db0e0efaf498ef289ee9cb219b Mon Sep 17 00:00:00 2001 From: Drew Scoggins Date: Fri, 8 May 2020 10:50:13 -0700 Subject: [PATCH 065/420] Add mono performance runs (#34825) * Add mono perf job * Move runtimeFlavor to the right level * chnage variable access * Change condition * Add steps to download mono and build the patched dotnet * Change variable access * Pass variables directly * Plumb through mono path to runner * Fix parameter reference * Fix variables access? * Fix typo * Fix pathing issue * Add log saving for publish to helix step * Fix variable in shell script * Fix up mv command and publish logs step * Change runkind and add Windows runs * Add Windows mono build * Fixup parsing * Remove Windows runs for now * Switch to using build command to generate mono testhost * Fixup parens * Forgot to add a slash * Add Windows runs and fix pathing issue * Add backslash for Windows and -r for cp on Linux * Switch to using corerun argument * Switch to monopath * Use CoreRun * Remove mono property and use corerun instead * Fixing closing tags * Change xcopy to copy * Add llvm config flag * Add AOT and Interpreter config flags * Change order to ensure config gets added * Change order * Add exlusion filter for Perf_Image_Load tests * Add more to exclusion list * Remove Windows legs for now --- eng/common/performance/perfhelixpublish.proj | 8 +++++ eng/common/performance/performance-setup.ps1 | 27 ++++++++++++++ eng/common/performance/performance-setup.sh | 34 ++++++++++++++++++ eng/pipelines/coreclr/perf.yml | 23 +++++++++++- eng/pipelines/coreclr/templates/perf-job.yml | 36 ++++++++++++++++--- .../coreclr/templates/run-performance-job.yml | 8 +++++ 6 files changed, 130 insertions(+), 6 deletions(-) diff --git a/eng/common/performance/perfhelixpublish.proj b/eng/common/performance/perfhelixpublish.proj index cf5941e1b6455..1db5e8a84d758 100644 --- a/eng/common/performance/perfhelixpublish.proj +++ b/eng/common/performance/perfhelixpublish.proj @@ -6,6 +6,7 @@ py -3 %HELIX_CORRELATION_PAYLOAD%\Core_Root\CoreRun.exe %HELIX_CORRELATION_PAYLOAD%\Baseline_Core_Root\CoreRun.exe + $(HelixPreCommands);call %HELIX_CORRELATION_PAYLOAD%\performance\tools\machine-setup.cmd;set PYTHONPATH=%HELIX_WORKITEM_PAYLOAD%\scripts%3B%HELIX_WORKITEM_PAYLOAD% %HELIX_CORRELATION_PAYLOAD%\artifacts\BenchmarkDotNet.Artifacts %HELIX_CORRELATION_PAYLOAD%\artifacts\BenchmarkDotNet.Artifacts_Baseline @@ -40,6 +41,13 @@ $HELIX_WORKITEM_ROOT/testResults.xml + + --corerun %HELIX_CORRELATION_PAYLOAD%\dotnet-mono\shared\Microsoft.NETCore.App\5.0.0\corerun.exe + + + --corerun $(BaseDirectory)/dotnet-mono/shared/Microsoft.NETCore.App/5.0.0/corerun + + --corerun $(CoreRun) diff --git a/eng/common/performance/performance-setup.ps1 b/eng/common/performance/performance-setup.ps1 index f5e6ca688b709..31a99e49015f4 100644 --- a/eng/common/performance/performance-setup.ps1 +++ b/eng/common/performance/performance-setup.ps1 @@ -12,8 +12,12 @@ Param( [string] $RunCategories="Libraries Runtime", [string] $Csproj="src\benchmarks\micro\MicroBenchmarks.csproj", [string] $Kind="micro", + [switch] $LLVM, + [switch] $MonoInterpreter, + [switch] $MonoAOT, [switch] $Internal, [switch] $Compare, + [string] $MonoDotnet="", [string] $Configurations="CompilationMode=$CompilationMode RunKind=$Kind" ) @@ -50,6 +54,21 @@ if ($Internal) { $HelixSourcePrefix = "official" } +if($MonoDotnet -ne "") +{ + $Configurations += " LLVM=$LLVM MonoInterpreter=$MonoInterpreter MonoAOT=$MonoAOT" + if($ExtraBenchmarkDotNetArguments -eq "") + { + #FIX ME: We need to block these tests as they don't run on mono for now + $ExtraBenchmarkDotNetArguments = "--exclusion-filter *Perf_Image* *Perf_NamedPipeStream*" + } + else + { + #FIX ME: We need to block these tests as they don't run on mono for now + $ExtraBenchmarkDotNetArguments += " --exclusion-filter *Perf_Image* *Perf_NamedPipeStream*" + } +} + # FIX ME: This is a workaround until we get this from the actual pipeline $CommonSetupArguments="--channel master --queue $Queue --build-number $BuildNumber --build-configs $Configurations --architecture $Architecture" $SetupArguments = "--repository https://github.com/$Repository --branch $Branch --get-perf-hash --commit-sha $CommitSha $CommonSetupArguments" @@ -70,6 +89,13 @@ else { git clone --branch master --depth 1 --quiet https://github.com/dotnet/performance $PerformanceDirectory } +if($MonoDotnet -ne "") +{ + $UsingMono = "true" + $MonoDotnetPath = (Join-Path $PayloadDirectory "dotnet-mono") + Move-Item -Path $MonoDotnet -Destination $MonoDotnetPath +} + if ($UseCoreRun) { $NewCoreRoot = (Join-Path $PayloadDirectory "Core_Root") Move-Item -Path $CoreRootDirectory -Destination $NewCoreRoot @@ -105,6 +131,7 @@ Write-PipelineSetVariable -Name 'UseCoreRun' -Value "$UseCoreRun" -IsMultiJobVar Write-PipelineSetVariable -Name 'UseBaselineCoreRun' -Value "$UseBaselineCoreRun" -IsMultiJobVariable $false Write-PipelineSetVariable -Name 'RunFromPerfRepo' -Value "$RunFromPerformanceRepo" -IsMultiJobVariable $false Write-PipelineSetVariable -Name 'Compare' -Value "$Compare" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'MonoDotnet' -Value "$UsingMono" -IsMultiJobVariable $false # Helix Arguments Write-PipelineSetVariable -Name 'Creator' -Value "$Creator" -IsMultiJobVariable $false diff --git a/eng/common/performance/performance-setup.sh b/eng/common/performance/performance-setup.sh index 34eed8b672f18..9409e4d85e92e 100755 --- a/eng/common/performance/performance-setup.sh +++ b/eng/common/performance/performance-setup.sh @@ -12,13 +12,18 @@ commit_sha=$BUILD_SOURCEVERSION build_number=$BUILD_BUILDNUMBER internal=false compare=false +mono_dotnet= kind="micro" +llvm=false +monointerpreter=false +monoaot=false run_categories="Libraries Runtime" csproj="src\benchmarks\micro\MicroBenchmarks.csproj" configurations="CompliationMode=$compilation_mode RunKind=$kind" run_from_perf_repo=false use_core_run=true use_baseline_core_run=true +using_mono=false while (($# > 0)); do lowerI="$(echo $1 | awk '{print tolower($0)}')" @@ -65,6 +70,7 @@ while (($# > 0)); do ;; --kind) kind=$2 + configurations="CompliationMode=$compilation_mode RunKind=$kind" shift 2 ;; --runcategories) @@ -79,6 +85,22 @@ while (($# > 0)); do internal=true shift 1 ;; + --llvm) + llvm=true + shift 1 + ;; + --monointerpreter) + monointerpreter=true + shift 1 + ;; + --monoaot) + monoaot=true + shift 1 + ;; + --monodotnet) + mono_dotnet=$2 + shift 2 + ;; --compare) compare=true shift 1 @@ -107,6 +129,7 @@ while (($# > 0)); do echo " --kind Related to csproj. The kind of benchmarks that should be run. Defaults to micro" echo " --runcategories Related to csproj. Categories of benchmarks to run. Defaults to \"coreclr corefx\"" echo " --internal If the benchmarks are running as an official job." + echo " --monodotnet Pass the path to the mono dotnet for mono performance testing." echo "" exit 0 ;; @@ -164,6 +187,10 @@ if [[ "$internal" == true ]]; then fi fi +if [[ "$mono_dotnet" != "" ]]; then + configurations="$configurations LLVM=$llvm MonoInterpreter=$monointerpreter MonoAOT=$monoaot" +fi + common_setup_arguments="--channel master --queue $queue --build-number $build_number --build-configs $configurations --architecture $architecture" setup_arguments="--repository https://github.com/$repository --branch $branch --get-perf-hash --commit-sha $commit_sha $common_setup_arguments" @@ -186,6 +213,12 @@ else mv $docs_directory $workitem_directory fi +if [[ "$mono_dotnet" != "" ]]; then + using_mono=true + mono_dotnet_path=$payload_directory/dotnet-mono + mv $mono_dotnet $mono_dotnet_path +fi + if [[ "$use_core_run" = true ]]; then new_core_root=$payload_directory/Core_Root mv $core_root_directory $new_core_root @@ -221,3 +254,4 @@ Write-PipelineSetVariable -name "HelixSourcePrefix" -value "$helix_source_prefix Write-PipelineSetVariable -name "Kind" -value "$kind" -is_multi_job_variable false Write-PipelineSetVariable -name "_BuildConfig" -value "$architecture.$kind.$framework" -is_multi_job_variable false Write-PipelineSetVariable -name "Compare" -value "$compare" -is_multi_job_variable false +Write-PipelineSetVariable -name "MonoDotnet" -value "$using_mono" -is_multi_job_variable false diff --git a/eng/pipelines/coreclr/perf.yml b/eng/pipelines/coreclr/perf.yml index ffa22b8afc751..952fab6827849 100644 --- a/eng/pipelines/coreclr/perf.yml +++ b/eng/pipelines/coreclr/perf.yml @@ -60,11 +60,32 @@ jobs: - Windows_NT_x86 jobParameters: testGroup: perf - + +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/mono/templates/build-job.yml + runtimeFlavor: mono + buildConfig: release + platforms: + - Linux_x64 + +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml + buildConfig: release + runtimeFlavor: mono + platforms: + - Linux_x64 + jobParameters: + testGroup: perf + liveLibrariesBuildConfig: Release + runtimeType: mono + - template: /eng/pipelines/common/platform-matrix.yml parameters: jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml buildConfig: release + runtimeFlavor: coreclr platforms: - Linux_x64 - Windows_NT_x64 diff --git a/eng/pipelines/coreclr/templates/perf-job.yml b/eng/pipelines/coreclr/templates/perf-job.yml index 1e532b52ead0e..8bfd67fb7024a 100644 --- a/eng/pipelines/coreclr/templates/perf-job.yml +++ b/eng/pipelines/coreclr/templates/perf-job.yml @@ -7,6 +7,7 @@ parameters: framework: net5.0 # Specify the appropriate framework when running release branches (ie netcoreapp3.0 for release/3.0) liveLibrariesBuildConfig: '' variables: {} + runtimeType: 'coreclr' pool: '' ### Perf job @@ -18,24 +19,33 @@ jobs: - template: run-performance-job.yml parameters: # Compute job name from template parameters - jobName: ${{ format('perfbuild_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - displayName: ${{ format('Performance {0}{1} {2} {3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + jobName: ${{ format('perfbuild_{0}{1}_{2}_{3}_{4}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.runtimeType) }} + displayName: ${{ format('Performance {0}{1} {2} {3} {4}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.runtimeType) }} pool: ${{ parameters.pool }} buildConfig: ${{ parameters.buildConfig }} archType: ${{ parameters.archType }} osGroup: ${{ parameters.osGroup }} osSubgroup: ${{ parameters.osSubgroup }} liveLibrariesBuildConfig: ${{ parameters.liveLibrariesBuildConfig }} + runtimeType: ${{ parameters.runtimeType }} # Test job depends on the corresponding build job dependsOn: - ${{ format('coreclr_product_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}: - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveLibrariesBuildConfig) }} + - ${{ if eq(parameters.runtimeType, 'mono') }}: + - ${{ format('mono_product_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} ${{ if eq(parameters.osGroup, 'Windows_NT') }}: - extraSetupParameters: -CoreRootDirectory $(Build.SourcesDirectory)\artifacts\tests\coreclr\${{ parameters.osGroup }}.${{ parameters.archType }}.Release\Tests\Core_Root -Architecture ${{ parameters.archType }} + ${{ if eq(parameters.runtimeType, 'mono') }}: + extraSetupParameters: -Architecture ${{ parameters.archType }} -MonoDotnet $(Build.SourcesDirectory)\.dotnet-mono -Kind micro_mono + ${{ if ne(parameters.runtimeType, 'mono') }}: + extraSetupParameters: -CoreRootDirectory $(Build.SourcesDirectory)\artifacts\tests\coreclr\${{ parameters.osGroup }}.${{ parameters.archType }}.Release\Tests\Core_Root -Architecture ${{ parameters.archType }} ${{ if ne(parameters.osGroup, 'Windows_NT') }}: - extraSetupParameters: --corerootdirectory $(Build.SourcesDirectory)/artifacts/tests/coreclr/${{ parameters.osGroup }}.${{ parameters.archType }}.Release/Tests/Core_Root --architecture ${{ parameters.archType }} + ${{ if eq(parameters.runtimeType, 'mono') }}: + extraSetupParameters: --architecture ${{ parameters.archType }} --monodotnet $(Build.SourcesDirectory)/.dotnet-mono --kind micro_mono + ${{ if ne(parameters.runtimeType, 'mono') }}: + extraSetupParameters: --corerootdirectory $(Build.SourcesDirectory)/artifacts/tests/coreclr/${{ parameters.osGroup }}.${{ parameters.archType }}.Release/Tests/Core_Root --architecture ${{ parameters.archType }} variables: ${{ parameters.variables }} @@ -44,7 +54,6 @@ jobs: steps: # Extra steps that will be passed to the performance template and run before sending the job to helix (all of which is done in the template) - # Optionally download live-built libraries - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}: - template: /eng/pipelines/common/download-artifact-step.yml @@ -64,7 +73,24 @@ jobs: artifactName: '$(buildProductArtifactName)' displayName: 'product build' + - ${{ if eq(parameters.runtimeType, 'mono') }}: + - template: /eng/pipelines/common/download-artifact-step.yml + parameters: + unpackFolder: $(librariesDownloadDir)/bin/mono/$(osGroup).$(archType).$(buildConfigUpper) + cleanUnpackFolder: false + artifactFileName: 'MonoProduct_$(osGroup)_$(archType)_$(buildConfig)$(archiveExtension)' + artifactName: 'MonoProduct_$(osGroup)_$(archType)_$(buildConfig)' + displayName: 'Mono runtime' # Create Core_Root - script: $(coreClrRepoRootDir)build-test$(scriptExt) $(buildConfig) $(archType) generatelayoutonly $(librariesOverrideArg) displayName: Create Core_Root + condition: and(succeeded(), ne(variables.runtimeFlavorName, 'Mono')) + + - script: "build.cmd -subset libs.pretest -configuration release -ci -arch $(archType) -testscope innerloop /p:RuntimeArtifactsPath=$(librariesDownloadDir)\\bin\\mono\\$(osGroup).$(archType).$(buildConfigUpper) /p:RuntimeFlavor=mono;xcopy $(Build.SourcesDirectory)\\artifacts\\bin\\testhost\\$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)\\* $(Build.SourcesDirectory)\\.dotnet-mono /E /I /Y;copy $(Build.SourcesDirectory)\\artifacts\\bin\\coreclr\\$(osGroup).$(archType).$(buildConfigUpper)\\corerun.exe $(Build.SourcesDirectory)\\.dotnet-mono\\shared\\Microsoft.NETCore.App\\5.0.0\\corerun.exe" + displayName: "Create mono dotnet (Windows)" + condition: and(and(succeeded(), eq(variables.runtimeFlavorName, 'Mono')), eq(variables.osGroup, 'Windows_NT')) + + - script: "mkdir $(Build.SourcesDirectory)/.dotnet-mono;./build.sh -subset libs.pretest -configuration release -ci -arch $(archType) -testscope innerloop /p:RuntimeArtifactsPath=$(librariesDownloadDir)/bin/mono/$(osGroup).$(archType).$(buildConfigUpper) /p:RuntimeFlavor=mono;cp $(Build.SourcesDirectory)/artifacts/bin/testhost/$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)/* $(Build.SourcesDirectory)/.dotnet-mono -r;cp $(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(buildConfigUpper)/corerun $(Build.SourcesDirectory)/.dotnet-mono/shared/Microsoft.NETCore.App/5.0.0/corerun" + displayName: "Create mono dotnet (Linux)" + condition: and(and(succeeded(), eq(variables.runtimeFlavorName, 'Mono')), ne(variables.osGroup, 'Windows_NT')) diff --git a/eng/pipelines/coreclr/templates/run-performance-job.yml b/eng/pipelines/coreclr/templates/run-performance-job.yml index 1e37e86c8a645..881a498fbd20d 100644 --- a/eng/pipelines/coreclr/templates/run-performance-job.yml +++ b/eng/pipelines/coreclr/templates/run-performance-job.yml @@ -16,6 +16,7 @@ parameters: timeoutInMinutes: 320 # optional -- timeout for the job enableTelemetry: false # optional -- enable for telemetry liveLibrariesBuildConfig: '' # optional -- live-live libraries configuration to use for the run + runtimeType: 'coreclr' jobs: - template: xplat-pipeline-job.yml @@ -103,3 +104,10 @@ jobs: WorkItemTimeout: 4:00 # 4 hours WorkItemDirectory: '$(WorkItemDirectory)' # WorkItemDirectory can not be empty, so we send it some docs to keep it happy CorrelationPayloadDirectory: '$(PayloadDirectory)' # it gets checked out to a folder with shorter path than WorkItemDirectory so we can avoid file name too long exceptions + - task: PublishPipelineArtifact@1 + displayName: Publish Logs + inputs: + targetPath: $(Build.SourcesDirectory)/artifacts/log + artifactName: 'Performance_Run_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)_${{ parameters.runtimeType }}' + continueOnError: true + condition: always() From a17dae5443d2ef835f1bbefa275d0bb050339fed Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 8 May 2020 11:34:07 -0700 Subject: [PATCH 066/420] Fix reverse marshalling of refs to blittable types (#8140) (#36119) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hit in selfhosted ilc.exe. In JitInterface we have a couple cases where we do reverse p/invoke with a delegate that has a ref parameter. Sometimes the `ref` is null (and we don't touch it). The marshaller was trying to make a copy of the pointed to value, NullRefing in the process because the pointer was null. We don't actually need to make a copy because the value is blittable. Co-authored-by: Michal Strehovský --- .../src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs index 50bbebb49f08b..17931e448fcff 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs @@ -909,7 +909,7 @@ protected override void EmitMarshalArgumentManagedToNative() protected override void EmitMarshalArgumentNativeToManaged() { - if (Out) + if (Out && !IsNativeByRef) { base.EmitMarshalArgumentNativeToManaged(); } From 2cd041bbee2170dfa388d37336d50554ea89eb2e Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Fri, 8 May 2020 21:03:17 +0200 Subject: [PATCH 067/420] Document F5 and Test Explorer prerequisites (#36117) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Document F5 and Test Explorer prerequisites * Update docs/workflow/testing/visualstudio.md Co-authored-by: Alexander Köplinger --- docs/workflow/testing/libraries/testing.md | 10 ---------- docs/workflow/testing/visualstudio.md | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 10 deletions(-) create mode 100644 docs/workflow/testing/visualstudio.md diff --git a/docs/workflow/testing/libraries/testing.md b/docs/workflow/testing/libraries/testing.md index bf100c4ba485a..986d0e9606e4c 100644 --- a/docs/workflow/testing/libraries/testing.md +++ b/docs/workflow/testing/libraries/testing.md @@ -63,13 +63,3 @@ Each test project can potentially have multiple target frameworks. There are som ```cmd dotnet build src\libraries\System.Runtime\tests\System.Runtime.Tests.csproj /p:BuildTargetFramework=net472 ``` - -## Running tests from Visual Studio - -**Test Explorer** will be able to discover the tests only if the solution is opened with `build -vs` command, e.g.: -```cmd -build -vs System.Net.Http -``` -If running the tests from **Test Explorer** does nothing, it probably tries to use x86 dotnet installation instead of the x64 one. It can be fixed by setting the x64 architecture manually in the test settings. - -It is also possible to execute the tests by simply debugging the test project once it's been built. It will underneath call the same command as `dotnet build /t:Test` does. diff --git a/docs/workflow/testing/visualstudio.md b/docs/workflow/testing/visualstudio.md new file mode 100644 index 0000000000000..c8c20b9cfc7fa --- /dev/null +++ b/docs/workflow/testing/visualstudio.md @@ -0,0 +1,16 @@ +# Visual Studio Test Explorer support +For Visual Studio Test Explorer to work in dotnet/runtime, the following test settings need to be enabled: +- Test parameters (like which `dotnet` host to use) are persisted in an auto-generated .runsettings file. For that to work, make sure that the "Auto detect runsettings Files" (`Options -> Test`) option is enabled. +- Make sure that the "Processor Architecture for AnyCPU project" (`Test Explore pane -> Test Explorer toolbar options --> Settings`) value is set to `auto`. + +# Visual Studio F5 Debugging support +dotnet/runtime uses `dotnet test` ([VSTest](https://github.com/Microsoft/vstest)) which spawns child processes during test execution. +Visual Studio by default doesn't automatically debug child processes, therefore preliminary steps need to be done to enable Debugging "F5" support. +Note that these steps aren't necessary for Visual Studio Test Explorer support. +1. Install the [Microsoft Child Process Debugging Power Tool](https://marketplace.visualstudio.com/items?itemName=vsdbgplat.MicrosoftChildProcessDebuggingPowerTool) extension. +2. Go to the child process debug settings (`Debug -> Other Debug Targets -> Child Process Debugging Settings...`), enable the "Enable child process debugging" option and hit save. +3. Go to the project debug settings (`Debug -> $ProjectName Properties`) and enable the "Enable native code debugging" option. + +## References +- https://github.com/dotnet/project-system/issues/6176 tracks enabling the native code debugging functionality for multiple projects without user interaction. +- https://github.com/dotnet/sdk/issues/7419#issuecomment-298261617 explains the necessary steps to install and enable the mentioned extension in more detail. From 863d4583f34b3d84010308edb3dd66721f7696ee Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Fri, 8 May 2020 12:07:15 -0700 Subject: [PATCH 068/420] Add windows 8 and windows 7 testing for PRs in a reduced way (#36096) --- eng/pipelines/libraries/helix-queues-setup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index c221d8b780c7f..3b3ac9d1106c9 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -98,7 +98,7 @@ jobs: - ${{ if eq(parameters.jobParameters.isFullMatrix, false) }}: # Bring back once: https://github.com/dotnet/runtime/issues/35689 is fixed # - Windows.7.Amd64.Open - # - Windows.81.Amd64.Open + - Windows.81.Amd64.Open - Windows.10.Amd64.Server19H1.ES.Open - ${{ if ne(parameters.jobParameters.runtimeFlavor, 'mono') }}: - (Windows.Nano.1809.Amd64.Open)windows.10.amd64.serverrs5.open@mcr.microsoft.com/dotnet-buildtools/prereqs:nanoserver-1809-helix-amd64-08e8e40-20200107182504 @@ -125,8 +125,8 @@ jobs: - ${{ if eq(parameters.jobParameters.buildConfig, 'Release') }}: - Windows.10.Amd64.Server19H1.ES.Open - ${{ if eq(parameters.jobParameters.buildConfig, 'Debug') }}: + - Windows.7.Amd64.Open # Bring back once: https://github.com/dotnet/runtime/issues/35689 is fixed - # - Windows.7.Amd64.Open # - Windows.81.Amd64.Open - Windows.10.Amd64.Server19H1.Open From fd82afe3826d7778a46bda33db4b6e92de679a05 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Fri, 8 May 2020 22:12:25 +0200 Subject: [PATCH 069/420] Enable VS Test Explorer without the -vs switch (#36126) * Enable VS Test Explorer without the -vs switch --- eng/build.ps1 | 1 + eng/testing/coverage.targets | 14 +++++++++++++- eng/testing/runsettings.targets | 26 ++++++++++++-------------- eng/testing/tests.targets | 1 - src/libraries/Directory.Build.props | 4 +++- src/libraries/Directory.Build.targets | 5 +++-- src/libraries/pretest.proj | 11 +++++++++++ 7 files changed, 43 insertions(+), 19 deletions(-) diff --git a/eng/build.ps1 b/eng/build.ps1 index 09d8164516acd..e811cf6db27d7 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -61,6 +61,7 @@ if ($help -or (($null -ne $properties) -and ($properties.Contains('/help') -or $ # VS Test Explorer support for libraries if ($vs) { + Write-Host "!!! VS Test Explorer now works without the -vs switch. The switch will be removed eventually. !!! " . $PSScriptRoot\common\tools.ps1 # Microsoft.DotNet.CoreSetup.sln is special - hosting tests are currently meant to run on the diff --git a/eng/testing/coverage.targets b/eng/testing/coverage.targets index fd53a86bda515..6f8ac2648f06e 100644 --- a/eng/testing/coverage.targets +++ b/eng/testing/coverage.targets @@ -4,7 +4,7 @@ We need to filter the data to only the assembly being tested. Otherwise we will gather tons of data about other assemblies. If the code being tested is part of the runtime itself, it requires special treatment. --> - + <_ProjectDirectoryUnderSourceDir>$(MSBuildProjectDirectory.SubString($(LibrariesProjectRoot.Length))) $(_ProjectDirectoryUnderSourceDir.SubString(0, $(_ProjectDirectoryUnderSourceDir.IndexOfAny("\\/")))) @@ -74,4 +74,16 @@ + + + + + + diff --git a/eng/testing/runsettings.targets b/eng/testing/runsettings.targets index ffd1939b54255..10496127b8a90 100644 --- a/eng/testing/runsettings.targets +++ b/eng/testing/runsettings.targets @@ -1,9 +1,18 @@ - $(MSBuildThisFileDirectory).runsettings - $(OutDir).runsettings + $(MSBuildThisFileDirectory).runsettings + $(ArtifactsObjDir)$(TargetOS)-$(Configuration)-$(TargetArchitecture).runsettings + $(OutDir).runsettings + + false + $(RunSettingsIntermediateOutputFilePath) + $(RunSettingsAppOutputFilePath) + - $(RunSettingsOutputFilePath) + $(RunSettingsAppOutputFilePath) + + $(RunSettingsIntermediateOutputFilePath) + GenerateRunSettingsFile;$(PrepareForRunDependsOn) @@ -41,15 +50,4 @@ $(RunSettingsOutputFilePath) - - - - - diff --git a/eng/testing/tests.targets b/eng/testing/tests.targets index 56097fa6566d2..e4257a349d687 100644 --- a/eng/testing/tests.targets +++ b/eng/testing/tests.targets @@ -217,7 +217,6 @@ - diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index f358b94b2a5ae..49f01af7d36bb 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -327,7 +327,9 @@ true - true + + true + true diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index 7c2f62de0a78f..c2124d089bdbc 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -136,9 +136,10 @@ - - + + + diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj index eeac3ea516223..a55bd441c79b0 100644 --- a/src/libraries/pretest.proj +++ b/src/libraries/pretest.proj @@ -6,6 +6,12 @@ $(TargetFrameworkIdentifier) + + + true + true + + @@ -19,6 +25,11 @@ Properties="$(TraversalGlobalProperties)" /> + + From ca8c9dea8e30a9701160e4cd61b5b26f209499ff Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Fri, 8 May 2020 14:30:35 -0700 Subject: [PATCH 070/420] Revert "Remove superflous CheckReleased call which will slow down Event Log Reading up to 20x times. (#35911)" (#36143) This reverts commit 4602a61526631a5b29d451b40be3e3e321b86c00. --- .../Diagnostics/Reader/ProviderMetadataCachedInformation.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/ProviderMetadataCachedInformation.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/ProviderMetadataCachedInformation.cs index 9b02652d60526..8e49408433bea 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/ProviderMetadataCachedInformation.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/ProviderMetadataCachedInformation.cs @@ -156,6 +156,7 @@ private ProviderMetadata GetProviderMetadata(ProviderMetadataId key) try { + pm.CheckReleased(); UpdateCacheValueInfoForHit(cacheItem); } catch (EventLogException) From e77572ffccc566186f47207f3c5475533c87538e Mon Sep 17 00:00:00 2001 From: Nathan Ricci Date: Fri, 8 May 2020 17:58:24 -0400 Subject: [PATCH 071/420] Naricc/test mono is mono (#36079) Add test to test if we are running mono. --- src/coreclr/tests/issues.targets | 3 +++ .../src/baseservices/mono/runningmono.cs | 26 +++++++++++++++++++ .../src/baseservices/mono/runningmono.csproj | 11 ++++++++ 3 files changed, 40 insertions(+) create mode 100644 src/coreclr/tests/src/baseservices/mono/runningmono.cs create mode 100644 src/coreclr/tests/src/baseservices/mono/runningmono.csproj diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index be29df300d538..f4b1eb4c147d1 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -116,6 +116,9 @@ https://github.com/dotnet/runtime/issues/3893 + + This test is to verify we are running mono, and therefore only makes sense on mono. + diff --git a/src/coreclr/tests/src/baseservices/mono/runningmono.cs b/src/coreclr/tests/src/baseservices/mono/runningmono.cs new file mode 100644 index 0000000000000..1a6a4151a38b6 --- /dev/null +++ b/src/coreclr/tests/src/baseservices/mono/runningmono.cs @@ -0,0 +1,26 @@ +// 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. +using System; + +namespace TestRunningMono +{ + class Program + { + public static int Main(string[] args) + { + const int Pass = 100, Fail = 1; + bool isMono = typeof(object).Assembly.GetType("Mono.RuntimeStructs") != null; + + if(isMono) + { + return Pass; + } + else + { + return Fail; + } + } + } +} + diff --git a/src/coreclr/tests/src/baseservices/mono/runningmono.csproj b/src/coreclr/tests/src/baseservices/mono/runningmono.csproj new file mode 100644 index 0000000000000..c560a028e3b8c --- /dev/null +++ b/src/coreclr/tests/src/baseservices/mono/runningmono.csproj @@ -0,0 +1,11 @@ + + + Exe + false + 0 + + + + + + From 8d2695accc2aa2c434bff2de854ac5a7f5b6f247 Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Fri, 8 May 2020 12:07:36 -0700 Subject: [PATCH 072/420] remove dependency on System.Native from System.IO.Ports --- .../Unix/System.IO.Ports.Native/pal_serial.c | 386 ++++++++++++++++++ .../Unix/System.IO.Ports.Native/pal_serial.h | 147 +++++++ .../src/Interop/Unix/Interop.Serial.cs | 94 +++++ .../src/System.IO.Ports.csproj | 8 - .../IO/Ports/SafeSerialDeviceHandle.Unix.cs | 2 +- .../src/System/IO/Ports/SerialStream.Unix.cs | 26 +- 6 files changed, 641 insertions(+), 22 deletions(-) diff --git a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c index cca1c53aa63e0..0615b450fbf70 100644 --- a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c +++ b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c @@ -10,6 +10,9 @@ #include #include #include +#include +#include +#include /* Open device file in non-blocking mode and without controlling terminal */ intptr_t SystemIoPortsNative_SerialPortOpen(const char * name) @@ -44,3 +47,386 @@ int SystemIoPortsNative_SerialPortClose(intptr_t handle) ioctl(fd, TIOCNXCL); return close(fd); } + +int32_t ConvertErrorPlatformToPal(int32_t platformErrno) +{ + switch (platformErrno) + { + case 0: + return Error_SUCCESS; + case E2BIG: + return Error_E2BIG; + case EACCES: + return Error_EACCES; + case EADDRINUSE: + return Error_EADDRINUSE; + case EADDRNOTAVAIL: + return Error_EADDRNOTAVAIL; + case EAFNOSUPPORT: + return Error_EAFNOSUPPORT; + case EAGAIN: + return Error_EAGAIN; + case EALREADY: + return Error_EALREADY; + case EBADF: + return Error_EBADF; + case EBADMSG: + return Error_EBADMSG; + case EBUSY: + return Error_EBUSY; + case ECANCELED: + return Error_ECANCELED; + case ECHILD: + return Error_ECHILD; + case ECONNABORTED: + return Error_ECONNABORTED; + case ECONNREFUSED: + return Error_ECONNREFUSED; + case ECONNRESET: + return Error_ECONNRESET; + case EDEADLK: + return Error_EDEADLK; + case EDESTADDRREQ: + return Error_EDESTADDRREQ; + case EDOM: + return Error_EDOM; + case EDQUOT: + return Error_EDQUOT; + case EEXIST: + return Error_EEXIST; + case EFAULT: + return Error_EFAULT; + case EFBIG: + return Error_EFBIG; + case EHOSTUNREACH: + return Error_EHOSTUNREACH; + case EIDRM: + return Error_EIDRM; + case EILSEQ: + return Error_EILSEQ; + case EINPROGRESS: + return Error_EINPROGRESS; + case EINTR: + return Error_EINTR; + case EINVAL: + return Error_EINVAL; + case EIO: + return Error_EIO; + case EISCONN: + return Error_EISCONN; + case EISDIR: + return Error_EISDIR; + case ELOOP: + return Error_ELOOP; + case EMFILE: + return Error_EMFILE; + case EMLINK: + return Error_EMLINK; + case EMSGSIZE: + return Error_EMSGSIZE; + case EMULTIHOP: + return Error_EMULTIHOP; + case ENAMETOOLONG: + return Error_ENAMETOOLONG; + case ENETDOWN: + return Error_ENETDOWN; + case ENETRESET: + return Error_ENETRESET; + case ENETUNREACH: + return Error_ENETUNREACH; + case ENFILE: + return Error_ENFILE; + case ENOBUFS: + return Error_ENOBUFS; + case ENODEV: + return Error_ENODEV; + case ENOENT: + return Error_ENOENT; + case ENOEXEC: + return Error_ENOEXEC; + case ENOLCK: + return Error_ENOLCK; + case ENOLINK: + return Error_ENOLINK; + case ENOMEM: + return Error_ENOMEM; + case ENOMSG: + return Error_ENOMSG; + case ENOPROTOOPT: + return Error_ENOPROTOOPT; + case ENOSPC: + return Error_ENOSPC; + case ENOSYS: + return Error_ENOSYS; + case ENOTCONN: + return Error_ENOTCONN; + case ENOTDIR: + return Error_ENOTDIR; +#if ENOTEMPTY != EEXIST // AIX defines this + case ENOTEMPTY: + return Error_ENOTEMPTY; +#endif +#ifdef ENOTRECOVERABLE // not available in NetBSD + case ENOTRECOVERABLE: + return Error_ENOTRECOVERABLE; +#endif + case ENOTSOCK: + return Error_ENOTSOCK; + case ENOTSUP: + return Error_ENOTSUP; + case ENOTTY: + return Error_ENOTTY; + case ENXIO: + return Error_ENXIO; + case EOVERFLOW: + return Error_EOVERFLOW; +#ifdef EOWNERDEAD // not available in NetBSD + case EOWNERDEAD: + return Error_EOWNERDEAD; +#endif + case EPERM: + return Error_EPERM; + case EPIPE: + return Error_EPIPE; + case EPROTO: + return Error_EPROTO; + case EPROTONOSUPPORT: + return Error_EPROTONOSUPPORT; + case EPROTOTYPE: + return Error_EPROTOTYPE; + case ERANGE: + return Error_ERANGE; + case EROFS: + return Error_EROFS; + case ESPIPE: + return Error_ESPIPE; + case ESRCH: + return Error_ESRCH; + case ESTALE: + return Error_ESTALE; + case ETIMEDOUT: + return Error_ETIMEDOUT; + case ETXTBSY: + return Error_ETXTBSY; + case EXDEV: + return Error_EXDEV; +#ifdef ESOCKTNOSUPPORT + case ESOCKTNOSUPPORT: + return Error_ESOCKTNOSUPPORT; +#endif + case EPFNOSUPPORT: + return Error_EPFNOSUPPORT; + case ESHUTDOWN: + return Error_ESHUTDOWN; + case EHOSTDOWN: + return Error_EHOSTDOWN; + case ENODATA: + return Error_ENODATA; + +// #if because these will trigger duplicate case label warnings when +// they have the same value, which is permitted by POSIX and common. +#if EOPNOTSUPP != ENOTSUP + case EOPNOTSUPP: + return Error_EOPNOTSUPP; +#endif +#if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: + return Error_EWOULDBLOCK; +#endif + } + + return Error_ENONSTANDARD; +} + +int32_t SystemIoPortsNative_Read(intptr_t fd, void* buffer, int32_t bufferSize) +{ + assert(buffer != NULL || bufferSize == 0); + assert(bufferSize >= 0); + + if (bufferSize < 0) + { + errno = EINVAL; + return -1; + } + + ssize_t count; + while ((count = read(ToFileDescriptor(fd), buffer, (uint32_t)bufferSize)) < 0 && errno == EINTR); + + assert(count >= -1 && count <= bufferSize); + return (int32_t)count; +} + +int32_t SystemIoPortsNative_Write(intptr_t fd, const void* buffer, int32_t bufferSize) +{ + assert(buffer != NULL || bufferSize == 0); + assert(bufferSize >= 0); + + if (bufferSize < 0) + { + errno = ERANGE; + return -1; + } + + ssize_t count; + while ((count = write(ToFileDescriptor(fd), buffer, (uint32_t)bufferSize)) < 0 && errno == EINTR); + + assert(count >= -1 && count <= bufferSize); + return (int32_t)count; +} + +int32_t SystemIoPortsNative_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t milliseconds, uint32_t* triggered) +{ + if (pollEvents == NULL || triggered == NULL) + { + return Error_EFAULT; + } + + if (milliseconds < -1) + { + return Error_EINVAL; + } + + struct pollfd stackBuffer[(uint32_t)(2048/sizeof(struct pollfd))]; + int useStackBuffer = eventCount <= ARRAY_SIZE(stackBuffer); + struct pollfd* pollfds = NULL; + if (useStackBuffer) + { + pollfds = &stackBuffer[0]; + } + else + { + pollfds = calloc(eventCount, sizeof(*pollfds)); + if (pollfds == NULL) + { + return Error_ENOMEM; + } + } + + for (uint32_t i = 0; i < eventCount; i++) + { + const PollEvent* event = &pollEvents[i]; + pollfds[i].fd = event->FileDescriptor; + // we need to do this for platforms like AIX where PAL_POLL* doesn't + // match up to their reality; this is PollEvent -> system polling + switch (event->Events) + { + case PAL_POLLIN: + pollfds[i].events = POLLIN; + break; + case PAL_POLLPRI: + pollfds[i].events = POLLPRI; + break; + case PAL_POLLOUT: + pollfds[i].events = POLLOUT; + break; + case PAL_POLLERR: + pollfds[i].events = POLLERR; + break; + case PAL_POLLHUP: + pollfds[i].events = POLLHUP; + break; + case PAL_POLLNVAL: + pollfds[i].events = POLLNVAL; + break; + default: + pollfds[i].events = event->Events; + break; + } + pollfds[i].revents = 0; + } + + int rv; + while ((rv = poll(pollfds, (nfds_t)eventCount, milliseconds)) < 0 && errno == EINTR); + + if (rv < 0) + { + if (!useStackBuffer) + { + free(pollfds); + } + + *triggered = 0; + return ConvertErrorPlatformToPal(errno); + } + + for (uint32_t i = 0; i < eventCount; i++) + { + const struct pollfd* pfd = &pollfds[i]; + assert(pfd->fd == pollEvents[i].FileDescriptor); + assert(pfd->events == pollEvents[i].Events); + + // same as the other switch, just system -> PollEvent + switch (pfd->revents) + { + case POLLIN: + pollEvents[i].TriggeredEvents = PAL_POLLIN; + break; + case POLLPRI: + pollEvents[i].TriggeredEvents = PAL_POLLPRI; + break; + case POLLOUT: + pollEvents[i].TriggeredEvents = PAL_POLLOUT; + break; + case POLLERR: + pollEvents[i].TriggeredEvents = PAL_POLLERR; + break; + case POLLHUP: + pollEvents[i].TriggeredEvents = PAL_POLLHUP; + break; + case POLLNVAL: + pollEvents[i].TriggeredEvents = PAL_POLLNVAL; + break; + default: + pollEvents[i].TriggeredEvents = (int16_t)pfd->revents; + break; + } + } + + *triggered = (uint32_t)rv; + + if (!useStackBuffer) + { + free(pollfds); + } + + return Error_SUCCESS; +} + +/* + * Socket shutdown modes. + * + * NOTE: these values are taken from System.Net.SocketShutdown. + */ +typedef enum +{ + SocketShutdown_SHUT_READ = 0, // SHUT_RD + SocketShutdown_SHUT_WRITE = 1, // SHUT_WR + SocketShutdown_SHUT_BOTH = 2, // SHUT_RDWR +} SocketShutdown; + +int32_t SystemIoPortsNative_Shutdown(intptr_t socket, int32_t socketShutdown) +{ + int fd = ToFileDescriptor(socket); + + int how; + switch (socketShutdown) + { + case SocketShutdown_SHUT_READ: + how = SHUT_RD; + break; + + case SocketShutdown_SHUT_WRITE: + how = SHUT_WR; + break; + + case SocketShutdown_SHUT_BOTH: + how = SHUT_RDWR; + break; + + default: + return Error_EINVAL; + } + + int err = shutdown(fd, how); + return err == 0 ? Error_SUCCESS : ConvertErrorPlatformToPal(errno); +} diff --git a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.h b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.h index 3d35b8186ed89..dd32304e0774f 100644 --- a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.h +++ b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.h @@ -5,5 +5,152 @@ #include "pal_types.h" #include "pal_compiler.h" +/** + * Our intermediate pollfd struct to normalize the data types + */ +typedef struct +{ + int32_t FileDescriptor; // The file descriptor to poll + int16_t Events; // The events to poll for + int16_t TriggeredEvents; // The events that triggered the poll +} PollEvent; + PALEXPORT intptr_t SystemIoPortsNative_SerialPortOpen(const char * name); PALEXPORT int SystemIoPortsNative_SerialPortClose(intptr_t fd); +PALEXPORT int32_t SystemIoPortsNative_Read(intptr_t fd, void* buffer, int32_t bufferSize); +PALEXPORT int32_t SystemIoPortsNative_Write(intptr_t fd, const void* buffer, int32_t bufferSize); +PALEXPORT int32_t SystemIoPortsNative_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t milliseconds, uint32_t* triggered); +PALEXPORT int32_t SystemIoPortsNative_Shutdown(intptr_t socket, int32_t socketShutdown); + +/** + * Constants passed to and from poll describing what to poll for and what + * kind of data was received from poll. + */ +typedef enum +{ + PAL_POLLIN = 0x0001, /* non-urgent readable data available */ + PAL_POLLPRI = 0x0002, /* urgent readable data available */ + PAL_POLLOUT = 0x0004, /* data can be written without blocked */ + PAL_POLLERR = 0x0008, /* an error occurred */ + PAL_POLLHUP = 0x0010, /* the file descriptor hung up */ + PAL_POLLNVAL = 0x0020, /* the requested events were invalid */ +} PollEvents; + +/** + * Error codes returned via ConvertErrno. + * + * Only the names (without the PAL_ prefix) are specified by POSIX. + * + * The values chosen below are simply assigned arbitrarily (originally + * in alphabetical order they appear in the spec, but they can't change so + * add new values to the end!). + * + * Also, the values chosen are deliberately outside the range of + * typical UNIX errnos (small numbers), HRESULTs (negative for errors) + * and Win32 errors (0x0000 - 0xFFFF). This isn't required for + * correctness, but may help debug a caller that is interpreting a raw + * int incorrectly. + * + * Wherever the spec says "x may be the same value as y", we do use + * the same value so that callers cannot not take a dependency on + * being able to distinguish between them. + */ +typedef enum +{ + Error_SUCCESS = 0, + + Error_E2BIG = 0x10001, // Argument list too long. + Error_EACCES = 0x10002, // Permission denied. + Error_EADDRINUSE = 0x10003, // Address in use. + Error_EADDRNOTAVAIL = 0x10004, // Address not available. + Error_EAFNOSUPPORT = 0x10005, // Address family not supported. + Error_EAGAIN = 0x10006, // Resource unavailable, try again (same value as EWOULDBLOCK), + Error_EALREADY = 0x10007, // Connection already in progress. + Error_EBADF = 0x10008, // Bad file descriptor. + Error_EBADMSG = 0x10009, // Bad message. + Error_EBUSY = 0x1000A, // Device or resource busy. + Error_ECANCELED = 0x1000B, // Operation canceled. + Error_ECHILD = 0x1000C, // No child processes. + Error_ECONNABORTED = 0x1000D, // Connection aborted. + Error_ECONNREFUSED = 0x1000E, // Connection refused. + Error_ECONNRESET = 0x1000F, // Connection reset. + Error_EDEADLK = 0x10010, // Resource deadlock would occur. + Error_EDESTADDRREQ = 0x10011, // Destination address required. + Error_EDOM = 0x10012, // Mathematics argument out of domain of function. + Error_EDQUOT = 0x10013, // Reserved. + Error_EEXIST = 0x10014, // File exists. + Error_EFAULT = 0x10015, // Bad address. + Error_EFBIG = 0x10016, // File too large. + Error_EHOSTUNREACH = 0x10017, // Host is unreachable. + Error_EIDRM = 0x10018, // Identifier removed. + Error_EILSEQ = 0x10019, // Illegal byte sequence. + Error_EINPROGRESS = 0x1001A, // Operation in progress. + Error_EINTR = 0x1001B, // Interrupted function. + Error_EINVAL = 0x1001C, // Invalid argument. + Error_EIO = 0x1001D, // I/O error. + Error_EISCONN = 0x1001E, // Socket is connected. + Error_EISDIR = 0x1001F, // Is a directory. + Error_ELOOP = 0x10020, // Too many levels of symbolic links. + Error_EMFILE = 0x10021, // File descriptor value too large. + Error_EMLINK = 0x10022, // Too many links. + Error_EMSGSIZE = 0x10023, // Message too large. + Error_EMULTIHOP = 0x10024, // Reserved. + Error_ENAMETOOLONG = 0x10025, // Filename too long. + Error_ENETDOWN = 0x10026, // Network is down. + Error_ENETRESET = 0x10027, // Connection aborted by network. + Error_ENETUNREACH = 0x10028, // Network unreachable. + Error_ENFILE = 0x10029, // Too many files open in system. + Error_ENOBUFS = 0x1002A, // No buffer space available. + Error_ENODEV = 0x1002C, // No such device. + Error_ENOENT = 0x1002D, // No such file or directory. + Error_ENOEXEC = 0x1002E, // Executable file format error. + Error_ENOLCK = 0x1002F, // No locks available. + Error_ENOLINK = 0x10030, // Reserved. + Error_ENOMEM = 0x10031, // Not enough space. + Error_ENOMSG = 0x10032, // No message of the desired type. + Error_ENOPROTOOPT = 0x10033, // Protocol not available. + Error_ENOSPC = 0x10034, // No space left on device. + Error_ENOSYS = 0x10037, // Function not supported. + Error_ENOTCONN = 0x10038, // The socket is not connected. + Error_ENOTDIR = 0x10039, // Not a directory or a symbolic link to a directory. + Error_ENOTEMPTY = 0x1003A, // Directory not empty. + Error_ENOTRECOVERABLE = 0x1003B, // State not recoverable. + Error_ENOTSOCK = 0x1003C, // Not a socket. + Error_ENOTSUP = 0x1003D, // Not supported (same value as EOPNOTSUP). + Error_ENOTTY = 0x1003E, // Inappropriate I/O control operation. + Error_ENXIO = 0x1003F, // No such device or address. + Error_EOVERFLOW = 0x10040, // Value too large to be stored in data type. + Error_EOWNERDEAD = 0x10041, // Previous owner died. + Error_EPERM = 0x10042, // Operation not permitted. + Error_EPIPE = 0x10043, // Broken pipe. + Error_EPROTO = 0x10044, // Protocol error. + Error_EPROTONOSUPPORT = 0x10045, // Protocol not supported. + Error_EPROTOTYPE = 0x10046, // Protocol wrong type for socket. + Error_ERANGE = 0x10047, // Result too large. + Error_EROFS = 0x10048, // Read-only file system. + Error_ESPIPE = 0x10049, // Invalid seek. + Error_ESRCH = 0x1004A, // No such process. + Error_ESTALE = 0x1004B, // Reserved. + Error_ETIMEDOUT = 0x1004D, // Connection timed out. + Error_ETXTBSY = 0x1004E, // Text file busy. + Error_EXDEV = 0x1004F, // Cross-device link. + Error_ESOCKTNOSUPPORT = 0x1005E, // Socket type not supported. + Error_EPFNOSUPPORT = 0x10060, // Protocol family not supported. + Error_ESHUTDOWN = 0x1006C, // Socket shutdown. + Error_EHOSTDOWN = 0x10070, // Host is down. + Error_ENODATA = 0x10071, // No data available. + + // Error codes to track errors beyond kernel. + Error_EHOSTNOTFOUND = 0x20001, // Name lookup failed. + + // POSIX permits these to have the same value and we make them + // always equal so that we cannot introduce a dependency on + // distinguishing between them that would not work on all + // platforms. + Error_EOPNOTSUPP = Error_ENOTSUP, // Operation not supported on socket + Error_EWOULDBLOCK = Error_EAGAIN, // Operation would block + + // This one is not part of POSIX, but is a catch-all for the case + // where we cannot convert the raw errno value to something above. + Error_ENONSTANDARD = 0x1FFFF, +} Error; diff --git a/src/libraries/System.IO.Ports/src/Interop/Unix/Interop.Serial.cs b/src/libraries/System.IO.Ports/src/Interop/Unix/Interop.Serial.cs index 66822a7f9ca84..44264a53463a3 100644 --- a/src/libraries/System.IO.Ports/src/Interop/Unix/Interop.Serial.cs +++ b/src/libraries/System.IO.Ports/src/Interop/Unix/Interop.Serial.cs @@ -4,6 +4,7 @@ using System; using System.IO.Ports; +using System.Net.Sockets; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; @@ -11,10 +12,103 @@ internal static partial class Interop { internal static partial class Serial { + [Flags] + internal enum PollEvents : short + { + POLLNONE = 0x0000, // No events occurred. + POLLIN = 0x0001, // non-urgent readable data available + POLLPRI = 0x0002, // urgent readable data available + POLLOUT = 0x0004, // data can be written without blocked + POLLERR = 0x0008, // an error occurred + POLLHUP = 0x0010, // the file descriptor hung up + POLLNVAL = 0x0020, // the requested events were invalid + } + + internal struct PollEvent + { + internal int FileDescriptor; // The file descriptor to poll + internal PollEvents Events; // The events to poll for + internal PollEvents TriggeredEvents; // The events that occurred which triggered the poll + } + [DllImport(Libraries.IOPortsNative, EntryPoint = "SystemIoPortsNative_SerialPortOpen", SetLastError = true)] internal static extern SafeSerialDeviceHandle SerialPortOpen(string name); [DllImport(Libraries.IOPortsNative, EntryPoint = "SystemIoPortsNative_SerialPortClose", SetLastError = true)] internal static extern int SerialPortClose(IntPtr handle); + + [DllImport(Libraries.IOPortsNative, EntryPoint = "SystemIoPortsNative_Shutdown")] + internal static extern Error Shutdown(IntPtr socket, SocketShutdown how); + + /// + /// Reads a number of bytes from an open file descriptor into a specified buffer. + /// + /// The open file descriptor to try to read from + /// The buffer to read info into + /// The size of the buffer + /// + /// Returns the number of bytes read on success; otherwise, -1 is returned + /// Note - on fail. the position of the stream may change depending on the platform; consult man 2 read for more info + /// + [DllImport(Libraries.IOPortsNative, EntryPoint = "SystemIoPortsNative_Read", SetLastError = true)] + internal static extern unsafe int Read(SafeHandle fd, byte* buffer, int count); + + /// + /// Writes the specified buffer to the provided open file descriptor + /// + /// The file descriptor to try and write to + /// The data to attempt to write + /// The amount of data to write, in bytes + /// + /// Returns the number of bytes written on success; otherwise, returns -1 and sets errno + /// + [DllImport(Libraries.IOPortsNative, EntryPoint = "SystemIoPortsNative_Write", SetLastError = true)] + internal static extern unsafe int Write(SafeHandle fd, byte* buffer, int bufferSize); + + /// + /// Polls a set of file descriptors for signals and returns what signals have been set + /// + /// A list of PollEvent entries + /// The number of entries in pollEvents + /// The amount of time to wait; -1 for infinite, 0 for immediate return, and a positive number is the number of milliseconds + /// The number of events triggered (i.e. the number of entries in pollEvents with a non-zero TriggeredEvents). May be zero in the event of a timeout. + /// An error or Error.SUCCESS. + [DllImport(Libraries.IOPortsNative, EntryPoint = "SystemIoPortsNative_Poll")] + private static extern unsafe Error Poll(PollEvent* pollEvents, uint eventCount, int timeout, uint* triggered); + + /// + /// Polls a File Descriptor for the passed in flags. + /// + /// The descriptor to poll + /// The events to poll for + /// The amount of time to wait; -1 for infinite, 0 for immediate return, and a positive number is the number of milliseconds + /// The events that were returned by the poll call. May be PollEvents.POLLNONE in the case of a timeout. + /// An error or Error.SUCCESS. + internal static unsafe Error Poll(SafeHandle fd, PollEvents events, int timeout, out PollEvents triggered) + { + bool gotRef = false; + try + { + fd.DangerousAddRef(ref gotRef); + + var pollEvent = new PollEvent + { + FileDescriptor = fd.DangerousGetHandle().ToInt32(), + Events = events, + }; + + uint unused; + Error err = Poll(&pollEvent, 1, timeout, &unused); + triggered = pollEvent.TriggeredEvents; + return err; + } + finally + { + if (gotRef) + { + fd.DangerousRelease(); + } + } + } } } diff --git a/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj b/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj index c4896b1f163f2..915a0a86e392a 100644 --- a/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj +++ b/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj @@ -129,14 +129,6 @@ Link="Common\Interop\Unix\Interop.Errors.cs" /> - - - - diff --git a/src/libraries/System.IO.Ports/src/System/IO/Ports/SafeSerialDeviceHandle.Unix.cs b/src/libraries/System.IO.Ports/src/System/IO/Ports/SafeSerialDeviceHandle.Unix.cs index db9d881dec64a..a98bcd4954215 100644 --- a/src/libraries/System.IO.Ports/src/System/IO/Ports/SafeSerialDeviceHandle.Unix.cs +++ b/src/libraries/System.IO.Ports/src/System/IO/Ports/SafeSerialDeviceHandle.Unix.cs @@ -35,7 +35,7 @@ internal static SafeSerialDeviceHandle Open(string portName) protected override bool ReleaseHandle() { - Interop.Sys.Shutdown(handle, SocketShutdown.Both); + Interop.Serial.Shutdown(handle, SocketShutdown.Both); int result = Interop.Serial.SerialPortClose(handle); Debug.Assert(result == 0, $"Close failed with result {result} and error {Interop.Sys.GetLastErrorInfo()}"); diff --git a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs index 4616384198b9e..887c869321339 100644 --- a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs +++ b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs @@ -464,7 +464,7 @@ public override IAsyncResult BeginRead(byte[] array, int offset, int numBytes, A // Will wait `timeout` miliseconds or until reading or writing is possible // If no operation is requested it will throw // Returns event which has happened - private Interop.Sys.PollEvents PollEvents(int timeout, bool pollReadEvents, bool pollWriteEvents, out Interop.ErrorInfo? error) + private Interop.Serial.PollEvents PollEvents(int timeout, bool pollReadEvents, bool pollWriteEvents, out Interop.ErrorInfo? error) { if (!pollReadEvents && !pollWriteEvents) { @@ -472,20 +472,20 @@ private Interop.Sys.PollEvents PollEvents(int timeout, bool pollReadEvents, bool throw new Exception(); } - Interop.Sys.PollEvents eventsToPoll = Interop.Sys.PollEvents.POLLERR; + Interop.Serial.PollEvents eventsToPoll = Interop.Serial.PollEvents.POLLERR; if (pollReadEvents) { - eventsToPoll |= Interop.Sys.PollEvents.POLLIN; + eventsToPoll |= Interop.Serial.PollEvents.POLLIN; } if (pollWriteEvents) { - eventsToPoll |= Interop.Sys.PollEvents.POLLOUT; + eventsToPoll |= Interop.Serial.PollEvents.POLLOUT; } - Interop.Sys.PollEvents events = Interop.Sys.PollEvents.POLLNONE; - Interop.Error ret = Interop.Sys.Poll( + Interop.Serial.PollEvents events = Interop.Serial.PollEvents.POLLNONE; + Interop.Error ret = Interop.Serial.Poll( _handle, eventsToPoll, timeout, @@ -699,7 +699,7 @@ private unsafe int ProcessRead(SerialStreamIORequest r) fixed (byte* bufPtr = buff) { // assumes dequeue-ing happens on a single thread - int numBytes = Interop.Sys.Read(_handle, bufPtr, buff.Length); + int numBytes = Interop.Serial.Read(_handle, bufPtr, buff.Length); if (numBytes < 0) { @@ -731,7 +731,7 @@ private unsafe int ProcessWrite(SerialStreamIORequest r) fixed (byte* bufPtr = buff) { // assumes dequeue-ing happens on a single thread - int numBytes = Interop.Sys.Write(_handle, bufPtr, buff.Length); + int numBytes = Interop.Serial.Write(_handle, bufPtr, buff.Length); if (numBytes <= 0) { @@ -843,7 +843,7 @@ private unsafe void IOLoop() } else { - Interop.Sys.PollEvents events = PollEvents(1, + Interop.Serial.PollEvents events = PollEvents(1, pollReadEvents: hasPendingReads, pollWriteEvents: hasPendingWrites, out Interop.ErrorInfo? error); @@ -854,21 +854,21 @@ private unsafe void IOLoop() break; } - if (events.HasFlag(Interop.Sys.PollEvents.POLLNVAL) || - events.HasFlag(Interop.Sys.PollEvents.POLLERR)) + if (events.HasFlag(Interop.Serial.PollEvents.POLLNVAL) || + events.HasFlag(Interop.Serial.PollEvents.POLLERR)) { // bad descriptor or some other error we can't handle FinishPendingIORequests(); break; } - if (events.HasFlag(Interop.Sys.PollEvents.POLLIN)) + if (events.HasFlag(Interop.Serial.PollEvents.POLLIN)) { int bytesRead = DoIORequest(_readQueue, _processReadDelegate); _totalBytesRead += bytesRead; } - if (events.HasFlag(Interop.Sys.PollEvents.POLLOUT)) + if (events.HasFlag(Interop.Serial.PollEvents.POLLOUT)) { DoIORequest(_writeQueue, _processWriteDelegate); } From cd61959b394c34d71fafa83c153339a5c3861da1 Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Fri, 8 May 2020 18:09:55 -0700 Subject: [PATCH 073/420] Fix ENODATA error on FreeBSD --- .../Native/Unix/System.IO.Ports.Native/pal_serial.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c index 0615b450fbf70..ac243fd29eaa2 100644 --- a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c +++ b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c @@ -14,6 +14,11 @@ #include #include +// ENODATA is not defined in FreeBSD 10.3 but is defined in 11.0 +#if defined(__FreeBSD__) & !defined(ENODATA) +#define ENODATA ENOATTR +#endif + /* Open device file in non-blocking mode and without controlling terminal */ intptr_t SystemIoPortsNative_SerialPortOpen(const char * name) { From edbb2625bfcc577d693c86c6497b514c9defe204 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Fri, 8 May 2020 20:12:52 -0700 Subject: [PATCH 074/420] React to latest Roslyn nullability changes (#36104) Also updates the compiler toolset to the latest version --- eng/Versions.props | 4 +- .../Generic/BidirectionalDictionary.cs | 5 +- .../ref/System.Collections.Concurrent.cs | 2 +- .../Concurrent/BlockingCollection.cs | 6 + .../Collections/Concurrent/ConcurrentBag.cs | 17 +- .../Collections/Concurrent/ConcurrentStack.cs | 2 +- .../tests/BlockingCollectionTests.cs | 16 + .../ref/System.Collections.Immutable.cs | 4 +- .../ref/System.Collections.Specialized.cs | 2 +- .../ref/System.Collections.cs | 26 +- .../ref/System.Diagnostics.TraceSource.cs | 4 +- .../ref/System.Linq.Expressions.cs | 12 +- .../src/System/Net/Mime/HeaderCollection.cs | 20 +- .../ref/System.Net.WebHeaderCollection.cs | 8 + .../src/System/Net/WebHeaderCollection.cs | 16 +- .../ref/System.Runtime.InteropServices.cs | 8 +- .../InteropServices/ComAwareEventInfo.cs | 4 + .../Serialization/SurrogateSelector.cs | 5 +- .../System.Runtime/ref/System.Runtime.cs | 668 +++++++++--------- .../ref/System.Text.RegularExpressions.cs | 30 +- 20 files changed, 450 insertions(+), 409 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 7febd65b98e5c..0b398500e1356 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -18,8 +18,8 @@ true true false - - 3.6.0-2.20166.2 + + 3.7.0-2.20258.1 dotnet $(ContainerName) diff --git a/src/libraries/Common/src/System/Collections/Generic/BidirectionalDictionary.cs b/src/libraries/Common/src/System/Collections/Generic/BidirectionalDictionary.cs index 6b5923d8f46dc..5e3dec7e8268d 100644 --- a/src/libraries/Common/src/System/Collections/Generic/BidirectionalDictionary.cs +++ b/src/libraries/Common/src/System/Collections/Generic/BidirectionalDictionary.cs @@ -4,6 +4,7 @@ #nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Collections.Generic { @@ -36,12 +37,12 @@ public void Add(T1 item1, T2 item2) _backward.Add(item2, item1); } - public bool TryGetForward(T1 item1, out T2 item2) + public bool TryGetForward(T1 item1, [MaybeNullWhen(false)] out T2 item2) { return _forward.TryGetValue(item1, out item2); } - public bool TryGetBackward(T2 item2, out T1 item1) + public bool TryGetBackward(T2 item2, [MaybeNullWhen(false)] out T1 item1) { return _backward.TryGetValue(item2, out item1); } diff --git a/src/libraries/System.Collections.Concurrent/ref/System.Collections.Concurrent.cs b/src/libraries/System.Collections.Concurrent/ref/System.Collections.Concurrent.cs index 022d5ce0456e5..c19a7197d8fce 100644 --- a/src/libraries/System.Collections.Concurrent/ref/System.Collections.Concurrent.cs +++ b/src/libraries/System.Collections.Concurrent/ref/System.Collections.Concurrent.cs @@ -113,7 +113,7 @@ public partial class ConcurrentDictionary : System.Collections.Gen void System.Collections.Generic.IDictionary.Add(TKey key, TValue value) { } bool System.Collections.Generic.IDictionary.Remove(TKey key) { throw null; } void System.Collections.ICollection.CopyTo(System.Array array, int index) { } - void System.Collections.IDictionary.Add(object key, object value) { } + void System.Collections.IDictionary.Add(object key, object? value) { } bool System.Collections.IDictionary.Contains(object key) { throw null; } System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator() { throw null; } void System.Collections.IDictionary.Remove(object key) { } diff --git a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs index 71d94c8dc72d0..1939dd9d68b29 100644 --- a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs +++ b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs @@ -755,7 +755,13 @@ private bool TryTakeWithNoTimeValidation([MaybeNullWhen(false)] out T item, int } } } + +#pragma warning disable CS8762 + // https://github.com/dotnet/runtime/issues/36132 + // Compiler can't automatically deduce that nullability constraints + // for 'item' are satisfied at this exit point. return waitForSemaphoreWasSuccessful; +#pragma warning restore CS8762 } diff --git a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs index c37a08aa82f87..3088224b47186 100644 --- a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs +++ b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs @@ -170,7 +170,7 @@ private WorkStealingQueue CreateWorkStealingQueueForCurrentThread() /// To receive the item retrieved from the bag /// Whether to remove or peek. /// True if succeeded, false otherwise. - private bool TrySteal(out T result, bool take) + private bool TrySteal([MaybeNullWhen(false)] out T result, bool take) { if (CDSCollectionETWBCLProvider.Log.IsEnabled()) { @@ -219,7 +219,12 @@ private bool TrySteal(out T result, bool take) (TryStealFromTo(localQueue._nextQueue, null, out result, take) || TryStealFromTo(_workStealingQueues, localQueue, out result, take)); if (gotItem) { +#pragma warning disable CS8762 + // https://github.com/dotnet/runtime/issues/36132 + // Compiler can't automatically deduce that nullability constraints + // for 'result' are satisfied at this exit point. return true; +#pragma warning restore CS8762 } if (Interlocked.Read(ref _emptyToNonEmptyListTransitionCount) == initialEmptyToNonEmptyCounts) @@ -248,7 +253,7 @@ private bool TryStealFromTo(WorkStealingQueue? startInclusive, WorkStealingQueue } } - result = default(T)!; + result = default(T); return false; } @@ -870,7 +875,7 @@ internal bool TryLocalPop([MaybeNullWhen(false)] out T result) int tail = _tailIndex; if (_headIndex - tail >= 0) { - result = default(T)!; + result = default(T); return false; } @@ -914,7 +919,7 @@ internal bool TryLocalPop([MaybeNullWhen(false)] out T result) { // We encountered a race condition and the element was stolen, restore the tail. _tailIndex = tail + 1; - result = default(T)!; + result = default(T); return false; } } @@ -958,7 +963,7 @@ internal bool TryLocalPeek([MaybeNullWhen(false)] out T result) } } - result = default(T)!; + result = default(T); return false; } @@ -1015,7 +1020,7 @@ internal bool TrySteal([MaybeNullWhen(false)] out T result, bool take) } // The queue was empty. - result = default(T)!; + result = default(T); return false; } diff --git a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentStack.cs b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentStack.cs index 6d5ca3a6af701..0d9ea6434ea7a 100644 --- a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentStack.cs +++ b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentStack.cs @@ -692,7 +692,7 @@ private static void CopyRemovedItems(Node head, T[] collection, int startIndex, /// For , this operation will attempt to pope the object at /// the top of the . /// - bool IProducerConsumerCollection.TryTake(out T item) + bool IProducerConsumerCollection.TryTake([MaybeNullWhen(false)] out T item) { return TryPop(out item); } diff --git a/src/libraries/System.Collections.Concurrent/tests/BlockingCollectionTests.cs b/src/libraries/System.Collections.Concurrent/tests/BlockingCollectionTests.cs index 6f8a107ccb8c6..9a21bc6ef01e7 100644 --- a/src/libraries/System.Collections.Concurrent/tests/BlockingCollectionTests.cs +++ b/src/libraries/System.Collections.Concurrent/tests/BlockingCollectionTests.cs @@ -966,6 +966,22 @@ public static void Test21_CopyToExceptions() }); } + [Fact] + public static void Test_WithNullEntries() + { + BlockingCollection collection = new BlockingCollection() + { + "hello", + null, + "goodbye" + }; + + Assert.Equal("hello", collection.Take()); + Assert.Null(collection.Take()); + Assert.Equal("goodbye", collection.Take()); + Assert.False(collection.TryTake(out _)); + } + [Fact] public static void Test_LargeSize() { diff --git a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs index 060f87f330fc5..25cdd45c80070 100644 --- a/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs +++ b/src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs @@ -702,7 +702,7 @@ public sealed partial class Builder : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } void System.Collections.ICollection.CopyTo(System.Array array, int arrayIndex) { } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - int System.Collections.IList.Add(object value) { throw null; } + int System.Collections.IList.Add(object? value) { throw null; } void System.Collections.IList.Clear() { } bool System.Collections.IList.Contains(object? value) { throw null; } int System.Collections.IList.IndexOf(object? value) { throw null; } @@ -819,7 +819,7 @@ public sealed partial class ImmutableSortedDictionary : System.Col bool System.Collections.Generic.IDictionary.Remove(TKey key) { throw null; } System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() { throw null; } void System.Collections.ICollection.CopyTo(System.Array array, int index) { } - void System.Collections.IDictionary.Add(object key, object value) { } + void System.Collections.IDictionary.Add(object key, object? value) { } void System.Collections.IDictionary.Clear() { } bool System.Collections.IDictionary.Contains(object key) { throw null; } System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator() { throw null; } diff --git a/src/libraries/System.Collections.Specialized/ref/System.Collections.Specialized.cs b/src/libraries/System.Collections.Specialized/ref/System.Collections.Specialized.cs index fd2e1cbdd8de5..d99c32ebed762 100644 --- a/src/libraries/System.Collections.Specialized/ref/System.Collections.Specialized.cs +++ b/src/libraries/System.Collections.Specialized/ref/System.Collections.Specialized.cs @@ -189,7 +189,7 @@ public partial class OrderedDictionary : System.Collections.ICollection, System. public void Remove(object key) { } public void RemoveAt(int index) { } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { } + void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object? sender) { } } public partial class StringCollection : System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList { diff --git a/src/libraries/System.Collections/ref/System.Collections.cs b/src/libraries/System.Collections/ref/System.Collections.cs index 918809a121156..92958369371d2 100644 --- a/src/libraries/System.Collections/ref/System.Collections.cs +++ b/src/libraries/System.Collections/ref/System.Collections.cs @@ -56,7 +56,7 @@ public abstract partial class Comparer : System.Collections.Generic.IComparer public static System.Collections.Generic.Comparer Default { get { throw null; } } public abstract int Compare([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T x, [System.Diagnostics.CodeAnalysis.AllowNullAttribute] T y); public static System.Collections.Generic.Comparer Create(System.Comparison comparison) { throw null; } - int System.Collections.IComparer.Compare(object x, object y) { throw null; } + int System.Collections.IComparer.Compare(object? x, object? y) { throw null; } } public partial class Dictionary : System.Collections.Generic.ICollection>, System.Collections.Generic.IDictionary, System.Collections.Generic.IEnumerable>, System.Collections.Generic.IReadOnlyCollection>, System.Collections.Generic.IReadOnlyDictionary, System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable where TKey : notnull { @@ -102,7 +102,7 @@ public partial class Dictionary : System.Collections.Generic.IColl bool System.Collections.Generic.ICollection>.Remove(System.Collections.Generic.KeyValuePair keyValuePair) { throw null; } System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() { throw null; } void System.Collections.ICollection.CopyTo(System.Array array, int index) { } - void System.Collections.IDictionary.Add(object key, object value) { } + void System.Collections.IDictionary.Add(object key, object? value) { } bool System.Collections.IDictionary.Contains(object key) { throw null; } System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator() { throw null; } void System.Collections.IDictionary.Remove(object key) { } @@ -187,7 +187,7 @@ public abstract partial class EqualityComparer : System.Collections.Generic.I public static System.Collections.Generic.EqualityComparer Default { get { throw null; } } public abstract bool Equals([System.Diagnostics.CodeAnalysis.AllowNullAttribute] T x, [System.Diagnostics.CodeAnalysis.AllowNullAttribute] T y); public abstract int GetHashCode([System.Diagnostics.CodeAnalysis.DisallowNullAttribute] T obj); - bool System.Collections.IEqualityComparer.Equals(object x, object y) { throw null; } + bool System.Collections.IEqualityComparer.Equals(object? x, object? y) { throw null; } int System.Collections.IEqualityComparer.GetHashCode(object obj) { throw null; } } public partial class HashSet : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.ISet, System.Collections.Generic.IReadOnlySet, System.Collections.IEnumerable, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable @@ -295,7 +295,7 @@ public partial struct Enumerator : System.Collections.Generic.IEnumerator, Sy public void Dispose() { } public bool MoveNext() { throw null; } void System.Collections.IEnumerator.Reset() { } - void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { } + void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object? sender) { } void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } } } @@ -361,11 +361,11 @@ public partial class List : System.Collections.Generic.ICollection, System System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } void System.Collections.ICollection.CopyTo(System.Array array, int arrayIndex) { } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - int System.Collections.IList.Add(object item) { throw null; } - bool System.Collections.IList.Contains(object item) { throw null; } - int System.Collections.IList.IndexOf(object item) { throw null; } - void System.Collections.IList.Insert(int index, object item) { } - void System.Collections.IList.Remove(object item) { } + int System.Collections.IList.Add(object? item) { throw null; } + bool System.Collections.IList.Contains(object? item) { throw null; } + int System.Collections.IList.IndexOf(object? item) { throw null; } + void System.Collections.IList.Insert(int index, object? item) { } + void System.Collections.IList.Remove(object? item) { } public T[] ToArray() { throw null; } public void TrimExcess() { } public bool TrueForAll(System.Predicate match) { throw null; } @@ -457,7 +457,7 @@ public partial class SortedDictionary : System.Collections.Generic bool System.Collections.Generic.ICollection>.Remove(System.Collections.Generic.KeyValuePair keyValuePair) { throw null; } System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() { throw null; } void System.Collections.ICollection.CopyTo(System.Array array, int index) { } - void System.Collections.IDictionary.Add(object key, object value) { } + void System.Collections.IDictionary.Add(object key, object? value) { } bool System.Collections.IDictionary.Contains(object key) { throw null; } System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator() { throw null; } void System.Collections.IDictionary.Remove(object key) { } @@ -572,7 +572,7 @@ public partial class SortedList : System.Collections.Generic.IColl bool System.Collections.Generic.ICollection>.Remove(System.Collections.Generic.KeyValuePair keyValuePair) { throw null; } System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() { throw null; } void System.Collections.ICollection.CopyTo(System.Array array, int arrayIndex) { } - void System.Collections.IDictionary.Add(object key, object value) { } + void System.Collections.IDictionary.Add(object key, object? value) { } bool System.Collections.IDictionary.Contains(object key) { throw null; } System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator() { throw null; } void System.Collections.IDictionary.Remove(object key) { } @@ -624,7 +624,7 @@ public partial class SortedSet : System.Collections.Generic.ICollection, S System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } void System.Collections.ICollection.CopyTo(System.Array array, int index) { } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { } + void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object? sender) { } void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public bool TryGetValue(T equalValue, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out T actualValue) { throw null; } public void UnionWith(System.Collections.Generic.IEnumerable other) { } @@ -637,7 +637,7 @@ public partial struct Enumerator : System.Collections.Generic.IEnumerator, Sy public void Dispose() { } public bool MoveNext() { throw null; } void System.Collections.IEnumerator.Reset() { } - void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { } + void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object? sender) { } void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } } } diff --git a/src/libraries/System.Diagnostics.TraceSource/ref/System.Diagnostics.TraceSource.cs b/src/libraries/System.Diagnostics.TraceSource/ref/System.Diagnostics.TraceSource.cs index 3252a3187f594..da867700460dd 100644 --- a/src/libraries/System.Diagnostics.TraceSource/ref/System.Diagnostics.TraceSource.cs +++ b/src/libraries/System.Diagnostics.TraceSource/ref/System.Diagnostics.TraceSource.cs @@ -263,10 +263,10 @@ public partial class TraceListenerCollection : System.Collections.ICollection, S public void Remove(string name) { } public void RemoveAt(int index) { } void System.Collections.ICollection.CopyTo(System.Array array, int index) { } - int System.Collections.IList.Add(object value) { throw null; } + int System.Collections.IList.Add(object? value) { throw null; } bool System.Collections.IList.Contains(object? value) { throw null; } int System.Collections.IList.IndexOf(object? value) { throw null; } - void System.Collections.IList.Insert(int index, object value) { } + void System.Collections.IList.Insert(int index, object? value) { } void System.Collections.IList.Remove(object? value) { } } [System.FlagsAttribute] diff --git a/src/libraries/System.Linq.Expressions/ref/System.Linq.Expressions.cs b/src/libraries/System.Linq.Expressions/ref/System.Linq.Expressions.cs index f52a771eba278..196c19e62d903 100644 --- a/src/libraries/System.Linq.Expressions/ref/System.Linq.Expressions.cs +++ b/src/libraries/System.Linq.Expressions/ref/System.Linq.Expressions.cs @@ -142,7 +142,7 @@ public sealed partial class ExpandoObject : System.Collections.Generic.ICollecti bool System.Collections.Generic.ICollection>.Contains(System.Collections.Generic.KeyValuePair item) { throw null; } void System.Collections.Generic.ICollection>.CopyTo(System.Collections.Generic.KeyValuePair[] array, int arrayIndex) { } bool System.Collections.Generic.ICollection>.Remove(System.Collections.Generic.KeyValuePair item) { throw null; } - void System.Collections.Generic.IDictionary.Add(string key, object value) { } + void System.Collections.Generic.IDictionary.Add(string key, object? value) { } bool System.Collections.Generic.IDictionary.ContainsKey(string key) { throw null; } bool System.Collections.Generic.IDictionary.Remove(string key) { throw null; } bool System.Collections.Generic.IDictionary.TryGetValue(string key, out object? value) { throw null; } @@ -1193,11 +1193,11 @@ public sealed partial class ReadOnlyCollectionBuilder : System.Collections.Ge public void Reverse(int index, int count) { } void System.Collections.ICollection.CopyTo(System.Array array, int index) { } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - int System.Collections.IList.Add(object value) { throw null; } - bool System.Collections.IList.Contains(object value) { throw null; } - int System.Collections.IList.IndexOf(object value) { throw null; } - void System.Collections.IList.Insert(int index, object value) { } - void System.Collections.IList.Remove(object value) { } + int System.Collections.IList.Add(object? value) { throw null; } + bool System.Collections.IList.Contains(object? value) { throw null; } + int System.Collections.IList.IndexOf(object? value) { throw null; } + void System.Collections.IList.Insert(int index, object? value) { } + void System.Collections.IList.Remove(object? value) { } public T[] ToArray() { throw null; } public System.Collections.ObjectModel.ReadOnlyCollection ToReadOnlyCollection() { throw null; } } diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mime/HeaderCollection.cs b/src/libraries/System.Net.Mail/src/System/Net/Mime/HeaderCollection.cs index 6c4b282717502..1162b0138015f 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mime/HeaderCollection.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mime/HeaderCollection.cs @@ -22,9 +22,9 @@ internal HeaderCollection() : base(StringComparer.OrdinalIgnoreCase) { } -#pragma warning disable CS8610 // Nullability of reference types in type of parameter doesn't match overridden member. +#pragma warning disable CS8765 // Nullability of parameter 'name' doesn't match overridden member public override void Remove(string name) -#pragma warning restore CS8610 +#pragma warning restore CS8765 { if (name == null) { @@ -51,9 +51,9 @@ public override void Remove(string name) } -#pragma warning disable CS8610 // Nullability of reference types in type of parameter doesn't match overridden member. +#pragma warning disable CS8765 // Nullability of parameter 'name' doesn't match overridden member public override string? Get(string name) -#pragma warning restore CS8610 +#pragma warning restore CS8765 { if (name == null) { @@ -78,9 +78,9 @@ public override void Remove(string name) return base.Get(name); } -#pragma warning disable CS8610 // Nullability of reference types in type of parameter doesn't match overridden member. +#pragma warning disable CS8765 // Nullability of parameter 'name' doesn't match overridden member public override string[]? GetValues(string name) -#pragma warning restore CS8610 +#pragma warning restore CS8765 { if (name == null) { @@ -124,9 +124,9 @@ internal void InternalAdd(string name, string value) } } -#pragma warning disable CS8610 // Nullability of reference types in type of parameter doesn't match overridden member. +#pragma warning disable CS8765 // Nullability of parameters 'name' and 'value' don't match overridden member public override void Set(string name, string value) -#pragma warning restore CS8610 +#pragma warning restore CS8765 { if (name == null) { @@ -175,9 +175,9 @@ public override void Set(string name, string value) } -#pragma warning disable CS8610 // Nullability of reference types in type of parameter doesn't match overridden member. +#pragma warning disable CS8765 // Nullability of parameters 'name' and 'value' don't match overridden member public override void Add(string name, string value) -#pragma warning restore CS8610 +#pragma warning restore CS8765 { if (name == null) { diff --git a/src/libraries/System.Net.WebHeaderCollection/ref/System.Net.WebHeaderCollection.cs b/src/libraries/System.Net.WebHeaderCollection/ref/System.Net.WebHeaderCollection.cs index f4aa1444be251..0cdc475f1a94a 100644 --- a/src/libraries/System.Net.WebHeaderCollection/ref/System.Net.WebHeaderCollection.cs +++ b/src/libraries/System.Net.WebHeaderCollection/ref/System.Net.WebHeaderCollection.cs @@ -97,7 +97,9 @@ public partial class WebHeaderCollection : System.Collections.Specialized.NameVa public void Add(System.Net.HttpRequestHeader header, string? value) { } public void Add(System.Net.HttpResponseHeader header, string? value) { } public void Add(string header) { } +#pragma warning disable CS8765 // Nullability of parameter 'name' doesn't match overridden member public override void Add(string name, string? value) { } +#pragma warning restore CS8765 protected void AddWithoutValidate(string headerName, string? headerValue) { } public override void Clear() { } public override string? Get(int index) { throw null; } @@ -106,16 +108,22 @@ public partial class WebHeaderCollection : System.Collections.Specialized.NameVa public override string GetKey(int index) { throw null; } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) { } public override string[]? GetValues(int index) { throw null; } +#pragma warning disable CS8765 // Nullability of parameter 'header' doesn't match overridden member public override string[]? GetValues(string header) { throw null; } +#pragma warning restore CS8765 public static bool IsRestricted(string headerName) { throw null; } public static bool IsRestricted(string headerName, bool response) { throw null; } public override void OnDeserialization(object? sender) { } public void Remove(System.Net.HttpRequestHeader header) { } public void Remove(System.Net.HttpResponseHeader header) { } +#pragma warning disable CS8765 // Nullability of parameter 'name' doesn't match overridden member public override void Remove(string name) { } +#pragma warning restore CS8765 public void Set(System.Net.HttpRequestHeader header, string? value) { } public void Set(System.Net.HttpResponseHeader header, string? value) { } +#pragma warning disable CS8765 // Nullability of parameter 'name' doesn't match overridden member public override void Set(string name, string? value) { } +#pragma warning restore CS8765 void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) { } public byte[] ToByteArray() { throw null; } public override string ToString() { throw null; } diff --git a/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs b/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs index 875caac4c46fd..ae3a1a4e5ffcf 100644 --- a/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs +++ b/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs @@ -132,9 +132,9 @@ private bool AllowHttpResponseHeader } } -#pragma warning disable CS8610 // Nullability of parameter 'name' doesn't match overridden member +#pragma warning disable CS8765 // Nullability of parameter 'name' doesn't match overridden member public override void Set(string name, string? value) -#pragma warning restore CS8610 +#pragma warning restore CS8765 { if (string.IsNullOrEmpty(name)) { @@ -241,9 +241,9 @@ public static bool IsRestricted(string headerName, bool response) // header - Name of the header. // Return Value: // string[] - array of parsed string objects -#pragma warning disable CS8610 // Nullability of parameter 'header' doesn't match overridden member +#pragma warning disable CS8765 // Nullability of parameter 'header' doesn't match overridden member public override string[]? GetValues(string header) -#pragma warning restore CS8610 +#pragma warning restore CS8765 { // First get the information about the header and the values for // the header. @@ -385,9 +385,9 @@ public void Add(string header) InnerCollection.Add(name, value); } -#pragma warning disable CS8610 // Nullability of parameter 'name' doesn't match overridden member +#pragma warning disable CS8765 // Nullability of parameter 'name' doesn't match overridden member public override void Add(string name, string? value) -#pragma warning restore CS8610 +#pragma warning restore CS8765 { if (name == null) { @@ -460,9 +460,9 @@ internal void ThrowOnRestrictedHeader(string headerName) /// /// Removes the specified header. /// -#pragma warning disable CS8610 // Nullability of parameter 'name' doesn't match overridden member +#pragma warning disable CS8765 // Nullability of parameter 'name' doesn't match overridden member public override void Remove(string name) -#pragma warning restore CS8610 +#pragma warning restore CS8765 { if (string.IsNullOrEmpty(name)) { diff --git a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs index d2a0de7091b94..24d334cdf0f48 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -181,9 +181,9 @@ public partial class ComAwareEventInfo : System.Reflection.EventInfo public override System.Reflection.Module Module { get { throw null; } } public override string Name { get { throw null; } } public override System.Type? ReflectedType { get { throw null; } } -#pragma warning disable CS8610 +#pragma warning disable CS8765 // Nullability of parameters 'target' and 'handler' don't match overridden member public override void AddEventHandler(object target, System.Delegate handler) { } -#pragma warning restore CS8610 +#pragma warning restore CS8765 public override System.Reflection.MethodInfo? GetAddMethod(bool nonPublic) { throw null; } public override object[] GetCustomAttributes(bool inherit) { throw null; } public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; } @@ -192,9 +192,9 @@ public partial class ComAwareEventInfo : System.Reflection.EventInfo public override System.Reflection.MethodInfo? GetRaiseMethod(bool nonPublic) { throw null; } public override System.Reflection.MethodInfo? GetRemoveMethod(bool nonPublic) { throw null; } public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; } -#pragma warning disable CS8610 +#pragma warning disable CS8765 // Nullability of parameters 'target' and 'handler' don't match overridden member public override void RemoveEventHandler(object target, System.Delegate handler) { } -#pragma warning restore CS8610 +#pragma warning restore CS8765 } [System.AttributeUsageAttribute(System.AttributeTargets.Assembly, Inherited=false)] public sealed partial class ComCompatibleVersionAttribute : System.Attribute diff --git a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/ComAwareEventInfo.cs b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/ComAwareEventInfo.cs index 3985477bb627d..dced7924e7109 100644 --- a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/ComAwareEventInfo.cs +++ b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/ComAwareEventInfo.cs @@ -20,7 +20,9 @@ public ComAwareEventInfo(Type type, string eventName) _innerEventInfo = type.GetEvent(eventName)!; } +#pragma warning disable CS8765 // Nullability of parameters 'target' and 'handler' don't match overridden member public override void AddEventHandler(object target, Delegate handler) +#pragma warning restore CS8765 { if (Marshal.IsComObject(target)) { @@ -35,7 +37,9 @@ public override void AddEventHandler(object target, Delegate handler) } } +#pragma warning disable CS8765 // Nullability of parameters 'target' and 'handler' don't match overridden member public override void RemoveEventHandler(object target, Delegate handler) +#pragma warning restore CS8765 { if (Marshal.IsComObject(target)) { diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/SurrogateSelector.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/SurrogateSelector.cs index 0b73a24dc39e3..940d5e7c37ead 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/SurrogateSelector.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/SurrogateSelector.cs @@ -213,9 +213,10 @@ internal SurrogateHashtable(int size) : base(size) // is a subset of the context for which the serialization selector is provided (presentContext) // Note: This is done by overriding KeyEquals rather than overriding Equals() in the SurrogateKey // class because Equals() method must be commutative. -#pragma warning disable CS8610 + // n.b. 'key' and 'item' parameter positions swapped from base method! +#pragma warning disable CS8765 // Nullability of parameter 'key' doesn't match overridden member protected override bool KeyEquals(object key, object item) -#pragma warning restore CS8610 +#pragma warning restore CS8765 { SurrogateKey givenValue = (SurrogateKey)item; SurrogateKey presentValue = (SurrogateKey)key; diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 040f2cbeed453..0ff7018d9f5d1 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -354,7 +354,7 @@ public abstract partial class Array : System.Collections.ICollection, System.Col public static int LastIndexOf(T[] array, T value) { throw null; } public static int LastIndexOf(T[] array, T value, int startIndex) { throw null; } public static int LastIndexOf(T[] array, T value, int startIndex, int count) { throw null; } - public static void Resize([System.Diagnostics.CodeAnalysis.NotNullAttribute] ref T[]? array, int newSize) { } + public static void Resize([System.Diagnostics.CodeAnalysis.NotNullAttribute] ref T[]? array, int newSize) { throw null; } public static void Reverse(System.Array array) { } public static void Reverse(System.Array array, int index, int length) { } public static void Reverse(T[] array) { } @@ -384,15 +384,15 @@ public abstract partial class Array : System.Collections.ICollection, System.Col public static void Sort(TKey[] keys, TValue[]? items, System.Collections.Generic.IComparer? comparer) { } public static void Sort(TKey[] keys, TValue[]? items, int index, int length) { } public static void Sort(TKey[] keys, TValue[]? items, int index, int length, System.Collections.Generic.IComparer? comparer) { } - int System.Collections.IList.Add(object value) { throw null; } + int System.Collections.IList.Add(object? value) { throw null; } void System.Collections.IList.Clear() { } - bool System.Collections.IList.Contains(object value) { throw null; } - int System.Collections.IList.IndexOf(object value) { throw null; } - void System.Collections.IList.Insert(int index, object value) { } - void System.Collections.IList.Remove(object value) { } + bool System.Collections.IList.Contains(object? value) { throw null; } + int System.Collections.IList.IndexOf(object? value) { throw null; } + void System.Collections.IList.Insert(int index, object? value) { } + void System.Collections.IList.Remove(object? value) { } void System.Collections.IList.RemoveAt(int index) { } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } public static bool TrueForAll(T[] array, System.Predicate match) { throw null; } } @@ -625,21 +625,21 @@ public static partial class BitConverter public System.TypeCode GetTypeCode() { throw null; } public static System.Boolean Parse(System.ReadOnlySpan value) { throw null; } public static System.Boolean Parse(string value) { throw null; } - System.Boolean System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + System.Boolean System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public override string ToString() { throw null; } public string ToString(System.IFormatProvider? provider) { throw null; } public System.Boolean TryFormat(System.Span destination, out int charsWritten) { throw null; } @@ -673,21 +673,21 @@ public static partial class Buffer public static System.Byte Parse(string s, System.Globalization.NumberStyles style) { throw null; } public static System.Byte Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } public static System.Byte Parse(string s, System.IFormatProvider? provider) { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - System.Byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + System.Byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public override string ToString() { throw null; } public string ToString(System.IFormatProvider? provider) { throw null; } public string ToString(string? format) { throw null; } @@ -754,21 +754,21 @@ public partial class CannotUnloadAppDomainException : System.SystemException public static bool IsWhiteSpace(System.Char c) { throw null; } public static bool IsWhiteSpace(string s, int index) { throw null; } public static System.Char Parse(string s) { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - System.Char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + System.Char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public static System.Char ToLower(System.Char c) { throw null; } public static System.Char ToLower(System.Char c, System.Globalization.CultureInfo culture) { throw null; } public static System.Char ToLowerInvariant(System.Char c) { throw null; } @@ -1344,21 +1344,21 @@ public static partial class Convert public static System.DateTime SpecifyKind(System.DateTime value, System.DateTimeKind kind) { throw null; } public System.TimeSpan Subtract(System.DateTime value) { throw null; } public System.DateTime Subtract(System.TimeSpan value) { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public long ToBinary() { throw null; } public long ToFileTime() { throw null; } @@ -1461,8 +1461,8 @@ public enum DateTimeKind public static System.DateTimeOffset ParseExact(string input, string[] formats, System.IFormatProvider? formatProvider, System.Globalization.DateTimeStyles styles) { throw null; } public System.TimeSpan Subtract(System.DateTimeOffset value) { throw null; } public System.DateTimeOffset Subtract(System.TimeSpan value) { throw null; } - int System.IComparable.CompareTo(object obj) { throw null; } - void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { } + int System.IComparable.CompareTo(object? obj) { throw null; } + void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object? sender) { } void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public long ToFileTime() { throw null; } public System.DateTimeOffset ToLocalTime() { throw null; } @@ -1500,21 +1500,21 @@ public sealed partial class DBNull : System.IConvertible, System.Runtime.Seriali public static readonly System.DBNull Value; public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public System.TypeCode GetTypeCode() { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public override string ToString() { throw null; } public string ToString(System.IFormatProvider? provider) { throw null; } } @@ -1615,22 +1615,22 @@ public sealed partial class DBNull : System.IConvertible, System.Runtime.Seriali public static System.Decimal Round(System.Decimal d, int decimals, System.MidpointRounding mode) { throw null; } public static System.Decimal Round(System.Decimal d, System.MidpointRounding mode) { throw null; } public static System.Decimal Subtract(System.Decimal d1, System.Decimal d2) { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - System.Decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } - void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + System.Decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } + void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object? sender) { } public static byte ToByte(System.Decimal value) { throw null; } public static double ToDouble(System.Decimal d) { throw null; } public static short ToInt16(System.Decimal value) { throw null; } @@ -1734,21 +1734,21 @@ public partial class DivideByZeroException : System.ArithmeticException public static System.Double Parse(string s, System.Globalization.NumberStyles style) { throw null; } public static System.Double Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } public static System.Double Parse(string s, System.IFormatProvider? provider) { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - System.Double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + System.Double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public override string ToString() { throw null; } public string ToString(System.IFormatProvider? provider) { throw null; } public string ToString(string? format) { throw null; } @@ -1792,21 +1792,21 @@ public abstract partial class Enum : System.ValueType, System.IComparable, Syste public static object Parse(System.Type enumType, string value, bool ignoreCase) { throw null; } public static TEnum Parse(string value) where TEnum : struct { throw null; } public static TEnum Parse(string value, bool ignoreCase) where TEnum : struct { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public static object ToObject(System.Type enumType, byte value) { throw null; } public static object ToObject(System.Type enumType, short value) { throw null; } public static object ToObject(System.Type enumType, int value) { throw null; } @@ -2000,7 +2000,7 @@ public abstract partial class FormattableString : System.IFormattable public abstract object? GetArgument(int index); public abstract object?[] GetArguments(); public static string Invariant(System.FormattableString formattable) { throw null; } - string System.IFormattable.ToString(string ignored, System.IFormatProvider formatProvider) { throw null; } + string System.IFormattable.ToString(string? ignored, System.IFormatProvider? formatProvider) { throw null; } public override string ToString() { throw null; } public abstract string ToString(System.IFormatProvider? formatProvider); } @@ -2281,21 +2281,21 @@ public sealed partial class InsufficientMemoryException : System.OutOfMemoryExce public static System.Int16 Parse(string s, System.Globalization.NumberStyles style) { throw null; } public static System.Int16 Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } public static System.Int16 Parse(string s, System.IFormatProvider? provider) { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - System.Int16 System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + System.Int16 System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public override string ToString() { throw null; } public string ToString(System.IFormatProvider? provider) { throw null; } public string ToString(string? format) { throw null; } @@ -2322,21 +2322,21 @@ public sealed partial class InsufficientMemoryException : System.OutOfMemoryExce public static System.Int32 Parse(string s, System.Globalization.NumberStyles style) { throw null; } public static System.Int32 Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } public static System.Int32 Parse(string s, System.IFormatProvider? provider) { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - System.Int32 System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + System.Int32 System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public override string ToString() { throw null; } public string ToString(System.IFormatProvider? provider) { throw null; } public string ToString(string? format) { throw null; } @@ -2363,21 +2363,21 @@ public sealed partial class InsufficientMemoryException : System.OutOfMemoryExce public static System.Int64 Parse(string s, System.Globalization.NumberStyles style) { throw null; } public static System.Int64 Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } public static System.Int64 Parse(string s, System.IFormatProvider? provider) { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - System.Int64 System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + System.Int64 System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public override string ToString() { throw null; } public string ToString(System.IFormatProvider? provider) { throw null; } public string ToString(string? format) { throw null; } @@ -3150,21 +3150,21 @@ public partial struct RuntimeTypeHandle : System.Runtime.Serialization.ISerializ public static System.SByte Parse(string s, System.Globalization.NumberStyles style) { throw null; } public static System.SByte Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } public static System.SByte Parse(string s, System.IFormatProvider? provider) { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - System.SByte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + System.SByte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public override string ToString() { throw null; } public string ToString(System.IFormatProvider? provider) { throw null; } public string ToString(string? format) { throw null; } @@ -3214,21 +3214,21 @@ public sealed partial class SerializableAttribute : System.Attribute public static System.Single Parse(string s, System.Globalization.NumberStyles style) { throw null; } public static System.Single Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } public static System.Single Parse(string s, System.IFormatProvider? provider) { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - System.Single System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + System.Single System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public override string ToString() { throw null; } public string ToString(System.IFormatProvider? provider) { throw null; } public string ToString(string? format) { throw null; } @@ -3449,21 +3449,21 @@ public sealed partial class String : System.Collections.Generic.IEnumerable System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public char[] ToCharArray() { throw null; } public char[] ToCharArray(int startIndex, int length) { throw null; } public System.String ToLower() { throw null; } @@ -3687,7 +3687,7 @@ public sealed partial class TimeZoneInfo : System.IEquatable, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable @@ -3721,7 +3721,7 @@ public sealed partial class AdjustmentRule : System.IEquatable : System.Collections.IStructuralComparable, Syste int System.Runtime.CompilerServices.ITuple.Length { get { throw null; } } public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object obj) { throw null; } + int System.IComparable.CompareTo(object? obj) { throw null; } public override string ToString() { throw null; } } public partial class Tuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.Runtime.CompilerServices.ITuple @@ -3853,10 +3853,10 @@ public partial class Tuple : System.Collections.IStructuralComparable, S int System.Runtime.CompilerServices.ITuple.Length { get { throw null; } } public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object obj) { throw null; } + int System.IComparable.CompareTo(object? obj) { throw null; } public override string ToString() { throw null; } } public partial class Tuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.Runtime.CompilerServices.ITuple @@ -3869,10 +3869,10 @@ public partial class Tuple : System.Collections.IStructuralComparabl int System.Runtime.CompilerServices.ITuple.Length { get { throw null; } } public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object obj) { throw null; } + int System.IComparable.CompareTo(object? obj) { throw null; } public override string ToString() { throw null; } } public partial class Tuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.Runtime.CompilerServices.ITuple @@ -3886,10 +3886,10 @@ public partial class Tuple : System.Collections.IStructuralCompa int System.Runtime.CompilerServices.ITuple.Length { get { throw null; } } public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object obj) { throw null; } + int System.IComparable.CompareTo(object? obj) { throw null; } public override string ToString() { throw null; } } public partial class Tuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.Runtime.CompilerServices.ITuple @@ -3904,10 +3904,10 @@ public partial class Tuple : System.Collections.IStructuralC int System.Runtime.CompilerServices.ITuple.Length { get { throw null; } } public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object obj) { throw null; } + int System.IComparable.CompareTo(object? obj) { throw null; } public override string ToString() { throw null; } } public partial class Tuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.Runtime.CompilerServices.ITuple @@ -3923,10 +3923,10 @@ public partial class Tuple : System.Collections.IStructu int System.Runtime.CompilerServices.ITuple.Length { get { throw null; } } public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object obj) { throw null; } + int System.IComparable.CompareTo(object? obj) { throw null; } public override string ToString() { throw null; } } public partial class Tuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.Runtime.CompilerServices.ITuple @@ -3943,10 +3943,10 @@ public partial class Tuple : System.Collections.IStr int System.Runtime.CompilerServices.ITuple.Length { get { throw null; } } public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object obj) { throw null; } + int System.IComparable.CompareTo(object? obj) { throw null; } public override string ToString() { throw null; } } public partial class Tuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.Runtime.CompilerServices.ITuple where TRest : notnull @@ -3964,10 +3964,10 @@ public partial class Tuple : System.Collectio int System.Runtime.CompilerServices.ITuple.Length { get { throw null; } } public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object obj) { throw null; } + int System.IComparable.CompareTo(object? obj) { throw null; } public override string ToString() { throw null; } } public abstract partial class Type : System.Reflection.MemberInfo, System.Reflection.IReflect @@ -4244,21 +4244,21 @@ public partial class TypeUnloadedException : System.SystemException public static System.UInt16 Parse(string s, System.Globalization.NumberStyles style) { throw null; } public static System.UInt16 Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } public static System.UInt16 Parse(string s, System.IFormatProvider? provider) { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - System.UInt16 System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + System.UInt16 System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public override string ToString() { throw null; } public string ToString(System.IFormatProvider? provider) { throw null; } public string ToString(string? format) { throw null; } @@ -4286,21 +4286,21 @@ public partial class TypeUnloadedException : System.SystemException public static System.UInt32 Parse(string s, System.Globalization.NumberStyles style) { throw null; } public static System.UInt32 Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } public static System.UInt32 Parse(string s, System.IFormatProvider? provider) { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - System.UInt32 System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + System.UInt32 System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public override string ToString() { throw null; } public string ToString(System.IFormatProvider? provider) { throw null; } public string ToString(string? format) { throw null; } @@ -4328,21 +4328,21 @@ public partial class TypeUnloadedException : System.SystemException public static System.UInt64 Parse(string s, System.Globalization.NumberStyles style) { throw null; } public static System.UInt64 Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider? provider) { throw null; } public static System.UInt64 Parse(string s, System.IFormatProvider? provider) { throw null; } - bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; } - byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; } - char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; } - System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; } - decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; } - double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; } - short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; } - int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; } - long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; } - sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; } - float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; } - object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; } - ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; } - uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; } - System.UInt64 System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; } + bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; } + byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; } + char System.IConvertible.ToChar(System.IFormatProvider? provider) { throw null; } + System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider? provider) { throw null; } + decimal System.IConvertible.ToDecimal(System.IFormatProvider? provider) { throw null; } + double System.IConvertible.ToDouble(System.IFormatProvider? provider) { throw null; } + short System.IConvertible.ToInt16(System.IFormatProvider? provider) { throw null; } + int System.IConvertible.ToInt32(System.IFormatProvider? provider) { throw null; } + long System.IConvertible.ToInt64(System.IFormatProvider? provider) { throw null; } + sbyte System.IConvertible.ToSByte(System.IFormatProvider? provider) { throw null; } + float System.IConvertible.ToSingle(System.IFormatProvider? provider) { throw null; } + object System.IConvertible.ToType(System.Type type, System.IFormatProvider? provider) { throw null; } + ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } + uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } + System.UInt64 System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } public override string ToString() { throw null; } public string ToString(System.IFormatProvider? provider) { throw null; } public string ToString(string? format) { throw null; } @@ -4617,10 +4617,10 @@ public partial struct ValueTuple : System.Collections.IStructuralComparable, Sys public override bool Equals(object? obj) { throw null; } public bool Equals(System.ValueTuple other) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object other) { throw null; } + int System.IComparable.CompareTo(object? other) { throw null; } public override string ToString() { throw null; } } public partial struct ValueTuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.IComparable>, System.IEquatable>, System.Runtime.CompilerServices.ITuple @@ -4633,10 +4633,10 @@ public partial struct ValueTuple : System.Collections.IStructuralComparable, public override bool Equals(object? obj) { throw null; } public bool Equals(System.ValueTuple other) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object other) { throw null; } + int System.IComparable.CompareTo(object? other) { throw null; } public override string ToString() { throw null; } } public partial struct ValueTuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.IComparable<(T1, T2)>, System.IEquatable<(T1, T2)>, System.Runtime.CompilerServices.ITuple @@ -4650,10 +4650,10 @@ public partial struct ValueTuple : System.Collections.IStructuralCompara public override bool Equals(object? obj) { throw null; } public bool Equals((T1, T2) other) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object other) { throw null; } + int System.IComparable.CompareTo(object? other) { throw null; } public override string ToString() { throw null; } } public partial struct ValueTuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.IComparable<(T1, T2, T3)>, System.IEquatable<(T1, T2, T3)>, System.Runtime.CompilerServices.ITuple @@ -4668,10 +4668,10 @@ public partial struct ValueTuple : System.Collections.IStructuralCom public override bool Equals(object? obj) { throw null; } public bool Equals((T1, T2, T3) other) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object other) { throw null; } + int System.IComparable.CompareTo(object? other) { throw null; } public override string ToString() { throw null; } } public partial struct ValueTuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.IComparable<(T1, T2, T3, T4)>, System.IEquatable<(T1, T2, T3, T4)>, System.Runtime.CompilerServices.ITuple @@ -4687,10 +4687,10 @@ public partial struct ValueTuple : System.Collections.IStructura public override bool Equals(object? obj) { throw null; } public bool Equals((T1, T2, T3, T4) other) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object other) { throw null; } + int System.IComparable.CompareTo(object? other) { throw null; } public override string ToString() { throw null; } } public partial struct ValueTuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.IComparable<(T1, T2, T3, T4, T5)>, System.IEquatable<(T1, T2, T3, T4, T5)>, System.Runtime.CompilerServices.ITuple @@ -4707,10 +4707,10 @@ public partial struct ValueTuple : System.Collections.IStruc public override bool Equals(object? obj) { throw null; } public bool Equals((T1, T2, T3, T4, T5) other) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object other) { throw null; } + int System.IComparable.CompareTo(object? other) { throw null; } public override string ToString() { throw null; } } public partial struct ValueTuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.IComparable<(T1, T2, T3, T4, T5, T6)>, System.IEquatable<(T1, T2, T3, T4, T5, T6)>, System.Runtime.CompilerServices.ITuple @@ -4728,10 +4728,10 @@ public partial struct ValueTuple : System.Collections.IS public override bool Equals(object? obj) { throw null; } public bool Equals((T1, T2, T3, T4, T5, T6) other) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object other) { throw null; } + int System.IComparable.CompareTo(object? other) { throw null; } public override string ToString() { throw null; } } public partial struct ValueTuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.IComparable<(T1, T2, T3, T4, T5, T6, T7)>, System.IEquatable<(T1, T2, T3, T4, T5, T6, T7)>, System.Runtime.CompilerServices.ITuple @@ -4750,10 +4750,10 @@ public partial struct ValueTuple : System.Collection public override bool Equals(object? obj) { throw null; } public bool Equals((T1, T2, T3, T4, T5, T6, T7) other) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object other) { throw null; } + int System.IComparable.CompareTo(object? other) { throw null; } public override string ToString() { throw null; } } public partial struct ValueTuple : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.IComparable>, System.IEquatable>, System.Runtime.CompilerServices.ITuple where TRest : struct @@ -4773,10 +4773,10 @@ public partial struct ValueTuple : System.Col public override bool Equals(object? obj) { throw null; } public bool Equals(System.ValueTuple other) { throw null; } public override int GetHashCode() { throw null; } - int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; } - bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; } + int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; } + bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; } int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; } - int System.IComparable.CompareTo(object other) { throw null; } + int System.IComparable.CompareTo(object? other) { throw null; } public override string ToString() { throw null; } } public abstract partial class ValueType @@ -5300,11 +5300,11 @@ public partial class Collection : System.Collections.Generic.ICollection, protected virtual void SetItem(int index, T item) { } void System.Collections.ICollection.CopyTo(System.Array array, int index) { } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - int System.Collections.IList.Add(object value) { throw null; } - bool System.Collections.IList.Contains(object value) { throw null; } - int System.Collections.IList.IndexOf(object value) { throw null; } - void System.Collections.IList.Insert(int index, object value) { } - void System.Collections.IList.Remove(object value) { } + int System.Collections.IList.Add(object? value) { throw null; } + bool System.Collections.IList.Contains(object? value) { throw null; } + int System.Collections.IList.IndexOf(object? value) { throw null; } + void System.Collections.IList.Insert(int index, object? value) { } + void System.Collections.IList.Remove(object? value) { } } public partial class ReadOnlyCollection : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList { @@ -5330,12 +5330,12 @@ public partial class ReadOnlyCollection : System.Collections.Generic.ICollect void System.Collections.Generic.IList.RemoveAt(int index) { } void System.Collections.ICollection.CopyTo(System.Array array, int index) { } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - int System.Collections.IList.Add(object value) { throw null; } + int System.Collections.IList.Add(object? value) { throw null; } void System.Collections.IList.Clear() { } - bool System.Collections.IList.Contains(object value) { throw null; } - int System.Collections.IList.IndexOf(object value) { throw null; } - void System.Collections.IList.Insert(int index, object value) { } - void System.Collections.IList.Remove(object value) { } + bool System.Collections.IList.Contains(object? value) { throw null; } + int System.Collections.IList.IndexOf(object? value) { throw null; } + void System.Collections.IList.Insert(int index, object? value) { } + void System.Collections.IList.Remove(object? value) { } void System.Collections.IList.RemoveAt(int index) { } } } @@ -5872,7 +5872,7 @@ public sealed partial class CompareInfo : System.Runtime.Serialization.IDeserial public int LastIndexOf(string source, string value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; } public int LastIndexOf(System.ReadOnlySpan source, System.ReadOnlySpan value, System.Globalization.CompareOptions options = System.Globalization.CompareOptions.None) { throw null; } public int LastIndexOf(System.ReadOnlySpan source, System.Text.Rune value, System.Globalization.CompareOptions options = System.Globalization.CompareOptions.None) { throw null; } - void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { } + void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object? sender) { } public override string ToString() { throw null; } } [System.FlagsAttribute] @@ -6495,7 +6495,7 @@ public sealed partial class TextInfo : System.ICloneable, System.Runtime.Seriali public override bool Equals(object? obj) { throw null; } public override int GetHashCode() { throw null; } public static System.Globalization.TextInfo ReadOnly(System.Globalization.TextInfo textInfo) { throw null; } - void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { } + void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object? sender) { } public char ToLower(char c) { throw null; } public string ToLower(string str) { throw null; } public override string ToString() { throw null; } @@ -8379,7 +8379,7 @@ public partial class StrongNameKeyPair : System.Runtime.Serialization.IDeseriali protected StrongNameKeyPair(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public StrongNameKeyPair(string keyPairContainer) { } public byte[] PublicKey { get { throw null; } } - void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { } + void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object? sender) { } void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } } public partial class TargetException : System.ApplicationException diff --git a/src/libraries/System.Text.RegularExpressions/ref/System.Text.RegularExpressions.cs b/src/libraries/System.Text.RegularExpressions/ref/System.Text.RegularExpressions.cs index f97324489a8bf..c063564dd4244 100644 --- a/src/libraries/System.Text.RegularExpressions/ref/System.Text.RegularExpressions.cs +++ b/src/libraries/System.Text.RegularExpressions/ref/System.Text.RegularExpressions.cs @@ -37,12 +37,12 @@ public partial class CaptureCollection : System.Collections.Generic.ICollection< int System.Collections.Generic.IList.IndexOf(System.Text.RegularExpressions.Capture item) { throw null; } void System.Collections.Generic.IList.Insert(int index, System.Text.RegularExpressions.Capture item) { } void System.Collections.Generic.IList.RemoveAt(int index) { } - int System.Collections.IList.Add(object value) { throw null; } + int System.Collections.IList.Add(object? value) { throw null; } void System.Collections.IList.Clear() { } - bool System.Collections.IList.Contains(object value) { throw null; } - int System.Collections.IList.IndexOf(object value) { throw null; } - void System.Collections.IList.Insert(int index, object value) { } - void System.Collections.IList.Remove(object value) { } + bool System.Collections.IList.Contains(object? value) { throw null; } + int System.Collections.IList.IndexOf(object? value) { throw null; } + void System.Collections.IList.Insert(int index, object? value) { } + void System.Collections.IList.Remove(object? value) { } void System.Collections.IList.RemoveAt(int index) { } } public partial class Group : System.Text.RegularExpressions.Capture @@ -80,12 +80,12 @@ public partial class GroupCollection : System.Collections.Generic.ICollection.IndexOf(System.Text.RegularExpressions.Group item) { throw null; } void System.Collections.Generic.IList.Insert(int index, System.Text.RegularExpressions.Group item) { } void System.Collections.Generic.IList.RemoveAt(int index) { } - int System.Collections.IList.Add(object value) { throw null; } + int System.Collections.IList.Add(object? value) { throw null; } void System.Collections.IList.Clear() { } - bool System.Collections.IList.Contains(object value) { throw null; } - int System.Collections.IList.IndexOf(object value) { throw null; } - void System.Collections.IList.Insert(int index, object value) { } - void System.Collections.IList.Remove(object value) { } + bool System.Collections.IList.Contains(object? value) { throw null; } + int System.Collections.IList.IndexOf(object? value) { throw null; } + void System.Collections.IList.Insert(int index, object? value) { } + void System.Collections.IList.Remove(object? value) { } void System.Collections.IList.RemoveAt(int index) { } #pragma warning disable CS8614 // Nullability of reference types in type of parameter doesn't match implicitly implemented member. public bool TryGetValue(string key, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Text.RegularExpressions.Group? value) { throw null; } @@ -122,12 +122,12 @@ public partial class MatchCollection : System.Collections.Generic.ICollection.IndexOf(System.Text.RegularExpressions.Match item) { throw null; } void System.Collections.Generic.IList.Insert(int index, System.Text.RegularExpressions.Match item) { } void System.Collections.Generic.IList.RemoveAt(int index) { } - int System.Collections.IList.Add(object value) { throw null; } + int System.Collections.IList.Add(object? value) { throw null; } void System.Collections.IList.Clear() { } - bool System.Collections.IList.Contains(object value) { throw null; } - int System.Collections.IList.IndexOf(object value) { throw null; } - void System.Collections.IList.Insert(int index, object value) { } - void System.Collections.IList.Remove(object value) { } + bool System.Collections.IList.Contains(object? value) { throw null; } + int System.Collections.IList.IndexOf(object? value) { throw null; } + void System.Collections.IList.Insert(int index, object? value) { } + void System.Collections.IList.Remove(object? value) { } void System.Collections.IList.RemoveAt(int index) { } } public delegate string MatchEvaluator(System.Text.RegularExpressions.Match match); From caf692387fc53e835f3bff48abb8328c941f858e Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 8 May 2020 21:39:46 -0700 Subject: [PATCH 075/420] Finish the other part of the GCTotalPhysicalMemory config implementation (#36152) * Finish the other part of the GCTotalPhysicalMemory config implementation The total physical memory specified by the GCTotalPhysicalMemory config needs to communicated over to the VM side for memory load calculation. Otherwise inside GC we are using the correct physical memory specified, but when we ask for the memory load it's still based on the total available memory. * Delete unnecessary delay-loading of kernel32.dll * Avoid mutable restricted memory limit inside OS PAL Co-authored-by: Maoni0 --- src/coreclr/src/gc/env/gcenv.os.h | 7 +- src/coreclr/src/gc/gc.cpp | 15 ++-- src/coreclr/src/gc/gcpriv.h | 3 + src/coreclr/src/gc/unix/gcenv.unix.cpp | 19 ++--- src/coreclr/src/gc/windows/gcenv.windows.cpp | 78 ++++--------------- src/coreclr/src/vm/gcenv.os.cpp | 82 ++++---------------- 6 files changed, 56 insertions(+), 148 deletions(-) diff --git a/src/coreclr/src/gc/env/gcenv.os.h b/src/coreclr/src/gc/env/gcenv.os.h index ae398e5503e3b..a2d837a82d50d 100644 --- a/src/coreclr/src/gc/env/gcenv.os.h +++ b/src/coreclr/src/gc/env/gcenv.os.h @@ -433,20 +433,19 @@ class GCToOSInterface // Remarks: // If a process runs with a restricted memory limit, it returns the limit. If there's no limit // specified, it returns amount of actual physical memory. - // - // PERF TODO: Requires more work to not treat the restricted case to be special. - // To be removed before 3.0 ships. static uint64_t GetPhysicalMemoryLimit(bool* is_restricted=NULL); // Get memory status // Parameters: + // restricted_limit - The amount of physical memory in bytes that the current process is being restricted to. If non-zero, it used to calculate + // memory_load and available_physical. If zero, memory_load and available_physical is calculate based on all available memory. // memory_load - A number between 0 and 100 that specifies the approximate percentage of physical memory // that is in use (0 indicates no memory use and 100 indicates full memory use). // available_physical - The amount of physical memory currently available, in bytes. // available_page_file - The maximum amount of memory the current process can commit, in bytes. // Remarks: // Any parameter can be null. - static void GetMemoryStatus(uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file); + static void GetMemoryStatus(uint64_t restricted_limit, uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file); // Get size of an OS memory page static size_t GetPageSize(); diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index a91de0d388d5e..c09b2c0182f26 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -2175,6 +2175,8 @@ uint32_t gc_heap::m_high_memory_load_th; uint32_t gc_heap::v_high_memory_load_th; +bool gc_heap::is_restricted_physical_mem; + uint64_t gc_heap::total_physical_mem = 0; uint64_t gc_heap::entry_available_physical_mem = 0; @@ -19628,7 +19630,7 @@ void gc_heap::get_memory_info (uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file) { - GCToOSInterface::GetMemoryStatus(memory_load, available_physical, available_page_file); + GCToOSInterface::GetMemoryStatus(is_restricted_physical_mem ? total_physical_mem : 0, memory_load, available_physical, available_page_file); } void fire_mark_event (int heap_num, int root_type, size_t bytes_marked) @@ -34925,11 +34927,14 @@ HRESULT GCHeap::Initialize() g_num_processors = GCToOSInterface::GetTotalProcessorCount(); assert(g_num_processors != 0); - bool is_restricted; gc_heap::total_physical_mem = (size_t)GCConfig::GetGCTotalPhysicalMemory(); - if (!(gc_heap::total_physical_mem)) + if (gc_heap::total_physical_mem != 0) + { + gc_heap::is_restricted_physical_mem = true; + } + else { - gc_heap::total_physical_mem = GCToOSInterface::GetPhysicalMemoryLimit (&is_restricted); + gc_heap::total_physical_mem = GCToOSInterface::GetPhysicalMemoryLimit (&gc_heap::is_restricted_physical_mem); } #ifdef HOST_64BIT @@ -34948,7 +34953,7 @@ HRESULT GCHeap::Initialize() // running in a container, use this limit for the GC heap. if (!(gc_heap::heap_hard_limit)) { - if (is_restricted) + if (gc_heap::is_restricted_physical_mem) { uint64_t physical_mem_for_gc = gc_heap::total_physical_mem * (uint64_t)75 / (uint64_t)100; gc_heap::heap_hard_limit = (size_t)max ((20 * 1024 * 1024), physical_mem_for_gc); diff --git a/src/coreclr/src/gc/gcpriv.h b/src/coreclr/src/gc/gcpriv.h index 3bcb383870773..e3a6c1f5b60ab 100644 --- a/src/coreclr/src/gc/gcpriv.h +++ b/src/coreclr/src/gc/gcpriv.h @@ -3289,6 +3289,9 @@ class gc_heap PER_HEAP_ISOLATED uint32_t v_high_memory_load_th; + PER_HEAP_ISOLATED + bool is_restricted_physical_mem; + PER_HEAP_ISOLATED uint64_t mem_one_percent; diff --git a/src/coreclr/src/gc/unix/gcenv.unix.cpp b/src/coreclr/src/gc/unix/gcenv.unix.cpp index fd3cd5ec91b6d..9d074231a690d 100644 --- a/src/coreclr/src/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/src/gc/unix/gcenv.unix.cpp @@ -957,7 +957,7 @@ uint32_t GCToOSInterface::GetCurrentProcessCpuCount() // Return the size of the user-mode portion of the virtual address space of this process. // Return: -// non zero if it has succeeded, 0 if it has failed +// non zero if it has succeeded, (size_t)-1 if not available size_t GCToOSInterface::GetVirtualMemoryLimit() { #ifdef HOST_64BIT @@ -1143,11 +1143,13 @@ uint64_t GetAvailablePageFile() // Get memory status // Parameters: +// restricted_limit - The amount of physical memory in bytes that the current process is being restricted to. If non-zero, it used to calculate +// memory_load and available_physical. If zero, memory_load and available_physical is calculate based on all available memory. // memory_load - A number between 0 and 100 that specifies the approximate percentage of physical memory // that is in use (0 indicates no memory use and 100 indicates full memory use). // available_physical - The amount of physical memory currently available, in bytes. // available_page_file - The maximum amount of memory the current process can commit, in bytes. -void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file) +void GCToOSInterface::GetMemoryStatus(uint64_t restricted_limit, uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file) { uint64_t available = 0; uint32_t load = 0; @@ -1155,16 +1157,14 @@ void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available if (memory_load != nullptr || available_physical != nullptr) { size_t used; - bool isRestricted; - uint64_t total = GetPhysicalMemoryLimit(&isRestricted); - if (isRestricted) + if (restricted_limit != 0) { // Get the physical memory in use - from it, we can get the physical memory available. // We do this only when we have the total physical memory available. if (GetPhysicalMemoryUsed(&used)) { - available = total > used ? total-used : 0; - load = (uint32_t)(((float)used * 100) / (float)total); + available = restricted_limit > used ? restricted_limit - used : 0; + load = (uint32_t)(((float)used * 100) / (float)restricted_limit); } } else @@ -1173,7 +1173,9 @@ void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available if (memory_load != NULL) { - uint32_t load = 0; + bool isRestricted; + uint64_t total = GetPhysicalMemoryLimit(&isRestricted); + if (total > available) { used = total - available; @@ -1191,7 +1193,6 @@ void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available if (available_page_file != nullptr) *available_page_file = GetAvailablePageFile(); - } // Get a high precision performance counter diff --git a/src/coreclr/src/gc/windows/gcenv.windows.cpp b/src/coreclr/src/gc/windows/gcenv.windows.cpp index 2aaf7ba19aa5e..a9504bd4b69ad 100644 --- a/src/coreclr/src/gc/windows/gcenv.windows.cpp +++ b/src/coreclr/src/gc/windows/gcenv.windows.cpp @@ -18,22 +18,12 @@ GCSystemInfo g_SystemInfo; -typedef BOOL (WINAPI *PGET_PROCESS_MEMORY_INFO)(HANDLE handle, PROCESS_MEMORY_COUNTERS* memCounters, uint32_t cb); -static PGET_PROCESS_MEMORY_INFO GCGetProcessMemoryInfo = 0; - static size_t g_RestrictedPhysicalMemoryLimit = (size_t)UINTPTR_MAX; -// For 32-bit processes the virtual address range could be smaller than the amount of physical -// memory on the machine/in the container, we need to restrict by the VM. -static bool g_UseRestrictedVirtualMemory = false; - static bool g_SeLockMemoryPrivilegeAcquired = false; static AffinitySet g_processAffinitySet; -typedef BOOL (WINAPI *PIS_PROCESS_IN_JOB)(HANDLE processHandle, HANDLE jobHandle, BOOL* result); -typedef BOOL (WINAPI *PQUERY_INFORMATION_JOB_OBJECT)(HANDLE jobHandle, JOBOBJECTINFOCLASS jobObjectInfoClass, void* lpJobObjectInfo, DWORD cbJobObjectInfoLength, LPDWORD lpReturnLength); - namespace { static bool g_fEnableGCNumaAware; @@ -297,36 +287,14 @@ static size_t GetRestrictedPhysicalMemoryLimit() uint64_t total_virtual = 0; uint64_t total_physical = 0; BOOL in_job_p = FALSE; - HINSTANCE hinstKernel32 = 0; - - PIS_PROCESS_IN_JOB GCIsProcessInJob = 0; - PQUERY_INFORMATION_JOB_OBJECT GCQueryInformationJobObject = 0; - - hinstKernel32 = LoadLibraryEx(L"kernel32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); - if (!hinstKernel32) - goto exit; - GCIsProcessInJob = (PIS_PROCESS_IN_JOB)GetProcAddress(hinstKernel32, "IsProcessInJob"); - if (!GCIsProcessInJob) - goto exit; - - if (!GCIsProcessInJob(GetCurrentProcess(), NULL, &in_job_p)) + if (!IsProcessInJob(GetCurrentProcess(), NULL, &in_job_p)) goto exit; if (in_job_p) { - GCGetProcessMemoryInfo = (PGET_PROCESS_MEMORY_INFO)GetProcAddress(hinstKernel32, "K32GetProcessMemoryInfo"); - - if (!GCGetProcessMemoryInfo) - goto exit; - - GCQueryInformationJobObject = (PQUERY_INFORMATION_JOB_OBJECT)GetProcAddress(hinstKernel32, "QueryInformationJobObject"); - - if (!GCQueryInformationJobObject) - goto exit; - JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info; - if (GCQueryInformationJobObject (NULL, JobObjectExtendedLimitInformation, &limit_info, + if (QueryInformationJobObject (NULL, JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info), NULL)) { size_t job_memory_limit = (size_t)UINTPTR_MAX; @@ -373,13 +341,6 @@ static size_t GetRestrictedPhysicalMemoryLimit() if (job_physical_memory_limit == (size_t)UINTPTR_MAX) { job_physical_memory_limit = 0; - - if (hinstKernel32 != 0) - { - FreeLibrary(hinstKernel32); - hinstKernel32 = 0; - GCGetProcessMemoryInfo = 0; - } } // Check to see if we are limited by VM. @@ -399,15 +360,8 @@ static size_t GetRestrictedPhysicalMemoryLimit() if (total_virtual < total_physical) { - if (hinstKernel32 != 0) - { - // We can also free the lib here - if we are limited by VM we will not be calling - // GetProcessMemoryInfo. - FreeLibrary(hinstKernel32); - GCGetProcessMemoryInfo = 0; - } - g_UseRestrictedVirtualMemory = true; - job_physical_memory_limit = (size_t)total_virtual; + // Limited by virtual address space + job_physical_memory_limit = 0; } VolatileStore(&g_RestrictedPhysicalMemoryLimit, job_physical_memory_limit); @@ -1044,7 +998,7 @@ uint32_t GCToOSInterface::GetCurrentProcessCpuCount() // Return the size of the user-mode portion of the virtual address space of this process. // Return: -// non zero if it has succeeded, 0 if it has failed +// non zero if it has succeeded, (size_t)-1 if not available size_t GCToOSInterface::GetVirtualMemoryLimit() { MEMORYSTATUSEX memStatus; @@ -1067,7 +1021,7 @@ uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted) size_t restricted_limit = GetRestrictedPhysicalMemoryLimit(); if (restricted_limit != 0) { - if (is_restricted && !g_UseRestrictedVirtualMemory) + if (is_restricted) *is_restricted = true; return restricted_limit; @@ -1081,23 +1035,22 @@ uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted) // Get memory status // Parameters: +// restricted_limit - The amount of physical memory in bytes that the current process is being restricted to. If non-zero, it used to calculate +// memory_load and available_physical. If zero, memory_load and available_physical is calculate based on all available memory. // memory_load - A number between 0 and 100 that specifies the approximate percentage of physical memory // that is in use (0 indicates no memory use and 100 indicates full memory use). // available_physical - The amount of physical memory currently available, in bytes. // available_page_file - The maximum amount of memory the current process can commit, in bytes. -void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file) +void GCToOSInterface::GetMemoryStatus(uint64_t restricted_limit, uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file) { - uint64_t restricted_limit = GetRestrictedPhysicalMemoryLimit(); if (restricted_limit != 0) { size_t workingSetSize; BOOL status = FALSE; - if (!g_UseRestrictedVirtualMemory) - { - PROCESS_MEMORY_COUNTERS pmc; - status = GCGetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)); - workingSetSize = pmc.WorkingSetSize; - } + + PROCESS_MEMORY_COUNTERS pmc; + status = GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)); + workingSetSize = pmc.WorkingSetSize; if(status) { @@ -1123,9 +1076,10 @@ void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available MEMORYSTATUSEX ms; ::GetProcessMemoryLoad(&ms); - if (g_UseRestrictedVirtualMemory) + // For 32-bit processes the virtual address range could be smaller than the amount of physical + // memory on the machine/in the container, we need to restrict by the VM. + if (ms.ullTotalVirtual < ms.ullTotalPhys) { - _ASSERTE (ms.ullTotalVirtual == restricted_limit); if (memory_load != NULL) *memory_load = (uint32_t)((float)(ms.ullTotalVirtual - ms.ullAvailVirtual) * 100.0 / (float)ms.ullTotalVirtual); if (available_physical != NULL) diff --git a/src/coreclr/src/vm/gcenv.os.cpp b/src/coreclr/src/vm/gcenv.os.cpp index 6b9e042f04e9b..e7add3b29e08b 100644 --- a/src/coreclr/src/vm/gcenv.os.cpp +++ b/src/coreclr/src/vm/gcenv.os.cpp @@ -756,7 +756,7 @@ uint32_t GCToOSInterface::GetCurrentProcessCpuCount() // Return the size of the user-mode portion of the virtual address space of this process. // Return: -// non zero if it has succeeded, 0 if it has failed +// non zero if it has succeeded, (size_t)-1 if not available size_t GCToOSInterface::GetVirtualMemoryLimit() { LIMITED_METHOD_CONTRACT; @@ -771,16 +771,6 @@ static size_t g_RestrictedPhysicalMemoryLimit = (size_t)MAX_PTR; #ifndef TARGET_UNIX -// For 32-bit processes the virtual address range could be smaller than the amount of physical -// memory on the machine/in the container, we need to restrict by the VM. -static bool g_UseRestrictedVirtualMemory = false; - -typedef BOOL (WINAPI *PGET_PROCESS_MEMORY_INFO)(HANDLE handle, PROCESS_MEMORY_COUNTERS* memCounters, uint32_t cb); -static PGET_PROCESS_MEMORY_INFO GCGetProcessMemoryInfo = 0; - -typedef BOOL (WINAPI *PIS_PROCESS_IN_JOB)(HANDLE processHandle, HANDLE jobHandle, BOOL* result); -typedef BOOL (WINAPI *PQUERY_INFORMATION_JOB_OBJECT)(HANDLE jobHandle, JOBOBJECTINFOCLASS jobObjectInfoClass, void* lpJobObjectInfo, DWORD cbJobObjectInfoLength, LPDWORD lpReturnLength); - static size_t GetRestrictedPhysicalMemoryLimit() { LIMITED_METHOD_CONTRACT; @@ -793,34 +783,14 @@ static size_t GetRestrictedPhysicalMemoryLimit() uint64_t total_virtual = 0; uint64_t total_physical = 0; BOOL in_job_p = FALSE; - HINSTANCE hinstKernel32 = 0; - - PIS_PROCESS_IN_JOB GCIsProcessInJob = 0; - PQUERY_INFORMATION_JOB_OBJECT GCQueryInformationJobObject = 0; - - GCIsProcessInJob = &(::IsProcessInJob); - if (!GCIsProcessInJob(GetCurrentProcess(), NULL, &in_job_p)) + if (!IsProcessInJob(GetCurrentProcess(), NULL, &in_job_p)) goto exit; if (in_job_p) { - hinstKernel32 = WszLoadLibrary(L"kernel32.dll"); - if (!hinstKernel32) - goto exit; - - GCGetProcessMemoryInfo = (PGET_PROCESS_MEMORY_INFO)GetProcAddress(hinstKernel32, "K32GetProcessMemoryInfo"); - - if (!GCGetProcessMemoryInfo) - goto exit; - - GCQueryInformationJobObject = &(::QueryInformationJobObject); - - if (!GCQueryInformationJobObject) - goto exit; - JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info; - if (GCQueryInformationJobObject (NULL, JobObjectExtendedLimitInformation, &limit_info, + if (QueryInformationJobObject(NULL, JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info), NULL)) { size_t job_memory_limit = (size_t)MAX_PTR; @@ -867,13 +837,6 @@ static size_t GetRestrictedPhysicalMemoryLimit() if (job_physical_memory_limit == (size_t)MAX_PTR) { job_physical_memory_limit = 0; - - if (hinstKernel32 != 0) - { - FreeLibrary(hinstKernel32); - hinstKernel32 = 0; - GCGetProcessMemoryInfo = 0; - } } // Check to see if we are limited by VM. @@ -893,15 +856,8 @@ static size_t GetRestrictedPhysicalMemoryLimit() if (total_virtual < total_physical) { - if (hinstKernel32 != 0) - { - // We can also free the lib here - if we are limited by VM we will not be calling - // GetProcessMemoryInfo. - FreeLibrary(hinstKernel32); - GCGetProcessMemoryInfo = 0; - } - g_UseRestrictedVirtualMemory = true; - job_physical_memory_limit = (size_t)total_virtual; + // Limited by virtual address space + job_physical_memory_limit = 0; } VolatileStore(&g_RestrictedPhysicalMemoryLimit, job_physical_memory_limit); @@ -928,9 +884,6 @@ static size_t GetRestrictedPhysicalMemoryLimit() // Get the physical memory that this process can use. // Return: // non zero if it has succeeded, 0 if it has failed -// -// PERF TODO: Requires more work to not treat the restricted case to be special. -// To be removed before 3.0 ships. uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted) { LIMITED_METHOD_CONTRACT; @@ -941,11 +894,7 @@ uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted) size_t restricted_limit = GetRestrictedPhysicalMemoryLimit(); if (restricted_limit != 0) { - if (is_restricted -#ifndef TARGET_UNIX - && !g_UseRestrictedVirtualMemory -#endif - ) + if (is_restricted) *is_restricted = true; return restricted_limit; @@ -965,26 +914,22 @@ uint64_t GCToOSInterface::GetPhysicalMemoryLimit(bool* is_restricted) // available_page_file - The maximum amount of memory the current process can commit, in bytes. // Remarks: // Any parameter can be null. -void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file) +void GCToOSInterface::GetMemoryStatus(uint64_t restricted_limit, uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file) { LIMITED_METHOD_CONTRACT; - uint64_t restricted_limit = GetRestrictedPhysicalMemoryLimit(); if (restricted_limit != 0) { size_t workingSetSize; BOOL status = FALSE; #ifndef TARGET_UNIX - if (!g_UseRestrictedVirtualMemory) - { - PROCESS_MEMORY_COUNTERS pmc; - status = GCGetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)); - workingSetSize = pmc.WorkingSetSize; - } + PROCESS_MEMORY_COUNTERS pmc; + status = GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)); + workingSetSize = pmc.WorkingSetSize; #else status = PAL_GetPhysicalMemoryUsed(&workingSetSize); #endif - if(status) + if (status) { if (memory_load) *memory_load = (uint32_t)((float)workingSetSize * 100.0 / (float)restricted_limit); @@ -1009,9 +954,10 @@ void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available GetProcessMemoryLoad(&ms); #ifndef TARGET_UNIX - if (g_UseRestrictedVirtualMemory) + // For 32-bit processes the virtual address range could be smaller than the amount of physical + // memory on the machine/in the container, we need to restrict by the VM. + if (ms.ullTotalVirtual < ms.ullTotalPhys) { - _ASSERTE (ms.ullTotalVirtual == restricted_limit); if (memory_load != NULL) *memory_load = (uint32_t)((float)(ms.ullTotalVirtual - ms.ullAvailVirtual) * 100.0 / (float)ms.ullTotalVirtual); if (available_physical != NULL) From 930d80dfb2affbc37bdc53c1c375222fc3b0b304 Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Fri, 8 May 2020 22:20:34 -0700 Subject: [PATCH 076/420] Fixing test failing on arm64 (#36145) --- .../tests/BerConverterTests.cs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs index 30836ff3d2aab..890ce024efbb6 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/BerConverterTests.cs @@ -30,8 +30,8 @@ public static IEnumerable Encode_TestData() yield return new object[] { "[]", new object[] { "a" }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 49, 132, 0, 0, 0, 0 } : new byte[] { 49, 0 } }; yield return new object[] { "n", new object[] { "a" }, new byte[] { 5, 0 } }; - yield return new object[] { "tetie", new object[] { -1, 0, 1, 2, 3 }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 255, 1, 0, 1, 1, 2, 10, 1, 3 } : new byte[] { 10, 1, 0, 1, 1, 2, 10, 1, 3 } }; - yield return new object[] { "{tetie}", new object[] { -1, 0, 1, 2, 3 }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 9, 255, 1, 0, 1, 1, 2, 10, 1, 3 } : new byte[] { 48, 9, 10, 1, 0, 1, 1, 2, 10, 1, 3 } }; + yield return new object[] { "tetie", new object[] { 128, 0, 133, 2, 3 }, new byte[] { 128, 1, 0, 133, 1, 2, 10, 1, 3 } }; + yield return new object[] { "{tetie}", new object[] { 128, 0, 133, 2, 3 }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 9, 128, 1, 0, 133, 1, 2, 10, 1, 3 } : new byte[] { 48, 9, 128, 1, 0, 133, 1, 2, 10, 1, 3 } }; yield return new object[] { "bb", new object[] { true, false }, new byte[] { 1, 1, 255, 1, 1, 0 } }; yield return new object[] { "{bb}", new object[] { true, false }, (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? new byte[] { 48, 132, 0, 0, 0, 6, 1, 1, 255, 1, 1, 0 } : new byte[] { 48, 6, 1, 1, 255, 1, 1, 0 } }; @@ -43,15 +43,10 @@ public static IEnumerable Encode_TestData() yield return new object[] { "VVVV", new object[] { null, new byte[][] { new byte[] { 0, 1, 2, 3 }, null }, new byte[][] { new byte[0] }, new byte[0][] }, new byte[] { 4, 4, 0, 1, 2, 3, 4, 0, 4, 0 } }; } - [ConditionalTheory] + [Theory] [MemberData(nameof(Encode_TestData))] public void Encode_Objects_ReturnsExpected(string format, object[] values, byte[] expected) { - if (PlatformDetection.IsArm64Process && format.Contains("tetie")) - { - throw new SkipTestException("Active issue: https://github.com/dotnet/runtime/issues/36087"); - } - AssertExtensions.Equal(expected, BerConverter.Encode(format, values)); } From 3cd02dfcd116d0cbb76525331bcaa908cd352884 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Sat, 9 May 2020 04:26:43 -0400 Subject: [PATCH 077/420] [interp] Fix sdks build (#36121) Co-authored-by: BrzVlad --- src/mono/mono/mini/interp/interp.c | 2 +- src/mono/mono/mini/mini-x86.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index f51fb3d7aa0aa..4563f1caab66c 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -2941,7 +2941,7 @@ interp_create_method_pointer (MonoMethod *method, gboolean compile, MonoError *e } } else { #ifndef MONO_ARCH_HAVE_INTERP_ENTRY_TRAMPOLINE - mono_error_assertf_ok (error, "couldn't compile wrapper \"%s\" for \"%s\"", + g_assertion_message ("couldn't compile wrapper \"%s\" for \"%s\"", mono_method_get_name_full (wrapper, TRUE, TRUE, MONO_TYPE_NAME_FORMAT_IL), mono_method_get_name_full (method, TRUE, TRUE, MONO_TYPE_NAME_FORMAT_IL)); #else diff --git a/src/mono/mono/mini/mini-x86.c b/src/mono/mono/mini/mini-x86.c index 9bfa7beafeced..e717acdec8527 100644 --- a/src/mono/mono/mini/mini-x86.c +++ b/src/mono/mono/mini/mini-x86.c @@ -607,7 +607,7 @@ void mono_arch_set_native_call_context_args (CallContext *ccontext, gpointer frame, MonoMethodSignature *sig) { CallInfo *cinfo = get_call_info (NULL, sig); - MonoEECallbacks *interp_cb = mini_get_interp_callbacks (); + const MonoEECallbacks *interp_cb = mini_get_interp_callbacks (); gpointer storage; ArgInfo *ainfo; From 386ee4658291003d1d4fe8e28612d9c7927f5d40 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Sat, 9 May 2020 06:12:15 -0400 Subject: [PATCH 078/420] Apply Regex starting loop optimization to non-atomic loops as well (#35936) * Apply Regex starting loop optimization to non-atomic loops as well * Remove min iteration restriction The node.N > 0 restriction isn't necessary, and prevents this optimization from being used with * loops. Worst case, the loop doesn't match anything, and we pay to overwrite the starting position with itself. Best case, we eliminate a ton of cost. --- .../Text/RegularExpressions/RegexNode.cs | 25 +++++++++++-------- .../tests/Regex.Match.Tests.cs | 2 ++ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexNode.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexNode.cs index 1479c2ea6de06..79f352130f5d7 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexNode.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexNode.cs @@ -310,18 +310,18 @@ internal RegexNode FinalOptimize() // to implementations that don't support backtracking. EliminateEndingBacktracking(rootNode.Child(0), DefaultMaxRecursionDepth); - // Optimization: unnecessary re-processing of atomic starting groups. - // If an expression is guaranteed to begin with a single-character infinite atomic group that isn't part of an alternation (in which case it + // Optimization: unnecessary re-processing of starting loops. + // If an expression is guaranteed to begin with a single-character unbounded loop that isn't part of an alternation (in which case it // wouldn't be guaranteed to be at the beginning) or a capture (in which case a back reference could be influenced by its length), then we // can update the tree with a temporary node to indicate that the implementation should use that node's ending position in the input text // as the next starting position at which to start the next match. This avoids redoing matches we've already performed, e.g. matching // "\w+@dot.net" against "is this a valid address@dot.net", the \w+ will initially match the "is" and then will fail to match the "@". - // Rather than bumping the scan loop by 1 and trying again to match at the "s", we can instead start at the " ". We limit ourselves to - // one/set atomic loops with a min iteration count of 1 so that we know we'll get something in exchange for the extra overhead of storing - // the updated position. For functional correctness we can only consider infinite atomic loops, as to be able to start at the end of the - // loop we need the loop to have consumed all possible matches; otherwise, you could end up with a pattern like "a{1,3}b" matching - // against "aaaabc", which should match, but if we pre-emptively stop consuming after the first three a's and re-start from that position, - // we'll end up failing the match even though it should have succeeded. + // Rather than bumping the scan loop by 1 and trying again to match at the "s", we can instead start at the " ". For functional correctness + // we can only consider unbounded loops, as to be able to start at the end of the loop we need the loop to have consumed all possible matches; + // otherwise, you could end up with a pattern like "a{1,3}b" matching against "aaaabc", which should match, but if we pre-emptively stop consuming + // after the first three a's and re-start from that position, we'll end up failing the match even though it should have succeeded. We can also + // apply this optimization to non-atomic loops. Even though backtracking could be necessary, such backtracking would be handled within the processing + // of a single starting position. { RegexNode node = rootNode.Child(0); // skip implicit root capture node while (true) @@ -333,9 +333,12 @@ internal RegexNode FinalOptimize() node = node.Child(0); continue; - case Oneloopatomic when node.M > 0 && node.N == int.MaxValue: - case Notoneloopatomic when node.M > 0 && node.N == int.MaxValue: - case Setloopatomic when node.M > 0 && node.N == int.MaxValue: + case Oneloop when node.N == int.MaxValue: + case Oneloopatomic when node.N == int.MaxValue: + case Notoneloop when node.N == int.MaxValue: + case Notoneloopatomic when node.N == int.MaxValue: + case Setloop when node.N == int.MaxValue: + case Setloopatomic when node.N == int.MaxValue: RegexNode? parent = node.Next; if (parent != null && parent.Type == Concatenate) { diff --git a/src/libraries/System.Text.RegularExpressions/tests/Regex.Match.Tests.cs b/src/libraries/System.Text.RegularExpressions/tests/Regex.Match.Tests.cs index cf25c63f18afb..efd7b3cc7d8cc 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/Regex.Match.Tests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/Regex.Match.Tests.cs @@ -124,6 +124,8 @@ public static IEnumerable Match_Basic_TestData() yield return new object[] { @"\w+(?\w+)(?\w+)(? Date: Sat, 9 May 2020 05:55:15 -0700 Subject: [PATCH 079/420] add platform to two tests to avoid test skip on Unix (#36082) --- .../System.Net.Sockets/tests/FunctionalTests/KeepAliveTest.cs | 1 + .../tests/FunctionalTests/UnixDomainSocketTest.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/KeepAliveTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/KeepAliveTest.cs index 6a6e07a962257..77b41f8e8245a 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/KeepAliveTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/KeepAliveTest.cs @@ -54,6 +54,7 @@ public void Socket_KeepAlive_RetryCount_Success() } [ConditionalFact(typeof(KeepAliveTest), nameof(IsWindowsBelow1703))] // RetryCount not supported by earlier versions of Windows + [PlatformSpecific(TestPlatforms.Windows)] public void Socket_KeepAlive_RetryCount_Failure() { using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/UnixDomainSocketTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/UnixDomainSocketTest.cs index 2a4a361444cb2..34654c50b39e1 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/UnixDomainSocketTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/UnixDomainSocketTest.cs @@ -484,6 +484,7 @@ public void UnixDomainSocketEndPoint_UsingAbstractSocketAddressOnUnsupported_Thr } [ConditionalFact(nameof(IsSubWindows10))] + [PlatformSpecific(TestPlatforms.Windows)] public void Socket_CreateUnixDomainSocket_Throws_OnWindows() { AssertExtensions.Throws("path", () => new UnixDomainSocketEndPoint(null)); From 8b02df8daca876d7eb28148d899ed9773f1cc495 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Sat, 9 May 2020 05:57:20 -0700 Subject: [PATCH 080/420] increase FailingTestTimeoutMiliseconds for Ssl server tests. (#36101) * increase FailingTestTimeoutMiliseconds * use standard ITestOutputHelper helper * set timeout to to 500ms * rework protocol mismatch Co-authored-by: Tomas Weinfurt --- .../TestUtilities/System/PlatformDetection.cs | 1 + .../src/System/Net/Security/TlsFrameHelper.cs | 4 ++++ .../ClientAsyncAuthenticateTest.cs | 4 ++-- .../ServerAllowNoEncryptionTest.cs | 4 ++-- .../ServerAsyncAuthenticateTest.cs | 17 ++++++++++++----- .../FunctionalTests/ServerNoEncryptionTest.cs | 4 ++-- .../ServerRequireEncryptionTest.cs | 4 ++-- .../tests/FunctionalTests/TestConfiguration.cs | 2 +- 8 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index e6b1845a1ea68..37fd12003365c 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -63,6 +63,7 @@ public static bool IsDrawingSupported public static bool IsInContainer => GetIsInContainer(); public static bool SupportsSsl3 => GetSsl3Support(); + public static bool SupportsSsl2 => IsWindows && !PlatformDetection.IsWindows10Version1607OrGreater; #if NETCOREAPP public static bool IsReflectionEmitSupported = RuntimeFeature.IsDynamicCodeSupported; diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs b/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs index ec18be1b8e374..58906a3dda740 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs @@ -92,6 +92,7 @@ internal class TlsFrameHelper private static byte[] s_protocolMismatch12 = new byte[] { (byte)TlsContentType.Alert, 3, 3, 0, 2, 2, 70 }; private static byte[] s_protocolMismatch11 = new byte[] { (byte)TlsContentType.Alert, 3, 2, 0, 2, 2, 70 }; private static byte[] s_protocolMismatch10 = new byte[] { (byte)TlsContentType.Alert, 3, 1, 0, 2, 2, 70 }; + private static byte[] s_protocolMismatch30 = new byte[] { (byte)TlsContentType.Alert, 3, 0, 0, 2, 2, 40 }; public static bool TryGetFrameHeader(ReadOnlySpan frame, ref TlsFrameHeader header) { @@ -200,6 +201,9 @@ version switch SslProtocols.Tls12 => s_protocolMismatch12, SslProtocols.Tls11 => s_protocolMismatch11, SslProtocols.Tls => s_protocolMismatch10, +#pragma warning disable 0618 + SslProtocols.Ssl3 => s_protocolMismatch30, +#pragma warning restore 0618 _ => Array.Empty(), }; diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs index 3a8bf3bd8b53a..2ea89a4148b94 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs @@ -19,9 +19,9 @@ public class ClientAsyncAuthenticateTest { private readonly ITestOutputHelper _log; - public ClientAsyncAuthenticateTest() + public ClientAsyncAuthenticateTest(ITestOutputHelper output) { - _log = TestLogging.GetInstance(); + _log = output; } [Fact] diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAllowNoEncryptionTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAllowNoEncryptionTest.cs index 12918eaf9c2a4..cc59578b61930 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAllowNoEncryptionTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAllowNoEncryptionTest.cs @@ -17,9 +17,9 @@ public class ServerAllowNoEncryptionTest { private readonly ITestOutputHelper _log; - public ServerAllowNoEncryptionTest() + public ServerAllowNoEncryptionTest(ITestOutputHelper output) { - _log = TestLogging.GetInstance(); + _log = output; } // The following method is invoked by the RemoteCertificateValidationDelegate. diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs index 9bf0afb5b2290..28ff72a1f0563 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs @@ -23,9 +23,9 @@ public class ServerAsyncAuthenticateTest : IDisposable private readonly ITestOutputHelper _logVerbose; private readonly X509Certificate2 _serverCertificate; - public ServerAsyncAuthenticateTest() + public ServerAsyncAuthenticateTest(ITestOutputHelper output) { - _log = TestLogging.GetInstance(); + _log = output; _logVerbose = VerboseTestLogging.GetInstance(); _serverCertificate = Configuration.Certificates.GetServerCertificate(); } @@ -72,11 +72,18 @@ public async Task ServerAsyncAuthenticate_EachSupportedProtocol_Success(SslProto public static IEnumerable ProtocolMismatchData() { + if (PlatformDetection.SupportsSsl3) + { #pragma warning disable 0618 - yield return new object[] { SslProtocols.Ssl2, SslProtocols.Ssl3, typeof(Exception) }; - yield return new object[] { SslProtocols.Ssl2, SslProtocols.Tls12, typeof(Exception) }; - yield return new object[] { SslProtocols.Ssl3, SslProtocols.Tls12, typeof(Exception) }; + yield return new object[] { SslProtocols.Ssl3, SslProtocols.Tls12, typeof(Exception) }; + if (PlatformDetection.SupportsSsl2) + { + yield return new object[] { SslProtocols.Ssl2, SslProtocols.Ssl3, typeof(Exception) }; + yield return new object[] { SslProtocols.Ssl2, SslProtocols.Tls12, typeof(Exception) }; + } #pragma warning restore 0618 + } + yield return new object[] { SslProtocols.Tls, SslProtocols.Tls11, typeof(AuthenticationException) }; yield return new object[] { SslProtocols.Tls, SslProtocols.Tls12, typeof(AuthenticationException) }; yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls, typeof(AuthenticationException) }; diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs index d062fac791c1d..5dd06233c06a3 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs @@ -17,9 +17,9 @@ public class ServerNoEncryptionTest { private readonly ITestOutputHelper _log; - public ServerNoEncryptionTest() + public ServerNoEncryptionTest(ITestOutputHelper output) { - _log = TestLogging.GetInstance(); + _log = output; } // The following method is invoked by the RemoteCertificateValidationDelegate. diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerRequireEncryptionTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerRequireEncryptionTest.cs index 1b15a408084ef..f538b55bebcec 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerRequireEncryptionTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerRequireEncryptionTest.cs @@ -17,9 +17,9 @@ public class ServerRequireEncryptionTest { private readonly ITestOutputHelper _log; - public ServerRequireEncryptionTest() + public ServerRequireEncryptionTest(ITestOutputHelper output) { - _log = TestLogging.GetInstance(); + _log = output; } // The following method is invoked by the RemoteCertificateValidationDelegate. diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs index 577d2ce1f58ef..1473b3065c46a 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs @@ -16,7 +16,7 @@ namespace System.Net.Security.Tests internal static class TestConfiguration { public const int PassingTestTimeoutMilliseconds = 4 * 60 * 1000; - public const int FailingTestTimeoutMiliseconds = 250; + public const int FailingTestTimeoutMiliseconds = 500; public const string Realm = "TEST.COREFX.NET"; public const string KerberosUser = "krb_user"; From 6b5850fa7cf476b66be9d01a3ed05f4484b01d3a Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Sat, 9 May 2020 07:41:33 -0700 Subject: [PATCH 081/420] Use C# compiler provided nint/nuint (#36159) --- .../src/System/Array.CoreCLR.cs | 7 ---- .../src/System/Buffer.CoreCLR.cs | 9 ----- .../src/System/Object.CoreCLR.cs | 7 ---- .../Runtime/CompilerServices/CastHelpers.cs | 7 ---- .../RuntimeHelpers.CoreCLR.cs | 37 +++++++----------- .../Runtime/CompilerServices/Unsafe.cs | 22 ----------- .../src/System/Buffer.Unix.cs | 19 +++------ .../src/System/Buffer.Windows.cs | 9 +---- .../src/System/Buffer.cs | 11 +----- .../Collections/Generic/ArraySortHelper.cs | 7 ---- .../System/Globalization/CharUnicodeInfo.cs | 7 ---- .../src/System/Globalization/TextInfo.cs | 7 ---- .../src/System/IO/UnmanagedMemoryStream.cs | 7 ---- .../src/System/IntPtr.cs | 39 +++++++++---------- .../src/System/Marvin.OrdinalIgnoreCase.cs | 7 ---- .../src/System/Marvin.cs | 7 ---- .../src/System/Memory.cs | 9 +---- .../src/System/MemoryExtensions.cs | 7 ---- .../src/System/Numerics/Vector.cs | 7 ---- .../src/System/Numerics/Vector.tt | 7 ---- .../src/System/ReadOnlyMemory.cs | 9 +---- .../src/System/ReadOnlySpan.cs | 7 ---- .../InteropServices/ArrayWithOffset.cs | 7 ---- .../Runtime/InteropServices/GCHandle.cs | 7 ---- .../System/Runtime/InteropServices/Marshal.cs | 7 ---- .../System.Private.CoreLib/src/System/Span.cs | 9 +---- .../src/System/SpanHelpers.Byte.cs | 31 ++++++--------- .../src/System/SpanHelpers.Char.cs | 17 ++------ .../src/System/SpanHelpers.cs | 29 ++++++-------- .../src/System/String.Comparison.cs | 7 ---- .../src/System/Text/ASCIIUtility.cs | 26 ++----------- .../Text/Unicode/Utf16Utility.Validation.cs | 18 ++++----- .../Text/Unicode/Utf8Utility.Transcoding.cs | 24 ------------ .../Text/Unicode/Utf8Utility.Validation.cs | 22 ----------- .../Unicode/Utf8Utility.WhiteSpace.CoreLib.cs | 8 ---- .../src/System/Text/Utf8Span.cs | 16 +------- .../src/System/UIntPtr.cs | 35 ++++++++--------- .../src/System/Utf8String.cs | 16 +------- .../src/System/Array.Mono.cs | 9 +---- .../src/System/Buffer.Mono.cs | 7 ---- 40 files changed, 102 insertions(+), 448 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Array.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Array.CoreCLR.cs index 55ed9f70b082b..75f6aa40ce4d1 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Array.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Array.CoreCLR.cs @@ -9,13 +9,6 @@ using System.Reflection; using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System { // Note that we make a T[] (single-dimensional w/ zero as the lower bound) implement both diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Buffer.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Buffer.CoreCLR.cs index 8c7bc784ad896..5e1d8249e3ddd 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Buffer.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Buffer.CoreCLR.cs @@ -7,15 +7,6 @@ using System.Runtime.InteropServices; using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -using nint = System.UInt64; -#else -using nuint = System.UInt32; -using nint = System.UInt32; -#endif - namespace System { public partial class Buffer diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Object.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Object.CoreCLR.cs index 3c7cb5c23982a..a65358449ee8c 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Object.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Object.CoreCLR.cs @@ -4,13 +4,6 @@ using System.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System { public partial class Object diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs index a5db6f21277f4..15cad52659557 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs @@ -9,13 +9,6 @@ using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System.Runtime.CompilerServices { internal static unsafe class CastHelpers diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index a0e841070d15e..49e8a4e08c8c0 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -7,13 +7,6 @@ using System.Runtime.InteropServices; using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System.Runtime.CompilerServices { public static partial class RuntimeHelpers @@ -348,31 +341,31 @@ internal unsafe struct MethodTable | 0x40000000 // enum_flag_ComObject | 0x00400000;// enum_flag_ICastable; - private const int ParentMethodTableOffset = 0x10 + private const int DebugClassNamePtr = // adjust for debug_m_szClassName #if DEBUG - + sizeof(nuint) // adjust for debug_m_szClassName -#endif - ; - #if TARGET_64BIT - private const int ElementTypeOffset = 0x30 + 8 #else - private const int ElementTypeOffset = 0x20 + 4 #endif -#if DEBUG - + sizeof(nuint) // adjust for debug_m_szClassName +#else + 0 #endif - ; + ; + + private const int ParentMethodTableOffset = 0x10 + DebugClassNamePtr; #if TARGET_64BIT - private const int InterfaceMapOffset = 0x38 + private const int ElementTypeOffset = 0x30 + DebugClassNamePtr; #else - private const int InterfaceMapOffset = 0x24 + private const int ElementTypeOffset = 0x20 + DebugClassNamePtr; #endif -#if DEBUG - + sizeof(nuint) // adjust for debug_m_szClassName + +#if TARGET_64BIT + private const int InterfaceMapOffset = 0x38 + DebugClassNamePtr; +#else + private const int InterfaceMapOffset = 0x24 + DebugClassNamePtr; #endif - ; public bool HasComponentSize { diff --git a/src/libraries/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/Unsafe.cs b/src/libraries/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/Unsafe.cs index 62649b4c22463..ca63162736745 100644 --- a/src/libraries/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/Unsafe.cs +++ b/src/libraries/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/Unsafe.cs @@ -8,15 +8,6 @@ using System.Runtime.CompilerServices; using System.Runtime.Versioning; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -using nint = System.Int64; -#else -using nuint = System.UInt32; -using nint = System.Int32; -#endif - // // The implementations of most the methods in this file are provided as intrinsics. // In CoreCLR, the body of the functions are replaced by the EE with unsafe code. See see getILIntrinsicImplementationForUnsafe for details. @@ -145,19 +136,6 @@ public static int SizeOf() #endif } -#if TARGET_64BIT - /// - /// Adds an element offset to the given reference. - /// - [Intrinsic] - [NonVersionable] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static ref T Add(ref T source, nint elementOffset) - { - return ref Unsafe.Add(ref source, (IntPtr)(void*)elementOffset); - } -#endif - /// /// Adds an byte offset to the given reference. /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffer.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Buffer.Unix.cs index 6c6a823a521e0..18f55d3bb3981 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffer.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffer.Unix.cs @@ -2,26 +2,19 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System { public static partial class Buffer { #if TARGET_ARM64 - // Managed code is currently faster than glibc unoptimized memmove - // TODO-ARM64-UNIX-OPT revisit when glibc optimized memmove is in Linux distros - // https://github.com/dotnet/runtime/issues/8897 - private const nuint MemmoveNativeThreshold = ulong.MaxValue; + // Managed code is currently faster than glibc unoptimized memmove + // TODO-ARM64-UNIX-OPT revisit when glibc optimized memmove is in Linux distros + // https://github.com/dotnet/runtime/issues/8897 + private static nuint MemmoveNativeThreshold => nuint.MaxValue; #elif TARGET_ARM - private const nuint MemmoveNativeThreshold = 512; + private const nuint MemmoveNativeThreshold = 512; #else - private const nuint MemmoveNativeThreshold = 2048; + private const nuint MemmoveNativeThreshold = 2048; #endif } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffer.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Buffer.Windows.cs index 226a0cd7e1d1b..d5607de913478 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffer.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffer.Windows.cs @@ -2,13 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System { public static partial class Buffer @@ -16,7 +9,7 @@ public static partial class Buffer #if TARGET_ARM64 // Determine optimal value for Windows. // https://github.com/dotnet/runtime/issues/8896 - private const nuint MemmoveNativeThreshold = ulong.MaxValue; + private static nuint MemmoveNativeThreshold => nuint.MaxValue; #else private const nuint MemmoveNativeThreshold = 2048; #endif diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs index e8d9b77828221..3880d590ca4ce 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs @@ -12,15 +12,6 @@ using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nint = System.Int64; -using nuint = System.UInt64; -#else -using nint = System.Int32; -using nuint = System.UInt32; -#endif - namespace System { public static partial class Buffer @@ -341,7 +332,7 @@ internal static void Memmove(ref T destination, ref T source, nuint elementCo private static void Memmove(ref byte dest, ref byte src, nuint len) { // P/Invoke into the native version when the buffers are overlapping. - if (((nuint)Unsafe.ByteOffset(ref src, ref dest) < len) || ((nuint)Unsafe.ByteOffset(ref dest, ref src) < len)) + if (((nuint)(nint)Unsafe.ByteOffset(ref src, ref dest) < len) || ((nuint)(nint)Unsafe.ByteOffset(ref dest, ref src) < len)) { goto BuffersOverlap; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs index b1253aa3ff290..321c2119cfe56 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs @@ -8,13 +8,6 @@ using System.Runtime.InteropServices; using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nint = System.Int64; -#else -using nint = System.Int32; -#endif - namespace System.Collections.Generic { #region ArraySortHelper for single arrays diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CharUnicodeInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CharUnicodeInfo.cs index 9a1c24607e71f..51d0ae46b3ae1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CharUnicodeInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CharUnicodeInfo.cs @@ -9,13 +9,6 @@ using System.Text.Unicode; using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System.Globalization { /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs index eaa2042fd9e55..0481c684cd8a9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs @@ -10,13 +10,6 @@ using System.Text.Unicode; using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else // TARGET_64BIT -using nuint = System.UInt32; -#endif // TARGET_64BIT - namespace System.Globalization { /// diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs index ecdb454203bf4..6c17ca92ac85a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs @@ -8,13 +8,6 @@ using System.Threading; using System.Threading.Tasks; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System.IO { /* diff --git a/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs b/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs index d82c18f1fa78e..720da614f236e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs @@ -11,9 +11,9 @@ #pragma warning disable SA1121 // explicitly using type aliases instead of built-in types #if TARGET_64BIT -using nint = System.Int64; +using nint_t = System.Int64; #else -using nint = System.Int32; +using nint_t = System.Int32; #endif namespace System @@ -162,7 +162,7 @@ public unsafe int ToInt32() public static int Size { [NonVersionable] - get => sizeof(nint); + get => sizeof(nint_t); } [CLSCompliant(false)] @@ -172,25 +172,24 @@ public static int Size public static IntPtr MaxValue { [NonVersionable] - get => (IntPtr)nint.MaxValue; + get => (IntPtr)nint_t.MaxValue; } public static IntPtr MinValue { [NonVersionable] - get => (IntPtr)nint.MinValue; + get => (IntPtr)nint_t.MinValue; } - // Don't just delegate to nint.CompareTo as it needs to throw when not IntPtr + // Don't just delegate to nint_t.CompareTo as it needs to throw when not IntPtr public unsafe int CompareTo(object? value) { if (value is null) { return 1; } - if (value is IntPtr o) + if (value is nint i) { - nint i = (nint)o; if ((nint)_value < i) return -1; if ((nint)_value > i) return 1; return 0; @@ -199,31 +198,31 @@ public unsafe int CompareTo(object? value) throw new ArgumentException(SR.Arg_MustBeIntPtr); } - public unsafe int CompareTo(IntPtr value) => ((nint)_value).CompareTo((nint)value); + public unsafe int CompareTo(IntPtr value) => ((nint_t)_value).CompareTo((nint_t)value); [NonVersionable] - public unsafe bool Equals(IntPtr other) => (nint)_value == (nint)other; + public unsafe bool Equals(IntPtr other) => (nint_t)_value == (nint_t)other; - public unsafe override string ToString() => ((nint)_value).ToString(); - public unsafe string ToString(string? format) => ((nint)_value).ToString(format); - public unsafe string ToString(IFormatProvider? provider) => ((nint)_value).ToString(provider); - public unsafe string ToString(string? format, IFormatProvider? provider) => ((nint)_value).ToString(format, provider); + public unsafe override string ToString() => ((nint_t)_value).ToString(); + public unsafe string ToString(string? format) => ((nint_t)_value).ToString(format); + public unsafe string ToString(IFormatProvider? provider) => ((nint_t)_value).ToString(provider); + public unsafe string ToString(string? format, IFormatProvider? provider) => ((nint_t)_value).ToString(format, provider); - public static IntPtr Parse(string s) => (IntPtr)nint.Parse(s); - public static IntPtr Parse(string s, NumberStyles style) => (IntPtr)nint.Parse(s, style); - public static IntPtr Parse(string s, IFormatProvider? provider) => (IntPtr)nint.Parse(s, provider); - public static IntPtr Parse(string s, NumberStyles style, IFormatProvider? provider) => (IntPtr)nint.Parse(s, style, provider); + public static IntPtr Parse(string s) => (IntPtr)nint_t.Parse(s); + public static IntPtr Parse(string s, NumberStyles style) => (IntPtr)nint_t.Parse(s, style); + public static IntPtr Parse(string s, IFormatProvider? provider) => (IntPtr)nint_t.Parse(s, provider); + public static IntPtr Parse(string s, NumberStyles style, IFormatProvider? provider) => (IntPtr)nint_t.Parse(s, style, provider); public static bool TryParse(string? s, out IntPtr result) { Unsafe.SkipInit(out result); - return nint.TryParse(s, out Unsafe.As(ref result)); + return nint_t.TryParse(s, out Unsafe.As(ref result)); } public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out IntPtr result) { Unsafe.SkipInit(out result); - return nint.TryParse(s, style, provider, out Unsafe.As(ref result)); + return nint_t.TryParse(s, style, provider, out Unsafe.As(ref result)); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Marvin.OrdinalIgnoreCase.cs b/src/libraries/System.Private.CoreLib/src/System/Marvin.OrdinalIgnoreCase.cs index c8ff3fb7eaefe..9867caac97dbd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Marvin.OrdinalIgnoreCase.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Marvin.OrdinalIgnoreCase.cs @@ -8,13 +8,6 @@ using System.Text.Unicode; using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System { internal static partial class Marvin diff --git a/src/libraries/System.Private.CoreLib/src/System/Marvin.cs b/src/libraries/System.Private.CoreLib/src/System/Marvin.cs index 4e5b9d5a035b6..f397c230b5019 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Marvin.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Marvin.cs @@ -8,13 +8,6 @@ using System.Runtime.InteropServices; using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System { internal static partial class Marvin diff --git a/src/libraries/System.Private.CoreLib/src/System/Memory.cs b/src/libraries/System.Private.CoreLib/src/System/Memory.cs index cb8f631c5d44c..bed73caea1357 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Memory.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Memory.cs @@ -12,13 +12,6 @@ using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else // TARGET_64BIT -using nuint = System.UInt32; -#endif // TARGET_64BIT - namespace System { /// @@ -364,7 +357,7 @@ public unsafe Span Span ThrowHelper.ThrowArgumentOutOfRangeException(); } #else - if ((uint)desiredStartIndex > (uint)lengthOfUnderlyingSpan || (uint)desiredLength > (uint)(lengthOfUnderlyingSpan - desiredStartIndex)) + if ((uint)desiredStartIndex > (uint)lengthOfUnderlyingSpan || (uint)desiredLength > (uint)lengthOfUnderlyingSpan - (uint)desiredStartIndex) { ThrowHelper.ThrowArgumentOutOfRangeException(); } diff --git a/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs b/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs index 2a66efac7709c..33bc6f9e1fffc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs @@ -8,13 +8,6 @@ using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif // TARGET_64BIT - namespace System { /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs index f20b762afbf13..e27b5bf883d1c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs @@ -10,13 +10,6 @@ using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nint = System.Int64; -#else -using nint = System.Int32; -#endif - namespace System.Numerics { /* Note: The following patterns are used throughout the code here and are described here diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.tt b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.tt index 3c02ba2bebac0..86bd98984a947 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.tt +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.tt @@ -15,13 +15,6 @@ using System.Text; using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nint = System.Int64; -#else -using nint = System.Int32; -#endif - namespace System.Numerics { /* Note: The following patterns are used throughout the code here and are described here diff --git a/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs b/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs index 77552dea34750..c66cd3b699a56 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs @@ -12,13 +12,6 @@ using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else // TARGET_64BIT -using nuint = System.UInt32; -#endif // TARGET_64BIT - namespace System { /// @@ -286,7 +279,7 @@ public unsafe ReadOnlySpan Span ThrowHelper.ThrowArgumentOutOfRangeException(); } #else - if ((uint)desiredStartIndex > (uint)lengthOfUnderlyingSpan || (uint)desiredLength > (uint)(lengthOfUnderlyingSpan - desiredStartIndex)) + if ((uint)desiredStartIndex > (uint)lengthOfUnderlyingSpan || (uint)desiredLength > (uint)lengthOfUnderlyingSpan - (uint)desiredStartIndex) { ThrowHelper.ThrowArgumentOutOfRangeException(); } diff --git a/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs b/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs index a765967f5f87a..7ce5284ad2d33 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs @@ -13,13 +13,6 @@ #pragma warning disable 0809 //warning CS0809: Obsolete member 'Span.Equals(object)' overrides non-obsolete member 'object.Equals(object)' -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System { /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ArrayWithOffset.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ArrayWithOffset.cs index 2413cacd01d02..736259d2334f8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ArrayWithOffset.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ArrayWithOffset.cs @@ -4,13 +4,6 @@ using System.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System.Runtime.InteropServices { public struct ArrayWithOffset diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.cs index b7bd0361d53cc..c163c364771d4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.cs @@ -7,13 +7,6 @@ using System.Threading; using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nint = System.Int64; -#else -using nint = System.Int32; -#endif - namespace System.Runtime.InteropServices { /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs index 227e84e71c2fa..76aab4ab2c4b1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs @@ -10,13 +10,6 @@ using Internal.Runtime.CompilerServices; using System.Diagnostics.CodeAnalysis; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System.Runtime.InteropServices { /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Span.cs b/src/libraries/System.Private.CoreLib/src/System/Span.cs index 25bab98c88991..6016674dcdfdf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Span.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Span.cs @@ -13,13 +13,6 @@ #pragma warning disable 0809 //warning CS0809: Obsolete member 'Span.Equals(object)' overrides non-obsolete member 'object.Equals(object)' -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System { /// @@ -273,7 +266,7 @@ public bool MoveNext() /// Clears the contents of this span. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Clear() + public unsafe void Clear() { if (RuntimeHelpers.IsReferenceOrContainsReferences()) { diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs index f965f98ac7f5e..c396bb06fe653 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs @@ -10,15 +10,6 @@ using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -using nint = System.Int64; -#else -using nuint = System.UInt32; -using nint = System.Int32; -#endif // TARGET_64BIT - namespace System { internal static partial class SpanHelpers // .Byte @@ -1311,11 +1302,11 @@ public static int LastIndexOfAny(ref byte searchSpace, byte value0, byte value1, // Optimized byte-based SequenceEquals. The "length" parameter for this one is declared a nuint rather than int as we also use it for types other than byte // where the length can exceed 2Gb once scaled by sizeof(T). - public static bool SequenceEqual(ref byte first, ref byte second, nuint length) + public static unsafe bool SequenceEqual(ref byte first, ref byte second, nuint length) { bool result; // Use nint for arithmetic to avoid unnecessary 64->32->64 truncations - if (length >= sizeof(nuint)) + if (length >= (nuint)sizeof(nuint)) { // Conditional jmp foward to favor shorter lengths. (See comment at "Equal:" label) // The longer lengths can make back the time due to branch misprediction @@ -1473,9 +1464,9 @@ public static bool SequenceEqual(ref byte first, ref byte second, nuint length) #if TARGET_64BIT if (Sse2.IsSupported) { - Debug.Assert(length <= sizeof(nuint) * 2); + Debug.Assert(length <= (nuint)sizeof(nuint) * 2); - nuint offset = length - sizeof(nuint); + nuint offset = length - (nuint)sizeof(nuint); nuint differentBits = LoadNUInt(ref first) - LoadNUInt(ref second); differentBits |= LoadNUInt(ref first, offset) - LoadNUInt(ref second, offset); result = (differentBits == 0); @@ -1484,10 +1475,10 @@ public static bool SequenceEqual(ref byte first, ref byte second, nuint length) else #endif { - Debug.Assert(length >= sizeof(nuint)); + Debug.Assert(length >= (nuint)sizeof(nuint)); { nuint offset = 0; - nuint lengthToExamine = length - sizeof(nuint); + nuint lengthToExamine = length - (nuint)sizeof(nuint); // Unsigned, so it shouldn't have overflowed larger than length (rather than negative) Debug.Assert(lengthToExamine < length); if (lengthToExamine > 0) @@ -1499,7 +1490,7 @@ public static bool SequenceEqual(ref byte first, ref byte second, nuint length) { goto NotEqual; } - offset += sizeof(nuint); + offset += (nuint)sizeof(nuint); } while (lengthToExamine > offset); } @@ -1540,7 +1531,7 @@ private static int LocateFirstFoundByte(Vector match) } [MethodImpl(MethodImplOptions.AggressiveOptimization)] - public static int SequenceCompareTo(ref byte first, int firstLength, ref byte second, int secondLength) + public static unsafe int SequenceCompareTo(ref byte first, int firstLength, ref byte second, int secondLength) { Debug.Assert(firstLength >= 0); Debug.Assert(secondLength >= 0); @@ -1693,16 +1684,16 @@ public static int SequenceCompareTo(ref byte first, int firstLength, ref byte se } } - if (lengthToExamine > sizeof(nuint)) + if (lengthToExamine > (nuint)sizeof(nuint)) { - lengthToExamine -= sizeof(nuint); + lengthToExamine -= (nuint)sizeof(nuint); while (lengthToExamine > offset) { if (LoadNUInt(ref first, offset) != LoadNUInt(ref second, offset)) { goto BytewiseCheck; } - offset += sizeof(nuint); + offset += (nuint)sizeof(nuint); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs index 0f21d07c107c0..b3234e4aa77a1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs @@ -10,15 +10,6 @@ using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -using nint = System.Int64; -#else -using nuint = System.UInt32; -using nint = System.Int32; -#endif - namespace System { internal static partial class SpanHelpers // .Char @@ -66,7 +57,7 @@ public static int IndexOf(ref char searchSpace, int searchSpaceLength, ref char } [MethodImpl(MethodImplOptions.AggressiveOptimization)] - public static int SequenceCompareTo(ref char first, int firstLength, ref char second, int secondLength) + public static unsafe int SequenceCompareTo(ref char first, int firstLength, ref char second, int secondLength) { Debug.Assert(firstLength >= 0); Debug.Assert(secondLength >= 0); @@ -79,7 +70,7 @@ public static int SequenceCompareTo(ref char first, int firstLength, ref char se nuint minLength = (nuint)(((uint)firstLength < (uint)secondLength) ? (uint)firstLength : (uint)secondLength); nuint i = 0; // Use nuint for arithmetic to avoid unnecessary 64->32->64 truncations - if (minLength >= (sizeof(nuint) / sizeof(char))) + if (minLength >= (nuint)(sizeof(nuint) / sizeof(char))) { if (Vector.IsHardwareAccelerated && minLength >= (nuint)Vector.Count) { @@ -96,14 +87,14 @@ public static int SequenceCompareTo(ref char first, int firstLength, ref char se while (nLength >= i); } - while (minLength >= (i + sizeof(nuint) / sizeof(char))) + while (minLength >= (i + (nuint)(sizeof(nuint) / sizeof(char)))) { if (Unsafe.ReadUnaligned (ref Unsafe.As(ref Unsafe.Add(ref first, (nint)i))) != Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.Add(ref second, (nint)i)))) { break; } - i += sizeof(nuint) / sizeof(char); + i += (nuint)(sizeof(nuint) / sizeof(char)); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs index ddd2416eceaea..24e82c21a8267 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs @@ -6,13 +6,6 @@ using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System { internal static partial class SpanHelpers @@ -348,14 +341,14 @@ public static unsafe void ClearWithReferences(ref IntPtr ip, nuint pointerSizeLe for (; pointerSizeLength >= 8; pointerSizeLength -= 8) { - Unsafe.Add(ref Unsafe.Add(ref ip, (IntPtr)pointerSizeLength), -1) = default; - Unsafe.Add(ref Unsafe.Add(ref ip, (IntPtr)pointerSizeLength), -2) = default; - Unsafe.Add(ref Unsafe.Add(ref ip, (IntPtr)pointerSizeLength), -3) = default; - Unsafe.Add(ref Unsafe.Add(ref ip, (IntPtr)pointerSizeLength), -4) = default; - Unsafe.Add(ref Unsafe.Add(ref ip, (IntPtr)pointerSizeLength), -5) = default; - Unsafe.Add(ref Unsafe.Add(ref ip, (IntPtr)pointerSizeLength), -6) = default; - Unsafe.Add(ref Unsafe.Add(ref ip, (IntPtr)pointerSizeLength), -7) = default; - Unsafe.Add(ref Unsafe.Add(ref ip, (IntPtr)pointerSizeLength), -8) = default; + Unsafe.Add(ref Unsafe.Add(ref ip, (nint)pointerSizeLength), -1) = default; + Unsafe.Add(ref Unsafe.Add(ref ip, (nint)pointerSizeLength), -2) = default; + Unsafe.Add(ref Unsafe.Add(ref ip, (nint)pointerSizeLength), -3) = default; + Unsafe.Add(ref Unsafe.Add(ref ip, (nint)pointerSizeLength), -4) = default; + Unsafe.Add(ref Unsafe.Add(ref ip, (nint)pointerSizeLength), -5) = default; + Unsafe.Add(ref Unsafe.Add(ref ip, (nint)pointerSizeLength), -6) = default; + Unsafe.Add(ref Unsafe.Add(ref ip, (nint)pointerSizeLength), -7) = default; + Unsafe.Add(ref Unsafe.Add(ref ip, (nint)pointerSizeLength), -8) = default; } Debug.Assert(pointerSizeLength <= 7); @@ -396,15 +389,15 @@ public static unsafe void ClearWithReferences(ref IntPtr ip, nuint pointerSizeLe // Write first four and last three. Unsafe.Add(ref ip, 2) = default; Unsafe.Add(ref ip, 3) = default; - Unsafe.Add(ref Unsafe.Add(ref ip, (IntPtr)pointerSizeLength), -3) = default; - Unsafe.Add(ref Unsafe.Add(ref ip, (IntPtr)pointerSizeLength), -2) = default; + Unsafe.Add(ref Unsafe.Add(ref ip, (nint)pointerSizeLength), -3) = default; + Unsafe.Add(ref Unsafe.Add(ref ip, (nint)pointerSizeLength), -2) = default; Write2To3: Debug.Assert(pointerSizeLength >= 2); // Write first two and last one. Unsafe.Add(ref ip, 1) = default; - Unsafe.Add(ref Unsafe.Add(ref ip, (IntPtr)pointerSizeLength), -1) = default; + Unsafe.Add(ref Unsafe.Add(ref ip, (nint)pointerSizeLength), -1) = default; Write1: Debug.Assert(pointerSizeLength >= 1); diff --git a/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs b/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs index 5ceed67a563a9..1708b2cb1e328 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs @@ -10,13 +10,6 @@ using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System { public partial class String diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs index c0bdbf03f7059..31de76bfd0c9a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs @@ -12,32 +12,10 @@ using Internal.Runtime.CompilerServices; #endif -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if SYSTEM_PRIVATE_CORELIB -#if TARGET_64BIT -using nint = System.Int64; -using nuint = System.UInt64; -#else // TARGET_64BIT -using nint = System.Int32; -using nuint = System.UInt32; -#endif // TARGET_64BIT -#else -using nint = System.Int64; // https://github.com/dotnet/runtime/issues/33575 - use long/ulong outside of corelib until the compiler supports it -using nuint = System.UInt64; -#endif - namespace System.Text { internal static partial class ASCIIUtility { -#if DEBUG && SYSTEM_PRIVATE_CORELIB - static ASCIIUtility() - { - Debug.Assert(sizeof(nint) == IntPtr.Size && nint.MinValue < 0, "nint is defined incorrectly."); - Debug.Assert(sizeof(nuint) == IntPtr.Size && nuint.MinValue == 0, "nuint is defined incorrectly."); - } -#endif // DEBUG && SYSTEM_PRIVATE_CORELIB - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool AllBytesInUInt64AreAscii(ulong value) { @@ -524,7 +502,9 @@ private static unsafe nuint GetIndexOfFirstNonAsciiChar_Default(char* pBuffer, n char* pOriginalBuffer = pBuffer; +#if SYSTEM_PRIVATE_CORELIB Debug.Assert(bufferLength <= nuint.MaxValue / sizeof(char)); +#endif // Before we drain off char-by-char, try a generic vectorized loop. // Only run the loop if we have at least two vectors we can pull out. @@ -687,7 +667,9 @@ private static unsafe nuint GetIndexOfFirstNonAsciiChar_Sse2(char* pBuffer, nuin Vector128 asciiMaskForPADDUSW = Vector128.Create((ushort)0x7F80); // used for PADDUSW const uint NonAsciiDataSeenMask = 0b_1010_1010_1010_1010; // used for determining whether 'currentMask' contains non-ASCII data +#if SYSTEM_PRIVATE_CORELIB Debug.Assert(bufferLength <= nuint.MaxValue / sizeof(char)); +#endif // Read the first vector unaligned. diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs index 73bfa603f9252..c2b38f159d6aa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs @@ -15,15 +15,12 @@ #pragma warning disable SA1121 // explicitly using type aliases instead of built-in types #if SYSTEM_PRIVATE_CORELIB #if TARGET_64BIT -using nint = System.Int64; -using nuint = System.UInt64; +using nuint_t = System.UInt64; #else // TARGET_64BIT -using nint = System.Int32; -using nuint = System.UInt32; +using nuint_t = System.UInt32; #endif // TARGET_64BIT #else -using nint = System.Int64; // https://github.com/dotnet/runtime/issues/33575 - use long/ulong outside of corelib until the compiler supports it -using nuint = System.UInt64; +using nuint_t = System.UInt64; #endif namespace System.Text.Unicode @@ -33,8 +30,7 @@ internal static unsafe partial class Utf16Utility #if DEBUG && SYSTEM_PRIVATE_CORELIB static Utf16Utility() { - Debug.Assert(sizeof(nint) == IntPtr.Size && nint.MinValue < 0, "nint is defined incorrectly."); - Debug.Assert(sizeof(nuint) == IntPtr.Size && nuint.MinValue == 0, "nuint is defined incorrectly."); + Debug.Assert(sizeof(nuint_t) == IntPtr.Size && nuint.MinValue == 0, "nuint_t is defined incorrectly."); } #endif // DEBUG && SYSTEM_PRIVATE_CORELIB @@ -291,15 +287,15 @@ static Utf16Utility() Vector utf16Data = Unsafe.ReadUnaligned>(pInputBuffer); Vector twoOrMoreUtf8Bytes = Vector.GreaterThanOrEqual(utf16Data, vector0080); Vector threeOrMoreUtf8Bytes = Vector.GreaterThanOrEqual(utf16Data, vector0800); - Vector sumVector = (Vector)(Vector.Zero - twoOrMoreUtf8Bytes - threeOrMoreUtf8Bytes); + Vector sumVector = (Vector)(Vector.Zero - twoOrMoreUtf8Bytes - threeOrMoreUtf8Bytes); // We'll try summing by a natural word (rather than a 16-bit word) at a time, // which should halve the number of operations we must perform. nuint popcnt = 0; - for (int i = 0; i < Vector.Count; i++) + for (int i = 0; i < Vector.Count; i++) { - popcnt += sumVector[i]; + popcnt += (nuint)sumVector[i]; } uint popcnt32 = (uint)popcnt; diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Transcoding.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Transcoding.cs index 64f76fec69147..201626fd6b876 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Transcoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Transcoding.cs @@ -13,34 +13,10 @@ using Internal.Runtime.CompilerServices; #endif -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if SYSTEM_PRIVATE_CORELIB -#if TARGET_64BIT -using nint = System.Int64; -using nuint = System.UInt64; -#else // TARGET_64BIT -using nint = System.Int32; -using nuint = System.UInt32; -#endif // TARGET_64BIT -#else -using nint = System.Int64; // https://github.com/dotnet/runtime/issues/33575 - use long/ulong outside of corelib until the compiler supports it -using nuint = System.UInt64; -#endif - namespace System.Text.Unicode { internal static unsafe partial class Utf8Utility { -#if DEBUG && SYSTEM_PRIVATE_CORELIB - static Utf8Utility() - { - Debug.Assert(sizeof(nint) == IntPtr.Size && nint.MinValue < 0, "nint is defined incorrectly."); - Debug.Assert(sizeof(nuint) == IntPtr.Size && nuint.MinValue == 0, "nuint is defined incorrectly."); - - _ValidateAdditionalNIntDefinitions(); - } -#endif // DEBUG && SYSTEM_PRIVATE_CORELIB - // On method return, pInputBufferRemaining and pOutputBufferRemaining will both point to where // the next byte would have been consumed from / the next char would have been written to. // inputLength in bytes, outputCharsRemaining in chars. diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Validation.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Validation.cs index 8284828d53043..636829e289c26 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Validation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Validation.cs @@ -11,32 +11,10 @@ using Internal.Runtime.CompilerServices; #endif -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if SYSTEM_PRIVATE_CORELIB -#if TARGET_64BIT -using nint = System.Int64; -using nuint = System.UInt64; -#else // TARGET_64BIT -using nint = System.Int32; -using nuint = System.UInt32; -#endif // TARGET_64BIT -#else -using nint = System.Int64; // https://github.com/dotnet/runtime/issues/33575 - use long/ulong outside of corelib until the compiler supports it -using nuint = System.UInt64; -#endif - namespace System.Text.Unicode { internal static unsafe partial class Utf8Utility { -#if DEBUG && SYSTEM_PRIVATE_CORELIB - private static void _ValidateAdditionalNIntDefinitions() - { - Debug.Assert(sizeof(nint) == IntPtr.Size && nint.MinValue < 0, "nint is defined incorrectly."); - Debug.Assert(sizeof(nuint) == IntPtr.Size && nuint.MinValue == 0, "nuint is defined incorrectly."); - } -#endif // DEBUG && SYSTEM_PRIVATE_CORELIB - // Returns &inputBuffer[inputLength] if the input buffer is valid. /// /// Given an input buffer of byte length , diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.WhiteSpace.CoreLib.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.WhiteSpace.CoreLib.cs index cf656bc1dc2d1..6c34b06728dd9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.WhiteSpace.CoreLib.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.WhiteSpace.CoreLib.cs @@ -5,14 +5,6 @@ using System.Runtime.InteropServices; using Internal.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nint = System.Int32; -using nuint = System.UInt32; -#endif - namespace System.Text.Unicode { internal static partial class Utf8Utility diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.cs index eb6cdb6527d41..3a90590bb6da7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.cs @@ -15,20 +15,6 @@ #pragma warning disable 0809 //warning CS0809: Obsolete member 'Utf8Span.Equals(object)' overrides non-obsolete member 'object.Equals(object)' -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if SYSTEM_PRIVATE_CORELIB -#if TARGET_64BIT -using nint = System.Int64; -using nuint = System.UInt64; -#else -using nint = System.Int32; -using nuint = System.UInt32; -#endif -#else -using nint = System.Int64; // https://github.com/dotnet/runtime/issues/33575 - use long/ulong outside of corelib until the compiler supports it -using nuint = System.UInt64; -#endif - namespace System.Text { [StructLayout(LayoutKind.Auto)] @@ -132,7 +118,7 @@ private Utf8Span(ReadOnlySpan rawData) #if SYSTEM_PRIVATE_CORELIB return ref Unsafe.AddByteOffset(ref DangerousGetMutableReference(), index); #else - return ref Unsafe.AddByteOffset(ref DangerousGetMutableReference(), (IntPtr)index); + return ref Unsafe.AddByteOffset(ref DangerousGetMutableReference(), (nint)index); #endif } diff --git a/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs b/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs index 99eb0cf759087..d28bd83c90a31 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs @@ -11,9 +11,9 @@ #pragma warning disable SA1121 // explicitly using type aliases instead of built-in types #if TARGET_64BIT -using nuint = System.UInt64; +using nuint_t = System.UInt64; #else -using nuint = System.UInt32; +using nuint_t = System.UInt32; #endif namespace System @@ -156,7 +156,7 @@ public unsafe uint ToUInt32() public static int Size { [NonVersionable] - get => sizeof(nuint); + get => sizeof(nuint_t); } [NonVersionable] @@ -165,13 +165,13 @@ public static int Size public static UIntPtr MaxValue { [NonVersionable] - get => (UIntPtr)nuint.MaxValue; + get => (UIntPtr)nuint_t.MaxValue; } public static UIntPtr MinValue { [NonVersionable] - get => (UIntPtr)nuint.MinValue; + get => (UIntPtr)nuint_t.MinValue; } public unsafe int CompareTo(object? value) @@ -180,9 +180,8 @@ public unsafe int CompareTo(object? value) { return 1; } - if (value is UIntPtr o) + if (value is nuint i) { - nuint i = (nuint)o; if ((nuint)_value < i) return -1; if ((nuint)_value > i) return 1; return 0; @@ -191,31 +190,31 @@ public unsafe int CompareTo(object? value) throw new ArgumentException(SR.Arg_MustBeUIntPtr); } - public unsafe int CompareTo(UIntPtr value) => ((nuint)_value).CompareTo((nuint)value); + public unsafe int CompareTo(UIntPtr value) => ((nuint_t)_value).CompareTo((nuint_t)value); [NonVersionable] public unsafe bool Equals(UIntPtr other) => (nuint)_value == (nuint)other; - public unsafe override string ToString() => ((nuint)_value).ToString(); - public unsafe string ToString(string? format) => ((nuint)_value).ToString(format); - public unsafe string ToString(IFormatProvider? provider) => ((nuint)_value).ToString(provider); - public unsafe string ToString(string? format, IFormatProvider? provider) => ((nuint)_value).ToString(format, provider); + public unsafe override string ToString() => ((nuint_t)_value).ToString(); + public unsafe string ToString(string? format) => ((nuint_t)_value).ToString(format); + public unsafe string ToString(IFormatProvider? provider) => ((nuint_t)_value).ToString(provider); + public unsafe string ToString(string? format, IFormatProvider? provider) => ((nuint_t)_value).ToString(format, provider); - public static UIntPtr Parse(string s) => (UIntPtr)nuint.Parse(s); - public static UIntPtr Parse(string s, NumberStyles style) => (UIntPtr)nuint.Parse(s, style); - public static UIntPtr Parse(string s, IFormatProvider? provider) => (UIntPtr)nuint.Parse(s, provider); - public static UIntPtr Parse(string s, NumberStyles style, IFormatProvider? provider) => (UIntPtr)nuint.Parse(s, style, provider); + public static UIntPtr Parse(string s) => (UIntPtr)nuint_t.Parse(s); + public static UIntPtr Parse(string s, NumberStyles style) => (UIntPtr)nuint_t.Parse(s, style); + public static UIntPtr Parse(string s, IFormatProvider? provider) => (UIntPtr)nuint_t.Parse(s, provider); + public static UIntPtr Parse(string s, NumberStyles style, IFormatProvider? provider) => (UIntPtr)nuint_t.Parse(s, style, provider); public static bool TryParse(string? s, out UIntPtr result) { Unsafe.SkipInit(out result); - return nuint.TryParse(s, out Unsafe.As(ref result)); + return nuint_t.TryParse(s, out Unsafe.As(ref result)); } public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out UIntPtr result) { Unsafe.SkipInit(out result); - return nuint.TryParse(s, style, provider, out Unsafe.As(ref result)); + return nuint_t.TryParse(s, style, provider, out Unsafe.As(ref result)); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Utf8String.cs b/src/libraries/System.Private.CoreLib/src/System/Utf8String.cs index e6cba4d2e4c2b..0989371e22878 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Utf8String.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Utf8String.cs @@ -13,20 +13,6 @@ using Internal.Runtime.CompilerServices; #endif -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if SYSTEM_PRIVATE_CORELIB -#if TARGET_64BIT -using nint = System.Int64; -using nuint = System.UInt64; -#else -using nint = System.Int32; -using nuint = System.UInt32; -#endif -#else -using nint = System.Int64; // https://github.com/dotnet/runtime/issues/33575 - use long/ulong outside of corelib until the compiler supports it -using nuint = System.UInt64; -#endif - namespace System { /// @@ -133,7 +119,7 @@ public int CompareTo(Utf8String? other, StringComparison comparison) #if SYSTEM_PRIVATE_CORELIB return ref Unsafe.AddByteOffset(ref DangerousGetMutableReference(), index); #else - return ref Unsafe.AddByteOffset(ref DangerousGetMutableReference(), (IntPtr)index); + return ref Unsafe.AddByteOffset(ref DangerousGetMutableReference(), (nint)index); #endif } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Array.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Array.Mono.cs index 908a3baa8e761..e04efea520a93 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Array.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Array.Mono.cs @@ -9,13 +9,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System { public partial class Array @@ -61,7 +54,7 @@ public static unsafe void Clear(Array array, int index, int length) int lowerBound = array.GetLowerBound(0); int elementSize = array.GetElementSize(); - nuint numComponents = (nuint)Unsafe.As(array).Count; + nuint numComponents = (nuint)(nint)Unsafe.As(array).Count; int offset = index - lowerBound; diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Buffer.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Buffer.Mono.cs index b4772965b6ad3..6f04b9742a55a 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Buffer.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Buffer.Mono.cs @@ -4,13 +4,6 @@ using System.Runtime.CompilerServices; -#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types -#if TARGET_64BIT -using nuint = System.UInt64; -#else -using nuint = System.UInt32; -#endif - namespace System { public partial class Buffer From e18250bd8f23f85f670599177118d6b957f9a3dd Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Sat, 9 May 2020 21:26:16 +0200 Subject: [PATCH 082/420] Make Uri Thread-Safe (#33042) * Do not lock on string in Uri * Make Uri thread-safe without locks *A lock may still be used for custom parsers * Update comments * Use existing style for enum values * Add a comment about locking for custom parsers * Add a comment about DebugSetLeftCtor usage * Add trailing dot in exception message * Fix typos * Fix typo Co-authored-by: Stephen Toub Co-authored-by: Stephen Toub --- .../src/Resources/Strings.resx | 6 +- .../System.Private.Uri/src/System/Uri.cs | 239 ++++++++++-------- .../System.Private.Uri/src/System/UriExt.cs | 41 ++- .../src/System/UriScheme.cs | 23 ++ .../src/System/UriSyntax.cs | 8 + .../tests/FunctionalTests/UriParserTest.cs | 47 +++- .../tests/FunctionalTests/UriTests.cs | 31 +++ 7 files changed, 269 insertions(+), 126 deletions(-) diff --git a/src/libraries/System.Private.Uri/src/Resources/Strings.resx b/src/libraries/System.Private.Uri/src/Resources/Strings.resx index 655f2820692e2..16e3b576da63a 100644 --- a/src/libraries/System.Private.Uri/src/Resources/Strings.resx +++ b/src/libraries/System.Private.Uri/src/Resources/Strings.resx @@ -1,4 +1,5 @@ - + + + AssemblyFile="$(AndroidAppBuilderDir)AndroidAppBuilder.dll" /> $(OutDir)\Bundle @@ -119,18 +119,18 @@ --> - - - + + + - - + + - - + + @@ -149,7 +149,7 @@ @@ -164,7 +164,7 @@ + AssemblyFile="$(AppleTestBuilderDir)AppleAppBuilder.dll" /> $(OutDir)\Bundle @@ -174,16 +174,16 @@ 2) Test Runner (with xharness client-side lib) --> - - - - + + + + - + - - + + @@ -195,15 +195,15 @@ diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index 49f01af7d36bb..31abeb86bdfe3 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -272,10 +272,10 @@ $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'testhost', '$(BuildSettings)')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'lib-runtime-packs')) - $([MSBuild]::NormalizeDirectory('$(NETCoreAppRuntimePackPath)', 'runtimes', '$(PackageRID)')) - $([MSBuild]::NormalizeDirectory('$(NETCoreAppRuntimePackRIDPath)' 'lib', '$(NETCoreAppFramework)')) - $([MSBuild]::NormalizeDirectory('$(NETCoreAppRuntimePackRIDPath)', 'native')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'lib-runtime-packs', '$(BuildSettings)')) + $([MSBuild]::NormalizeDirectory('$(RuntimePackDir)', 'runtimes', '$(PackageRID)')) + $([MSBuild]::NormalizeDirectory('$(RuntimePackRidDir)', 'lib', '$(NetCoreAppCurrent)')) + $([MSBuild]::NormalizeDirectory('$(RuntimePackRidDir)', 'native')) runtimes/$(PackageRID) $(ArtifactsObjDir)version.txt diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index c2124d089bdbc..d03b42639c2e6 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -95,11 +95,11 @@ - $(NETCoreAppRuntimePackLibPath) + $(RuntimePackLibDir) - $(NETCoreAppRuntimePackNativePath) + $(RuntimePackNativeDir) NativeBinPlaceItem diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj index a55bd441c79b0..d073141959ef5 100644 --- a/src/libraries/pretest.proj +++ b/src/libraries/pretest.proj @@ -78,15 +78,15 @@ AfterTargets="RestoreTestHost"> RuntimeList.xml - $(NETCoreAppRuntimePackPath)/data/$(FrameworkListFilename) + $(RuntimePackDir)/data/$(FrameworkListFilename) - <_runtimePackLibFiles Include="$(NETCoreAppRuntimePackLibPath)*.*"> + <_runtimePackLibFiles Include="$(RuntimePackLibDir)*.*"> $(RuntimePackTargetFrameworkPath)/lib/$(NETCoreAppFramework) true - <_runtimePackNativeFiles Include="$(NETCoreAppRuntimePackNativePath)*.*"> + <_runtimePackNativeFiles Include="$(RuntimePackNativeDir)*.*"> $(RuntimePackTargetFrameworkPath)/native true diff --git a/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.csproj b/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.csproj index 81ac0dede8395..987d10d54c5f1 100644 --- a/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.csproj +++ b/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.csproj @@ -1,9 +1,6 @@ Library - $(AndroidAppBuilder) - $(NetCoreAppCurrent) - enable true false diff --git a/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.csproj b/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.csproj index 75396c49b0f7b..6ab597f0b08ad 100644 --- a/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.csproj +++ b/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.csproj @@ -1,9 +1,6 @@ Exe - $(AndroidTestRunner) - $(NetCoreAppCurrent) - enable diff --git a/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj b/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj index a9ad9fca464b5..32022609a7d61 100644 --- a/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj +++ b/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj @@ -1,9 +1,6 @@ Library - $(AppleAppBuilder) - $(NetCoreAppCurrent) - enable true false diff --git a/src/mono/msbuild/AppleTestRunner/AppleTestRunner.csproj b/src/mono/msbuild/AppleTestRunner/AppleTestRunner.csproj index 45cccc572889e..6ab597f0b08ad 100644 --- a/src/mono/msbuild/AppleTestRunner/AppleTestRunner.csproj +++ b/src/mono/msbuild/AppleTestRunner/AppleTestRunner.csproj @@ -1,9 +1,6 @@ Exe - $(AppleTestRunner) - $(NetCoreAppCurrent) - enable diff --git a/src/mono/msbuild/Directory.Build.props b/src/mono/msbuild/Directory.Build.props new file mode 100644 index 0000000000000..c3f2519a25b0c --- /dev/null +++ b/src/mono/msbuild/Directory.Build.props @@ -0,0 +1,9 @@ + + + + + $(NetCoreAppCurrent) + $([MSBuild]::NormalizeDirectory('$(BaseOutputPath)', '$(TargetFramework)-$(MonoConfiguration)')) + enable + + From 91868a2c440f217209a0c8044f00d425acbd5eac Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sun, 10 May 2020 07:13:17 -0400 Subject: [PATCH 088/420] Update dependencies from https://github.com/dotnet/runtime-assets build 20200508.1 (#36161) - System.ComponentModel.TypeConverter.TestData: 5.0.0-beta.20257.1 -> 5.0.0-beta.20258.1 - System.Drawing.Common.TestData: 5.0.0-beta.20257.1 -> 5.0.0-beta.20258.1 - System.IO.Compression.TestData: 5.0.0-beta.20257.1 -> 5.0.0-beta.20258.1 - System.IO.Packaging.TestData: 5.0.0-beta.20257.1 -> 5.0.0-beta.20258.1 - System.Net.TestData: 5.0.0-beta.20257.1 -> 5.0.0-beta.20258.1 - System.Private.Runtime.UnicodeData: 5.0.0-beta.20257.1 -> 5.0.0-beta.20258.1 - System.Security.Cryptography.X509Certificates.TestData: 5.0.0-beta.20257.1 -> 5.0.0-beta.20258.1 - System.Windows.Extensions.TestData: 5.0.0-beta.20257.1 -> 5.0.0-beta.20258.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 32 ++++++++++++++++---------------- eng/Versions.props | 16 ++++++++-------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d7c8650bf65e4..e19c6206fc00f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -86,37 +86,37 @@ https://github.com/microsoft/vstest df61f73a1f4608df5ee0957350fbd3e81f924c6b - + https://github.com/dotnet/runtime-assets - 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d + 71b9284907ebc69e5f80b491a51084c75e0ef7d3 - + https://github.com/dotnet/runtime-assets - 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d + 71b9284907ebc69e5f80b491a51084c75e0ef7d3 - + https://github.com/dotnet/runtime-assets - 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d + 71b9284907ebc69e5f80b491a51084c75e0ef7d3 - + https://github.com/dotnet/runtime-assets - 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d + 71b9284907ebc69e5f80b491a51084c75e0ef7d3 - + https://github.com/dotnet/runtime-assets - 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d + 71b9284907ebc69e5f80b491a51084c75e0ef7d3 - + https://github.com/dotnet/runtime-assets - 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d + 71b9284907ebc69e5f80b491a51084c75e0ef7d3 - + https://github.com/dotnet/runtime-assets - 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d + 71b9284907ebc69e5f80b491a51084c75e0ef7d3 - + https://github.com/dotnet/runtime-assets - 4f4305bdda9b49dc2487cb73a17c2216fa1fb98d + 71b9284907ebc69e5f80b491a51084c75e0ef7d3 https://github.com/dotnet/llvm-project diff --git a/eng/Versions.props b/eng/Versions.props index 0b398500e1356..258b54f2c7570 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -80,14 +80,14 @@ 5.0.0-preview.4.20202.18 5.0.0-alpha.1.19563.3 - 5.0.0-beta.20257.1 - 5.0.0-beta.20257.1 - 5.0.0-beta.20257.1 - 5.0.0-beta.20257.1 - 5.0.0-beta.20257.1 - 5.0.0-beta.20257.1 - 5.0.0-beta.20257.1 - 5.0.0-beta.20257.1 + 5.0.0-beta.20258.1 + 5.0.0-beta.20258.1 + 5.0.0-beta.20258.1 + 5.0.0-beta.20258.1 + 5.0.0-beta.20258.1 + 5.0.0-beta.20258.1 + 5.0.0-beta.20258.1 + 5.0.0-beta.20258.1 2.2.0-prerelease.19564.1 From 5ee73c3452cae931d6be99e8f6b1cd47d22d69e8 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Sun, 10 May 2020 18:59:43 +0300 Subject: [PATCH 089/420] Remove CompareOrdinalEx (#36184) --- src/coreclr/src/classlibnative/bcltype/stringnative.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/coreclr/src/classlibnative/bcltype/stringnative.h b/src/coreclr/src/classlibnative/bcltype/stringnative.h index 6aea696e41af7..c8e1fcecc9f35 100644 --- a/src/coreclr/src/classlibnative/bcltype/stringnative.h +++ b/src/coreclr/src/classlibnative/bcltype/stringnative.h @@ -42,10 +42,8 @@ class COMString { public: // - // Search/Query Methods + // Query Methods // - static FCDECL6(INT32, CompareOrdinalEx, StringObject* strA, INT32 indexA, INT32 countA, StringObject* strB, INT32 indexB, INT32 countB); - static FCDECL2(FC_CHAR_RET, GetCharAt, StringObject* pThisRef, INT32 index); static FCDECL1(INT32, Length, StringObject* pThisRef); From 09ee4814cb669e4b703a458c63483fa75a47c58f Mon Sep 17 00:00:00 2001 From: ts2do Date: Sun, 10 May 2020 14:17:15 -0500 Subject: [PATCH 090/420] Add tests for changes in #34438 (#36166) --- .../DateTimeFormatInfoLongDatePattern.cs | 11 +++++++++++ .../DateTimeFormatInfoLongTimePattern.cs | 15 +++++++++++++++ .../DateTimeFormatInfoShortDatePattern.cs | 15 +++++++++++++++ .../DateTimeFormatInfoShortTimePattern.cs | 11 +++++++++++ 4 files changed, 52 insertions(+) diff --git a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoLongDatePattern.cs b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoLongDatePattern.cs index 5899092a5cf4f..e15b89b064ac1 100644 --- a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoLongDatePattern.cs +++ b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoLongDatePattern.cs @@ -36,6 +36,17 @@ public void LongDatePattern_Set_GetReturnsExpected(string value) Assert.Equal(value, format.LongDatePattern); } + [Fact] + public void LongDatePattern_Set_InvalidatesDerivedPattern() + { + const string Pattern = "#$"; + var format = new DateTimeFormatInfo(); + var d = DateTimeOffset.Now; + d.ToString("F", format); // FullDateTimePattern + format.LongDatePattern = Pattern; + Assert.Contains(Pattern, d.ToString("F", format)); + } + [Fact] public void LongDatePattern_SetNullValue_ThrowsArgumentNullException() { diff --git a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoLongTimePattern.cs b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoLongTimePattern.cs index 8e783154aa9ef..5367dc0f1e3b6 100644 --- a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoLongTimePattern.cs +++ b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoLongTimePattern.cs @@ -35,6 +35,21 @@ public void LongTimePattern_Set_GetReturnsExpected(string value) Assert.Equal(value, format.LongTimePattern); } + [Fact] + public void LongTimePattern_Set_InvalidatesDerivedPatterns() + { + const string Pattern = "#$"; + var format = new DateTimeFormatInfo(); + var d = DateTimeOffset.Now; + d.ToString("F", format); // FullDateTimePattern + d.ToString("G", format); // GeneralLongTimePattern + d.ToString(format); // DateTimeOffsetPattern + format.LongTimePattern = Pattern; + Assert.Contains(Pattern, d.ToString("F", format)); + Assert.Contains(Pattern, d.ToString("G", format)); + Assert.Contains(Pattern, d.ToString(format)); + } + [Fact] public void LongTimePattern_SetNullValue_ThrowsArgumentNullException() { diff --git a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoShortDatePattern.cs b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoShortDatePattern.cs index 4e67e1dcc7b08..b0dcb3705f26c 100644 --- a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoShortDatePattern.cs +++ b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoShortDatePattern.cs @@ -33,6 +33,21 @@ public void ShortDatePattern_Set_GetReturnsExpected(string value) Assert.Equal(value, format.ShortDatePattern); } + [Fact] + public void ShortDatePattern_Set_InvalidatesDerivedPatterns() + { + const string Pattern = "#$"; + var format = new DateTimeFormatInfo(); + var d = DateTimeOffset.Now; + d.ToString("G", format); // GeneralLongTimePattern + d.ToString("g", format); // GeneralShortTimePattern + d.ToString(format); // DateTimeOffsetPattern + format.ShortDatePattern = Pattern; + Assert.Contains(Pattern, d.ToString("G", format)); + Assert.Contains(Pattern, d.ToString("g", format)); + Assert.Contains(Pattern, d.ToString(format)); + } + [Fact] public void ShortDatePattern_SetNullValue_ThrowsArgumentNullException() { diff --git a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoShortTimePattern.cs b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoShortTimePattern.cs index bcea88b745296..8c87f92ae81fa 100644 --- a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoShortTimePattern.cs +++ b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoShortTimePattern.cs @@ -33,6 +33,17 @@ public void ShortTimePattern_Set_GetReturnsExpected(string value) Assert.Equal(value, format.ShortTimePattern); } + [Fact] + public void ShortTimePattern_Set_InvalidatesDerivedPattern() + { + const string Pattern = "#$"; + var format = new DateTimeFormatInfo(); + var d = DateTimeOffset.Now; + d.ToString("g", format); // GeneralShortTimePattern + format.ShortTimePattern = Pattern; + Assert.Contains(Pattern, d.ToString("g", format)); + } + [Fact] public void ShortTimePattern_SetNull_ThrowsArgumentNullException() { From c577f2ef9bf1c5612db1d67e5dcfb9d0330fffa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Andr=C3=A9?= <2341261+manandre@users.noreply.github.com> Date: Sun, 10 May 2020 22:37:54 +0200 Subject: [PATCH 091/420] Fix sync call in XContainer.ReadContentFromAsync (#35789) * Fix sync call in XContainer.ReadContentFromAsync --- .../src/System/Xml/Linq/XContainer.cs | 183 ++++++++++++- .../tests/misc/LoadSaveAsyncTests.cs | 242 ++++++++++++++++++ 2 files changed, 423 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs index 19e72023bb9b5..7311a99327caa 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs @@ -882,7 +882,7 @@ internal async Task ReadContentFromAsync(XmlReader r, CancellationToken cancella { cancellationToken.ThrowIfCancellationRequested(); } - while (cr.ReadContentFrom(this, r) && await r.ReadAsync().ConfigureAwait(false)); + while (await cr.ReadContentFromAsync(this, r).ConfigureAwait(false) && await r.ReadAsync().ConfigureAwait(false)); } internal async Task ReadContentFromAsync(XmlReader r, LoadOptions o, CancellationToken cancellationToken) @@ -899,7 +899,7 @@ internal async Task ReadContentFromAsync(XmlReader r, LoadOptions o, Cancellatio { cancellationToken.ThrowIfCancellationRequested(); } - while (cr.ReadContentFrom(this, r, o) && await r.ReadAsync().ConfigureAwait(false)); + while (await cr.ReadContentFromAsync(this, r, o).ConfigureAwait(false) && await r.ReadAsync().ConfigureAwait(false)); } private sealed class ContentReader @@ -979,6 +979,65 @@ public bool ReadContentFrom(XContainer rootContainer, XmlReader r) return true; } + public async ValueTask ReadContentFromAsync(XContainer rootContainer, XmlReader r) + { + switch (r.NodeType) + { + case XmlNodeType.Element: + XElement e = new XElement(_eCache.Get(r.NamespaceURI).GetName(r.LocalName)); + if (r.MoveToFirstAttribute()) + { + do + { + e.AppendAttributeSkipNotify(new XAttribute( + _aCache.Get(r.Prefix.Length == 0 ? string.Empty : r.NamespaceURI).GetName(r.LocalName), + await r.GetValueAsync().ConfigureAwait(false))); + } while (r.MoveToNextAttribute()); + r.MoveToElement(); + } + _currentContainer.AddNodeSkipNotify(e); + if (!r.IsEmptyElement) + { + _currentContainer = e; + } + break; + case XmlNodeType.EndElement: + if (_currentContainer.content == null) + { + _currentContainer.content = string.Empty; + } + if (_currentContainer == rootContainer) return false; + _currentContainer = _currentContainer.parent; + break; + case XmlNodeType.Text: + case XmlNodeType.SignificantWhitespace: + case XmlNodeType.Whitespace: + _currentContainer.AddStringSkipNotify(await r.GetValueAsync().ConfigureAwait(false)); + break; + case XmlNodeType.CDATA: + _currentContainer.AddNodeSkipNotify(new XCData(await r.GetValueAsync().ConfigureAwait(false))); + break; + case XmlNodeType.Comment: + _currentContainer.AddNodeSkipNotify(new XComment(await r.GetValueAsync().ConfigureAwait(false))); + break; + case XmlNodeType.ProcessingInstruction: + _currentContainer.AddNodeSkipNotify(new XProcessingInstruction(r.Name, await r.GetValueAsync().ConfigureAwait(false))); + break; + case XmlNodeType.DocumentType: + _currentContainer.AddNodeSkipNotify(new XDocumentType(r.LocalName, r.GetAttribute("PUBLIC"), r.GetAttribute("SYSTEM"), await r.GetValueAsync().ConfigureAwait(false))); + break; + case XmlNodeType.EntityReference: + if (!r.CanResolveEntity) throw new InvalidOperationException(SR.InvalidOperation_UnresolvedEntityReference); + r.ResolveEntity(); + break; + case XmlNodeType.EndEntity: + break; + default: + throw new InvalidOperationException(SR.Format(SR.InvalidOperation_UnexpectedNodeType, r.NodeType)); + } + return true; + } + public bool ReadContentFrom(XContainer rootContainer, XmlReader r, LoadOptions o) { XNode newNode = null; @@ -1096,6 +1155,126 @@ public bool ReadContentFrom(XContainer rootContainer, XmlReader r, LoadOptions o return true; } + + public async ValueTask ReadContentFromAsync(XContainer rootContainer, XmlReader r, LoadOptions o) + { + XNode newNode = null; + string baseUri = r.BaseURI; + + switch (r.NodeType) + { + case XmlNodeType.Element: + { + XElement e = new XElement(_eCache.Get(r.NamespaceURI).GetName(r.LocalName)); + if (_baseUri != null && _baseUri != baseUri) + { + e.SetBaseUri(baseUri); + } + if (_lineInfo != null && _lineInfo.HasLineInfo()) + { + e.SetLineInfo(_lineInfo.LineNumber, _lineInfo.LinePosition); + } + if (r.MoveToFirstAttribute()) + { + do + { + XAttribute a = new XAttribute( + _aCache.Get(r.Prefix.Length == 0 ? string.Empty : r.NamespaceURI).GetName(r.LocalName), + await r.GetValueAsync().ConfigureAwait(false)); + if (_lineInfo != null && _lineInfo.HasLineInfo()) + { + a.SetLineInfo(_lineInfo.LineNumber, _lineInfo.LinePosition); + } + e.AppendAttributeSkipNotify(a); + } while (r.MoveToNextAttribute()); + r.MoveToElement(); + } + _currentContainer.AddNodeSkipNotify(e); + if (!r.IsEmptyElement) + { + _currentContainer = e; + if (_baseUri != null) + { + _baseUri = baseUri; + } + } + break; + } + case XmlNodeType.EndElement: + { + if (_currentContainer.content == null) + { + _currentContainer.content = string.Empty; + } + // Store the line info of the end element tag. + // Note that since we've got EndElement the current container must be an XElement + XElement e = _currentContainer as XElement; + Debug.Assert(e != null, "EndElement received but the current container is not an element."); + if (e != null && _lineInfo != null && _lineInfo.HasLineInfo()) + { + e.SetEndElementLineInfo(_lineInfo.LineNumber, _lineInfo.LinePosition); + } + if (_currentContainer == rootContainer) return false; + if (_baseUri != null && _currentContainer.HasBaseUri) + { + _baseUri = _currentContainer.parent.BaseUri; + } + _currentContainer = _currentContainer.parent; + break; + } + case XmlNodeType.Text: + case XmlNodeType.SignificantWhitespace: + case XmlNodeType.Whitespace: + if ((_baseUri != null && _baseUri != baseUri) || + (_lineInfo != null && _lineInfo.HasLineInfo())) + { + newNode = new XText(await r.GetValueAsync().ConfigureAwait(false)); + } + else + { + _currentContainer.AddStringSkipNotify(await r.GetValueAsync().ConfigureAwait(false)); + } + break; + case XmlNodeType.CDATA: + newNode = new XCData(await r.GetValueAsync().ConfigureAwait(false)); + break; + case XmlNodeType.Comment: + newNode = new XComment(await r.GetValueAsync().ConfigureAwait(false)); + break; + case XmlNodeType.ProcessingInstruction: + newNode = new XProcessingInstruction(r.Name, await r.GetValueAsync().ConfigureAwait(false)); + break; + case XmlNodeType.DocumentType: + newNode = new XDocumentType(r.LocalName, r.GetAttribute("PUBLIC"), r.GetAttribute("SYSTEM"), await r.GetValueAsync().ConfigureAwait(false)); + break; + case XmlNodeType.EntityReference: + if (!r.CanResolveEntity) throw new InvalidOperationException(SR.InvalidOperation_UnresolvedEntityReference); + r.ResolveEntity(); + break; + case XmlNodeType.EndEntity: + break; + default: + throw new InvalidOperationException(SR.Format(SR.InvalidOperation_UnexpectedNodeType, r.NodeType)); + } + + if (newNode != null) + { + if (_baseUri != null && _baseUri != baseUri) + { + newNode.SetBaseUri(baseUri); + } + + if (_lineInfo != null && _lineInfo.HasLineInfo()) + { + newNode.SetLineInfo(_lineInfo.LineNumber, _lineInfo.LinePosition); + } + + _currentContainer.AddNodeSkipNotify(newNode); + newNode = null; + } + + return true; + } } internal void RemoveNode(XNode n) diff --git a/src/libraries/System.Private.Xml.Linq/tests/misc/LoadSaveAsyncTests.cs b/src/libraries/System.Private.Xml.Linq/tests/misc/LoadSaveAsyncTests.cs index 0e436827430fe..2e9db3bc282ca 100644 --- a/src/libraries/System.Private.Xml.Linq/tests/misc/LoadSaveAsyncTests.cs +++ b/src/libraries/System.Private.Xml.Linq/tests/misc/LoadSaveAsyncTests.cs @@ -232,6 +232,155 @@ public async Task SaveAsync_CallsAsyncOnly_SaveSync_CallsSyncOnly(bool isAsync, } } } + + [Theory] + [MemberData(nameof(RoundtripOptions_MemberData))] + public static async Task RoundtripSyncAsyncCheckAndMatches_XmlReader(bool document, LoadOptions loadOptions, SaveOptions saveOptions) + { + // Create reader and writer settings + var readerSettings = new XmlReaderSettings(); + var writerSettings = new XmlWriterSettings(); + if ((saveOptions & SaveOptions.OmitDuplicateNamespaces) != 0) + { + writerSettings.NamespaceHandling = NamespaceHandling.OmitDuplicates; + } + if ((saveOptions & SaveOptions.DisableFormatting) != 0) + { + writerSettings.Indent = false; + writerSettings.NewLineHandling = NewLineHandling.None; + } + + // Roundtrip XML using synchronous and XmlReader/Writer + CheckSyncAsyncStream syncInput = new CheckSyncAsyncStream(async: false, FilePathUtil.getStream(GetTestFileName())); + MemoryStream syncOutputMemory = new MemoryStream(); + CheckSyncAsyncStream syncOutput = new CheckSyncAsyncStream(async: false, syncOutputMemory); + using (XmlReader syncReader = XmlReader.Create(syncInput, readerSettings)) + using (XmlWriter syncWriter = XmlWriter.Create(syncOutput, writerSettings)) + { + if (document) + { + XDocument syncDoc = XDocument.Load(syncReader, loadOptions); + syncDoc.Save(syncWriter); + } + else + { + XElement syncElement = XElement.Load(syncReader, loadOptions); + syncElement.Save(syncWriter); + } + } + + // Roundtrip XML using asynchronous and XmlReader/Writer + readerSettings.Async = true; + writerSettings.Async = true; + CheckSyncAsyncStream asyncInput = new CheckSyncAsyncStream(async: true, FilePathUtil.getStream(GetTestFileName())); + MemoryStream asyncOutputMemory = new MemoryStream(); + CheckSyncAsyncStream asyncOutput = new CheckSyncAsyncStream(async: true, asyncOutputMemory); + using (XmlReader asyncReader = XmlReader.Create(asyncInput, readerSettings)) + await using (XmlWriter asyncWriter = XmlWriter.Create(asyncOutput, writerSettings)) + { + if (document) + { + XDocument asyncDoc = await XDocument.LoadAsync(asyncReader, loadOptions, CancellationToken.None); + await asyncDoc.SaveAsync(asyncWriter, CancellationToken.None); + } + else + { + XElement asyncElement = await XElement.LoadAsync(asyncReader, loadOptions, CancellationToken.None); + await asyncElement.SaveAsync(asyncWriter, CancellationToken.None); + } + } + + // Compare to make sure the synchronous and asynchronous results are the same + Assert.Equal(syncOutputMemory.ToArray(), asyncOutputMemory.ToArray()); + } + + [Theory] + [MemberData(nameof(RoundtripOptions_MemberData))] + public static async Task RoundtripSyncAsyncCheckAndMatches_StreamReader(bool document, LoadOptions loadOptions, SaveOptions saveOptions) + { + // Roundtrip XML using synchronous and StreamReader/Writer + CheckSyncAsyncStream syncInput = new CheckSyncAsyncStream(async: false, FilePathUtil.getStream(GetTestFileName())); + MemoryStream syncOutputMemory = new MemoryStream(); + CheckSyncAsyncStream syncOutput = new CheckSyncAsyncStream(async: false, syncOutputMemory); + using (StreamReader syncReader = new StreamReader(syncInput)) + using (StreamWriter syncWriter = new StreamWriter(syncOutput)) + { + if (document) + { + XDocument syncDoc = XDocument.Load(syncReader, loadOptions); + syncDoc.Save(syncWriter, saveOptions); + } + else + { + XElement syncElement = XElement.Load(syncReader, loadOptions); + syncElement.Save(syncWriter, saveOptions); + } + } + + // Roundtrip XML using asynchronous and StreamReader/Writer + CheckSyncAsyncStream asyncInput = new CheckSyncAsyncStream(async: true, FilePathUtil.getStream(GetTestFileName())); + MemoryStream asyncOutputMemory = new MemoryStream(); + CheckSyncAsyncStream asyncOutput = new CheckSyncAsyncStream(async: true, asyncOutputMemory); + using (StreamReader asyncReader = new StreamReader(asyncInput)) + await using (StreamWriter asyncWriter = new StreamWriter(asyncOutput)) + { + if (document) + { + XDocument asyncDoc = await XDocument.LoadAsync(asyncReader, loadOptions, CancellationToken.None); + await asyncDoc.SaveAsync(asyncWriter, saveOptions, CancellationToken.None); + } + else + { + XElement asyncElement = await XElement.LoadAsync(asyncReader, loadOptions, CancellationToken.None); + await asyncElement.SaveAsync(asyncWriter, saveOptions, CancellationToken.None); + } + } + + // Compare to make sure the synchronous and asynchronous results are the same + Assert.Equal(syncOutputMemory.ToArray(), asyncOutputMemory.ToArray()); + } + + [Theory] + [MemberData(nameof(RoundtripOptions_MemberData))] + public static async Task RoundtripSyncAsyncCheckAndMatches_Stream(bool document, LoadOptions loadOptions, SaveOptions saveOptions) + { + // Roundtrip XML using synchronous and Stream + MemoryStream syncOutputMemory = new MemoryStream(); + CheckSyncAsyncStream syncOutput = new CheckSyncAsyncStream(async: false, syncOutputMemory); + using (Stream syncStream = new CheckSyncAsyncStream(async: false, FilePathUtil.getStream(GetTestFileName()))) + { + if (document) + { + XDocument syncDoc = XDocument.Load(syncStream, loadOptions); + syncDoc.Save(syncOutput, saveOptions); + } + else + { + XElement syncElement = XElement.Load(syncStream, loadOptions); + syncElement.Save(syncOutput, saveOptions); + } + } + + // Roundtrip XML using asynchronous and Stream + MemoryStream asyncOutputMemory = new MemoryStream(); + CheckSyncAsyncStream asyncOutput = new CheckSyncAsyncStream(async: true, asyncOutputMemory); + await using (Stream asyncStream = new CheckSyncAsyncStream(async: true, FilePathUtil.getStream(GetTestFileName()))) + { + if (document) + { + XDocument asyncDoc = await XDocument.LoadAsync(asyncStream, loadOptions, CancellationToken.None); + await asyncDoc.SaveAsync(asyncOutput, saveOptions, CancellationToken.None); + } + else + { + XElement asyncElement = await XElement.LoadAsync(asyncStream, loadOptions, CancellationToken.None); + await asyncElement.SaveAsync(asyncOutput, saveOptions, CancellationToken.None); + } + } + + // Compare to make sure the synchronous and asynchronous results are the same + Assert.Equal(syncOutputMemory.ToArray(), asyncOutputMemory.ToArray()); + } } public class ForceSyncAsyncStream : MemoryStream @@ -267,4 +416,97 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati return Task.CompletedTask; } } + + public class CheckSyncAsyncStream : Stream + { + private readonly Stream _stream; + + private readonly bool _isAsync; + private bool _isAsyncInProgress; + + public CheckSyncAsyncStream(bool async, Stream stream = null) + { + _stream = stream ?? new MemoryStream(); + _isAsync = async; + } + + public override void Flush() + { + if (!_isAsyncInProgress) + Assert.False(_isAsync, "Stream is in asynchronous mode when synchronous Flush is called"); + _stream.Flush(); + } + + public override Task FlushAsync(CancellationToken cancellationToken) + { + try + { + Assert.True(_isAsync, "Stream is not in asynchronous mode when asynchronous Flush is called"); + _isAsyncInProgress = true; + return _stream.FlushAsync(cancellationToken); + } + finally + { + _isAsyncInProgress = false; + } + } + + public override void Write(byte[] buffer, int offset, int count) + { + if (!_isAsyncInProgress) + Assert.False(_isAsync, "Stream is in asynchronous mode when synchronous Write is called"); + _stream.Write(buffer, offset, count); + } + + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + try + { + Assert.True(_isAsync, "Stream is not in asynchronous mode when asynchronous Write is called"); + _isAsyncInProgress = true; + return _stream.WriteAsync(buffer, offset, count, cancellationToken); + } + finally + { + _isAsyncInProgress = false; + } + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (!_isAsyncInProgress) + Assert.False(_isAsync, "Stream is in asynchronous mode when synchronous Read is called"); + return _stream.Read(buffer, offset, count); + } + + public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + try + { + Assert.True(_isAsync, "Stream is not in asynchronous mode when asynchronous Read is called"); + _isAsyncInProgress = true; + return _stream.ReadAsync(buffer, offset, count, cancellationToken); + } + finally + { + _isAsyncInProgress = false; + } + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _stream.Dispose(); + } + } + + public override long Seek(long offset, SeekOrigin origin) => _stream.Seek(offset, origin); + public override void SetLength(long value) => _stream.SetLength(value); + public override bool CanRead => _stream.CanRead; + public override bool CanSeek => _stream.CanSeek; + public override bool CanWrite => _stream.CanWrite; + public override long Length => _stream.Length; + public override long Position { get => _stream.Position; set => _stream.Position = value; } + } } From 1c10ed946cdd7cd07c9626c5e933ac92a4629387 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Sun, 10 May 2020 17:12:15 -0400 Subject: [PATCH 092/420] [tests] Adjustments to interp disabled tests (#36178) Co-authored-by: BrzVlad --- src/mono/mono/tests/Makefile.am | 87 +++------------------------------ 1 file changed, 7 insertions(+), 80 deletions(-) diff --git a/src/mono/mono/tests/Makefile.am b/src/mono/mono/tests/Makefile.am index ffdf85a2c7ff1..6b20fc9c525b8 100755 --- a/src/mono/mono/tests/Makefile.am +++ b/src/mono/mono/tests/Makefile.am @@ -1947,72 +1947,17 @@ INTERP_DISABLED_TESTS += calli_sig_check.exe # Test is too sensitive. INTERP_DISABLED_TESTS += localloc-noinit.exe - -# bug-48015.exe: be careful when re-enabling, it happens that it returns with exit code 0, but doesn't actually execute the test. +INTERP_DISABLED_TESTS += dim-diamondshape.exe +INTERP_DISABLED_TESTS += pinvoke3.exe +INTERP_DISABLED_TESTS += cominterop.exe # bug-60862.exe: missing support to map IP->method; only works on platforms with altstack support. -# bug-60843.exe: something goes wrong when turning the decoded enum value into a boxed enum, so the loaded value ends up being random bytes - -if ARM -INTERP_DISABLED_TESTS += \ - appdomain-unload-callback.exe \ - appdomain-unload.exe \ - assemblyresolve_event6.exe \ - async-with-cb-throws.exe \ - block_guard_restore_aligment_on_exit.exe \ - bug-323114.exe \ - bug-335131.2.exe \ - bug-415577.exe \ - bug-45841-fpstack-exceptions.exe \ - bug-48015.exe \ - bug-60862.exe \ - bug-80307.exe \ - bug-80392.2.exe \ - bug445361.exe \ - calliGenericTest.exe \ - cominterop.exe \ - context-static.exe \ - delegate-async-exit.exe \ - delegate-delegate-exit.exe \ - delegate-exit.exe \ - delegate1.exe \ - delegate3.exe \ - delegate5.exe \ - delegate8.exe \ - delegate9.exe \ - dim-diamondshape.exe \ - dynamic-method-stack-traces.exe \ - even-odd.exe \ - exception18.exe \ - field-access.exe \ - finalizer-exception.exe \ - handleref.exe \ - monitor-abort.exe \ - nullable_boxing.2.exe \ - pinvoke2.exe \ - pinvoke3.exe \ - remoting2.exe \ - remoting3.exe \ - safehandle.2.exe \ - stackframes-async.2.exe \ - static-constructor.exe \ - threadpool-exceptions2.exe \ - threadpool-exceptions3.exe \ - threadpool-exceptions4.exe \ - threadpool-exceptions5.exe \ - threadpool-exceptions6.exe \ - thunks.exe \ - typeload-unaligned.exe \ - vararg.exe \ - vararg2.exe \ - vararg3.exe -endif +INTERP_DISABLED_TESTS += bug-60862.exe +# bug-48015.exe: remoting test that fails on fullaotinterp scenarios +INTERP_DISABLED_TESTS += bug-48015.exe if ARM64 INTERP_DISABLED_TESTS += \ - bug-48015.exe \ - bug-80307.exe \ - dim-diamondshape.exe \ - pinvoke3.exe + bug-80307.exe # Test is too sensitive. DISABLED_TESTS += localloc-noinit.exe @@ -2024,24 +1969,6 @@ if HOST_WIN32 DISABLED_TESTS += localloc-noinit.exe endif -if AMD64 -INTERP_DISABLED_TESTS += \ - assemblyresolve_event6.exe \ - bug-48015.exe \ - bug-60862.exe \ - cominterop.exe \ - dim-diamondshape.exe \ - pinvoke3.exe -endif - -if X86 -INTERP_DISABLED_TESTS += \ - bug-60862.exe \ - cominterop.exe \ - dim-diamondshape.exe \ - pinvoke3.exe -endif - TESTS_CS=$(filter-out $(DISABLED_TESTS),$(TESTS_CS_SRC:.cs=.exe)) TESTS_IL=$(filter-out $(DISABLED_TESTS),$(TESTS_IL_SRC:.il=.exe)) TESTS_BENCH=$(filter-out $(DISABLED_TESTS),$(TESTS_BENCH_SRC:.cs=.exe)) From 23e13a3c8f320fc5931d789c70e10f6f570a4afe Mon Sep 17 00:00:00 2001 From: mrj001 <62225294+mrj001@users.noreply.github.com> Date: Sun, 10 May 2020 20:41:54 -0600 Subject: [PATCH 093/420] =?UTF-8?q?Adding=20unit=20test=20to=20provoke=20e?= =?UTF-8?q?xception=20using=20Sch=5FWhiteSpaceRestriction=E2=80=A6=20(#350?= =?UTF-8?q?13)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adding unit test to provoke exception using Sch_WhiteSpaceRestriction1 as its message. --- .../src/Resources/Strings.resx | 6 +- .../XmlSchemaSet/TC_SchemaSet_Compile.cs | 215 ++++++++++++++++++ 2 files changed, 218 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/Resources/Strings.resx b/src/libraries/System.Private.Xml/src/Resources/Strings.resx index 73ea65d48d848..23846093ce581 100644 --- a/src/libraries/System.Private.Xml/src/Resources/Strings.resx +++ b/src/libraries/System.Private.Xml/src/Resources/Strings.resx @@ -1684,7 +1684,7 @@ Derived attribute's use has to be required if base attribute's use is required. - The {base type definition} must have an {attribute wildcard} and the {target namespace} of the R's {attribute declaration} must be valid with respect to that wildcard. + The base type definition must have an attribute wildcard and the target namespace of the attribute declaration in the 'redefine' must be valid with respect to that wildcard. The base attribute '{0}' whose use = 'required' does not have a corresponding derived attribute while redefining attribute group '{1}'. @@ -1771,10 +1771,10 @@ Values that are declared with fixed='true' in a base type can not be changed in a derived type. - It is an error if 'whiteSpace' is among the members of {facets} of {base type definition}, {value} is 'replace' or 'preserve', and the {value} of the parent 'whiteSpace' is 'collapse'. + It is an error if 'whiteSpace' is among the facets of the type definition, its value is 'replace' or 'preserve', and the value of the parent 'whiteSpace' is 'collapse'. - It is an error if 'whiteSpace' is among the members of {facets} of {base type definition}, {value} is 'preserve', and the {value} of the parent 'whiteSpace' is 'replace'. + It is an error if 'whiteSpace' is among the facets of the type definition, its value is 'preserve', and the value of the parent 'whiteSpace' is 'replace'. There must be no fixed value when an attribute is 'xsi:nil' and has a value of 'true'. diff --git a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_Compile.cs b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_Compile.cs index 83ac7b192991c..59a5320776db9 100644 --- a/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_Compile.cs +++ b/src/libraries/System.Private.Xml/tests/XmlSchema/XmlSchemaSet/TC_SchemaSet_Compile.cs @@ -7,6 +7,7 @@ using System.IO; using System.Xml.Schema; using System.Collections.Generic; +using System.Text; namespace System.Xml.Tests { @@ -1150,5 +1151,219 @@ public void TotalDigitsParseValue_Succeeds() ss.Compile(); } } + + #region tests causing XmlSchemaException with Sch_WhiteSpaceRestriction1 + public static IEnumerable WhiteSpaceRestriction1_Throws_TestData + { + get + { + return new List() + { + new object[] + { +@" + + + + + + + + + + + + +" + }, + new object[] + { +@" + + + + + + + + + + + + +" + } + }; + } + } + + [Theory] + [MemberData(nameof(WhiteSpaceRestriction1_Throws_TestData))] + public void WhiteSpaceRestriction1_Throws(string schema) + { + XmlSchemaSet ss = new XmlSchemaSet(); + using (StringReader sr = new StringReader(schema)) + using (XmlReader xmlrdr = XmlReader.Create(sr)) + { + ss.Add(null, xmlrdr); + } + + Exception ex = Assert.Throws(() => ss.Compile()); + + Assert.Contains("whiteSpace", ex.Message); + Assert.Contains("collapse", ex.Message); + Assert.Contains("preserve", ex.Message); + Assert.Contains("replace", ex.Message); + } + #endregion + + #region tests causing XmlSchemaException with Sch_WhiteSpaceRestriction2 + public static IEnumerable WhiteSpaceRestriction2_Throws_TestData + { + get + { + return new List() + { + new object[] + { +@" + + + + + + + + + + + + +" + } + }; + } + } + + [Theory] + [MemberData(nameof(WhiteSpaceRestriction2_Throws_TestData))] + public void WhiteSpaceRestriction2_Throws(string schema) + { + XmlSchemaSet ss = new XmlSchemaSet(); + using (StringReader sr = new StringReader(schema)) + using (XmlReader xmlrdr = XmlReader.Create(sr)) + { + ss.Add(null, xmlrdr); + } + + Exception ex = Assert.Throws(() => ss.Compile()); + + Assert.Contains("whiteSpace", ex.Message); + Assert.DoesNotContain("collapse", ex.Message); + Assert.Contains("preserve", ex.Message); + Assert.Contains("replace", ex.Message); + } + #endregion + + #region Attribute Restriction Invalid From WildCard tests + + public static IEnumerable AttributeRestrictionInvalidFromWildCard_Throws_TestData + { + get + { + return new List() + { + new object[] + { + @" + + + + + + + + + + + +" + }, + new object[] + { + @" + + + + + + + + + + + +" + } + }; + } + } + + [Theory] + [MemberData(nameof(AttributeRestrictionInvalidFromWildCard_Throws_TestData))] + public void AttributeRestrictionInvalidFromWildCard_Throws(string schema) + { + XmlSchemaSet ss = new XmlSchemaSet(); + ss.XmlResolver = new FakeXmlResolverAttributeRestriction(); + using (StringReader sr = new StringReader(schema)) + using (XmlReader xmlrdr = XmlReader.Create(sr)) + { + ss.Add(null, xmlrdr); + } + + Exception ex = Assert.Throws(() => ss.Compile()); + + Assert.Contains("wildcard", ex.Message); + Assert.Contains("redefine", ex.Message); + } + + private class FakeXmlResolverAttributeRestriction : XmlResolver + { + public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) + { + int uriIndex = int.Parse(absoluteUri.Host); + string[] schema = { @" + + + + + + + +", +@" + + + + + + + + +" + }; + + return new MemoryStream(Encoding.UTF8.GetBytes(schema[uriIndex])); + } + } + #endregion } } From e7c26f95ac75640e092bf36d25bda17ab94c7fe2 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Sun, 10 May 2020 22:29:50 -0700 Subject: [PATCH 094/420] Update ryujit-tutorial.md (#36191) --- docs/design/coreclr/jit/ryujit-tutorial.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/design/coreclr/jit/ryujit-tutorial.md b/docs/design/coreclr/jit/ryujit-tutorial.md index 77462044483ca..050c11495b6a8 100644 --- a/docs/design/coreclr/jit/ryujit-tutorial.md +++ b/docs/design/coreclr/jit/ryujit-tutorial.md @@ -5,9 +5,8 @@ ### .NET Runtime - An implementation of the Common Language Infrastructure [ECMA 335] - Supports multiple languages, including C#, F# and VB -- Sources are mostly shared between the "desktop" version and the open-source coreclr implementation: - http://www.github.com/dotnet/runtime/src/coreclr - RyuJIT is the "next generation" just in time compiler for .NET +- Sources are at https://github.com/dotnet/runtime/tree/master/src/coreclr/src/jit #### Notes For context, the .NET runtime has been around since about the turn of the millennium. It is a virtual machine that supports the execution of a number of languages, primarily C#, Visual Basic, and F#. @@ -19,7 +18,6 @@ RyuJIT is the re-architected JIT for .NET. ### Why "RyuJIT"? - Ryujin is a Japanese Sea Dragon -We came up with the code name "RyuJIT" because our original code name had possible issues. We wanted something with "JIT" in the name, and the idea of a dragon came to mind because of the Dragon book that we all know and love. So – we just adapted the name of the Japanese sea dragon, Ryujin. From d48be104ffbd44c1bd2607b3dea45050b9e3e214 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Mon, 11 May 2020 04:35:19 -0400 Subject: [PATCH 095/420] [mono] Fix musl PowerPC build (#36162) PT_NIP and friends are in this kernel header, but glibc includes it somewhere in the chain implicitly. musl doesn't. Fix that. --- src/mono/mono/utils/mono-sigcontext.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mono/mono/utils/mono-sigcontext.h b/src/mono/mono/utils/mono-sigcontext.h index be0fbce43189d..9a73dff7c520c 100644 --- a/src/mono/mono/utils/mono-sigcontext.h +++ b/src/mono/mono/utils/mono-sigcontext.h @@ -324,6 +324,9 @@ typedef struct ucontext { #endif #if defined(__linux__) + +/* don't rely on glibc to include this for us, musl won't */ +#include typedef ucontext_t os_ucontext; #ifdef __mono_ppc64__ From 993db61f29b7a65ca2d20112973c199c1fa75b64 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Mon, 11 May 2020 03:57:07 -0700 Subject: [PATCH 096/420] Port GC changes from dotnet/corert (#36197) --- src/coreclr/src/gc/env/etmdummy.h | 1 + src/coreclr/src/gc/env/gcenv.os.h | 5 +- src/coreclr/src/gc/env/volatile.h | 4 +- src/coreclr/src/gc/unix/cgroup.cpp | 48 +------------- src/coreclr/src/gc/unix/gcenv.unix.cpp | 89 ++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 50 deletions(-) diff --git a/src/coreclr/src/gc/env/etmdummy.h b/src/coreclr/src/gc/env/etmdummy.h index 7435df7f8137b..ba4c4cf96a5db 100644 --- a/src/coreclr/src/gc/env/etmdummy.h +++ b/src/coreclr/src/gc/env/etmdummy.h @@ -164,6 +164,7 @@ #define FireEtwGCMarkWithType(HeapNum, ClrInstanceID, Type, Bytes) 0 #define FireEtwGCJoin_V2(Heap, JoinTime, JoinType, ClrInstanceID, JoinID) 0 #define FireEtwGCPerHeapHistory_V3(ClrInstanceID, FreeListAllocated, FreeListRejected, EndOfSegAllocated, CondemnedAllocated, PinnedAllocated, PinnedAllocatedAdvance, RunningFreeListEfficiency, CondemnReasons0, CondemnReasons1, CompactMechanisms, ExpandMechanisms, HeapIndex, ExtraGen0Commit, Count, Values_Len_, Values) 0 +#define FireEtwGCGlobalHeapHistory_V2(FinalYoungestDesired, NumHeaps, CondemnedGeneration, Gen0ReductionCount, Reason, GlobalMechanisms, ClrInstanceID, PauseMode, MemoryPressure) 0 #define FireEtwGCGlobalHeapHistory_V3(FinalYoungestDesired, NumHeaps, CondemnedGeneration, Gen0ReductionCount, Reason, GlobalMechanisms, ClrInstanceID, PauseMode, MemoryPressure, CondemnReasons0, CondemnReasons1) 0 #define FireEtwDebugIPCEventStart() 0 #define FireEtwDebugIPCEventEnd() 0 diff --git a/src/coreclr/src/gc/env/gcenv.os.h b/src/coreclr/src/gc/env/gcenv.os.h index a2d837a82d50d..6a6477f3c4650 100644 --- a/src/coreclr/src/gc/env/gcenv.os.h +++ b/src/coreclr/src/gc/env/gcenv.os.h @@ -66,8 +66,9 @@ struct VirtualReserveFlags // are run on process exit, potentially concurrently with other threads that may still be // operating on the static event. To avoid these sorts of unsafety, GCEvent chooses to // not have a destructor at all. The cost of this is leaking a small amount of memory, but -// this is not a problem since a majority of the uses of GCEvent are static. See CoreCLR#11111 -// for more details on the hazards of static destructors. +// this is not a problem since a majority of the uses of GCEvent are static. +// See https://github.com/dotnet/runtime/issues/7919 for more details on the hazards of +// static destructors. class GCEvent { private: class Impl; diff --git a/src/coreclr/src/gc/env/volatile.h b/src/coreclr/src/gc/env/volatile.h index c7964e9107d8f..32b6fca3b6a7c 100644 --- a/src/coreclr/src/gc/env/volatile.h +++ b/src/coreclr/src/gc/env/volatile.h @@ -67,8 +67,8 @@ #error The Volatile type is currently only defined for Visual C++ and GNU C++ #endif -#if defined(__GNUC__) && !defined(HOST_X86) && !defined(HOST_AMD64) && !defined(HOST_ARM) && !defined(HOST_ARM64) -#error The Volatile type is currently only defined for GCC when targeting x86, AMD64, ARM or ARM64 CPUs +#if defined(__GNUC__) && !defined(HOST_X86) && !defined(HOST_AMD64) && !defined(HOST_ARM) && !defined(HOST_ARM64) && !defined(HOST_WASM) +#error The Volatile type is currently only defined for GCC when targeting x86, AMD64, ARM, ARM64 or Wasm #endif #if defined(__GNUC__) diff --git a/src/coreclr/src/gc/unix/cgroup.cpp b/src/coreclr/src/gc/unix/cgroup.cpp index c2c1b2b588449..9cdc5b14df021 100644 --- a/src/coreclr/src/gc/unix/cgroup.cpp +++ b/src/coreclr/src/gc/unix/cgroup.cpp @@ -54,6 +54,8 @@ Module Name: #define CGROUP1_CFS_PERIOD_FILENAME "/cpu.cfs_period_us" #define CGROUP2_CPU_MAX_FILENAME "/cpu.max" +extern bool ReadMemoryValueFromFile(const char* filename, uint64_t* val); + class CGroup { // the cgroup version number or 0 to indicate cgroups are not found or not enabled @@ -420,52 +422,6 @@ class CGroup return result; } - static bool ReadMemoryValueFromFile(const char* filename, uint64_t* val) - { - bool result = false; - char *line = nullptr; - size_t lineLen = 0; - char* endptr = nullptr; - uint64_t num = 0, l, multiplier; - FILE* file = nullptr; - - if (val == nullptr) - goto done; - - file = fopen(filename, "r"); - if (file == nullptr) - goto done; - - if (getline(&line, &lineLen, file) == -1) - goto done; - - errno = 0; - num = strtoull(line, &endptr, 0); - if (line == endptr || errno != 0) - goto done; - - multiplier = 1; - switch(*endptr) - { - case 'g': - case 'G': multiplier = 1024; - case 'm': - case 'M': multiplier = multiplier*1024; - case 'k': - case 'K': multiplier = multiplier*1024; - } - - *val = num * multiplier; - result = true; - if (*val/multiplier != num) - result = false; - done: - if (file) - fclose(file); - free(line); - return result; - } - static bool GetCGroup1CpuLimit(uint32_t *val) { long long quota; diff --git a/src/coreclr/src/gc/unix/gcenv.unix.cpp b/src/coreclr/src/gc/unix/gcenv.unix.cpp index 9d074231a690d..9b78b70f53abb 100644 --- a/src/coreclr/src/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/src/gc/unix/gcenv.unix.cpp @@ -772,6 +772,52 @@ bool GCToOSInterface::GetWriteWatch(bool resetState, void* address, size_t size, return false; } +bool ReadMemoryValueFromFile(const char* filename, uint64_t* val) +{ + bool result = false; + char* line = nullptr; + size_t lineLen = 0; + char* endptr = nullptr; + uint64_t num = 0, l, multiplier; + FILE* file = nullptr; + + if (val == nullptr) + goto done; + + file = fopen(filename, "r"); + if (file == nullptr) + goto done; + + if (getline(&line, &lineLen, file) == -1) + goto done; + + errno = 0; + num = strtoull(line, &endptr, 0); + if (line == endptr || errno != 0) + goto done; + + multiplier = 1; + switch (*endptr) + { + case 'g': + case 'G': multiplier = 1024; + case 'm': + case 'M': multiplier = multiplier * 1024; + case 'k': + case 'K': multiplier = multiplier * 1024; + } + + *val = num * multiplier; + result = true; + if (*val / multiplier != num) + result = false; +done: + if (file) + fclose(file); + free(line); + return result; +} + static size_t GetLogicalProcessorCacheSizeFromOS() { size_t cacheSize = 0; @@ -789,6 +835,49 @@ static size_t GetLogicalProcessorCacheSizeFromOS() cacheSize = std::max(cacheSize, ( size_t) sysconf(_SC_LEVEL4_CACHE_SIZE)); #endif +#if defined(HOST_ARM64) + if (cacheSize == 0) + { + size_t size; + + if (ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index0/size", &size)) + cacheSize = std::max(cacheSize, size); + if (ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index1/size", &size)) + cacheSize = std::max(cacheSize, size); + if (ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index2/size", &size)) + cacheSize = std::max(cacheSize, size); + if (ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index3/size", &size)) + cacheSize = std::max(cacheSize, size); + if (ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index4/size", &size)) + cacheSize = std::max(cacheSize, size); + } + + if (cacheSize == 0) + { + // It is currently expected to be missing cache size info + // + // _SC_LEVEL*_*CACHE_SIZE is not yet present. Work is in progress to enable this for arm64 + // + // /sys/devices/system/cpu/cpu*/cache/index*/ is also not yet present in most systems. + // Arm64 patch is in Linux kernel tip. + // + // midr_el1 is available in "/sys/devices/system/cpu/cpu0/regs/identification/midr_el1", + // but without an exhaustive list of ARM64 processors any decode of midr_el1 + // Would likely be incomplete + + // Published information on ARM64 architectures is limited. + // If we use recent high core count chips as a guide for state of the art, we find + // total L3 cache to be 1-2MB/core. As always, there are exceptions. + + // Estimate cache size based on CPU count + // Assume lower core count are lighter weight parts which are likely to have smaller caches + // Assume L3$/CPU grows linearly from 256K to 1.5M/CPU as logicalCPUs grows from 2 to 12 CPUs + DWORD logicalCPUs = g_totalCpuCount; + + cacheSize = logicalCPUs * std::min(1536, std::max(256, (int)logicalCPUs * 128)) * 1024; + } +#endif + #if HAVE_SYSCTLBYNAME if (cacheSize == 0) { From 2d4acbde200dba78794d9baf8cc69c170267fde0 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 11 May 2020 09:47:01 -0500 Subject: [PATCH 097/420] Return the correct OSVersion on OSX like systems. (#36029) * Return the correct OSVersion on OSX like systems. Fix #34977 * Rename files to not have Linux when they aren't Linux specific. * Assert OSVersion Build number is valid. * PR feedback Move interop code to Common\src\Interop. Specify the full path to libobjc.dylib. Fix objc_msgSend_stret for ARM64. * Specify full path to libproc.dylib. Fix #24095 --- .../src/Interop/OSX/Interop.Libraries.cs | 4 +- .../Common/src/Interop/OSX/Interop.libobjc.cs | 59 ++++++++++++++++ .../System.Private.CoreLib.Shared.projitems | 17 ++++- ... => Environment.GetFolderPathCore.Unix.cs} | 0 .../src/System/Environment.OSVersion.OSX.cs | 18 +++++ .../src/System/Environment.OSVersion.Unix.cs | 67 +++++++++++++++++++ .../src/System/Environment.Unix.cs | 60 ----------------- ...leStream.OSX.cs => FileStream.Lock.OSX.cs} | 0 ...tream.Linux.cs => FileStream.Lock.Unix.cs} | 0 .../tests/System/EnvironmentTests.cs | 17 ++++- 10 files changed, 175 insertions(+), 67 deletions(-) create mode 100644 src/libraries/Common/src/Interop/OSX/Interop.libobjc.cs rename src/libraries/System.Private.CoreLib/src/System/{Environment.Unix.GetFolderPathCore.cs => Environment.GetFolderPathCore.Unix.cs} (100%) create mode 100644 src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.OSX.cs create mode 100644 src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.Unix.cs rename src/libraries/System.Private.CoreLib/src/System/IO/{FileStream.OSX.cs => FileStream.Lock.OSX.cs} (100%) rename src/libraries/System.Private.CoreLib/src/System/IO/{FileStream.Linux.cs => FileStream.Lock.Unix.cs} (100%) diff --git a/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs b/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs index 84bf6d6398da8..6c2a0ab78c8d7 100644 --- a/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs +++ b/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs @@ -9,13 +9,13 @@ internal static partial class Libraries internal const string CoreFoundationLibrary = "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"; internal const string CoreServicesLibrary = "/System/Library/Frameworks/CoreServices.framework/CoreServices"; internal const string CFNetworkLibrary = "/System/Library/Frameworks/CFNetwork.framework/CFNetwork"; - internal const string libproc = "libproc"; + internal const string libobjc = "/usr/lib/libobjc.dylib"; + internal const string libproc = "/usr/lib/libproc.dylib"; internal const string LibSystemCommonCrypto = "/usr/lib/system/libcommonCrypto"; internal const string LibSystemKernel = "/usr/lib/system/libsystem_kernel"; internal const string Odbc32 = "libodbc.2.dylib"; internal const string SystemConfigurationLibrary = "/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration"; internal const string AppleCryptoNative = "System.Security.Cryptography.Native.Apple"; internal const string MsQuic = "msquic"; - } } diff --git a/src/libraries/Common/src/Interop/OSX/Interop.libobjc.cs b/src/libraries/Common/src/Interop/OSX/Interop.libobjc.cs new file mode 100644 index 0000000000000..6658d2b4c5d40 --- /dev/null +++ b/src/libraries/Common/src/Interop/OSX/Interop.libobjc.cs @@ -0,0 +1,59 @@ +// 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. + +#nullable enable + +using System; +using System.Runtime.InteropServices; +using nint = System.IntPtr; + +internal static partial class Interop +{ + internal static partial class libobjc + { +#if TARGET_ARM64 + private const string MessageSendStructReturnEntryPoint = "objc_msgSend"; +#else + private const string MessageSendStructReturnEntryPoint = "objc_msgSend_stret"; +#endif + + [StructLayout(LayoutKind.Sequential)] + private struct NSOperatingSystemVersion + { + public nint majorVersion; + public nint minorVersion; + public nint patchVersion; + } + + [DllImport(Libraries.libobjc)] + private static extern IntPtr objc_getClass(string className); + [DllImport(Libraries.libobjc)] + private static extern IntPtr sel_getUid(string selector); + [DllImport(Libraries.libobjc)] + private static extern IntPtr objc_msgSend(IntPtr basePtr, IntPtr selector); + + internal static Version GetOperatingSystemVersion() + { + int major = 0; + int minor = 0; + int patch = 0; + + IntPtr processInfo = objc_msgSend(objc_getClass("NSProcessInfo"), sel_getUid("processInfo")); + + if (processInfo != IntPtr.Zero) + { + NSOperatingSystemVersion osVersion = get_operatingSystemVersion(processInfo, sel_getUid("operatingSystemVersion")); + + major = osVersion.majorVersion.ToInt32(); + minor = osVersion.minorVersion.ToInt32(); + patch = osVersion.patchVersion.ToInt32(); + } + + return new Version(major, minor, patch); + } + + [DllImport(Libraries.libobjc, EntryPoint = MessageSendStructReturnEntryPoint)] + private static extern NSOperatingSystemVersion get_operatingSystemVersion(IntPtr basePtr, IntPtr selector); + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 951552c11ba49..23fd990bfb42c 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -8,6 +8,7 @@ enable + true @@ -1750,14 +1751,16 @@ - + + + - - + + @@ -1773,6 +1776,14 @@ + + + Common\Interop\OSX\Interop.libobjc.cs + + + Common\Interop\OSX\Interop.Libraries.cs + + diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.Unix.GetFolderPathCore.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs similarity index 100% rename from src/libraries/System.Private.CoreLib/src/System/Environment.Unix.GetFolderPathCore.cs rename to src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.OSX.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.OSX.cs new file mode 100644 index 0000000000000..0c8771938f041 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.OSX.cs @@ -0,0 +1,18 @@ +// 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. + +namespace System +{ + public static partial class Environment + { + private static OperatingSystem GetOSVersion() + { + Version version = Interop.libobjc.GetOperatingSystemVersion(); + + // For compatibility reasons with Mono, PlatformID.Unix is returned on MacOSX. PlatformID.MacOSX + // is hidden from the editor and shouldn't be used. + return new OperatingSystem(PlatformID.Unix, version); + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.Unix.cs new file mode 100644 index 0000000000000..0ccea27611aed --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.Unix.cs @@ -0,0 +1,67 @@ +// 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. + +namespace System +{ + public static partial class Environment + { + private static OperatingSystem GetOSVersion() => GetOperatingSystem(Interop.Sys.GetUnixRelease()); + + // Tests exercise this method for corner cases via private reflection + private static OperatingSystem GetOperatingSystem(string release) + { + int major = 0, minor = 0, build = 0, revision = 0; + + // Parse the uname's utsname.release for the first four numbers found. + // This isn't perfect, but Version already doesn't map exactly to all possible release + // formats, e.g. 2.6.19-1.2895.fc6 + if (release != null) + { + int i = 0; + major = FindAndParseNextNumber(release, ref i); + minor = FindAndParseNextNumber(release, ref i); + build = FindAndParseNextNumber(release, ref i); + revision = FindAndParseNextNumber(release, ref i); + } + + return new OperatingSystem(PlatformID.Unix, new Version(major, minor, build, revision)); + } + + private static int FindAndParseNextNumber(string text, ref int pos) + { + // Move to the beginning of the number + for (; pos < text.Length; pos++) + { + char c = text[pos]; + if ('0' <= c && c <= '9') + { + break; + } + } + + // Parse the number; + int num = 0; + for (; pos < text.Length; pos++) + { + char c = text[pos]; + if ('0' > c || c > '9') + break; + + try + { + num = checked((num * 10) + (c - '0')); + } + // Integer overflow can occur for example with: + // Linux nelknet 4.15.0-24201807041620-generic + // To form a valid Version, num must be positive. + catch (OverflowException) + { + return int.MaxValue; + } + } + + return num; + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs index c29a56c14b53f..81b516dd45f5d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs @@ -63,66 +63,6 @@ public static string MachineName internal const string NewLineConst = "\n"; - private static OperatingSystem GetOSVersion() => GetOperatingSystem(Interop.Sys.GetUnixRelease()); - - // Tests exercise this method for corner cases via private reflection - private static OperatingSystem GetOperatingSystem(string release) - { - int major = 0, minor = 0, build = 0, revision = 0; - - // Parse the uname's utsname.release for the first four numbers found. - // This isn't perfect, but Version already doesn't map exactly to all possible release - // formats, e.g. 2.6.19-1.2895.fc6 - if (release != null) - { - int i = 0; - major = FindAndParseNextNumber(release, ref i); - minor = FindAndParseNextNumber(release, ref i); - build = FindAndParseNextNumber(release, ref i); - revision = FindAndParseNextNumber(release, ref i); - } - - // For compatibility reasons with Mono, PlatformID.Unix is returned on MacOSX. PlatformID.MacOSX - // is hidden from the editor and shouldn't be used. - return new OperatingSystem(PlatformID.Unix, new Version(major, minor, build, revision)); - } - - private static int FindAndParseNextNumber(string text, ref int pos) - { - // Move to the beginning of the number - for (; pos < text.Length; pos++) - { - char c = text[pos]; - if ('0' <= c && c <= '9') - { - break; - } - } - - // Parse the number; - int num = 0; - for (; pos < text.Length; pos++) - { - char c = text[pos]; - if ('0' > c || c > '9') - break; - - try - { - num = checked((num * 10) + (c - '0')); - } - // Integer overflow can occur for example with: - // Linux nelknet 4.15.0-24201807041620-generic - // To form a valid Version, num must be positive. - catch (OverflowException) - { - return int.MaxValue; - } - } - - return num; - } - public static string SystemDirectory => GetFolderPathCore(SpecialFolder.System, SpecialFolderOption.None); public static int SystemPageSize => CheckedSysConf(Interop.Sys.SysConfName._SC_PAGESIZE); diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.OSX.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Lock.OSX.cs similarity index 100% rename from src/libraries/System.Private.CoreLib/src/System/IO/FileStream.OSX.cs rename to src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Lock.OSX.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Linux.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Lock.Unix.cs similarity index 100% rename from src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Linux.cs rename to src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Lock.Unix.cs diff --git a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs index 3ea51bf15b4cf..5129caf6dc8e8 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs @@ -132,9 +132,9 @@ public void OSVersion_ValidVersion() Assert.Contains(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "Windows" : "Unix", versionString); } - // On Unix, we must parse the version from uname -r + // On non-OSX Unix, we must parse the version from uname -r [Theory] - [PlatformSpecific(TestPlatforms.AnyUnix)] + [PlatformSpecific(TestPlatforms.AnyUnix & ~TestPlatforms.OSX)] [InlineData("2.6.19-1.2895.fc6", 2, 6, 19, 1)] [InlineData("xxx1yyy2zzz3aaa4bbb", 1, 2, 3, 4)] [InlineData("2147483647.2147483647.2147483647.2147483647", int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue)] @@ -154,6 +154,19 @@ public void OSVersion_ParseVersion(string input, int major, int minor, int build Assert.Equal(expected, actual); } + [Fact] + [PlatformSpecific(TestPlatforms.OSX)] + public void OSVersion_ValidVersion_OSX() + { + Version version = Environment.OSVersion.Version; + + // verify that the Environment.OSVersion.Version matches the current RID + Assert.Contains(version.ToString(2), RuntimeInformation.RuntimeIdentifier); + + Assert.True(version.Build >= 0, "OSVersion Build should be non-negative"); + Assert.Equal(-1, version.Revision); // Revision is never set on OSX + } + [Fact] public void SystemPageSize_Valid() { From 230538bb8d1a6a7039c1873fc1e69fd5bb54b024 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Mon, 11 May 2020 10:54:41 -0500 Subject: [PATCH 098/420] Improve deserialization perf for case-insensitive and missing-property cases (#35848) --- .../src/System/Text/Json/JsonEncodedText.cs | 40 +++++ ...ParameterizedConstructorConverter.Large.cs | 4 +- ...ctWithParameterizedConstructorConverter.cs | 38 +--- .../Json/Serialization/JsonClassInfo.Cache.cs | 167 +++++++++++------- .../Text/Json/Serialization/JsonClassInfo.cs | 20 ++- .../Json/Serialization/JsonParameterInfo.cs | 18 +- .../Json/Serialization/JsonPropertyInfo.cs | 42 +++-- .../JsonSerializer.Read.HandlePropertyName.cs | 44 ++--- .../Text/Json/Serialization/ParameterRef.cs | 7 +- .../Text/Json/Serialization/PropertyRef.cs | 8 +- .../Text/Json/Serialization/ReadStack.cs | 5 +- .../Json/Serialization/ReferenceHandling.cs | 12 +- .../tests/Serialization/ExtensionDataTests.cs | 12 ++ .../tests/Serialization/PropertyNameTests.cs | 92 ++++++++++ 14 files changed, 324 insertions(+), 185 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/JsonEncodedText.cs b/src/libraries/System.Text.Json/src/System/Text/Json/JsonEncodedText.cs index 2993fac38ab54..023fa4b1342af 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/JsonEncodedText.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/JsonEncodedText.cs @@ -32,6 +32,15 @@ private JsonEncodedText(byte[] utf8Value) _utf8Value = utf8Value; } + private JsonEncodedText(string stringValue, byte[] utf8Value) + { + Debug.Assert(stringValue != null); + Debug.Assert(utf8Value != null); + + _value = stringValue; + _utf8Value = utf8Value; + } + /// /// Encodes the string text value as a JSON string. /// @@ -125,6 +134,37 @@ private static JsonEncodedText EncodeHelper(ReadOnlySpan utf8Value, JavaSc } } + /// + /// Internal version that keeps the existing string and byte[] references if there is no escaping required. + /// + internal static JsonEncodedText Encode(string stringValue, byte[] utf8Value, JavaScriptEncoder? encoder = null) + { + Debug.Assert(stringValue.Equals(JsonHelpers.Utf8GetString(utf8Value))); + + if (utf8Value.Length == 0) + { + return new JsonEncodedText(stringValue, utf8Value); + } + + JsonWriterHelper.ValidateValue(utf8Value); + return EncodeHelper(stringValue, utf8Value, encoder); + } + + private static JsonEncodedText EncodeHelper(string stringValue, byte[] utf8Value, JavaScriptEncoder? encoder) + { + int idx = JsonWriterHelper.NeedsEscaping(utf8Value, encoder); + + if (idx != -1) + { + return new JsonEncodedText(GetEscapedString(utf8Value, idx, encoder)); + } + else + { + // Encoding is not necessary; use the same stringValue and utf8Value references. + return new JsonEncodedText(stringValue, utf8Value); + } + } + private static byte[] GetEscapedString(ReadOnlySpan utf8Value, int firstEscapeIndexVal, JavaScriptEncoder? encoder) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8Value.Length); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.Large.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.Large.cs index af02cc267b5d1..a89d1910c365b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.Large.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.Large.cs @@ -14,11 +14,11 @@ internal sealed class LargeObjectWithParameterizedConstructorConverter : Obje { protected override bool ReadAndCacheConstructorArgument(ref ReadStack state, ref Utf8JsonReader reader, JsonParameterInfo jsonParameterInfo) { - bool success = jsonParameterInfo.ReadJson(ref state, ref reader, out object? arg0); + bool success = jsonParameterInfo.ReadJson(ref state, ref reader, out object? arg); if (success) { - ((object[])state.Current.CtorArgumentState!.Arguments)[jsonParameterInfo.Position] = arg0!; + ((object[])state.Current.CtorArgumentState!.Arguments)[jsonParameterInfo.Position] = arg!; } return success; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs index 7842a0b8b7b3b..7977458c42162 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs @@ -454,41 +454,19 @@ private void BeginRead(ref ReadStack state, ref Utf8JsonReader reader, JsonSeria ReadOnlySpan unescapedPropertyName = JsonSerializer.GetPropertyName(ref state, ref reader, options); - if (!state.Current.JsonClassInfo.TryGetParameter(unescapedPropertyName, ref state.Current, out jsonParameterInfo)) - { - return false; - } - - Debug.Assert(jsonParameterInfo != null); + jsonParameterInfo = state.Current.JsonClassInfo.GetParameter( + unescapedPropertyName, + ref state.Current, + out byte[] utf8PropertyName); - // Increment ConstructorParameterIndex so GetProperty() starts with the next parameter the next time this function is called. + // Increment ConstructorParameterIndex so GetParameter() checks the next parameter first when called again. state.Current.CtorArgumentState!.ParameterIndex++; - // Support JsonException.Path. - Debug.Assert( - jsonParameterInfo.JsonPropertyName == null || - options.PropertyNameCaseInsensitive || - unescapedPropertyName.SequenceEqual(jsonParameterInfo.JsonPropertyName)); - - if (jsonParameterInfo.JsonPropertyName == null) - { - byte[] propertyNameArray = unescapedPropertyName.ToArray(); - if (options.PropertyNameCaseInsensitive) - { - // Each payload can have a different name here; remember the value on the temporary stack. - state.Current.JsonPropertyName = propertyNameArray; - } - else - { - //Prevent future allocs by caching globally on the JsonPropertyInfo which is specific to a Type+PropertyName - // so it will match the incoming payload except when case insensitivity is enabled(which is handled above). - jsonParameterInfo.JsonPropertyName = propertyNameArray; - } - } + // For case insensitive and missing property support of JsonPath, remember the value on the temporary stack. + state.Current.JsonPropertyName = utf8PropertyName; state.Current.CtorArgumentState.JsonParameterInfo = jsonParameterInfo; - - return true; + return jsonParameterInfo != null; } internal override bool ConstructorIsParameterized => true; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Cache.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Cache.cs index 889471432accd..e9b99527cbc9f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Cache.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Cache.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -145,21 +144,24 @@ public static JsonPropertyInfo AddProperty(PropertyInfo propertyInfo, Type paren runtimePropertyType: runtimePropertyType, propertyInfo: null, // Not a real property so this is null. parentClassType: typeof(object), // a dummy value (not used) - converter : converter, + converter: converter, options); } // AggressiveInlining used although a large method it is only called from one location and is on a hot path. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public JsonPropertyInfo GetProperty(ReadOnlySpan propertyName, ref ReadStackFrame frame) + public JsonPropertyInfo GetProperty( + ReadOnlySpan propertyName, + ref ReadStackFrame frame, + out byte[] utf8PropertyName) { - JsonPropertyInfo? info = null; + PropertyRef propertyRef; + + ulong key = GetKey(propertyName); // Keep a local copy of the cache in case it changes by another thread. PropertyRef[]? localPropertyRefsSorted = _propertyRefsSorted; - ulong key = GetKey(propertyName); - // If there is an existing cache, then use it. if (localPropertyRefsSorted != null) { @@ -174,10 +176,11 @@ public JsonPropertyInfo GetProperty(ReadOnlySpan propertyName, ref ReadSta { if (iForward < count) { - PropertyRef propertyRef = localPropertyRefsSorted[iForward]; - if (TryIsPropertyRefEqual(propertyRef, propertyName, key, ref info)) + propertyRef = localPropertyRefsSorted[iForward]; + if (IsPropertyRefEqual(propertyRef, propertyName, key)) { - return info; + utf8PropertyName = propertyRef.NameFromJson; + return propertyRef.Info; } ++iForward; @@ -185,9 +188,10 @@ public JsonPropertyInfo GetProperty(ReadOnlySpan propertyName, ref ReadSta if (iBackward >= 0) { propertyRef = localPropertyRefsSorted[iBackward]; - if (TryIsPropertyRefEqual(propertyRef, propertyName, key, ref info)) + if (IsPropertyRefEqual(propertyRef, propertyName, key)) { - return info; + utf8PropertyName = propertyRef.NameFromJson; + return propertyRef.Info; } --iBackward; @@ -195,10 +199,11 @@ public JsonPropertyInfo GetProperty(ReadOnlySpan propertyName, ref ReadSta } else if (iBackward >= 0) { - PropertyRef propertyRef = localPropertyRefsSorted[iBackward]; - if (TryIsPropertyRefEqual(propertyRef, propertyName, key, ref info)) + propertyRef = localPropertyRefsSorted[iBackward]; + if (IsPropertyRefEqual(propertyRef, propertyName, key)) { - return info; + utf8PropertyName = propertyRef.NameFromJson; + return propertyRef.Info; } --iBackward; @@ -211,24 +216,39 @@ public JsonPropertyInfo GetProperty(ReadOnlySpan propertyName, ref ReadSta } } - // No cached item was found. Try the main list which has all of the properties. - - string stringPropertyName = JsonHelpers.Utf8GetString(propertyName); - + // No cached item was found. Try the main dictionary which has all of the properties. Debug.Assert(PropertyCache != null); - if (!PropertyCache.TryGetValue(stringPropertyName, out info)) + if (PropertyCache.TryGetValue(JsonHelpers.Utf8GetString(propertyName), out JsonPropertyInfo? info)) { - info = JsonPropertyInfo.s_missingProperty; - } + if (Options.PropertyNameCaseInsensitive) + { + if (propertyName.SequenceEqual(info.NameAsUtf8Bytes)) + { + Debug.Assert(key == GetKey(info.NameAsUtf8Bytes.AsSpan())); - Debug.Assert(info != null); + // Use the existing byte[] reference instead of creating another one. + utf8PropertyName = info.NameAsUtf8Bytes!; + } + else + { + // Make a copy of the original Span. + utf8PropertyName = propertyName.ToArray(); + } + } + else + { + Debug.Assert(key == GetKey(info.NameAsUtf8Bytes!.AsSpan())); + utf8PropertyName = info.NameAsUtf8Bytes!; + } + } + else + { + info = JsonPropertyInfo.s_missingProperty; - // Three code paths to get here: - // 1) info == s_missingProperty. Property not found. - // 2) key == info.PropertyNameKey. Exact match found. - // 3) key != info.PropertyNameKey. Match found due to case insensitivity. - Debug.Assert(info == JsonPropertyInfo.s_missingProperty || key == info.PropertyNameKey || Options.PropertyNameCaseInsensitive); + // Make a copy of the original Span. + utf8PropertyName = propertyName.ToArray(); + } // Check if we should add this to the cache. // Only cache up to a threshold length and then just use the dictionary when an item is not found in the cache. @@ -255,7 +275,9 @@ public JsonPropertyInfo GetProperty(ReadOnlySpan propertyName, ref ReadSta frame.PropertyRefCache = new List(); } - PropertyRef propertyRef = new PropertyRef(key, info); + Debug.Assert(info != null); + + propertyRef = new PropertyRef(key, info, utf8PropertyName); frame.PropertyRefCache.Add(propertyRef); } } @@ -265,18 +287,18 @@ public JsonPropertyInfo GetProperty(ReadOnlySpan propertyName, ref ReadSta // AggressiveInlining used although a large method it is only called from one location and is on a hot path. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryGetParameter( + public JsonParameterInfo? GetParameter( ReadOnlySpan propertyName, ref ReadStackFrame frame, - out JsonParameterInfo? jsonParameterInfo) + out byte[] utf8PropertyName) { - JsonParameterInfo? info = null; + ParameterRef parameterRef; + + ulong key = GetKey(propertyName); // Keep a local copy of the cache in case it changes by another thread. ParameterRef[]? localParameterRefsSorted = _parameterRefsSorted; - ulong key = GetKey(propertyName); - // If there is an existing cache, then use it. if (localParameterRefsSorted != null) { @@ -291,11 +313,11 @@ public JsonPropertyInfo GetProperty(ReadOnlySpan propertyName, ref ReadSta { if (iForward < count) { - ParameterRef parameterRef = localParameterRefsSorted[iForward]; - if (TryIsParameterRefEqual(parameterRef, propertyName, key, ref info)) + parameterRef = localParameterRefsSorted[iForward]; + if (IsParameterRefEqual(parameterRef, propertyName, key)) { - jsonParameterInfo = info; - return true; + utf8PropertyName = parameterRef.NameFromJson; + return parameterRef.Info; } ++iForward; @@ -303,10 +325,10 @@ public JsonPropertyInfo GetProperty(ReadOnlySpan propertyName, ref ReadSta if (iBackward >= 0) { parameterRef = localParameterRefsSorted[iBackward]; - if (TryIsParameterRefEqual(parameterRef, propertyName, key, ref info)) + if (IsParameterRefEqual(parameterRef, propertyName, key)) { - jsonParameterInfo = info; - return true; + utf8PropertyName = parameterRef.NameFromJson; + return parameterRef.Info; } --iBackward; @@ -314,11 +336,11 @@ public JsonPropertyInfo GetProperty(ReadOnlySpan propertyName, ref ReadSta } else if (iBackward >= 0) { - ParameterRef parameterRef = localParameterRefsSorted[iBackward]; - if (TryIsParameterRefEqual(parameterRef, propertyName, key, ref info)) + parameterRef = localParameterRefsSorted[iBackward]; + if (IsParameterRefEqual(parameterRef, propertyName, key)) { - jsonParameterInfo = info; - return true; + utf8PropertyName = parameterRef.NameFromJson; + return parameterRef.Info; } --iBackward; @@ -331,26 +353,39 @@ public JsonPropertyInfo GetProperty(ReadOnlySpan propertyName, ref ReadSta } } - string propertyNameAsString = JsonHelpers.Utf8GetString(propertyName); - + // No cached item was found. Try the main dictionary which has all of the parameters. Debug.Assert(ParameterCache != null); - if (!ParameterCache.TryGetValue(propertyNameAsString, out info)) + if (ParameterCache.TryGetValue(JsonHelpers.Utf8GetString(propertyName), out JsonParameterInfo? info)) { - // Constructor parameter not found. We'll check if it's a property next. - jsonParameterInfo = null; - return false; - } + if (Options.PropertyNameCaseInsensitive) + { + if (propertyName.SequenceEqual(info.NameAsUtf8Bytes)) + { + Debug.Assert(key == GetKey(info.NameAsUtf8Bytes.AsSpan())); - jsonParameterInfo = info; - Debug.Assert(info != null); + // Use the existing byte[] reference instead of creating another one. + utf8PropertyName = info.NameAsUtf8Bytes!; + } + else + { + // Make a copy of the original Span. + utf8PropertyName = propertyName.ToArray(); + } + } + else + { + Debug.Assert(key == GetKey(info.NameAsUtf8Bytes!.AsSpan())); + utf8PropertyName = info.NameAsUtf8Bytes!; + } + } + else + { + Debug.Assert(info == null); - // Two code paths to get here: - // 1) key == info.PropertyNameKey. Exact match found. - // 2) key != info.PropertyNameKey. Match found due to case insensitivity. - // TODO: recheck these conditions - Debug.Assert(key == info.ParameterNameKey || - propertyNameAsString.Equals(info.NameAsString, StringComparison.OrdinalIgnoreCase)); + // Make a copy of the original Span. + utf8PropertyName = propertyName.ToArray(); + } // Check if we should add this to the cache. // Only cache up to a threshold length and then just use the dictionary when an item is not found in the cache. @@ -377,24 +412,23 @@ public JsonPropertyInfo GetProperty(ReadOnlySpan propertyName, ref ReadSta frame.CtorArgumentState.ParameterRefCache = new List(); } - ParameterRef parameterRef = new ParameterRef(key, jsonParameterInfo); + parameterRef = new ParameterRef(key, info!, utf8PropertyName); frame.CtorArgumentState.ParameterRefCache.Add(parameterRef); } } - return true; + return info; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryIsPropertyRefEqual(in PropertyRef propertyRef, ReadOnlySpan propertyName, ulong key, [NotNullWhen(true)] ref JsonPropertyInfo? info) + private static bool IsPropertyRefEqual(in PropertyRef propertyRef, ReadOnlySpan propertyName, ulong key) { if (key == propertyRef.Key) { // We compare the whole name, although we could skip the first 7 bytes (but it's not any faster) if (propertyName.Length <= PropertyNameKeyLength || - propertyName.SequenceEqual(propertyRef.Info.Name)) + propertyName.SequenceEqual(propertyRef.NameFromJson)) { - info = propertyRef.Info; return true; } } @@ -403,15 +437,14 @@ private static bool TryIsPropertyRefEqual(in PropertyRef propertyRef, ReadOnlySp } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryIsParameterRefEqual(in ParameterRef parameterRef, ReadOnlySpan parameterName, ulong key, [NotNullWhen(true)] ref JsonParameterInfo? info) + private static bool IsParameterRefEqual(in ParameterRef parameterRef, ReadOnlySpan parameterName, ulong key) { if (key == parameterRef.Key) { // We compare the whole name, although we could skip the first 7 bytes (but it's not any faster) if (parameterName.Length <= PropertyNameKeyLength || - parameterName.SequenceEqual(parameterRef.Info.ParameterName)) + parameterName.SequenceEqual(parameterRef.NameFromJson)) { - info = parameterRef.Info; return true; } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs index ddb731c24c91d..f0adf7412981f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs @@ -168,15 +168,23 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) cacheArray = new JsonPropertyInfo[cache.Count]; } - // Set fields when finished to avoid concurrency issues. - PropertyCache = cache; + // Copy the dictionary cache to the array cache. cache.Values.CopyTo(cacheArray, 0); + + // Set the array cache field at this point since it is completely initialized. + // It can now be safely accessed by other threads. PropertyCacheArray = cacheArray; + // Allow constructor parameter logic to remove items from the dictionary since the JSON + // property values will be passed to the constructor and do not call a property setter. if (converter.ConstructorIsParameterized) { - InitializeConstructorParameters(converter.ConstructorInfo!); + InitializeConstructorParameters(cache, converter.ConstructorInfo!); } + + // Set the dictionary cache field at this point since it is completely initialized. + // It can now be safely accessed by other threads. + PropertyCache = cache; } break; case ClassType.Enumerable: @@ -210,13 +218,11 @@ private static bool IsNonPublicProperty(PropertyInfo propertyInfo) return !((getMethod != null && getMethod.IsPublic) || (setMethod != null && setMethod.IsPublic)); } - private void InitializeConstructorParameters(ConstructorInfo constructorInfo) + private void InitializeConstructorParameters(Dictionary propertyCache, ConstructorInfo constructorInfo) { ParameterInfo[] parameters = constructorInfo!.GetParameters(); Dictionary parameterCache = CreateParameterCache(parameters.Length, Options); - Dictionary propertyCache = PropertyCache!; - foreach (ParameterInfo parameterInfo in parameters) { PropertyInfo? firstMatch = null; @@ -251,7 +257,7 @@ private void InitializeConstructorParameters(ConstructorInfo constructorInfo) // One object property cannot map to multiple constructor // parameters (ConvertName above can't return multiple strings). - parameterCache.Add(jsonParameterInfo.NameAsString, jsonParameterInfo); + parameterCache.Add(jsonPropertyInfo.NameAsString!, jsonParameterInfo); // Remove property from deserialization cache to reduce the number of JsonPropertyInfos considered during JSON matching. propertyCache.Remove(jsonPropertyInfo.NameAsString!); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfo.cs index d531d9f9c2d27..f2d8408205d31 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfo.cs @@ -22,22 +22,13 @@ internal abstract class JsonParameterInfo // The default value of the parameter. This is `DefaultValue` of the `ParameterInfo`, if specified, or the CLR `default` for the `ParameterType`. public object? DefaultValue { get; protected set; } - // The name from a Json value. This is cached for performance on first deserialize. - public byte[]? JsonPropertyName { get; set; } - // Options can be referenced here since all JsonPropertyInfos originate from a JsonClassInfo that is cached on JsonSerializerOptions. protected JsonSerializerOptions Options { get; set; } = null!; // initialized in Init method public ParameterInfo ParameterInfo { get; private set; } = null!; // The name of the parameter as UTF-8 bytes. - public byte[] ParameterName { get; private set; } = null!; - - // The name of the parameter. - public string NameAsString { get; private set; } = null!; - - // Key for fast property name lookup. - public ulong ParameterNameKey { get; private set; } + public byte[] NameAsUtf8Bytes { get; private set; } = null!; // The zero-based position of the parameter in the formal parameter list. public int Position { get; private set; } @@ -77,12 +68,7 @@ public JsonClassInfo RuntimeClassInfo private void DetermineParameterName(JsonPropertyInfo matchingProperty) { - NameAsString = matchingProperty.NameAsString!; - - // `NameAsString` is valid UTF16, so just call the simple UTF16->UTF8 encoder. - ParameterName = Encoding.UTF8.GetBytes(NameAsString); - - ParameterNameKey = JsonClassInfo.GetKey(ParameterName); + NameAsUtf8Bytes = matchingProperty.NameAsUtf8Bytes!; } // Create a parameter that is ignored at run-time. It uses the same type (typeof(sbyte)) to help diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs index 5c43c5d8bfb0f..81455209d2b11 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs @@ -83,13 +83,10 @@ private void DeterminePropertyName() Debug.Assert(NameAsString != null); // At this point propertyName is valid UTF16, so just call the simple UTF16->UTF8 encoder. - Name = Encoding.UTF8.GetBytes(NameAsString); + NameAsUtf8Bytes = Encoding.UTF8.GetBytes(NameAsString); // Cache the escaped property name. - EscapedName = JsonEncodedText.Encode(Name, Options.Encoder); - - ulong key = JsonClassInfo.GetKey(Name); - PropertyNameKey = key; + EscapedName = JsonEncodedText.Encode(NameAsString, NameAsUtf8Bytes, Options.Encoder); } private void DetermineSerializationCapabilities(JsonIgnoreCondition? ignoreCondition) @@ -145,10 +142,6 @@ private void DetermineIgnoreCondition(JsonIgnoreCondition? ignoreCondition) } } - // The escaped name passed to the writer. - // Use a field here (not a property) to avoid value semantics. - public JsonEncodedText? EscapedName; - public static TAttribute? GetAttribute(PropertyInfo propertyInfo) where TAttribute : Attribute { return (TAttribute?)propertyInfo.GetCustomAttribute(typeof(TAttribute), inherit: false); @@ -194,15 +187,32 @@ public virtual void GetPolicies(JsonIgnoreCondition? ignoreCondition) public bool IsPropertyPolicy { get; protected set; } - // The name from a Json value. This is cached for performance on first deserialize. - public byte[]? JsonPropertyName { get; set; } - - // The name of the property with any casing policy or the name specified from JsonPropertyNameAttribute. - public byte[]? Name { get; private set; } + // There are 3 copies of the property name: + // 1) NameAsString. The unescaped property name. + // 2) NameAsUtf8Bytes. The Utf8 version of NameAsString. Used during during deserialization for property lookup. + // 3) EscapedName. The escaped verson of NameAsString and NameAsUtf8Bytes written during serialization. Internally shares + // the same instances of NameAsString and NameAsUtf8Bytes if there is no escaping. + + /// + /// The unescaped name of the property. + /// Is either the actual CLR property name, + /// the value specified in JsonPropertyNameAttribute, + /// or the value returned from PropertyNamingPolicy(clrPropertyName). + /// public string? NameAsString { get; private set; } - // Key for fast property name lookup. - public ulong PropertyNameKey { get; set; } + /// + /// Utf8 version of NameAsString. + /// + public byte[]? NameAsUtf8Bytes { get; private set; } + + /// + /// The escaped name passed to the writer. + /// + /// + /// JsonEncodedText is a value type so a field is used (not a property) to avoid unnecessary copies. + /// + public JsonEncodedText? EscapedName; // Options can be referenced here since all JsonPropertyInfos originate from a JsonClassInfo that is cached on JsonSerializerOptions. protected JsonSerializerOptions Options { get; set; } = null!; // initialized in Init method diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs index a59a14fd63489..6996f76561930 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs @@ -27,13 +27,21 @@ public static partial class JsonSerializer { Debug.Assert(state.Current.JsonClassInfo.ClassType == ClassType.Object); + useExtensionProperty = false; + ReadOnlySpan unescapedPropertyName = GetPropertyName(ref state, ref reader, options); - JsonPropertyInfo jsonPropertyInfo = state.Current.JsonClassInfo.GetProperty(unescapedPropertyName, ref state.Current); + JsonPropertyInfo jsonPropertyInfo = state.Current.JsonClassInfo.GetProperty( + unescapedPropertyName, + ref state.Current, + out byte[] utf8PropertyName); - // Increment PropertyIndex so GetProperty() starts with the next property the next time this function is called. + // Increment PropertyIndex so GetProperty() checks the next property first when called again. state.Current.PropertyIndex++; + // For case insensitive and missing property support of JsonPath, remember the value on the temporary stack. + state.Current.JsonPropertyName = utf8PropertyName; + // Determine if we should use the extension property. if (jsonPropertyInfo == JsonPropertyInfo.s_missingProperty) { @@ -50,41 +58,9 @@ public static partial class JsonSerializer jsonPropertyInfo = dataExtProperty; useExtensionProperty = true; } - else - { - useExtensionProperty = false; - } - - state.Current.JsonPropertyInfo = jsonPropertyInfo; - return jsonPropertyInfo; } - // Support JsonException.Path. - Debug.Assert( - jsonPropertyInfo.JsonPropertyName == null || - options.PropertyNameCaseInsensitive || - unescapedPropertyName.SequenceEqual(jsonPropertyInfo.JsonPropertyName)); - state.Current.JsonPropertyInfo = jsonPropertyInfo; - - if (jsonPropertyInfo.JsonPropertyName == null) - { - byte[] propertyNameArray = unescapedPropertyName.ToArray(); - if (options.PropertyNameCaseInsensitive) - { - // Each payload can have a different name here; remember the value on the temporary stack. - state.Current.JsonPropertyName = propertyNameArray; - } - else - { - // Prevent future allocs by caching globally on the JsonPropertyInfo which is specific to a Type+PropertyName - // so it will match the incoming payload except when case insensitivity is enabled (which is handled above). - state.Current.JsonPropertyInfo.JsonPropertyName = propertyNameArray; - } - } - - state.Current.JsonPropertyInfo = jsonPropertyInfo; - useExtensionProperty = false; return jsonPropertyInfo; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ParameterRef.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ParameterRef.cs index 9f2c654b5a913..f0ee05b6436ae 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ParameterRef.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ParameterRef.cs @@ -6,15 +6,18 @@ namespace System.Text.Json { internal readonly struct ParameterRef { - public ParameterRef(ulong key, JsonParameterInfo info) + public ParameterRef(ulong key, JsonParameterInfo info, byte[] nameFromJson) { Key = key; Info = info; + NameFromJson = nameFromJson; } - // The first 6 bytes are the first part of the name and last 2 bytes are the name's length. public readonly ulong Key; public readonly JsonParameterInfo Info; + + // NameFromJson may be different than Info.NameAsUtf8Bytes when case insensitive is enabled. + public readonly byte[] NameFromJson; } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/PropertyRef.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/PropertyRef.cs index 41dbbe5e411e2..e092a7cfe5cdd 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/PropertyRef.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/PropertyRef.cs @@ -6,15 +6,17 @@ namespace System.Text.Json { internal readonly struct PropertyRef { - public PropertyRef(ulong key, JsonPropertyInfo info) + public PropertyRef(ulong key, JsonPropertyInfo info, byte[] nameFromJson) { Key = key; Info = info; + NameFromJson = nameFromJson; } - // The first 6 bytes are the first part of the name and last 2 bytes are the name's length. public readonly ulong Key; - public readonly JsonPropertyInfo Info; + + // NameFromJson may be different than Info.NameAsUtf8Bytes when case insensitive is enabled. + public readonly byte[] NameFromJson; } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs index 3a9e0dddf145d..7e7f497a536cb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs @@ -298,8 +298,9 @@ static void AppendPropertyName(StringBuilder sb, string? propertyName) if (utf8PropertyName == null) { // Attempt to get the JSON property name from the JsonPropertyInfo or JsonParameterInfo. - utf8PropertyName = frame.JsonPropertyInfo?.JsonPropertyName ?? - frame.CtorArgumentState?.JsonParameterInfo?.JsonPropertyName; + utf8PropertyName = frame.JsonPropertyInfo?.NameAsUtf8Bytes ?? + frame.CtorArgumentState?.JsonParameterInfo?.NameAsUtf8Bytes; + if (utf8PropertyName == null) { // Attempt to get the JSON property name set manually for dictionary diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReferenceHandling.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReferenceHandling.cs index 2928b0f275814..269e0cb84b1bb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReferenceHandling.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReferenceHandling.cs @@ -53,8 +53,8 @@ public sealed class ReferenceHandling /// public static ReferenceHandling Preserve { get; } = new ReferenceHandling(PreserveReferencesHandling.All); - private readonly PreserveReferencesHandling _preserveHandlingOnSerialize; - private readonly PreserveReferencesHandling _preserveHandlingOnDeserialize; + private readonly bool _shouldReadPreservedReferences; + private readonly bool _shouldWritePreservedReferences; /// /// Creates a new instance of using the specified @@ -65,18 +65,18 @@ public sealed class ReferenceHandling // For future, someone may want to define their own custom Handler with different behaviors of PreserveReferenceHandling on Serialize vs Deserialize. private ReferenceHandling(PreserveReferencesHandling preserveHandlingOnSerialize, PreserveReferencesHandling preserveHandlingOnDeserialize) { - _preserveHandlingOnSerialize = preserveHandlingOnSerialize; - _preserveHandlingOnDeserialize = preserveHandlingOnDeserialize; + _shouldReadPreservedReferences = preserveHandlingOnDeserialize == PreserveReferencesHandling.All; + _shouldWritePreservedReferences = preserveHandlingOnSerialize == PreserveReferencesHandling.All; } internal bool ShouldReadPreservedReferences() { - return _preserveHandlingOnDeserialize == PreserveReferencesHandling.All; + return _shouldReadPreservedReferences; } internal bool ShouldWritePreservedReferences() { - return _preserveHandlingOnSerialize == PreserveReferencesHandling.All; + return _shouldWritePreservedReferences; } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/ExtensionDataTests.cs b/src/libraries/System.Text.Json/tests/Serialization/ExtensionDataTests.cs index b0e27027971c8..1e0b46b7e1b7e 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ExtensionDataTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ExtensionDataTests.cs @@ -99,6 +99,18 @@ public static void MultipleExtensionPropertyIgnoredWhenNull() Assert.Equal("{\"ActualDictionary\":{},\"test\":\"value\"}", actual); } + [Fact] + public static void ExtensionPropertyInvalidJsonFail() + { + const string BadJson = @"{""Good"":""OK"",""Bad"":!}"; + + JsonException jsonException = Assert.Throws(() => JsonSerializer.Deserialize(BadJson)); + Assert.Contains("Path: $.Bad | LineNumber: 0 | BytePositionInLine: 19.", jsonException.ToString()); + Assert.NotNull(jsonException.InnerException); + Assert.IsAssignableFrom(jsonException.InnerException); + Assert.Contains("!", jsonException.InnerException.ToString()); + } + [Fact] public static void ExtensionPropertyAlreadyInstantiated() { diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyNameTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyNameTests.cs index a13f36661798b..1b0ff3e70ae12 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyNameTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyNameTests.cs @@ -231,6 +231,89 @@ public static void EmptyPropertyName() } } + [Fact] + public static void EmptyPropertyNameInExtensionData() + { + { + string json = @"{"""":42}"; + EmptyClassWithExtensionProperty obj = JsonSerializer.Deserialize(json); + Assert.Equal(1, obj.MyOverflow.Count); + Assert.Equal(42, obj.MyOverflow[""].GetInt32()); + } + + { + // Verify that last-in wins. + string json = @"{"""":42, """":43}"; + EmptyClassWithExtensionProperty obj = JsonSerializer.Deserialize(json); + Assert.Equal(1, obj.MyOverflow.Count); + Assert.Equal(43, obj.MyOverflow[""].GetInt32()); + } + } + + [Fact] + public static void EmptyPropertyName_WinsOver_ExtensionDataEmptyPropertyName() + { + string json = @"{"""":1}"; + + ClassWithEmptyPropertyNameAndExtensionProperty obj; + + // Create a new options instances to re-set any caches. + JsonSerializerOptions options = new JsonSerializerOptions(); + + // Verify the real property wins over the extension data property. + obj = JsonSerializer.Deserialize(json, options); + Assert.Equal(1, obj.MyInt1); + Assert.Null(obj.MyOverflow); + } + + [Fact] + public static void EmptyPropertyNameAndExtensionData_ExtDataFirst() + { + // Verify any caching treats real property (with empty name) differently than a missing property. + + ClassWithEmptyPropertyNameAndExtensionProperty obj; + + // Create a new options instances to re-set any caches. + JsonSerializerOptions options = new JsonSerializerOptions(); + + // First populate cache with a missing property name. + string json = @"{""DoesNotExist"":42}"; + obj = JsonSerializer.Deserialize(json, options); + Assert.Equal(0, obj.MyInt1); + Assert.Equal(1, obj.MyOverflow.Count); + Assert.Equal(42, obj.MyOverflow["DoesNotExist"].GetInt32()); + + // Then use an empty property. + json = @"{"""":43}"; + obj = JsonSerializer.Deserialize(json, options); + Assert.Equal(43, obj.MyInt1); + Assert.Null(obj.MyOverflow); + } + + [Fact] + public static void EmptyPropertyAndExtensionData_PropertyFirst() + { + // Verify any caching treats real property (with empty name) differently than a missing property. + + ClassWithEmptyPropertyNameAndExtensionProperty obj; + + // Create a new options instances to re-set any caches. + JsonSerializerOptions options = new JsonSerializerOptions(); + + // First use an empty property. + string json = @"{"""":43}"; + obj = JsonSerializer.Deserialize(json, options); + Assert.Equal(43, obj.MyInt1); + Assert.Null(obj.MyOverflow); + + // Then populate cache with a missing property name. + json = @"{""DoesNotExist"":42}"; + obj = JsonSerializer.Deserialize(json, options); + Assert.Equal(0, obj.MyInt1); + Assert.Equal(1, obj.MyOverflow.Count); + Assert.Equal(42, obj.MyOverflow["DoesNotExist"].GetInt32()); + } + [Fact] public static void UnicodePropertyNames() { @@ -515,4 +598,13 @@ public class EmptyClassWithExtensionProperty [JsonExtensionData] public IDictionary MyOverflow { get; set; } } + + public class ClassWithEmptyPropertyNameAndExtensionProperty + { + [JsonPropertyName("")] + public int MyInt1 { get; set; } + + [JsonExtensionData] + public IDictionary MyOverflow { get; set; } + } } From 19a0db47c8796d4e689d4fe8a698d74066cb7d05 Mon Sep 17 00:00:00 2001 From: Omair Majid Date: Mon, 11 May 2020 11:58:20 -0400 Subject: [PATCH 099/420] Add some upcoming distro RIDs This adds some RIDs that we know are current/upcoming: - Fedora 33 is in development, and the version after this is most likely going to be Fedora 34. Adding this RID now, so we can get this RID in all current releases when it comes time to build on Fedora 34 - RHEL has generally committed to doing a major release every 3 years. With RHEL 8 released in 2019, RHEL 9 is under development. There's even a plan on how to create that from Fedora here: https://fedoraproject.org/wiki/Changes/ELN_Buildroot_and_Compose - If there's a RHEL 9, there will most likely be an equivalent CentOS 9. Lets add that too. - CentOS 7 has an aarch64 port. As does CentOS 8. --- .../runtime.compatibility.json | 134 ++++++++++++++++++ .../Microsoft.NETCore.Platforms/runtime.json | 67 +++++++++ .../runtimeGroups.props | 16 ++- 3 files changed, 215 insertions(+), 2 deletions(-) diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json index ecadced6e121d..79a50fab018df 100644 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json +++ b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json @@ -1125,6 +1125,18 @@ "any", "base" ], + "centos-arm64": [ + "centos-arm64", + "centos", + "rhel-arm64", + "rhel", + "linux-arm64", + "linux", + "unix-arm64", + "unix", + "any", + "base" + ], "centos-x64": [ "centos-x64", "centos", @@ -1173,6 +1185,22 @@ "any", "base" ], + "centos.8-arm64": [ + "centos.8-arm64", + "centos.8", + "centos-arm64", + "rhel.8-arm64", + "centos", + "rhel.8", + "rhel-arm64", + "rhel", + "linux-arm64", + "linux", + "unix-arm64", + "unix", + "any", + "base" + ], "centos.8-x64": [ "centos.8-x64", "centos.8", @@ -1189,6 +1217,48 @@ "any", "base" ], + "centos.9": [ + "centos.9", + "centos", + "rhel.9", + "rhel", + "linux", + "unix", + "any", + "base" + ], + "centos.9-arm64": [ + "centos.9-arm64", + "centos.9", + "centos-arm64", + "rhel.9-arm64", + "centos", + "rhel.9", + "rhel-arm64", + "rhel", + "linux-arm64", + "linux", + "unix-arm64", + "unix", + "any", + "base" + ], + "centos.9-x64": [ + "centos.9-x64", + "centos.9", + "centos-x64", + "rhel.9-x64", + "centos", + "rhel.9", + "rhel-x64", + "rhel", + "linux-x64", + "linux", + "unix-x64", + "unix", + "any", + "base" + ], "debian": [ "debian", "linux", @@ -1829,6 +1899,38 @@ "any", "base" ], + "fedora.34": [ + "fedora.34", + "fedora", + "linux", + "unix", + "any", + "base" + ], + "fedora.34-arm64": [ + "fedora.34-arm64", + "fedora.34", + "fedora-arm64", + "fedora", + "linux-arm64", + "linux", + "unix-arm64", + "unix", + "any", + "base" + ], + "fedora.34-x64": [ + "fedora.34-x64", + "fedora.34", + "fedora-x64", + "fedora", + "linux-x64", + "linux", + "unix-x64", + "unix", + "any", + "base" + ], "freebsd": [ "freebsd", "unix", @@ -3811,6 +3913,38 @@ "any", "base" ], + "rhel.9": [ + "rhel.9", + "rhel", + "linux", + "unix", + "any", + "base" + ], + "rhel.9-arm64": [ + "rhel.9-arm64", + "rhel.9", + "rhel-arm64", + "rhel", + "linux-arm64", + "linux", + "unix-arm64", + "unix", + "any", + "base" + ], + "rhel.9-x64": [ + "rhel.9-x64", + "rhel.9", + "rhel-x64", + "rhel", + "linux-x64", + "linux", + "unix-x64", + "unix", + "any", + "base" + ], "sles": [ "sles", "linux", diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json index 02151ad0b20c6..dd502f4ca3138 100644 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json +++ b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json @@ -406,6 +406,12 @@ "rhel" ] }, + "centos-arm64": { + "#import": [ + "centos", + "rhel-arm64" + ] + }, "centos-x64": { "#import": [ "centos", @@ -431,6 +437,13 @@ "rhel.8" ] }, + "centos.8-arm64": { + "#import": [ + "centos.8", + "centos-arm64", + "rhel.8-arm64" + ] + }, "centos.8-x64": { "#import": [ "centos.8", @@ -438,6 +451,26 @@ "rhel.8-x64" ] }, + "centos.9": { + "#import": [ + "centos", + "rhel.9" + ] + }, + "centos.9-arm64": { + "#import": [ + "centos.9", + "centos-arm64", + "rhel.9-arm64" + ] + }, + "centos.9-x64": { + "#import": [ + "centos.9", + "centos-x64", + "rhel.9-x64" + ] + }, "debian": { "#import": [ "linux" @@ -782,6 +815,23 @@ "fedora-x64" ] }, + "fedora.34": { + "#import": [ + "fedora" + ] + }, + "fedora.34-arm64": { + "#import": [ + "fedora.34", + "fedora-arm64" + ] + }, + "fedora.34-x64": { + "#import": [ + "fedora.34", + "fedora-x64" + ] + }, "freebsd": { "#import": [ "unix" @@ -1633,6 +1683,23 @@ "rhel.8.0-x64" ] }, + "rhel.9": { + "#import": [ + "rhel" + ] + }, + "rhel.9-arm64": { + "#import": [ + "rhel.9", + "rhel-arm64" + ] + }, + "rhel.9-x64": { + "#import": [ + "rhel.9", + "rhel-x64" + ] + }, "sles": { "#import": [ "linux" diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props index fd339ac8c0df7..cd8358675fc13 100644 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props +++ b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props @@ -38,7 +38,14 @@ rhel x64 - 7;8 + 7 + true + false + + + rhel + x64;arm64 + 8;9 true false @@ -53,7 +60,7 @@ linux x64;arm64 - 23;24;25;26;27;28;29;30;31;32;33 + 23;24;25;26;27;28;29;30;31;32;33;34 false @@ -140,6 +147,11 @@ x64;arm64 8;8.0;8.1 + + linux + x64;arm64 + 9 + linux From fa80f3866eba7971897f476703079dd7d6f7d675 Mon Sep 17 00:00:00 2001 From: Manish Godse <61718172+mangod9@users.noreply.github.com> Date: Mon, 11 May 2020 10:24:37 -0700 Subject: [PATCH 100/420] Preempt Watson exception handling (#36179) * switch to preemp GC before DW version lookup * move preempt to PopulateBucketParameters * Adding GC_TRIGGERS to callchain of CaptureUnhandledInfoForWatson * explictly adding PREEMPTIVE to all DwGetFileVersionInfo codepaths. --- src/coreclr/src/vm/dwbucketmanager.hpp | 33 ++++++++++++++------------ src/coreclr/src/vm/dwreport.cpp | 8 +++---- src/coreclr/src/vm/excep.cpp | 6 ++--- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/coreclr/src/vm/dwbucketmanager.hpp b/src/coreclr/src/vm/dwbucketmanager.hpp index 535adb3eb5d75..eb7beac884d2f 100644 --- a/src/coreclr/src/vm/dwbucketmanager.hpp +++ b/src/coreclr/src/vm/dwbucketmanager.hpp @@ -431,7 +431,7 @@ void BaseBucketParamsManager::PopulateBucketParameter(BucketParameterIndex param CONTRACTL { NOTHROW; - GC_NOTRIGGER; + GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; @@ -452,7 +452,7 @@ void BaseBucketParamsManager::GetAppName(__out_ecount(maxLength) WCHAR* targetPa { NOTHROW; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -475,8 +475,8 @@ void BaseBucketParamsManager::GetAppVersion(__out_ecount(maxLength) WCHAR* targe CONTRACTL { NOTHROW; - GC_NOTRIGGER; - MODE_ANY; + GC_TRIGGERS; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -511,7 +511,7 @@ void BaseBucketParamsManager::GetAppTimeStamp(__out_ecount(maxLength) WCHAR* tar { NOTHROW; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -543,7 +543,7 @@ void BaseBucketParamsManager::GetModuleName(__out_ecount(maxLength) WCHAR* targe { NOTHROW; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -632,8 +632,8 @@ void BaseBucketParamsManager::GetModuleVersion(__out_ecount(maxLength) WCHAR* ta CONTRACTL { NOTHROW; - GC_NOTRIGGER; - MODE_ANY; + GC_TRIGGERS; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -689,7 +689,7 @@ void BaseBucketParamsManager::GetModuleTimeStamp(__out_ecount(maxLength) WCHAR* { NOTHROW; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -742,7 +742,7 @@ void BaseBucketParamsManager::GetMethodDef(__out_ecount(maxLength) WCHAR* target { NOTHROW; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -767,7 +767,7 @@ void BaseBucketParamsManager::GetIlOffset(__out_ecount(maxLength) WCHAR* targetP { NOTHROW; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -786,7 +786,7 @@ void BaseBucketParamsManager::GetExceptionName(__out_ecount(maxLength) WCHAR* ta { NOTHROW; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -954,8 +954,8 @@ bool BaseBucketParamsManager::GetFileVersionInfoForModule(Module* pModule, USHOR CONTRACTL { NOTHROW; - GC_NOTRIGGER; - MODE_ANY; + GC_TRIGGERS; + MODE_PREEMPTIVE; PRECONDITION(pModule != NULL); } CONTRACTL_END; @@ -1215,11 +1215,14 @@ void CLR20r3BucketParamsManager::PopulateBucketParameters() CONTRACTL { NOTHROW; - GC_NOTRIGGER; + GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; + // Preempt to let GC suspend + GCX_PREEMP(); + PopulateEventName(g_WerEventTraits[CLR20r3].EventName); // the "+ 1" is to explicitly indicate which fields need to specify space for NULL diff --git a/src/coreclr/src/vm/dwreport.cpp b/src/coreclr/src/vm/dwreport.cpp index 4cc5950f7fc9a..0b9a2c9438293 100644 --- a/src/coreclr/src/vm/dwreport.cpp +++ b/src/coreclr/src/vm/dwreport.cpp @@ -189,8 +189,8 @@ HRESULT DwGetFileVersionInfo( CONTRACTL { NOTHROW; - GC_NOTRIGGER; - MODE_ANY; + GC_TRIGGERS; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -602,7 +602,7 @@ HRESULT GetManagedBucketParametersForIp( CONTRACTL { NOTHROW; - GC_NOTRIGGER; + GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; @@ -677,7 +677,7 @@ void* GetBucketParametersForManagedException(UINT_PTR ip, TypeOfReportedError to CONTRACTL { NOTHROW; - GC_NOTRIGGER; + GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; diff --git a/src/coreclr/src/vm/excep.cpp b/src/coreclr/src/vm/excep.cpp index 657717d6b3ada..ff2e67489c801 100644 --- a/src/coreclr/src/vm/excep.cpp +++ b/src/coreclr/src/vm/excep.cpp @@ -8916,7 +8916,7 @@ BOOL SetupWatsonBucketsForEscapingPreallocatedExceptions() CONTRACTL { - GC_NOTRIGGER; + GC_TRIGGERS; MODE_ANY; NOTHROW; PRECONDITION(GetThread() != NULL); @@ -9336,7 +9336,7 @@ PTR_EHWatsonBucketTracker GetWatsonBucketTrackerForPreallocatedException(OBJECTR #ifndef DACCESS_COMPILE CONTRACTL { - GC_NOTRIGGER; + GC_TRIGGERS; MODE_COOPERATIVE; NOTHROW; PRECONDITION(GetThread() != NULL); @@ -10877,7 +10877,7 @@ void EHWatsonBucketTracker::CaptureUnhandledInfoForWatson(TypeOfReportedError to CONTRACTL { NOTHROW; - GC_NOTRIGGER; + GC_TRIGGERS; MODE_ANY; PRECONDITION(IsWatsonEnabled()); } From 35eb262309e67c2595674afd1117f15c2aa22327 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Mon, 11 May 2020 10:29:17 -0700 Subject: [PATCH 101/420] Revert "Revert "Remove superflous CheckReleased call which will slow down Event Log Reading up to 20x times. (#35911)" (#36143)" (#36188) This reverts commit ca8c9dea8e30a9701160e4cd61b5b26f209499ff. --- .../Diagnostics/Reader/ProviderMetadataCachedInformation.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/ProviderMetadataCachedInformation.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/ProviderMetadataCachedInformation.cs index 8e49408433bea..9b02652d60526 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/ProviderMetadataCachedInformation.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/ProviderMetadataCachedInformation.cs @@ -156,7 +156,6 @@ private ProviderMetadata GetProviderMetadata(ProviderMetadataId key) try { - pm.CheckReleased(); UpdateCacheValueInfoForHit(cacheItem); } catch (EventLogException) From 97cc9e923bb2a11ed00220643c1afdbd67173022 Mon Sep 17 00:00:00 2001 From: ts2do Date: Mon, 11 May 2020 12:32:59 -0500 Subject: [PATCH 102/420] Add invalidation to DTFI's SetAllDateTimePatterns (#34438) Invalidate derived patterns to match the behavior of invoking the corresponding property setters --- .../Globalization/DateTimeFormatInfo.cs | 87 ++++++++++++------- 1 file changed, 57 insertions(+), 30 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs index 722c583920963..3766ba48be991 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs @@ -732,14 +732,19 @@ public string LongDatePattern // Remember the new string longDatePattern = value; - // Clear the token hash table - ClearTokenHashTable(); - - // Clean up cached values that will be affected by this property. - fullDateTimePattern = null; + OnLongDatePatternChanged(); } } + private void OnLongDatePatternChanged() + { + // Clear the token hash table + ClearTokenHashTable(); + + // Clean up cached values that will be affected by this property. + fullDateTimePattern = null; + } + /// /// For our "patterns" arrays we have 2 variables, a string and a string[] /// @@ -764,16 +769,21 @@ public string LongTimePattern // Remember the new string longTimePattern = value; - // Clear the token hash table - ClearTokenHashTable(); - - // Clean up cached values that will be affected by this property. - fullDateTimePattern = null; // Full date = long date + long Time - generalLongTimePattern = null; // General long date = short date + long Time - dateTimeOffsetPattern = null; + OnLongTimePatternChanged(); } } + private void OnLongTimePatternChanged() + { + // Clear the token hash table + ClearTokenHashTable(); + + // Clean up cached values that will be affected by this property. + fullDateTimePattern = null; // Full date = long date + long Time + generalLongTimePattern = null; // General long date = short date + long Time + dateTimeOffsetPattern = null; + } + /// /// Just to be confusing there's only 1 month day pattern, not a whole list /// @@ -862,16 +872,21 @@ public string ShortDatePattern // Remember the new string shortDatePattern = value; - // Clear the token hash table, note that even short dates could require this - ClearTokenHashTable(); - - // Clean up cached values that will be affected by this property. - generalLongTimePattern = null; // General long time = short date + long time - generalShortTimePattern = null; // General short time = short date + short Time - dateTimeOffsetPattern = null; + OnShortDatePatternChanged(); } } + private void OnShortDatePatternChanged() + { + // Clear the token hash table, note that even short dates could require this + ClearTokenHashTable(); + + // Clean up cached values that will be affected by this property. + generalLongTimePattern = null; // General long time = short date + long time + generalShortTimePattern = null; // General short time = short date + short Time + dateTimeOffsetPattern = null; + } + /// /// For our "patterns" arrays we have 2 variables, a string and a string[] /// @@ -896,14 +911,19 @@ public string ShortTimePattern // Remember the new string shortTimePattern = value; - // Clear the token hash table, note that even short times could require this - ClearTokenHashTable(); - - // Clean up cached values that will be affected by this property. - generalShortTimePattern = null; // General short date = short date + short time. + OnShortTimePatternChanged(); } } + private void OnShortTimePatternChanged() + { + // Clear the token hash table, note that even short times could require this + ClearTokenHashTable(); + + // Clean up cached values that will be affected by this property. + generalShortTimePattern = null; // General short date = short date + short time. + } + public string SortableDateTimePattern => sortableDateTimePattern; /// @@ -1036,11 +1056,16 @@ public string YearMonthPattern // Remember the new string yearMonthPattern = value; - // Clear the token hash table, note that even short times could require this - ClearTokenHashTable(); + OnYearMonthPatternChanged(); } } + private void OnYearMonthPatternChanged() + { + // Clear the token hash table, note that even short times could require this + ClearTokenHashTable(); + } + /// /// Check if a string array contains a null value, and throw ArgumentNullException with parameter name "value" /// @@ -1682,7 +1707,7 @@ public void SetAllDateTimePatterns(string[] patterns, char format) { if (patterns[i] == null) { - throw new ArgumentNullException("patterns[" + i + "]", SR.ArgumentNull_ArrayValue); + throw new ArgumentNullException(nameof(patterns) + "[" + i + "]", SR.ArgumentNull_ArrayValue); } } @@ -1692,35 +1717,37 @@ public void SetAllDateTimePatterns(string[] patterns, char format) case 'd': allShortDatePatterns = patterns; shortDatePattern = allShortDatePatterns[0]; + OnShortDatePatternChanged(); break; case 'D': allLongDatePatterns = patterns; longDatePattern = allLongDatePatterns[0]; + OnLongDatePatternChanged(); break; case 't': allShortTimePatterns = patterns; shortTimePattern = allShortTimePatterns[0]; + OnShortTimePatternChanged(); break; case 'T': allLongTimePatterns = patterns; longTimePattern = allLongTimePatterns[0]; + OnLongTimePatternChanged(); break; case 'y': case 'Y': allYearMonthPatterns = patterns; yearMonthPattern = allYearMonthPatterns[0]; + OnYearMonthPatternChanged(); break; default: throw new ArgumentException(SR.Format(SR.Format_BadFormatSpecifier, format), nameof(format)); } - - // Clear the token hash table, note that even short dates could require this - ClearTokenHashTable(); } public string[] AbbreviatedMonthGenitiveNames From ab71303f5c91de81fa18a9e9ca227a03f510deff Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 17:34:48 +0000 Subject: [PATCH 103/420] Update dependencies from https://github.com/dotnet/llvm-project build 20200511.1 (#36210) - runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: 6.0.1-alpha.1.20254.1 -> 6.0.1-alpha.1.20261.1 - runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: 6.0.1-alpha.1.20254.1 -> 6.0.1-alpha.1.20261.1 - runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: 6.0.1-alpha.1.20254.1 -> 6.0.1-alpha.1.20261.1 - runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: 6.0.1-alpha.1.20254.1 -> 6.0.1-alpha.1.20261.1 - runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: 6.0.1-alpha.1.20254.1 -> 6.0.1-alpha.1.20261.1 - runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: 6.0.1-alpha.1.20254.1 -> 6.0.1-alpha.1.20261.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 24 ++++++++++++------------ eng/Versions.props | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e19c6206fc00f..cc301e7537172 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -118,29 +118,29 @@ https://github.com/dotnet/runtime-assets 71b9284907ebc69e5f80b491a51084c75e0ef7d3 - + https://github.com/dotnet/llvm-project - e5fd1614a244e8441b2d79eb3ebb044d26ec63b2 + 89f53d2cb6cd37267794895ff2ab47a30c094e63 - + https://github.com/dotnet/llvm-project - e5fd1614a244e8441b2d79eb3ebb044d26ec63b2 + 89f53d2cb6cd37267794895ff2ab47a30c094e63 - + https://github.com/dotnet/llvm-project - e5fd1614a244e8441b2d79eb3ebb044d26ec63b2 + 89f53d2cb6cd37267794895ff2ab47a30c094e63 - + https://github.com/dotnet/llvm-project - e5fd1614a244e8441b2d79eb3ebb044d26ec63b2 + 89f53d2cb6cd37267794895ff2ab47a30c094e63 - + https://github.com/dotnet/llvm-project - e5fd1614a244e8441b2d79eb3ebb044d26ec63b2 + 89f53d2cb6cd37267794895ff2ab47a30c094e63 - + https://github.com/dotnet/llvm-project - e5fd1614a244e8441b2d79eb3ebb044d26ec63b2 + 89f53d2cb6cd37267794895ff2ab47a30c094e63 https://github.com/dotnet/runtime diff --git a/eng/Versions.props b/eng/Versions.props index 258b54f2c7570..da27adf5e0580 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -124,12 +124,12 @@ 5.0.0-preview.3.20257.4 - 6.0.1-alpha.1.20254.1 - 6.0.1-alpha.1.20254.1 - 6.0.1-alpha.1.20254.1 - 6.0.1-alpha.1.20254.1 - 6.0.1-alpha.1.20254.1 - 6.0.1-alpha.1.20254.1 + 6.0.1-alpha.1.20261.1 + 6.0.1-alpha.1.20261.1 + 6.0.1-alpha.1.20261.1 + 6.0.1-alpha.1.20261.1 + 6.0.1-alpha.1.20261.1 + 6.0.1-alpha.1.20261.1 From 2cda9035cbbc8fe665af527b328f2fab70c2f2d4 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 11 May 2020 20:00:11 +0200 Subject: [PATCH 104/420] Use TargetFramework conditions consistently in libraries (#35956) * Use TargetFramework condition consistently in libs * Add docs section to describe the guideline * Update Microsoft.Extensions.DependencyInjection.csproj * Outline TargetFramework DesingTimeBuild issue * Update Microsoft.Extensions.DependencyInjection.csproj --- docs/coding-guidelines/project-guidelines.md | 40 +++++++++++++++++++ .../tests/Microsoft.CSharp.Tests.csproj | 2 +- ...osoft.Extensions.Configuration.Json.csproj | 2 +- ...xtensions.Configuration.UserSecrets.csproj | 2 +- ....Extensions.Configuration.Xml.Tests.csproj | 2 +- ...soft.Extensions.DependencyInjection.csproj | 8 ++-- ...ons.Options.ConfigurationExtensions.csproj | 2 +- ....Extensions.Options.DataAnnotations.csproj | 2 +- .../src/Microsoft.Extensions.Options.csproj | 2 +- ...rosoft.Win32.Registry.AccessControl.csproj | 3 +- .../src/Microsoft.Win32.Registry.csproj | 2 +- .../src/Microsoft.Win32.SystemEvents.csproj | 2 +- .../System.CodeDom/src/System.CodeDom.csproj | 2 +- .../src/System.Collections.Immutable.csproj | 6 ++- .../System.Collections.Immutable.Tests.csproj | 4 +- .../System.ComponentModel.Composition.csproj | 10 ++--- .../src/System.Data.Odbc.csproj | 3 +- .../System.Diagnostics.Debug.Tests.csproj | 17 ++++---- ...System.Diagnostics.DiagnosticSource.csproj | 7 ++-- ...System.Diagnostics.DiagnosticSource.csproj | 18 ++++----- ....Diagnostics.DiagnosticSource.Tests.csproj | 4 +- .../src/System.Diagnostics.EventLog.csproj | 2 +- .../src/System.Diagnostics.Process.csproj | 1 - ...System.Diagnostics.StackTrace.Tests.csproj | 8 ++-- ...stics.TextWriterTraceListener.Tests.csproj | 8 ++-- ...DirectoryServices.AccountManagement.csproj | 7 ++-- .../System.DirectoryServices.Protocols.csproj | 7 ++-- .../src/System.DirectoryServices.csproj | 7 ++-- .../ref/System.Drawing.Common.csproj | 2 +- .../System.IO.FileSystem.AccessControl.csproj | 4 +- .../src/System.IO.FileSystem.DriveInfo.csproj | 2 - .../ref/System.IO.Packaging.csproj | 2 +- .../src/System.IO.Packaging.csproj | 4 +- .../ref/System.IO.Pipelines.csproj | 6 +-- .../src/System.IO.Ports.csproj | 2 +- .../src/System.Management.csproj | 6 +-- .../ref/System.Net.Http.Json.csproj | 2 +- ...em.Net.WebSockets.WebSocketProtocol.csproj | 2 +- .../ref/System.Numerics.Tensors.csproj | 3 +- .../src/System.Numerics.Tensors.csproj | 4 +- .../src/System.Reflection.Context.csproj | 6 ++- .../System.Reflection.DispatchProxy.csproj | 6 +-- ...System.Reflection.Emit.ILGeneration.csproj | 2 +- .../src/System.Reflection.Metadata.csproj | 7 +++- ...stem.Reflection.MetadataLoadContext.csproj | 3 +- ...ystem.Security.Cryptography.OpenSsl.csproj | 2 +- ...ystem.Security.Cryptography.OpenSsl.csproj | 4 +- .../System.Security.Cryptography.Pkcs.csproj | 2 +- .../src/System.Security.Permissions.csproj | 2 +- .../System.Security.Principal.Windows.csproj | 1 - .../src/System.Text.Json.csproj | 6 +-- .../tests/System.Text.Json.Tests.csproj | 4 +- .../System.Threading.Tasks.Dataflow.csproj | 7 +++- .../src/System.Utf8String.Experimental.csproj | 9 +++-- ...ystem.Utf8String.Experimental.Tests.csproj | 2 +- .../ref/System.Windows.Extensions.csproj | 2 +- 56 files changed, 159 insertions(+), 125 deletions(-) diff --git a/docs/coding-guidelines/project-guidelines.md b/docs/coding-guidelines/project-guidelines.md index 1f9793eb298e3..f0050a5858809 100644 --- a/docs/coding-guidelines/project-guidelines.md +++ b/docs/coding-guidelines/project-guidelines.md @@ -97,6 +97,46 @@ When building an individual project the `BuildTargetFramework` and `TargetOS` wi - .NET Framework latest -> `$(NetFrameworkCurrent)-Windows_NT` # Library project guidelines + +## TargetFramework conditions +`TargetFramework` conditions should be avoided in the first PropertyGroup as that causes DesignTimeBuild issues: https://github.com/dotnet/project-system/issues/6143 + +1. Use an equality check if the TargetFramework isn't overloaded with the OS portion. +Example: +``` + + netstandard2.0;netstandard2.1 + +... +``` +2. Use a StartsWith when you want to test for multiple .NETStandard or .NETFramework versions. +Example: +``` + + netstandard2.0;netstandard2.1 + +... +``` +4. Use negations if that makes the conditions easier. +Example: +``` + + netstandard2.0;net461;net472;net5.0 + +... +``` + +## Directory layout + Library projects should use the following directory layout. ``` diff --git a/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj b/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj index 2c74bc81f267d..11dfc740701cd 100644 --- a/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj +++ b/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj @@ -34,7 +34,7 @@ - + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.Configuration.Json/src/Microsoft.Extensions.Configuration.Json.csproj b/src/libraries/Microsoft.Extensions.Configuration.Json/src/Microsoft.Extensions.Configuration.Json.csproj index 61a5cedc58bd8..edd848567a5c4 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Json/src/Microsoft.Extensions.Configuration.Json.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Json/src/Microsoft.Extensions.Configuration.Json.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/Microsoft.Extensions.Configuration.UserSecrets.csproj b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/Microsoft.Extensions.Configuration.UserSecrets.csproj index 13214ba45ced1..654d0f9f53be6 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/Microsoft.Extensions.Configuration.UserSecrets.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.UserSecrets/src/Microsoft.Extensions.Configuration.UserSecrets.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/Microsoft.Extensions.Configuration.Xml.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/Microsoft.Extensions.Configuration.Xml.Tests.csproj index 348382d6fd9ff..dfb45ab9f8cec 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/Microsoft.Extensions.Configuration.Xml.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Xml/tests/Microsoft.Extensions.Configuration.Xml.Tests.csproj @@ -22,7 +22,7 @@ Link="Common\tests\Extensions\TestingUtils\Microsoft.AspNetCore.Testing\src\xunit\RuntimeFrameworks.cs" /> - + diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj b/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj index 8e8efebdf748b..50cdcabc140e5 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/Microsoft.Extensions.DependencyInjection.csproj @@ -3,17 +3,15 @@ $(NetCoreAppCurrent);$(NetFrameworkCurrent);net461;netstandard2.0;netstandard2.1 true - - True - $(DefineConstants);IL_EMIT - False - $(DefineConstants);SAVE_ASSEMBLIES + True + $(DefineConstants);IL_EMIT + $(DefineConstants);SAVE_ASSEMBLIES diff --git a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj index 67e55d95d6322..9feb20a52838a 100644 --- a/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj +++ b/src/libraries/Microsoft.Extensions.Options.ConfigurationExtensions/src/Microsoft.Extensions.Options.ConfigurationExtensions.csproj @@ -1,7 +1,7 @@ - netstandard2.0;$(NetCoreAppCurrent) + $(NetCoreAppCurrent);netstandard2.0 true diff --git a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj index 043d82dc2348f..8dadd0c88af19 100644 --- a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj +++ b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/Microsoft.Extensions.Options.DataAnnotations.csproj @@ -1,7 +1,7 @@ - netstandard2.0;$(NetCoreAppCurrent) + $(NetCoreAppCurrent);netstandard2.0 true diff --git a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj index 94e49733c1e11..fcc42385829ff 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj +++ b/src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj @@ -1,7 +1,7 @@ - netstandard2.0;$(NetCoreAppCurrent) + $(NetCoreAppCurrent);netstandard2.0 true diff --git a/src/libraries/Microsoft.Win32.Registry.AccessControl/src/Microsoft.Win32.Registry.AccessControl.csproj b/src/libraries/Microsoft.Win32.Registry.AccessControl/src/Microsoft.Win32.Registry.AccessControl.csproj index 4bcbb7f525744..c237f53d34828 100644 --- a/src/libraries/Microsoft.Win32.Registry.AccessControl/src/Microsoft.Win32.Registry.AccessControl.csproj +++ b/src/libraries/Microsoft.Win32.Registry.AccessControl/src/Microsoft.Win32.Registry.AccessControl.csproj @@ -1,13 +1,12 @@ - Microsoft.Win32.Registry.AccessControl true - SR.PlatformNotSupported_RegistryAccessControl netstandard2.0-Windows_NT;netstandard2.0;net461-Windows_NT;$(NetFrameworkCurrent)-Windows_NT true + SR.PlatformNotSupported_RegistryAccessControl true diff --git a/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj b/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj index c291861079963..9083620b97edd 100644 --- a/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj +++ b/src/libraries/Microsoft.Win32.Registry/src/Microsoft.Win32.Registry.csproj @@ -3,7 +3,6 @@ true $(NoWarn);CS1573 $(DefineConstants);REGISTRY_ASSEMBLY - $(NoWarn);CA1823 $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetFrameworkCurrent)-Windows_NT;netstandard2.0-Windows_NT;netstandard2.0-Unix;netstandard2.0;net461-Windows_NT true true @@ -13,6 +12,7 @@ true SR.PlatformNotSupported_Registry + $(NoWarn);CA1823 true - SR.PlatformNotSupported_SystemEvents + SR.PlatformNotSupported_SystemEvents true - + diff --git a/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj b/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj index d456db9f3e9a4..a942bf3a506cd 100644 --- a/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj +++ b/src/libraries/System.Collections.Immutable/src/System.Collections.Immutable.csproj @@ -1,11 +1,13 @@ - System.Collections.Immutable - netstandard1.0;portable-net45+win8+wp8+wpa81 $(NetCoreAppCurrent);netstandard1.0;netstandard1.3;netstandard2.0 true enable + + + netstandard1.0;portable-net45+win8+wp8+wpa81 + diff --git a/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj b/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj index 7eed443c2c2f4..f5130bcc181d6 100644 --- a/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj +++ b/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj @@ -4,7 +4,7 @@ $(NetCoreAppCurrent);$(NetFrameworkCurrent) - @@ -75,7 +75,7 @@ - + diff --git a/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj b/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj index 06fbf9985c8d9..d093096479037 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj +++ b/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj @@ -1,8 +1,6 @@ - System.ComponentModel.Composition - - + $(NoWarn);CS1573 $(NetCoreAppCurrent);netstandard2.0;netcoreapp2.0;_$(NetFrameworkCurrent) @@ -11,13 +9,13 @@ - SR.PlatformNotSupported_ComponentModel_Composition + SR.PlatformNotSupported_ComponentModel_Composition $(NoWarn);nullable - + @@ -188,7 +186,7 @@ - + diff --git a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj index ada2f69d139ae..33138aca3cfab 100644 --- a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj +++ b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj @@ -1,6 +1,5 @@ - System.Data.Odbc true netcoreapp2.0-FreeBSD;netcoreapp2.0-Linux;netcoreapp2.0-OSX;netcoreapp2.0-Windows_NT;net461-Windows_NT;netstandard2.0;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT true @@ -9,7 +8,7 @@ true - SR.Odbc_PlatformNotSupported + SR.Odbc_PlatformNotSupported - System.Diagnostics.Debug.Tests System.Diagnostics.Tests true None $(NetCoreAppCurrent) true - + @@ -15,17 +14,15 @@ - - + + + + + + - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.csproj index db385a8be9a16..1766bbf562536 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSource.csproj @@ -2,12 +2,13 @@ netstandard2.0;netstandard1.1;netstandard1.3;net45;$(NetFrameworkCurrent) true - true false enable - - $(DefineConstants);ALLOW_PARTIALLY_TRUSTED_CALLERS + + + true + $(DefineConstants);ALLOW_PARTIALLY_TRUSTED_CALLERS diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj index df8de8a03def2..e3bb30d9cea2b 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -1,25 +1,25 @@ - - netstandard1.1;portable-net45+win8+wpa81 true false $(NoWarn);SA1205 enable - $(DefineConstants);NO_EVENTSOURCE_COMPLEX_TYPE_SUPPORT - $(DefineConstants);EVENTSOURCE_ACTIVITY_SUPPORT - $(DefineConstants);EVENTSOURCE_ENUMERATE_SUPPORT $(NetCoreAppCurrent);netstandard1.1;netstandard1.3;net45;net46;netstandard2.0;$(NetFrameworkCurrent) true true - true + + netstandard1.1;portable-net45+win8+wpa81 + $(DefineConstants);NO_EVENTSOURCE_COMPLEX_TYPE_SUPPORT + $(DefineConstants);EVENTSOURCE_ACTIVITY_SUPPORT + $(DefineConstants);EVENTSOURCE_ENUMERATE_SUPPORT $(DefineConstants);ALLOW_PARTIALLY_TRUSTED_CALLERS;ENABLE_HTTP_HANDLER + true diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/System.Diagnostics.DiagnosticSource.Tests.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/tests/System.Diagnostics.DiagnosticSource.Tests.csproj index c466ff6d0a6ed..ed8d7de3079d1 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/System.Diagnostics.DiagnosticSource.Tests.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/System.Diagnostics.DiagnosticSource.Tests.csproj @@ -3,7 +3,7 @@ true $(NetCoreAppCurrent);$(NetFrameworkCurrent)-Windows_NT - + @@ -11,7 +11,7 @@ - + true - SR.PlatformNotSupported_EventLog + SR.PlatformNotSupported_EventLog diff --git a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj index 6e3ff47ece651..ffe15beea64d1 100644 --- a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj +++ b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj @@ -1,7 +1,6 @@ AnyCPU - System.Diagnostics.Process $(DefineConstants);FEATURE_REGISTRY true $(NoWarn);CS1573 diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj b/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj index 22f8deac3fe10..0290d8432c8ff 100644 --- a/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj +++ b/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj @@ -4,15 +4,13 @@ true + + + - - - - - \ No newline at end of file diff --git a/src/libraries/System.Diagnostics.TextWriterTraceListener/tests/System.Diagnostics.TextWriterTraceListener.Tests.csproj b/src/libraries/System.Diagnostics.TextWriterTraceListener/tests/System.Diagnostics.TextWriterTraceListener.Tests.csproj index ee76c5dd787b7..4a5c22ae09ef1 100644 --- a/src/libraries/System.Diagnostics.TextWriterTraceListener/tests/System.Diagnostics.TextWriterTraceListener.Tests.csproj +++ b/src/libraries/System.Diagnostics.TextWriterTraceListener/tests/System.Diagnostics.TextWriterTraceListener.Tests.csproj @@ -4,15 +4,13 @@ $(NetCoreAppCurrent) - + - - - - + + \ No newline at end of file diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj b/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj index 04dea616d3dba..41b0189dc0a7c 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj @@ -1,6 +1,5 @@ - System.DirectoryServices.AccountManagement true $(DefineConstants);FLAVOR_WHIDBEY;PAPI_AD;PAPI_REGSAM;USE_CTX_CACHE $(NoWarn);8073;CA1810 @@ -10,9 +9,9 @@ - SR.DirectoryServicesAccountManagement_PlatformNotSupported + SR.DirectoryServicesAccountManagement_PlatformNotSupported - + @@ -100,7 +99,7 @@ - + diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj index 09328b9fb2159..2ffb1d93dfbc6 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj +++ b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj @@ -1,6 +1,5 @@ - System.DirectoryServices.Protocols true $(NoWarn);0649;CA1810 true @@ -9,9 +8,9 @@ - SR.DirectoryServicesProtocols_PlatformNotSupported + SR.DirectoryServicesProtocols_PlatformNotSupported - + @@ -79,7 +78,7 @@ - + diff --git a/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj b/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj index 940e568b35d08..e8ca838dc2aff 100644 --- a/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj +++ b/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj @@ -1,6 +1,5 @@ - System.DirectoryServices true $(NoWarn);0649 $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT;_$(NetFrameworkCurrent) @@ -8,9 +7,9 @@ - SR.DirectoryServices_PlatformNotSupported + SR.DirectoryServices_PlatformNotSupported - + @@ -150,7 +149,7 @@ - + diff --git a/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.csproj b/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.csproj index 46ac878a5842e..34d6599a3369a 100644 --- a/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.csproj +++ b/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.csproj @@ -1,6 +1,6 @@ - netcoreapp3.0;$(NetCoreAppCurrent) + $(NetCoreAppCurrent);netcoreapp3.0 true enable diff --git a/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj b/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj index 323535b72d781..ac6c8e8a6690c 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj +++ b/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj @@ -1,7 +1,5 @@ - true - SR.PlatformNotSupported_AccessControl $(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netstandard2.0-Windows_NT;net461-Windows_NT;$(NetFrameworkCurrent)-Windows_NT true true @@ -10,6 +8,8 @@ true + true + SR.PlatformNotSupported_AccessControl diff --git a/src/libraries/System.IO.FileSystem.DriveInfo/src/System.IO.FileSystem.DriveInfo.csproj b/src/libraries/System.IO.FileSystem.DriveInfo/src/System.IO.FileSystem.DriveInfo.csproj index 50792a3e761b6..abc8eb70f910d 100644 --- a/src/libraries/System.IO.FileSystem.DriveInfo/src/System.IO.FileSystem.DriveInfo.csproj +++ b/src/libraries/System.IO.FileSystem.DriveInfo/src/System.IO.FileSystem.DriveInfo.csproj @@ -1,7 +1,5 @@ - System.IO.FileSystem.DriveInfo - System.IO.FileSystem.DriveInfo true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix enable diff --git a/src/libraries/System.IO.Packaging/ref/System.IO.Packaging.csproj b/src/libraries/System.IO.Packaging/ref/System.IO.Packaging.csproj index 6a1068da49eaa..56941538f8b06 100644 --- a/src/libraries/System.IO.Packaging/ref/System.IO.Packaging.csproj +++ b/src/libraries/System.IO.Packaging/ref/System.IO.Packaging.csproj @@ -1,11 +1,11 @@ - $(DefineConstants);netcoreapp netstandard2.0;netstandard1.3;net46;$(NetFrameworkCurrent) true + $(DefineConstants);netcoreapp true diff --git a/src/libraries/System.IO.Packaging/src/System.IO.Packaging.csproj b/src/libraries/System.IO.Packaging/src/System.IO.Packaging.csproj index 6dd1b630bc739..49d04496c3c32 100644 --- a/src/libraries/System.IO.Packaging/src/System.IO.Packaging.csproj +++ b/src/libraries/System.IO.Packaging/src/System.IO.Packaging.csproj @@ -1,12 +1,12 @@ true - $(DefineConstants);FEATURE_SERIALIZATION - net46;netstandard1.3;netstandard2.0;$(NetFrameworkCurrent)-Windows_NT + netstandard2.0;net46;netstandard1.3;$(NetFrameworkCurrent)-Windows_NT true + $(DefineConstants);FEATURE_SERIALIZATION true diff --git a/src/libraries/System.IO.Pipelines/ref/System.IO.Pipelines.csproj b/src/libraries/System.IO.Pipelines/ref/System.IO.Pipelines.csproj index 7f1bb21bb6b55..2af41b5283fb6 100644 --- a/src/libraries/System.IO.Pipelines/ref/System.IO.Pipelines.csproj +++ b/src/libraries/System.IO.Pipelines/ref/System.IO.Pipelines.csproj @@ -2,9 +2,9 @@ netstandard2.0 enable - - netcoreapp2.0 + + netcoreapp2.0 diff --git a/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj b/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj index c4896b1f163f2..e8c0d34e3d238 100644 --- a/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj +++ b/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj @@ -6,12 +6,12 @@ annotations netstandard2.0-Windows_NT;netstandard2.0-Linux;netstandard2.0-OSX;netstandard2.0;net461-Windows_NT;netstandard2.0-FreeBSD;$(NetFrameworkCurrent)-Windows_NT true - true true SR.PlatformNotSupported_IOPorts + true diff --git a/src/libraries/System.Management/src/System.Management.csproj b/src/libraries/System.Management/src/System.Management.csproj index 271afb85dff68..ac50cd7a9b1bf 100644 --- a/src/libraries/System.Management/src/System.Management.csproj +++ b/src/libraries/System.Management/src/System.Management.csproj @@ -8,9 +8,9 @@ - SR.PlatformNotSupported_SystemManagement + SR.PlatformNotSupported_SystemManagement - + - + diff --git a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj index 5a3ac5ef09098..af8add8a69fa8 100644 --- a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj +++ b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj @@ -1,6 +1,6 @@ - netstandard2.0;$(NetCoreAppCurrent) + $(NetCoreAppCurrent);netstandard2.0 enable diff --git a/src/libraries/System.Net.WebSockets.WebSocketProtocol/src/System.Net.WebSockets.WebSocketProtocol.csproj b/src/libraries/System.Net.WebSockets.WebSocketProtocol/src/System.Net.WebSockets.WebSocketProtocol.csproj index dd5ff48f1a7b7..a85b95b6c768d 100644 --- a/src/libraries/System.Net.WebSockets.WebSocketProtocol/src/System.Net.WebSockets.WebSocketProtocol.csproj +++ b/src/libraries/System.Net.WebSockets.WebSocketProtocol/src/System.Net.WebSockets.WebSocketProtocol.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj index 4f65c31e1ce46..ef145e7ec407d 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj @@ -1,9 +1,10 @@ netstandard2.0;netstandard1.1 - true + + true diff --git a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj index d56053cbd493f..5548e9a52d379 100644 --- a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj @@ -2,10 +2,10 @@ true netstandard2.0;netstandard1.1 - true - System.Numerics.Tensors + + true diff --git a/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj b/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj index daeb3ca8b239b..c48dcba448478 100644 --- a/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj +++ b/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj @@ -1,9 +1,11 @@ - Library - SR.PlatformNotSupported_ReflectionContext netstandard2.0;netstandard1.1;netstandard2.1 + + + SR.PlatformNotSupported_ReflectionContext + diff --git a/src/libraries/System.Reflection.DispatchProxy/src/System.Reflection.DispatchProxy.csproj b/src/libraries/System.Reflection.DispatchProxy/src/System.Reflection.DispatchProxy.csproj index 01e43ce383df2..93cbb7fb64f94 100644 --- a/src/libraries/System.Reflection.DispatchProxy/src/System.Reflection.DispatchProxy.csproj +++ b/src/libraries/System.Reflection.DispatchProxy/src/System.Reflection.DispatchProxy.csproj @@ -9,9 +9,9 @@ - SR.PlatformNotSupported_ReflectionDispatchProxy + SR.PlatformNotSupported_ReflectionDispatchProxy - + - + diff --git a/src/libraries/System.Reflection.Emit.ILGeneration/ref/System.Reflection.Emit.ILGeneration.csproj b/src/libraries/System.Reflection.Emit.ILGeneration/ref/System.Reflection.Emit.ILGeneration.csproj index c9ea3bff48f62..48837d6105f25 100644 --- a/src/libraries/System.Reflection.Emit.ILGeneration/ref/System.Reflection.Emit.ILGeneration.csproj +++ b/src/libraries/System.Reflection.Emit.ILGeneration/ref/System.Reflection.Emit.ILGeneration.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj b/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj index 2ace8896347f8..a60521d62461b 100644 --- a/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj +++ b/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj @@ -3,10 +3,13 @@ true en-US false - netstandard1.1;portable-net45+win8 $(NetCoreAppCurrent);netstandard1.1;netstandard2.0 true enable + + + + netstandard1.1;portable-net45+win8 - + diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj b/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj index 21c96c0c49de0..e200da5e03283 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj @@ -1,11 +1,10 @@ - System.Reflection.MetadataLoadContext System.Reflection true $(NoWarn);CS1573 - netcoreapp3.0;netstandard2.0;$(NetCoreAppCurrent) + $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.0 true enable diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.csproj b/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.csproj index 0f70b59154c8e..cc4944963eddd 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.csproj +++ b/src/libraries/System.Security.Cryptography.OpenSsl/ref/System.Security.Cryptography.OpenSsl.csproj @@ -1,6 +1,6 @@ - netcoreapp3.0;$(NetCoreAppCurrent) + $(NetCoreAppCurrent);netcoreapp3.0 true enable diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/src/System.Security.Cryptography.OpenSsl.csproj b/src/libraries/System.Security.Cryptography.OpenSsl/src/System.Security.Cryptography.OpenSsl.csproj index 4f7eff09e987c..03996c4a2fbdf 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/src/System.Security.Cryptography.OpenSsl.csproj +++ b/src/libraries/System.Security.Cryptography.OpenSsl/src/System.Security.Cryptography.OpenSsl.csproj @@ -1,7 +1,7 @@ true - netcoreapp3.0-Unix;netcoreapp3.0;netstandard2.0;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent) + $(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent);netcoreapp3.0-Unix;netcoreapp3.0;netstandard2.0 true enable @@ -104,7 +104,7 @@ - + diff --git a/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.csproj b/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.csproj index 87ca3d5be2561..07a5f1e62c220 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.csproj +++ b/src/libraries/System.Security.Cryptography.Pkcs/ref/System.Security.Cryptography.Pkcs.csproj @@ -1,6 +1,6 @@ - netcoreapp3.0;netstandard2.1;net461;$(NetFrameworkCurrent);$(NetCoreAppCurrent) + $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.1;net461;$(NetFrameworkCurrent) true true enable diff --git a/src/libraries/System.Security.Permissions/src/System.Security.Permissions.csproj b/src/libraries/System.Security.Permissions/src/System.Security.Permissions.csproj index e3b9aa3ab4ec2..174f60d9b0688 100644 --- a/src/libraries/System.Security.Permissions/src/System.Security.Permissions.csproj +++ b/src/libraries/System.Security.Permissions/src/System.Security.Permissions.csproj @@ -181,7 +181,7 @@ - + - System.Security.Principal.Windows true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;netstandard2.0;netcoreapp2.0-Windows_NT;netcoreapp2.0-Unix;netcoreapp2.1-Windows_NT;netcoreapp2.1-Unix;net461-Windows_NT;$(NetFrameworkCurrent)-Windows_NT true diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index 1311316b1caa5..5a704054c3e33 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -15,7 +15,7 @@ $(DefineConstants);BUILDING_INBOX_LIBRARY - $(NoWarn);nullable + $(NoWarn);nullable - + - + diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj index cebf7e44807f9..c55cc68b8500d 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj @@ -5,7 +5,7 @@ - $(DefineConstants);BUILDING_INBOX_LIBRARY + $(DefineConstants);BUILDING_INBOX_LIBRARY - + diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj b/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj index b0252a7b532cf..2af9d7adad7f4 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj @@ -1,11 +1,14 @@ + + netstandard2.0;netstandard1.0;netstandard1.1 + enable + + $(DefineConstants);FEATURE_TRACING $(DefineConstants);USE_INTERNAL_CONCURRENT_COLLECTIONS $(DefineConstants);USE_INTERNAL_THREADING netstandard1.1;portable-net45+win8+wpa81 - netstandard2.0;netstandard1.0;netstandard1.1 - enable diff --git a/src/libraries/System.Utf8String.Experimental/src/System.Utf8String.Experimental.csproj b/src/libraries/System.Utf8String.Experimental/src/System.Utf8String.Experimental.csproj index d40ffab549bb0..8c12e12713963 100644 --- a/src/libraries/System.Utf8String.Experimental/src/System.Utf8String.Experimental.csproj +++ b/src/libraries/System.Utf8String.Experimental/src/System.Utf8String.Experimental.csproj @@ -1,13 +1,16 @@ true + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;netstandard2.0;netstandard2.1;netcoreapp3.0 + enable + $(DefineContants);FEATURE_UTF8STRING + + + $(NoWarn);CS3019;CS0162 true - netstandard2.0;netstandard2.1;netcoreapp3.0;$(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix - enable - $(DefineContants);FEATURE_UTF8STRING diff --git a/src/libraries/System.Utf8String.Experimental/tests/System.Utf8String.Experimental.Tests.csproj b/src/libraries/System.Utf8String.Experimental/tests/System.Utf8String.Experimental.Tests.csproj index 92e4d04476e3c..73e52762cdf01 100644 --- a/src/libraries/System.Utf8String.Experimental/tests/System.Utf8String.Experimental.Tests.csproj +++ b/src/libraries/System.Utf8String.Experimental/tests/System.Utf8String.Experimental.Tests.csproj @@ -42,7 +42,7 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.csproj b/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.csproj index ac9792c7a5d07..ebbd3e46f7670 100644 --- a/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.csproj +++ b/src/libraries/System.Windows.Extensions/ref/System.Windows.Extensions.csproj @@ -1,6 +1,6 @@ - netcoreapp3.0;$(NetCoreAppCurrent) + $(NetCoreAppCurrent);netcoreapp3.0 true From cf1f24b6662b51a02ee588f70b7f9172f56718c5 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Mon, 11 May 2020 11:00:41 -0700 Subject: [PATCH 105/420] Expose the parsed signature in structured format (#36190) --- .../ReadyToRunReader.cs | 19 ++++++- .../ReadyToRunSignature.cs | 57 +++++++++++++++---- 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index 651c0cc36ac59..c252c306d46a0 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -97,6 +97,7 @@ public sealed class ReadyToRunReader // ImportSections private List _importSections; private Dictionary _importCellNames; + private Dictionary _importSignatures; // AvailableType private Dictionary> _availableTypes; @@ -308,6 +309,19 @@ public IReadOnlyList ImportSections } + /// + /// Map from import cell addresses to their symbolic names. + /// + public IReadOnlyDictionary ImportSignatures + { + get + { + EnsureImportSections(); + return _importSignatures; + } + + } + internal Dictionary RuntimeFunctionToDebugInfo { get @@ -945,6 +959,7 @@ private void EnsureImportSections() } _importSections = new List(); _importCellNames = new Dictionary(); + _importSignatures = new Dictionary(); if (!ReadyToRunHeader.Sections.TryGetValue(ReadyToRunSectionType.ImportSections, out ReadyToRunSection importSectionsSection)) { return; @@ -997,9 +1012,11 @@ private void EnsureImportSections() long section = NativeReader.ReadInt64(Image, ref sectionOffset); uint sigRva = NativeReader.ReadUInt32(Image, ref signatureOffset); int sigOffset = GetOffset((int)sigRva); - string cellName = MetadataNameFormatter.FormatSignature(_assemblyResolver, this, sigOffset); + ReadyToRunSignature signature; + string cellName = MetadataNameFormatter.FormatSignature(_assemblyResolver, this, sigOffset, out signature); entries.Add(new ReadyToRunImportSection.ImportSectionEntry(entries.Count, entryOffset, entryOffset + rva, section, sigRva, cellName)); _importCellNames.Add(rva + entrySize * i, cellName); + _importSignatures.Add(rva + entrySize * i, signature); } int auxDataRVA = NativeReader.ReadInt32(Image, ref offset); diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs index 355af566a46b8..fbbaf233118e6 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs @@ -12,6 +12,30 @@ namespace ILCompiler.Reflection.ReadyToRun { + /// + /// This represents all possible signatures that is + /// + public class ReadyToRunSignature + { + } + + /// + /// For now, this means the signature is not parsed yet + /// + public class TodoSignature : ReadyToRunSignature + { + } + + public class MethodDefEntrySignature : ReadyToRunSignature + { + public uint MethodDefToken { get; set; } + } + + public class MethodRefEntrySignature : ReadyToRunSignature + { + public uint MethodRefToken { get; set; } + } + /// /// Helper class for converting metadata tokens into their textual representation. /// @@ -39,11 +63,11 @@ public static string FormatHandle(MetadataReader metadataReader, Handle handle, return formatter.EmitHandleName(handle, namespaceQualified, owningTypeOverride, signaturePrefix); } - public static string FormatSignature(IAssemblyResolver assemblyResolver, ReadyToRunReader r2rReader, int imageOffset) + public static string FormatSignature(IAssemblyResolver assemblyResolver, ReadyToRunReader r2rReader, int imageOffset, out ReadyToRunSignature result) { SignatureDecoder decoder = new SignatureDecoder(assemblyResolver, r2rReader.GetGlobalMetadataReader(), r2rReader, imageOffset); - string result = decoder.ReadR2RSignature(); - return result; + string answer = decoder.ReadR2RSignature(out result); + return answer; } /// @@ -518,13 +542,14 @@ public CorElementType PeekElementType() /// by custom encoding per fixup type. /// /// - public string ReadR2RSignature() + public string ReadR2RSignature(out ReadyToRunSignature result) { + result = null; StringBuilder builder = new StringBuilder(); int startOffset = _offset; try { - ParseSignature(builder); + result = ParseSignature(builder); EmitSignatureBinaryFrom(builder, startOffset); } catch (Exception ex) @@ -634,7 +659,7 @@ private void EmitSignatureBinaryFrom(StringBuilder builder, int startOffset) /// Parse the signature into a given output string builder. /// /// Output signature builder - private void ParseSignature(StringBuilder builder) + private ReadyToRunSignature ParseSignature(StringBuilder builder) { uint fixupType = ReadByte(); EmitInlineSignatureBinaryBytes(builder, 1); @@ -650,8 +675,9 @@ private void ParseSignature(StringBuilder builder) moduleDecoder = new SignatureDecoder(_options, refAsmEcmaReader, _image, _offset, refAsmEcmaReader, _contextReader); } - moduleDecoder.ParseSignature((ReadyToRunFixupKind)fixupType, builder); + ReadyToRunSignature result = moduleDecoder.ParseSignature((ReadyToRunFixupKind)fixupType, builder); _offset = moduleDecoder.Offset; + return result; } /// @@ -659,14 +685,16 @@ private void ParseSignature(StringBuilder builder) /// /// Fixup type to parse /// Output signature builder - private void ParseSignature(ReadyToRunFixupKind fixupType, StringBuilder builder) + private ReadyToRunSignature ParseSignature(ReadyToRunFixupKind fixupType, StringBuilder builder) { + ReadyToRunSignature result = new TodoSignature(); switch (fixupType) { case ReadyToRunFixupKind.ThisObjDictionaryLookup: builder.Append("THISOBJ_DICTIONARY_LOOKUP @ "); ParseType(builder); builder.Append(": "); + // It looks like ReadyToRunSignature is potentially a composite pattern ParseSignature(builder); break; @@ -702,15 +730,17 @@ private void ParseSignature(ReadyToRunFixupKind fixupType, StringBuilder builder break; case ReadyToRunFixupKind.MethodEntry_DefToken: - ParseMethodDefToken(builder, owningTypeOverride: null); + uint methodDefToken = ParseMethodDefToken(builder, owningTypeOverride: null); builder.Append(" (METHOD_ENTRY"); builder.Append(_options.Naked ? ")" : "_DEF_TOKEN)"); + result = new MethodDefEntrySignature { MethodDefToken = methodDefToken }; break; case ReadyToRunFixupKind.MethodEntry_RefToken: - ParseMethodRefToken(builder, owningTypeOverride: null); + uint methodRefToken = ParseMethodRefToken(builder, owningTypeOverride: null); builder.Append(" (METHOD_ENTRY"); builder.Append(_options.Naked ? ")" : "_REF_TOKEN)"); + result = new MethodRefEntrySignature { MethodRefToken = methodRefToken }; break; @@ -909,6 +939,7 @@ private void ParseSignature(ReadyToRunFixupKind fixupType, StringBuilder builder builder.Append(string.Format("Unknown fixup type: {0:X2}", fixupType)); break; } + return result; } /// @@ -1235,7 +1266,7 @@ private void ParseMethod(StringBuilder builder) /// Read a methodDef token from the signature and output the corresponding object to the builder. /// /// Output string builder - private void ParseMethodDefToken(StringBuilder builder, string owningTypeOverride) + private uint ParseMethodDefToken(StringBuilder builder, string owningTypeOverride) { StringBuilder signaturePrefixBuilder = new StringBuilder(); uint methodDefToken = ReadUIntAndEmitInlineSignatureBinary(signaturePrefixBuilder) | (uint)CorTokenType.mdtMethodDef; @@ -1245,6 +1276,7 @@ private void ParseMethodDefToken(StringBuilder builder, string owningTypeOverrid namespaceQualified: true, owningTypeOverride: owningTypeOverride, signaturePrefix: signaturePrefixBuilder.ToString())); + return methodDefToken; } /// @@ -1252,7 +1284,7 @@ private void ParseMethodDefToken(StringBuilder builder, string owningTypeOverrid /// /// Output string builder /// Explicit owning type override - private void ParseMethodRefToken(StringBuilder builder, string owningTypeOverride) + private uint ParseMethodRefToken(StringBuilder builder, string owningTypeOverride) { StringBuilder signaturePrefixBuilder = new StringBuilder(); uint methodRefToken = ReadUIntAndEmitInlineSignatureBinary(signaturePrefixBuilder) | (uint)CorTokenType.mdtMemberRef; @@ -1262,6 +1294,7 @@ private void ParseMethodRefToken(StringBuilder builder, string owningTypeOverrid namespaceQualified: false, owningTypeOverride: owningTypeOverride, signaturePrefix: signaturePrefixBuilder.ToString())); + return methodRefToken; } /// From 98026a4648182d8f7f4bbaebfd4208a3917e9964 Mon Sep 17 00:00:00 2001 From: Youssef Victor <31348972+Youssef1313@users.noreply.github.com> Date: Mon, 11 May 2020 20:05:14 +0200 Subject: [PATCH 106/420] Include Content-Type in exception in ReadFromJsonAsync (#36186) * Update Strings.resx * Update HttpContentJsonExtensions.cs --- src/libraries/System.Net.Http.Json/src/Resources/Strings.resx | 2 +- .../src/System/Net/Http/Json/HttpContentJsonExtensions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Http.Json/src/Resources/Strings.resx b/src/libraries/System.Net.Http.Json/src/Resources/Strings.resx index 1722e93d5009d..332b5e17c461c 100644 --- a/src/libraries/System.Net.Http.Json/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Http.Json/src/Resources/Strings.resx @@ -127,7 +127,7 @@ The character set provided in ContentType is not supported. - The provided ContentType is not supported; the supported types are 'application/json' and the structured syntax suffix 'application/+json'. + The provided ContentType '{0}' is not supported; the supported types are 'application/json' and the structured syntax suffix 'application/+json'. The specified type {0} must derive from the specific value's type {1}. diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs index 79ecf1addd362..0d76a030f9fca 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs @@ -84,7 +84,7 @@ private static void ValidateContent(HttpContent content) !mediaType.Equals(JsonContent.JsonMediaType, StringComparison.OrdinalIgnoreCase) && !IsValidStructuredSyntaxJsonSuffix(mediaType.AsSpan())) { - throw new NotSupportedException(SR.ContentTypeNotSupported); + throw new NotSupportedException(SR.Format(SR.ContentTypeNotSupported, mediaType)); } } From 3764f3781e6dd78e1e8533eb76e1b317e55939d8 Mon Sep 17 00:00:00 2001 From: Elinor Fung <47805090+elinor-fung@users.noreply.github.com> Date: Mon, 11 May 2020 11:06:12 -0700 Subject: [PATCH 107/420] Make global ComWrappers for marshalling respect requested IID (#36054) --- src/coreclr/src/vm/interopconverter.cpp | 33 +++++++++++++------ .../src/Interop/COM/ComWrappers/Common.cs | 1 + .../GlobalInstance/GlobalInstance.cs | 23 ++++++++----- .../ReferenceTrackerRuntime.cpp | 7 +++- 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/coreclr/src/vm/interopconverter.cpp b/src/coreclr/src/vm/interopconverter.cpp index 2c67182df9bd3..00fa3cb6e4e8d 100644 --- a/src/coreclr/src/vm/interopconverter.cpp +++ b/src/coreclr/src/vm/interopconverter.cpp @@ -104,8 +104,15 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bEnable if (TryGetComIPFromObjectRefUsingComWrappers(*poref, &pUnk)) { - pUnk.SuppressRelease(); - RETURN pUnk; + GUID iid; + pMT->GetGuid(&iid, /*bGenerateIfNotFound*/ FALSE, /*bClassic*/ FALSE); + + IUnknown* pvObj; + hr = SafeQueryInterface(pUnk, iid, &pvObj); + if (FAILED(hr)) + COMPlusThrowHR(hr); + + RETURN pvObj; } SyncBlock* pBlock = (*poref)->GetSyncBlock(); @@ -176,15 +183,20 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, ComIpType ReqIpType, ComIpType { hr = S_OK; - SafeComHolder pvObj; + IUnknown* pvObj; if (ReqIpType & ComIpType_Dispatch) { - hr = pUnk->QueryInterface(IID_IDispatch, &pvObj); + hr = SafeQueryInterface(pUnk, IID_IDispatch, &pvObj); + pUnk->Release(); } else if (ReqIpType & ComIpType_Inspectable) { - SafeComHolder pvObj; - hr = pUnk->QueryInterface(IID_IInspectable, &pvObj); + hr = SafeQueryInterface(pUnk, IID_IInspectable, &pvObj); + pUnk->Release(); + } + else + { + pvObj = pUnk; } if (FAILED(hr)) @@ -193,7 +205,7 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, ComIpType ReqIpType, ComIpType if (pFetchedIpType != NULL) *pFetchedIpType = ReqIpType; - RETURN pUnk; + RETURN pvObj; } MethodTable *pMT = (*poref)->GetMethodTable(); @@ -463,12 +475,13 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, REFIID iid, bool throwIfNoComI if (TryGetComIPFromObjectRefUsingComWrappers(*poref, &pUnk)) { - SafeComHolder pvObj; - hr = pUnk->QueryInterface(iid, &pvObj); + IUnknown* pvObj; + hr = SafeQueryInterface(pUnk, iid, &pvObj); + pUnk->Release(); if (FAILED(hr)) COMPlusThrowHR(hr); - RETURN pUnk; + RETURN pvObj; } MethodTable *pMT = (*poref)->GetMethodTable(); diff --git a/src/coreclr/tests/src/Interop/COM/ComWrappers/Common.cs b/src/coreclr/tests/src/Interop/COM/ComWrappers/Common.cs index 2f322018f0f80..0e75049200c9b 100644 --- a/src/coreclr/tests/src/Interop/COM/ComWrappers/Common.cs +++ b/src/coreclr/tests/src/Interop/COM/ComWrappers/Common.cs @@ -11,6 +11,7 @@ namespace ComWrappersTests.Common // Managed object with native wrapper definition. // [Guid("447BB9ED-DA48-4ABC-8963-5BB5C3E0AA09")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface ITest { void SetValue(int i); diff --git a/src/coreclr/tests/src/Interop/COM/ComWrappers/GlobalInstance/GlobalInstance.cs b/src/coreclr/tests/src/Interop/COM/ComWrappers/GlobalInstance/GlobalInstance.cs index ef9870b08672d..b362bc641b037 100644 --- a/src/coreclr/tests/src/Interop/COM/ComWrappers/GlobalInstance/GlobalInstance.cs +++ b/src/coreclr/tests/src/Interop/COM/ComWrappers/GlobalInstance/GlobalInstance.cs @@ -48,9 +48,9 @@ struct MarshalInterface [DllImport(nameof(MockReferenceTrackerRuntime))] extern public static int UpdateTestObjectAsInterface( - [MarshalAs(UnmanagedType.Interface)] Test testObj, + [MarshalAs(UnmanagedType.Interface)] ITest testObj, int i, - [Out, MarshalAs(UnmanagedType.Interface)] out Test ret); + [Out, MarshalAs(UnmanagedType.Interface)] out ITest ret); } private const string ManagedServerTypeName = "ConsumeNETServerTesting"; @@ -298,6 +298,11 @@ private static void ValidateMarshalAPIs(bool validateUseRegistered) IntPtr dispatchWrapper = Marshal.GetIDispatchForObject(dispatchObj); Assert.AreNotEqual(IntPtr.Zero, dispatchWrapper); Assert.AreEqual(dispatchObj, registeredWrapper.LastComputeVtablesObject, "Registered ComWrappers instance should have been called"); + + Console.WriteLine($" -- Validate Marshal.GetIDispatchForObject != Marshal.GetIUnknownForObject..."); + IntPtr unknownWrapper = Marshal.GetIUnknownForObject(dispatchObj); + Assert.AreNotEqual(IntPtr.Zero, unknownWrapper); + Assert.AreNotEqual(unknownWrapper, dispatchWrapper); } Console.WriteLine($" -- Validate Marshal.GetObjectForIUnknown..."); @@ -326,33 +331,33 @@ private static void ValidatePInvokes(bool validateUseRegistered) GlobalComWrappers.Instance.ReturnInvalid = !validateUseRegistered; Console.WriteLine($" -- Validate MarshalAs IUnknown..."); - ValidateInterfaceMarshaler(MarshalInterface.UpdateTestObjectAsIUnknown, validateUseRegistered); + ValidateInterfaceMarshaler(MarshalInterface.UpdateTestObjectAsIUnknown, shouldSucceed: validateUseRegistered); object obj = MarshalInterface.CreateTrackerObjectAsIUnknown(); Assert.AreEqual(validateUseRegistered, obj is FakeWrapper, $"Should{(validateUseRegistered ? string.Empty : "not")} have returned {nameof(FakeWrapper)} instance"); if (validateUseRegistered) { Console.WriteLine($" -- Validate MarshalAs IDispatch..."); - ValidateInterfaceMarshaler(MarshalInterface.UpdateTestObjectAsIDispatch, validateUseRegistered, new TestEx(IID_IDISPATCH)); + ValidateInterfaceMarshaler(MarshalInterface.UpdateTestObjectAsIDispatch, shouldSucceed: true, new TestEx(IID_IDISPATCH)); Console.WriteLine($" -- Validate MarshalAs IInspectable..."); - ValidateInterfaceMarshaler(MarshalInterface.UpdateTestObjectAsIInspectable, validateUseRegistered, new TestEx(IID_IINSPECTABLE)); + ValidateInterfaceMarshaler(MarshalInterface.UpdateTestObjectAsIInspectable, shouldSucceed: true, new TestEx(IID_IINSPECTABLE)); } Console.WriteLine($" -- Validate MarshalAs Interface..."); - ValidateInterfaceMarshaler(MarshalInterface.UpdateTestObjectAsInterface, validateUseRegistered); + ValidateInterfaceMarshaler(MarshalInterface.UpdateTestObjectAsInterface, shouldSucceed: true); if (validateUseRegistered) { Assert.Throws(() => MarshalInterface.CreateTrackerObjectWrongType()); FakeWrapper wrapper = MarshalInterface.CreateTrackerObjectAsInterface(); - Assert.IsNotNull(obj, $"Should have returned {nameof(FakeWrapper)} instance"); + Assert.IsNotNull(wrapper, $"Should have returned {nameof(FakeWrapper)} instance"); } } private delegate int UpdateTestObject(T testObj, int i, out T ret) where T : class; - private static void ValidateInterfaceMarshaler(UpdateTestObject func, bool validateUseRegistered, Test testObj = null) where T : class + private static void ValidateInterfaceMarshaler(UpdateTestObject func, bool shouldSucceed, Test testObj = null) where T : class { const int E_NOINTERFACE = unchecked((int)0x80004002); int value = 10; @@ -363,7 +368,7 @@ private static void ValidatePInvokes(bool validateUseRegistered) T retObj; int hr = func(testObj as T, value, out retObj); Assert.AreEqual(testObj, GlobalComWrappers.Instance.LastComputeVtablesObject, "Registered ComWrappers instance should have been called"); - if (validateUseRegistered) + if (shouldSucceed) { Assert.IsTrue(retObj is Test); Assert.AreEqual(value, testObj.GetValue()); diff --git a/src/coreclr/tests/src/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp b/src/coreclr/tests/src/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp index 867efa01866e4..54cf0bb31f14b 100644 --- a/src/coreclr/tests/src/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp +++ b/src/coreclr/tests/src/Interop/COM/ComWrappers/MockReferenceTrackerRuntime/ReferenceTrackerRuntime.cpp @@ -374,5 +374,10 @@ extern "C" DLL_EXPORT int STDMETHODCALLTYPE UpdateTestObjectAsInterface(ITest *o if (obj == nullptr) return E_POINTER; - return UpdateTestObjectAsIUnknown(obj, i, (IUnknown**)out); + HRESULT hr; + RETURN_IF_FAILED(obj->SetValue(i)); + + obj->AddRef(); + *out = obj; + return S_OK; } From 18f65b666bd4ff85ab649f4053f46b883541c3e7 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 11 May 2020 21:47:13 +0300 Subject: [PATCH 108/420] Fix iOS and Android samples (#36223) --- src/mono/netcore/sample/Android/Program.csproj | 5 +++-- src/mono/netcore/sample/iOS/Program.csproj | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/mono/netcore/sample/Android/Program.csproj b/src/mono/netcore/sample/Android/Program.csproj index 065f601c4032e..7a7247fda82d5 100644 --- a/src/mono/netcore/sample/Android/Program.csproj +++ b/src/mono/netcore/sample/Android/Program.csproj @@ -2,9 +2,10 @@ Exe bin + Portable $(NetCoreAppCurrent) x64 - $(ArtifactsDir)bin\lib-runtime-packs\runtimes\android-$(TargetArchitecture) + $(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-Android-$(Configuration)-$(TargetArchitecture)\runtimes\android-$(TargetArchitecture) $(MSBuildThisFileDirectory)\bin\bundle $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder')) @@ -15,7 +16,7 @@ + AssemblyFile="$(AndroidAppBuilder)\$(NetCoreAppCurrent)-$(Configuration)\AndroidAppBuilder.dll" /> diff --git a/src/mono/netcore/sample/iOS/Program.csproj b/src/mono/netcore/sample/iOS/Program.csproj index ddc14fb0bb531..32e8b6ef336cd 100644 --- a/src/mono/netcore/sample/iOS/Program.csproj +++ b/src/mono/netcore/sample/iOS/Program.csproj @@ -2,9 +2,10 @@ Exe bin + Portable $(NetCoreAppCurrent) x64 - $(ArtifactsDir)bin\lib-runtime-packs\runtimes\ios-$(TargetArchitecture) + $(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-iOS-$(Configuration)-$(TargetArchitecture)\runtimes\ios-$(TargetArchitecture) $(ArtifactsDir)bin\mono\iOS.$(TargetArchitecture).$(Configuration) $(MSBuildThisFileDirectory)\bin\bundle $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder')) @@ -16,7 +17,7 @@ + AssemblyFile="$(AppleAppBuilder)\$(NetCoreAppCurrent)-$(Configuration)\AppleAppBuilder.dll" /> From 99aae90739c2ad5642a36873334c82a8b7fb2de9 Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Mon, 11 May 2020 12:29:42 -0700 Subject: [PATCH 109/420] Update the mscorlib.md document. (#36225) Rename mscorlib.md to corelib.md. Remove no longer relevant details. --- docs/design/coreclr/botr/README.md | 2 +- docs/design/coreclr/botr/corelib.md | 352 +++++++++++++++++ docs/design/coreclr/botr/method-descriptor.md | 2 +- docs/design/coreclr/botr/mscorlib.md | 355 ------------------ src/coreclr/src/vm/ceemain.cpp | 4 +- 5 files changed, 356 insertions(+), 359 deletions(-) create mode 100644 docs/design/coreclr/botr/corelib.md delete mode 100644 docs/design/coreclr/botr/mscorlib.md diff --git a/docs/design/coreclr/botr/README.md b/docs/design/coreclr/botr/README.md index fde9992daeb9c..4c6e6cb5b3bf6 100644 --- a/docs/design/coreclr/botr/README.md +++ b/docs/design/coreclr/botr/README.md @@ -19,7 +19,7 @@ Below is a table of contents. - [Method Descriptor](method-descriptor.md) - [Virtual Stub Dispatch](virtual-stub-dispatch.md) - [Stack Walking](stackwalking.md) -- [Mscorlib and Calling Into the Runtime](mscorlib.md) +- [`System.Private.CoreLib` and calling into the runtime](corelib.md) - [Data Access Component (DAC) Notes](dac-notes.md) - [Profiling](profiling.md) - [Implementing Profilability](profilability.md) diff --git a/docs/design/coreclr/botr/corelib.md b/docs/design/coreclr/botr/corelib.md new file mode 100644 index 0000000000000..9b6f5dbb7f4c2 --- /dev/null +++ b/docs/design/coreclr/botr/corelib.md @@ -0,0 +1,352 @@ +`System.Private.CoreLib` and calling into the runtime +=== + +# Introduction + +`System.Private.CoreLib.dll` is the assembly for defining the core parts of the type system, and a good portion of the Base Class Library in .NET Framework. It was originally named `mscorlib` in .NET Core, though many places in the code and documentation still refer to it as `mscorlib`. This document will endeavour to stick to using `System.Private.CoreLib` or CoreLib. Base data types live in this assembly, and it has a tight coupling with the CLR. Here you will learn exactly how and why CoreLib is special and the basics about calling into the CLR from managed code via QCall and FCall methods. It also discusses calling from within the CLR into managed code. + +## Dependencies + +Since CoreLib defines base data types like `Object`, `Int32`, and `String`, CoreLib cannot depend on other managed assemblies. However, there is a strong dependency between CoreLib and the CLR. Many of the types in CoreLib need to be accessed from native code, so the layout of many managed types is defined both in managed code and in native code inside the CLR. Additionally, some fields may be defined only in Debug, Checked, or Release builds, so typically CoreLib must be compiled separately for each type of build. + +`System.Private.CoreLib.dll` builds separately for 64 bit and 32 bit, and some public constants it exposes differ by bitness. By using these constants, such as `IntPtr.Size`, most libraries above CoreLib should not need to build separately for 32 bit vs. 64 bit. + +## What makes `System.Private.CoreLib` special? + +CoreLib has several unique properties, many of which are due to its tight coupling to the CLR. + +- CoreLib defines the core types necessary to implement the CLR's Virtual Object System, such as the base data types (`Object`, `Int32`, `String`, etc). +- The CLR must load CoreLib on startup to load certain system types. +- Can only have one CoreLib loaded in the process at a time, due to layout issues. Loading multiple CoreLibs would require formalizing a contract of behavior, FCall methods, and datatype layout between CLR and CoreLib, and keeping that contract relatively stable across versions. +- CoreLib's types are used heavily for native interop and managed exceptions should map correctly to native error codes/formats. +- The CLR's multiple JIT compilers may special case a small group of certain methods in CoreLib for performance reasons, both in terms of optimizing away the method (such as `Math.Cos(double)`), or calling a method in peculiar ways (such as `Array.Length`, or some implementation details on `StringBuilder` for getting the current thread). +- CoreLib will need to call into native code, via P/Invoke where appropriate, primarily into the underlying operating system or occasionally a platform adaptation layer. +- CoreLib will require calling into the CLR to expose some CLR-specific functionality, such as triggering a garbage collection, to load classes, or to interact with the type system in a non-trivial way. This requires a bridge between managed code and native, "manually managed" code within the CLR. +- The CLR will need to call into managed code to call managed methods, and to get at certain functionality that is only implemented in managed code. + +# Interface between managed and CLR code + +To reiterate, the needs of managed code in CoreLib include: + +- The ability to access fields of some managed data structures in both managed code and "manually managed" code within the CLR. +- Managed code must be able to call into the CLR. +- The CLR must be able to call managed code. + +To implement these, we need a way for the CLR to specify and optionally verify the layout of a managed object in native code, a managed mechanism for calling into native code, and a native mechanism for calling into managed code. + +The managed mechanism for calling into native code must also support the special managed calling convention used by `String`'s constructors, where the constructor allocates the memory used by the object (instead of the typical convention where the constructor is called after the GC allocates memory). + +The CLR provides a [`mscorlib` binder](https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/binder.cpp) internally, providing a mapping between unmanaged types and fields to managed types and fields. The binder will look up and load classes and allows the calling of managed methods. It also performs simple verification to ensure the correctness of any layout information specified in both managed and native code. The binder ensures that the managed class attempting to load exists in mscorlib, has been loaded, and the field offsets are correct. It also needs the ability to differentiate between method overloads with different signatures. + +# Calling from managed to native code + +Two techniques exist for calling into the CLR from managed code. FCall allows you to call directly into the CLR code, and provides a lot of flexibility in terms of manipulating objects, though it is easy to cause GC holes by not tracking object references correctly. QCall also allows you to call into the CLR via the P/Invoke, but is much harder to accidentally mis-use. FCalls are identified in managed code as extern methods with the [`MethodImplOptions.InternalCall`](https://docs.microsoft.com/dotnet/api/system.runtime.compilerservices.methodimploptions) bit set. QCalls are marked `static extern` methods similar to regular P/Invokes, but are directed toward a library called `"QCall"`. + +There is a small variant of FCall called HCall (for Helper call) for implementing JIT helpers. The HCall is intended for doing things like accessing multi-dimensional array elements, range checks, etc. The only difference between HCall and FCall is that HCall methods won't show up in an exception stack trace. + +### Choosing between FCall, QCall, P/Invoke, and writing in managed code + +First, remember that you should be writing as much as possible in managed code. You avoid a raft of potential GC hole issues, you get a better debugging experience, and the code is often simpler. + +Reasons to write FCalls in the past generally fell into three camps: missing language features, better performance, or implementing unique interactions with the runtime. C# now has almost every useful language feature that you could get from C++, including unsafe code and stack-allocated buffers, and this eliminates the first two reasons for FCalls. We have ported some parts of the CLR that were heavily reliant on FCalls to managed code in the past (such as Reflection, some Encoding, and String operations) and we intend to continue this momentum. + +If the only reason you're defining a FCall method is to call a native method, you should be using P/Invoke to call the method directly. [P/Invoke](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.dllimportattribute) is the public native method interface and should be doing everything you need in a correct manner. + +If you still need to implement a feature inside the runtime, consider if there is a way to reduce the frequency of transitioning to native code. Can you write the common case in managed and only call into native for some rare corner cases? You're usually best off keeping as much as possible in managed code. + +QCalls are the preferred mechanism going forward. You should only use FCalls when you are "forced" to. This happens when there is common "short path" through the code that is important to optimize. This short path should not be more than a few hundred instructions, cannot allocate GC memory, take locks or throw exceptions (`GC_NOTRIGGER`, `NOTHROWS`). In all other circumstances (and especially when you enter a FCall and then simply erect HelperMethodFrame), you should be using QCall. + +FCalls were specifically designed for short paths of code that must be optimized. They allowed explicit control over when erecting a frame was done. However, it is error prone and not worth the complexity for many APIs. QCalls are essentially P/Invokes into the CLR. In the event the performance of an FCall is required consider creating a QCall and marking it with [`SuppressGCTransitionAttribute`](https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.suppressgctransitionattribute). + +As a result, QCalls give you some advantageous marshaling for `SafeHandle`s automatically – your native method just takes a `HANDLE` type, and can be used without worrying whether someone will free the handle while in that method body. The resulting FCall method would need to use a `SafeHandleHolder` and may need to protect the `SafeHandle`, etc. Leveraging the P/Invoke marshaler can avoid this additional plumbing code. + +## QCall functional behavior + +QCalls are very much like a normal P/Invoke from CoreLib to CLR. Unlike FCalls, QCalls will marshal all arguments as unmanaged types like a normal P/Invoke. QCall also switch to preemptive GC mode like a normal P/Invoke. These two features should make QCalls easier to write reliably compared to FCalls. QCalls are not prone to GC holes and GC starvation bugs that are common with FCalls. + +QCalls perform better than FCalls that erect a `HelperMethodFrame`. The overhead is about 1.4x less compared to FCall w/ `HelperMethodFrame` overhead on x86 and x64. + +The preferred types for QCall arguments are primitive types that are efficiently handled by the P/Invoke marshaler (`INT32`, `LPCWSTR`, `BOOL`). Notice that `BOOL` is the correct boolean flavor for QCall arguments. On the other hand, `CLR_BOOL` is the correct boolean flavor for FCall arguments. + +The pointers to common unmanaged EE structures should be wrapped into handle types. This is to make the managed implementation type safe and avoid falling into unsafe C# everywhere. See AssemblyHandle in [vm\qcall.h][qcall] for an example. + +[qcall]: https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/qcall.h + +Passing object references in and out of QCalls is done by wrapping a pointer to a local variable in a handle. It is intentionally cumbersome and should be avoided if reasonably possible. See the `StringHandleOnStack` in the example below. Returning objects, especially strings, from QCalls is the only common pattern where passing the raw objects is widely acceptable. (For reasoning on why this set of restrictions helps make QCalls less prone to GC holes, read the ["GC Holes, FCall, and QCall"](#gcholes) section below.) + +### QCall example - managed + +Do not replicate the comments into your actual QCall implementation. This is for illustrative purposes. + +```CSharp +class Foo +{ + // All QCalls should have the following DllImport attribute + [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] + + // QCalls should always be static extern. + private static extern bool BarInternal(int flags, string inString, StringHandleOnStack retString); + + // Many QCalls have a thin managed wrapper around them to perform + // as much work prior to the transition as possible. An example would be + // argument validation which is easier in managed than native code. + public string Bar(int flags) + { + if (flags != 0) + throw new ArgumentException("Invalid flags"); + + string retString = null; + // The strings are returned from QCalls by taking address + // of a local variable using StringHandleOnStack + if (!BarInternal(flags, this.Id, new StringHandleOnStack(ref retString))) + FatalError(); + + return retString; + } +} +``` + +### QCall example - unmanaged + +Do not replicate the comments into your actual QCall implementation. + +The QCall entrypoint has to be registered in tables in [vm\ecalllist.h][ecalllist] using `QCFuncEntry` macro. See ["Registering your QCall or FCall Method"](#register) below. + +[ecalllist]: https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/ecalllist.h + +```C++ +class FooNative +{ +public: + // All QCalls should be static and tagged with QCALLTYPE + static + BOOL QCALLTYPE BarInternal(int flags, LPCWSTR wszString, QCall::StringHandleOnStack retString); +}; + +BOOL QCALLTYPE FooNative::BarInternal(int flags, LPCWSTR wszString, QCall::StringHandleOnStack retString) +{ + // All QCalls should have QCALL_CONTRACT. + // It is alias for THROWS; GC_TRIGGERS; MODE_PREEMPTIVE. + QCALL_CONTRACT; + + // Optionally, use QCALL_CHECK instead and the expanded form of the contract + // if you want to specify preconditions: + // CONTRACTL { + // QCALL_CHECK; + // PRECONDITION(wszString != NULL); + // } CONTRACTL_END; + + // The only line between QCALL_CONTRACT and BEGIN_QCALL + // should be the return value declaration if there is one. + BOOL retVal = FALSE; + + // The body has to be enclosed in BEGIN_QCALL/END_QCALL macro. + // It is necessary for exception handling. + BEGIN_QCALL; + + // Argument validation would ideally be in managed, but in some cases + // needs to be done in native. If argument validation is done in + // managed asserting in native is warranted. + _ASSERTE(flags != 0); + + // No need to worry about GC moving strings passed into QCall. + // Marshalling pins them for us. + printf("%S\n", wszString); + + // This is the most efficient way to return strings back + // to managed code. No need to use StringBuilder. + retString.Set(L"Hello"); + + // You can not return from inside of BEGIN_QCALL/END_QCALL. + // The return value has to be passed out in helper variable. + retVal = TRUE; + + END_QCALL; + + return retVal; +} +``` + +## FCall functional behavior + +FCalls allow more flexibility in terms of passing object references around, but with higher code complexity and more opportunities to make mistakes. Additionally, FCall methods must either erect a helper method frame along their common code paths, or for any FCall of non-trivial length, explicitly poll for whether a garbage collection must occur. Failing to do so will lead to starvation issues if managed code repeatedly calls the FCall method in a tight loop, because FCalls execute while the thread only allows the GC to run in a cooperative manner. + +FCalls require a lot of boilerplate code, too much to describe here. Refer to [fcall.h][fcall] for details. + +[fcall]: https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/fcall.h + +### GC holes, FCall, and QCall + +A more complete discussion on GC holes can be found in the [CLR Code Guide](../../../coding-guidelines/clr-code-guide.md). Look for ["Is your code GC-safe?"](../../../coding-guidelines/clr-code-guide.md#2.1). This tailored discussion motivates some of the reasons why FCall and QCall have some of their strange conventions. + +Object references passed as parameters to FCall methods are not GC-protected, meaning that if a GC occurs, those references will point to the old location in memory of an object, not the new location. For this reason, FCalls usually follow the discipline of accepting something like `StringObject*` as their parameter type, then explicitly converting that to a `STRINGREF` before doing operations that may trigger a GC. If you expect to use an object reference later, you must GC protect object references before triggering a GC. + +All GC heap allocations within an FCall method must happen within a helper method frame. If you allocate memory on the GC heap, the GC may collect dead objects and move objects around in unpredictable ways, with some low probability. For this reason, you must manually report any object references in your method to the GC, so that if a garbage collection occurs, your object reference will be updated to refer to the new location in memory. Any pointers into managed objects (like arrays or Strings) within your code will not be updated automatically, and must be re-fetched after any operation that may allocate memory and before your first usage. Reporting a reference can be done via the `GCPROTECT_*` macros or as parameters when erecting a helper method frame. + +Failing to properly report an `OBJECTREF` or to update an interior pointer is commonly referred to as a "GC hole", because the `OBJECTREF` class will do some validation that it points to a valid object every time you dereference it in Debug and Checked builds. When an `OBJECTREF` pointing to an invalid object is dereferenced, an assert will trigger saying something like "Detected an invalid object reference. Possible GC hole?". This assert is unfortunately easy to hit when writing "manually managed" code. + +Note that QCall's programming model is restrictive to sidestep GC holes by forcing you to pass in the address of an object reference on the stack. This guarantees that the object reference is GC protected by the JIT's reporting logic, and that the actual object reference will not move because it is not allocated in the GC heap. QCall is our recommended approach, precisely because it makes GC holes harder to write. + +### FCall epilog walker for x86 + +The managed stack walker needs to be able to find its way from FCalls. It is relative easy on newer platforms that define conventions for stack unwinding as part of the ABI. The stack unwinding conventions are not defined by an ABI for x86. The runtime works around this by implementing an epilog walker. The epilog walker computes the FCall return address and callee save registers by simulating the FCall execution. This imposes limits on what constructs are allowed in the FCall implementation. + +Complex constructs like stack allocated objects with destructors or exception handling in the FCall implementation may confuse the epilog walker. This can lead to GC holes or crashes during stack walking. There is no comprehensive list of what constructs should be avoided to prevent this class of bugs. An FCall implementation that is fine one day may break with the next C++ compiler update. We depend on stress runs and code coverage to find bugs in this area. + +Setting a breakpoint inside an FCall implementation may confuse the epilog walker. It leads to an "Invalid breakpoint in a helpermethod frame epilog" assert inside [vm\i386\gmsx86.cpp](https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/i386/gmsx86.cpp). + +### FCall example – managed + +Here's a real-world example from the `String` class: + +```CSharp +public partial sealed class String +{ + [MethodImpl(MethodImplOptions.InternalCall)] + private extern string? IsInterned(); + + public static string? IsInterned(string str) + { + if (str == null) + { + throw new ArgumentNullException(nameof(str)); + } + + return str.IsInterned(); + } +} +``` + +### FCall example – unmanaged + +The FCall entrypoint has to be registered in tables in [vm\ecalllist.h][ecalllist] using `FCFuncEntry` macro. See ["Registering your QCall or FCall Method"](#register). + +This method is an instance method in managed code, with the "this" parameter passed as the first argument. We use `StringObject*` as the argument type, then copy it into a `STRINGREF` so we get some error checking when we use it. + +```C++ +FCIMPL1(Object*, AppDomainNative::IsStringInterned, StringObject* pStringUNSAFE) +{ + FCALL_CONTRACT; + + STRINGREF refString = ObjectToSTRINGREF(pStringUNSAFE); + STRINGREF* prefRetVal = NULL; + + HELPER_METHOD_FRAME_BEGIN_RET_1(refString); + + if (refString == NULL) + COMPlusThrow(kArgumentNullException, W("ArgumentNull_String")); + + prefRetVal = GetAppDomain()->IsStringInterned(&refString); + + HELPER_METHOD_FRAME_END(); + + if (prefRetVal == NULL) + return NULL; + + return OBJECTREFToObject(*prefRetVal); +} +FCIMPLEND +``` + +## Registering your QCall or FCall method + +The CLR must know the name of your QCall and FCall methods, both in terms of the managed class and method names, as well as which native methods to call. That is done in [ecalllist.h][ecalllist], with two arrays. The first array maps namespace and class names to an array of function elements. That array of function elements then maps individual method names and signatures to function pointers. + +Say we defined an FCall method for `String.IsInterned()`, in the example above. First, we need to ensure that we have an array of function elements for the String class. + +``` C++ +// Note these have to remain sorted by name:namespace pair + ... + FCClassElement("String", "System", gStringFuncs) + ... +``` + +Second, we must then ensure that `gStringFuncs` contains a proper entry for `IsInterned`. Note that if a method name has multiple overloads then we can specify a signature: + +```C++ +FCFuncStart(gStringFuncs) + ... + FCFuncElement("IsInterned", AppDomainNative::IsStringInterned) + ... +FCFuncEnd() +``` + +There is a parallel `QCFuncElement` macro. + +## Naming convention + +FCalls and QCalls should not be publicly exposed. Instead wrap the actual FCall or QCall and provide a API approved name. + +The internal FCall or QCall should use the "Internal" suffix to disambiguate the name of the FCall or QCall from public entry point (e.g. the public entry point does error checking and then calls shared worker function with exactly same signature). This is no different from how you would deal with this situation in pure managed code in BCL. + +# Types with a managed/unmanaged duality + +Certain managed types must have a representation available in both managed and native code. You could ask whether the canonical definition of a type is in managed code or native code within the CLR, but the answer doesn't matter – the key thing is they must both be identical. This will allow the CLR's native code to access fields within a managed object in a fast and efficient manner. There is a more complex way of using essentially the CLR's equivalent of Reflection over `MethodTable`s and `FieldDesc`s to retrieve field values, but this doesn't perform as well as desired and isn't very usable. For commonly used types, it makes sense to declare a data structure in native code and keep the two in sync. + +The CLR provides a binder for this purpose. After you define your managed and native classes, you should provide some clues to the binder to help ensure that the field offsets remain the same to quickly spot when someone accidentally adds a field to only one definition of a type. + +In [mscorlib.h][mscorlib.h], use macros ending in "_U" to describe a type, the name of fields in managed code, and the name of fields in a corresponding native data structure. Additionally, you can specify a list of methods, and reference them by name when you attempt to call them later. + +[mscorlib.h]: https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/mscorlib.h + +``` C++ +DEFINE_CLASS_U(SAFE_HANDLE, Interop, SafeHandle, SafeHandle) +DEFINE_FIELD(SAFE_HANDLE, HANDLE, handle) +DEFINE_FIELD_U(SAFE_HANDLE, STATE, _state, SafeHandle, m_state) +DEFINE_FIELD_U(SAFE_HANDLE, OWNS_HANDLE, _ownsHandle, SafeHandle, m_ownsHandle) +DEFINE_FIELD_U(SAFE_HANDLE, INITIALIZED, _fullyInitialized, SafeHandle, m_fullyInitialized) +DEFINE_METHOD(SAFE_HANDLE, GET_IS_INVALID, get_IsInvalid, IM_RetBool) +DEFINE_METHOD(SAFE_HANDLE, RELEASE_HANDLE, ReleaseHandle, IM_RetBool) +DEFINE_METHOD(SAFE_HANDLE, DISPOSE, Dispose, IM_RetVoid) +DEFINE_METHOD(SAFE_HANDLE, DISPOSE_BOOL, Dispose, IM_Bool_RetVoid) +``` + +Then, you can use the `REF` template to create a type name like `SAFEHANDLEREF`. All the error checking from `OBJECTREF` is built into the `REF` template, and you can freely dereference this `SAFEHANDLEREF` and use fields off of it in native code. You still must GC protect these references. + +# Calling into managed code from unmanaged code + +Clearly there are places where the CLR must call into managed code from native. For this purpose, we have added a `MethodDescCallSite` class to handle a lot of plumbing for you. Conceptually, all you need to do is find the `MethodDesc*` for the method you want to call, find a managed object for the "this" pointer (if you're calling an instance method), pass in an array of arguments, and deal with the return value. Internally, you'll need to potentially toggle your thread's state to allow the GC to run in preemptive mode, etc. + +Here's a simplified example. Note how this instance uses the binder described in the previous section to call `SafeHandle`'s virtual `ReleaseHandle` method. + +```C++ +void SafeHandle::RunReleaseMethod(SafeHandle* psh) +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_COOPERATIVE; + } CONTRACTL_END; + + SAFEHANDLEREF sh(psh); + + GCPROTECT_BEGIN(sh); + + MethodDescCallSite releaseHandle(s_pReleaseHandleMethod, METHOD__SAFE_HANDLE__RELEASE_HANDLE, (OBJECTREF*)&sh, TypeHandle(), TRUE); + + ARG_SLOT releaseArgs[] = { ObjToArgSlot(sh) }; + if (!(BOOL)releaseHandle.Call_RetBool(releaseArgs)) { + MDA_TRIGGER_ASSISTANT(ReleaseHandleFailed, ReportViolation)(sh->GetTypeHandle(), sh->m_handle); + } + + GCPROTECT_END(); +} +``` + +# Interactions with other subsystems + +## Debugger + +One limitation of FCalls today is that you cannot easily debug both managed code and FCalls easily in Visual Studio's Interop (or mixed mode) debugging. Setting a breakpoint today in an FCall and debugging with Interop debugging just doesn't work. This most likely won't be fixed. + +# Physical architecture + +When the CLR starts up, CoreLib is loaded by a method called `SystemDomain::LoadBaseSystemClasses()`. Here, the base data types and other similar classes (like `Exception`) are loaded, and appropriate global pointers are set up to refer to CoreLib's types. + +For FCalls, look in [fcall.h][fcall] for infrastructure, and [ecalllist.h][ecalllist] to properly inform the runtime about your FCall method. + +For QCalls, look in [qcall.h][qcall] for associated infrastructure, and [ecalllist.h][ecalllist] to properly inform the runtime about your QCall method. + +More general infrastructure and some native type definitions can be found in [object.h][object.h]. The binder uses `mscorlib.h` to associate managed and native classes. + +[object.h]: https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/object.h diff --git a/docs/design/coreclr/botr/method-descriptor.md b/docs/design/coreclr/botr/method-descriptor.md index ea5123bdc4b9a..7d3f24ccf40f1 100644 --- a/docs/design/coreclr/botr/method-descriptor.md +++ b/docs/design/coreclr/botr/method-descriptor.md @@ -42,7 +42,7 @@ Used for less common IL methods that have generic instantiation or that do not h **FCall** -Internal methods implemented in unmanaged code. These are [methods marked with MethodImplAttribute(MethodImplOptions.InternalCall) attribute](mscorlib.md), delegate constructors and tlbimp constructors. +Internal methods implemented in unmanaged code. These are [methods marked with MethodImplAttribute(MethodImplOptions.InternalCall) attribute](corelib.md), delegate constructors and tlbimp constructors. **NDirect** diff --git a/docs/design/coreclr/botr/mscorlib.md b/docs/design/coreclr/botr/mscorlib.md deleted file mode 100644 index c2d995567f491..0000000000000 --- a/docs/design/coreclr/botr/mscorlib.md +++ /dev/null @@ -1,355 +0,0 @@ -Mscorlib and Calling Into the Runtime -=== - -Author: Brian Grunkemeyer ([@briangru](https://github.com/briangru)) - 2006 - -# Introduction - -Mscorlib is the assembly for defining the core parts of the type system, and a good portion of the Base Class Library in .NET Framework. It has been renamed to System.Private.CoreLib in .NET Core, though many places in the code and documentation still refer to it as mscorlib. Base data types live in this assembly, and it has a tight coupling with the CLR. Here you will learn exactly how & why mscorlib.dll is special, and the basics about calling into the CLR from managed code via QCall and FCall methods. It also discusses calling from within the CLR into managed code. - -## Dependencies - -Since mscorlib defines base data types like Object, Int32, and String, mscorlib cannot depend on other managed assemblies. However, there is a strong dependency between mscorlib and the CLR. Many of the types in mscorlib need to be accessed from native code, so the layout of many managed types is defined both in managed code and in native code inside the CLR. Additionally, some fields may be defined only in debug or checked builds, so typically mscorlib must be compiled separately for checked vs. retail builds. - -For 64 bit platforms, some constants are also defined at compile time. So a 64 bit mscorlib.dll is slightly different from a 32 bit mscorlib.dll. Due to these constants, such as IntPtr.Size, most libraries above mscorlib should not need to build separately for 32 bit vs. 64 bit. - -## What Makes Mscorlib Special? - -Mscorlib has several unique properties, many of which are due to its tight coupling to the CLR. - -- Mscorlib defines the core types necessary to implement the CLR's Virtual Object System, such as the base data types (Object, Int32, String, etc). -- The CLR must load mscorlib on startup to load certain system types. -- Can only have one mscorlib loaded in the process at a time, due to layout issues. Loading multiple mscorlibs would require formalizing a contract of behavior, FCall methods, and datatype layout between CLR & mscorlib, and keeping that contract relatively stable across versions. -- Mscorlib's types will be used heavily for native interop, and managed exceptions should map correctly to native error codes/formats. -- The CLR's multiple JIT compilers may special case a small group of certain methods in mscorlib for performance reasons, both in terms of optimizing away the method (such as Math.Cos(double)), or calling a method in peculiar ways (such as Array.Length, or some implementation details on StringBuilder for getting the current thread). -- Mscorlib will need to call into native code, via P/Invoke where appropriate, primarily into the underlying operating system or occasionally a platform adaptation layer. -- Mscorlib will require calling into the CLR to expose some CLR-specific functionality, such as triggering a garbage collection, to load classes, or to interact with the type system in a non-trivial way. This requires a bridge between managed code and native, "manually managed" code within the CLR. -- The CLR will need to call into managed code to call managed methods, and to get at certain functionality that is only implemented in managed code. - -# Interface between managed & CLR code - -To reiterate, the needs of managed code in mscorlib include: - -- The ability to access fields of some managed data structures in both managed code and "manually managed" code within the CLR -- Managed code must be able to call into the CLR -- The CLR must be able to call managed code. - -To implement these, we need a way for the CLR to specify and optionally verify the layout of a managed object in native code, a managed mechanism for calling into native code, and a native mechanism for calling into managed code. - -The managed mechanism for calling into native code must also support the special managed calling convention used by String's constructors, where the constructor allocates the memory used by the object (instead of the typical convention where the constructor is called after the GC allocates memory). - -The CLR provides a [mscorlib binder](https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/binder.cpp) internally, providing a mapping between unmanaged types and fields to managed types & fields. The binder will look up & load classes, allow you to call managed methods. It also does some simple verification to ensure the correctness of any layout information specified in both managed & native code. The binder ensures that the managed class you're attempting to use exists in mscorlib, has been loaded, and the field offsets are correct. It also needs the ability to differentiate between method overloads with different signatures. - -# Calling from managed to native code - -We have two techniques for calling into the CLR from managed code. FCall allows you to call directly into the CLR code, and provides a lot of flexibility in terms of manipulating objects, though it is easy to cause GC holes by not tracking object references correctly. QCall allows you to call into the CLR via the P/Invoke, and is much harder to accidentally mis-use than FCall. FCalls are identified in managed code as extern methods with the MethodImplOptions.InternalCall bit set. QCalls are _static_ extern methods that look like regular P/Invokes, but to a library called "QCall". - -There is a small variant of FCall called HCall (for Helper call) for implementing JIT helpers, for doing things like accessing multi-dimensional array elements, range checks, etc. The only difference between HCall and FCall is that HCall methods won't show up in an exception stack trace. - -### Choosing between FCall, QCall, P/Invoke, and writing in managed code - -First, remember that you should be writing as much as possible in managed code. You avoid a raft of potential GC hole issues, you get a good debugging experience, and the code is often simpler. It also is preparation for ongoing refactoring of mscorlib into smaller layered fully [managed libraries](https://github.com/dotnet/runtime/src/libraries). - -Reasons to write FCalls in the past generally fell into three camps: missing language features, better performance, or implementing unique interactions with the runtime. C# now has almost every useful language feature that you could get from C++, including unsafe code & stack-allocated buffers, and this eliminates the first two reasons for FCalls. We have ported some parts of the CLR that were heavily reliant on FCalls to managed code in the past (such as Reflection and some Encoding & String operations), and we want to continue this momentum. We may port our number formatting & String comparison code to managed in the future. - -If the only reason you're defining a FCall method is to call a native Win32 method, you should be using P/Invoke to call Win32 directly. P/Invoke is the public native method interface, and should be doing everything you need in a correct manner. - -If you still need to implement a feature inside the runtime, now consider if there is a way to reduce the frequency of transitioning to native code. Can you write the common case in managed, and only call into native for some rare corner cases? You're usually best off keeping as much as possible in managed code. - -QCalls are the preferred mechanism going forward. You should only use FCalls when you are "forced" to. This happens when there is common "short path" through the code that is important to optimize. This short path should not be more than a few hundred instructions, cannot allocate GC memory, take locks or throw exceptions (GC_NOTRIGGER, NOTHROWS). In all other circumstances (and especially when you enter a FCall and then simply erect HelperMethodFrame), you should be using QCall. - -FCalls were specifically designed for short paths of code that must be optimized. They allowed you to take explicit control over when erecting a frame was done. However it is error prone and is not worth it for many APIs. QCalls are essentially P/Invokes into CLR. - -As a result, QCalls give you some advantageous marshaling for SafeHandles automatically – your native method just takes a HANDLE type, and can use it without worrying whether someone will free the handle while you are in that method body. The resulting FCall method would need to use a SafeHandleHolder, and may need to protect the SafeHandle, etc. Leveraging the P/Invoke marshaler can avoid this additional plumbing code. - -## QCall Functional Behavior - -QCalls are very much like a normal P/Invoke from mscorlib.dll to CLR. Unlike FCalls, QCalls will marshal all arguments as unmanaged types like a normal P/Invoke. QCall also switch to preemptive GC mode like a normal P/Invoke. These two features should make QCalls easier to write reliably compared to FCalls. QCalls are not prone to GC holes and GC starvation bugs that are common with FCalls. - -QCalls perform better than FCalls that erect a HelperMethodFrame. The overhead is about 1.4x less compared to FCall w/ HelperMethodFrame overhead on x86 and x64. - -The preferred types for QCall arguments are primitive types that are efficiently handled by the P/Invoke marshaler (INT32, LPCWSTR, BOOL). Notice that BOOL is the correct boolean flavor for QCall arguments. On the other hand, CLR_BOOL is the correct boolean flavor for FCall arguments. - -The pointers to common unmanaged EE structures should be wrapped into handle types. This is to make the managed implementation type safe and avoid falling into unsafe C# everywhere. See AssemblyHandle in [vm\qcall.h][qcall] for an example. - -[qcall]: https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/qcall.h - -There is a way to pass a raw object references in and out of QCalls. It is done by wrapping a pointer to a local variable in a handle. It is intentionally cumbersome and should be avoided if reasonably possible. See the StringHandleOnStack in the example below. Returning objects, especially strings, from QCalls is the only common pattern where passing the raw objects is widely acceptable. (For reasoning on why this set of restrictions helps make QCalls less prone to GC holes, read the "GC Holes, FCall, and QCall" section below.) - -### QCall Example - Managed Part - -Do not replicate the comments into your actual QCall implementation. This is for illustrative purposes. - - class Foo - { - // All QCalls should have the following DllImport attribute - [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] - // QCalls should always be static extern. - private static extern bool Bar(int flags, string inString, StringHandleOnStack retString); - - // Many QCalls have a thin managed wrapper around them to expose them to - // the world in more meaningful way. - public string Bar(int flags) - { - string retString = null; - - // The strings are returned from QCalls by taking address - // of a local variable using StringHandleOnStack - if (!Bar(flags, this.Id, new StringHandleOnStack(ref retString))) - FatalError(); - - return retString; - } - } - -### QCall Example - Unmanaged Part - -Do not replicate the comments into your actual QCall implementation. - -The QCall entrypoint has to be registered in tables in [vm\ecalllist.h][ecalllist] using QCFuncEntry macro. See "Registering your QCall or FCall Method" below. - -[ecalllist]: https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/ecalllist.h - - class FooNative - { - public: - // All QCalls should be static and should be tagged with QCALLTYPE - static - BOOL QCALLTYPE Bar(int flags, LPCWSTR wszString, QCall::StringHandleOnStack retString); - }; - - BOOL QCALLTYPE FooNative::Bar(int flags, LPCWSTR wszString, QCall::StringHandleOnStack retString) - { - // All QCalls should have QCALL_CONTRACT. - // It is alias for THROWS; GC_TRIGGERS; MODE_PREEMPTIVE. - QCALL_CONTRACT; - - // Optionally, use QCALL_CHECK instead and the expanded form of the contract - // if you want to specify preconditions: - // CONTRACTL { - // QCALL_CHECK; - // PRECONDITION(wszString != NULL); - // } CONTRACTL_END; - - // The only line between QCALL_CONTRACT and BEGIN_QCALL - // should be the return value declaration if there is one. - BOOL retVal = FALSE; - - // The body has to be enclosed in BEGIN_QCALL/END_QCALL macro. It is necessary - // to make the exception handling work. - BEGIN_QCALL; - - // Validate arguments if necessary and throw exceptions. - // There is no convention currently on whether the argument validation should be - // done in managed or unmanaged code. - if (flags != 0) - COMPlusThrow(kArgumentException, L"InvalidFlags"); - - // No need to worry about GC moving strings passed into QCall. - // Marshalling pins them for us. - printf("%S", wszString); - - // This is most the efficient way to return strings back - // to managed code. No need to use StringBuilder. - retString.Set(L"Hello"); - - // You can not return from inside of BEGIN_QCALL/END_QCALL. - // The return value has to be passed out in helper variable. - retVal = TRUE; - - END_QCALL; - - return retVal; - } - -## FCall Functional Behavior - -FCalls allow more flexibility in terms of passing object references around, with a higher code complexity and more opportunities to hang yourself. Additionally, FCall methods must either erect a helper method frame along their common code paths, or for any FCall of non-trivial length, explicitly poll for whether a garbage collection must occur. Failing to do so will lead to starvation issues if managed code repeatedly calls the FCall method in a tight loop, because FCalls execute while the thread only allows the GC to run in a cooperative manner. - -FCalls require a lot of glue, too much to describe here. Look at [fcall.h][fcall] for details. - -[fcall]: https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/fcall.h - -### GC Holes, FCall, and QCall - -A much more complete discussion on GC holes can be found in the [CLR Code Guide](../../../coding-guidelines/clr-code-guide.md). Look for ["Is your code GC-safe?"](../../../coding-guidelines/clr-code-guide.md#2.1). This tailored discussion motivates some of the reasons why FCall and QCall have some of their strange conventions. - -Object references passed as parameters to FCall methods are not GC-protected, meaning that if a GC occurs, those references will point to the old location in memory of an object, not the new location. For this reason, FCalls usually follow the discipline of accepting something like "StringObject*" as their parameter type, then explicitly converting that to a STRINGREF before doing operations that may trigger a GC. You must GC protect object references before triggering a GC, if you expect to be able to use that object reference later. - -All GC heap allocations within an FCall method must happen within a helper method frame. If you allocate memory on the GC's heap, the GC may collect dead objects & move objects around in unpredictable ways, with some low probability. For this reason, you must manually report any object references in your method to the GC, so that if a garbage collection occurs, your object reference will be updated to refer to the new location in memory. Any pointers into managed objects (like arrays or Strings) within your code will not be updated automatically, and must be re-fetched after any operation that may allocate memory and before your first usage. Reporting a reference can be done via the GCPROTECT macros, or as parameters when you erect a helper method frame. - -Failing to properly report an OBJECTREF or to update an interior pointer is commonly referred to as a "GC hole", because the OBJECTREF class will do some validation that it points to a valid object every time you dereference it in checked builds. When an OBJECTREF pointing to an invalid object is dereferenced, you'll get an assert saying something like "Detected an invalid object reference. Possible GC hole?". This assert is unfortunately easy to hit when writing "manually managed" code. - -Note that QCall's programming model is restrictive to sidestep GC holes most of the time, by forcing you to pass in the address of an object reference on the stack. This guarantees that the object reference is GC protected by the JIT's reporting logic, and that the actual object reference will not move because it is not allocated in the GC heap. QCall is our recommended approach, precisely because it makes GC holes harder to write. - -### FCall Epilogue Walker for x86 - -The managed stack walker needs to be able to find its way from FCalls. It is relative easy on newer platforms that define conventions for stack unwinding as part of the ABI. The stack unwinding conventions are not defined by ABI for x86. The runtime works around it by implementing a epilog walker. The epilog walker computes the FCall return address and callee save registers by simulating the FCall execution. This imposes limits on what constructs are allowed in the FCall implementation. - -Complex constructs like stack allocated objects with destructors or exception handling in the FCall implementation may confuse the epilog walker. It leads to GC holes or crashes during stack walking. There is no exact list of what constructs should be avoided to prevent this class of bugs. An FCall implementation that is fine one day may break with the next C++ compiler update. We depend on stress runs & code coverage to find bugs in this area. - -Setting a breakpoint inside an FCall implementation may confuse the epilog walker. It leads to an "Invalid breakpoint in a helpermethod frame epilog" assert inside [vm\i386\gmsx86.cpp](https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/i386/gmsx86.cpp). - -### FCall Example – Managed Part - -Here's a real-world example from the String class: - - public partial sealed class String - { - // Replaces all instances of oldChar with newChar. - [MethodImplAttribute(MethodImplOptions.InternalCall)] - public extern String Replace (char oldChar, char newChar); - } - -### FCall Example – Native Part - -The FCall entrypoint has to be registered in tables in [vm\ecalllist.h][ecalllist] using FCFuncEntry macro. See "Registering your QCall or FCall Method". - -Notice how oldBuffer and newBuffer (interior pointers into String instances) are re-fetched after allocating memory. Also, this method is an instance method in managed code, with the "this" parameter passed as the first argument. We use StringObject* as the argument type, then copy it into a STRINGREF so we get some error checking when we use it. - - FCIMPL3(LPVOID, COMString::Replace, StringObject* thisRefUNSAFE, CLR_CHAR oldChar, CLR_CHAR newChar) - { - FCALL_CONTRACT; - - int length = 0; - int firstFoundIndex = -1; - WCHAR *oldBuffer = NULL; - WCHAR *newBuffer; - - STRINGREF newString = NULL; - STRINGREF thisRef = (STRINGREF)thisRefUNSAFE; - - if (thisRef==NULL) { - FCThrowRes(kNullReferenceException, L"NullReference_This"); - } - - [... Removed some uninteresting code here for illustrative purposes...] - - HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_2(Frame::FRAME_ATTR_RETURNOBJ, newString, thisRef); - - //Get the length and allocate a new String - //We will definitely do an allocation here. - newString = NewString(length); - - //After allocation, thisRef may have moved - oldBuffer = thisRef->GetBuffer(); - - //Get the buffers in both of the Strings. - newBuffer = newString->GetBuffer(); - - //Copy the characters, doing the replacement as we go. - for (int i=0; i template to create a type name like SAFEHANDLEREF. All the error checking from OBJECTREF is built into the REF macro, and you can freely dereference this SAFEHANDLEREF & use fields off of it in native code. You still must GC protect these references. - -# Calling Into Managed Code From Native - -Clearly there are places where the CLR must call into managed code from native. For this purpose, we have added a MethodDescCallSite class to handle a lot of plumbing for you. Conceptually, all you need to do is find the MethodDesc\* for the method you want to call, find a managed object for the "this" pointer (if you're calling an instance method), pass in an array of arguments, and deal with the return value. Internally, you'll need to potentially toggle your thread's state to allow the GC to run in preemptive mode, etc. - -Here's a simplified example. Note how this instance uses the binder described in the previous section to call SafeHandle's virtual ReleaseHandle method. - - void SafeHandle::RunReleaseMethod(SafeHandle* psh) - { - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } CONTRACTL_END; - - SAFEHANDLEREF sh(psh); - - GCPROTECT_BEGIN(sh); - - MethodDescCallSite releaseHandle(s_pReleaseHandleMethod, METHOD__SAFE_HANDLE__RELEASE_HANDLE, (OBJECTREF*)&sh, TypeHandle(), TRUE); - - ARG_SLOT releaseArgs[] = { ObjToArgSlot(sh) }; - if (!(BOOL)releaseHandle.Call_RetBool(releaseArgs)) { - MDA_TRIGGER_ASSISTANT(ReleaseHandleFailed, ReportViolation)(sh->GetTypeHandle(), sh->m_handle); - } - - GCPROTECT_END(); - } - -# Interactions with Other Subsystems - -## Debugger - -One limitation of FCalls today is that you cannot easily debug both managed code and FCalls easily in Visual Studio's Interop (or mixed mode) debugging. Setting a breakpoint today in an FCall and debugging with Interop debugging just doesn't work. This most likely won't be fixed. - -# Physical Architecture - -When the CLR starts up, mscorlib is loaded by a method called LoadBaseSystemClasses. Here, the base data types & other similar classes (like Exception) are loaded, and appropriate global pointers are set up to refer to mscorlib's types. - -For FCalls, look in [fcall.h][fcall] for infrastructure, and [ecalllist.h][ecalllist] to properly inform the runtime about your FCall method. - -For QCalls, look in [qcall.h][qcall] for associated infrastructure, and [ecalllist.h][ecalllist] to properly inform the runtime about your QCall method. - -More general infrastructure and some native type definitions can be found in [object.h][object.h]. The binder uses mscorlib.h to associate managed & native classes. - -[object.h]: https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/object.h diff --git a/src/coreclr/src/vm/ceemain.cpp b/src/coreclr/src/vm/ceemain.cpp index ee67d1e20a708..815635cbf5518 100644 --- a/src/coreclr/src/vm/ceemain.cpp +++ b/src/coreclr/src/vm/ceemain.cpp @@ -93,14 +93,14 @@ // file:threads.h#SuspendingTheRuntime and file:../../Documentation/botr/threading.md // * Garbage collection - file:gc.cpp#Overview and file:../../Documentation/botr/garbage-collection.md // * code:AppDomain - The managed version of a process. -// * Calling Into the runtime (FCALLs QCalls) file:../../Documentation/botr/mscorlib.md +// * Calling Into the runtime (FCALLs QCalls) file:../../Documentation/botr/corelib.md // * Exceptions - file:../../Documentation/botr/exceptions.md. The most important routine to start // with is code:COMPlusFrameHandler which is the routine that we hook up to get called when an unmanaged // exception happens. // * Assembly Loading file:../../Documentation/botr/type-loader.md // * Profiling file:../../Documentation/botr/profiling.md and file:../../Documentation/botr/profilability.md // * FCALLS QCALLS (calling into the runtime from managed code) -// file:../../Documentation/botr/mscorlib.md +// file:../../Documentation/botr/corelib.md // * Event Tracing for Windows // * file:../inc/eventtrace.h#EventTracing - // * This is the main file dealing with event tracing in CLR From 5922e80f54fc3ec8ed9129a1e7f5edf93df06108 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 11 May 2020 12:43:07 -0700 Subject: [PATCH 110/420] Ensure we mark op2 as delayFree if it is rmw and the parent node returns a non-SIMD type (#36226) --- src/coreclr/src/jit/lsraxarch.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/jit/lsraxarch.cpp b/src/coreclr/src/jit/lsraxarch.cpp index f784b55453871..348f971324843 100644 --- a/src/coreclr/src/jit/lsraxarch.cpp +++ b/src/coreclr/src/jit/lsraxarch.cpp @@ -2666,17 +2666,32 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) { srcCount += BuildAddrUses(op2->gtGetOp1()); } - else if (isRMW && !op2->isContained()) + else if (isRMW) { - if (HWIntrinsicInfo::IsCommutative(intrinsicId)) + if (!op2->isContained() && HWIntrinsicInfo::IsCommutative(intrinsicId)) { + // When op2 is not contained and we are commutative, we can set op2 + // to also be a tgtPrefUse. Codegen will then swap the operands. + tgtPrefUse2 = BuildUse(op2); srcCount += 1; } - else + else if (!op2->isContained() || varTypeIsArithmetic(intrinsicTree->TypeGet())) { + // When op2 is not contained or if we are producing a scalar value + // we need to mark it as delay free because the operand and target + // exist in the same register set. + srcCount += BuildDelayFreeUses(op2); } + else + { + // When op2 is contained and we are not producing a scalar value we + // have no concerns of overwriting op2 because they exist in different + // register sets. + + srcCount += BuildOperandUses(op2); + } } else { From 1a959590ea1e21be367ac78f1f4d3b85e0679c92 Mon Sep 17 00:00:00 2001 From: Jarret Shook Date: Mon, 11 May 2020 13:01:19 -0700 Subject: [PATCH 111/420] Setup pr and batch runs for dev/infrsatructure (#36218) --- eng/pipelines/runtime.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index eb52fca477815..d63762c70c50e 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -7,6 +7,7 @@ trigger: branches: include: - master + - dev/infrastructure - release/*.* paths: include: @@ -27,6 +28,7 @@ pr: branches: include: - master + - dev/infrastructure - release/*.* paths: include: From 322257f7785cb1711d1ad9af98623af3a4bc68a2 Mon Sep 17 00:00:00 2001 From: Anirudh Agnihotry Date: Mon, 11 May 2020 13:59:11 -0700 Subject: [PATCH 112/420] Use already defined generateAssemblyReferenceSource rather defining a new target (#35818) * use arcade target * extra space * fixes generation of reference src from runtime projects * run target to get genapi * use referencePath to get references * adding GenerateReferenceSource target * added the target name --- docs/coding-guidelines/updating-ref-source.md | 6 ++-- eng/Version.Details.xml | 4 +-- eng/Versions.props | 2 +- eng/outerBuild.targets | 4 +-- eng/referenceFromRuntime.targets | 2 +- src/libraries/Directory.Build.targets | 28 ++++++++----------- 6 files changed, 21 insertions(+), 25 deletions(-) diff --git a/docs/coding-guidelines/updating-ref-source.md b/docs/coding-guidelines/updating-ref-source.md index d702db01f695f..b6bcd1ed686fa 100644 --- a/docs/coding-guidelines/updating-ref-source.md +++ b/docs/coding-guidelines/updating-ref-source.md @@ -3,15 +3,15 @@ This document provides the steps you need to take to update the reference assemb ## For most assemblies within libraries 1. Implement the API in the source assembly and [build it](../workflow/building/libraries/README.md#building-individual-libraries). -2. Run the following command (from the src directory) `msbuild /t:GenerateReferenceSource` to update the reference assembly**. +2. Run the following command (from the src directory) `msbuild /t:GenerateReferenceAssemblySource` to update the reference assembly**. 3. Navigate to the ref directory and build the reference assembly. 4. Add, build, and run tests. -** **Note:** If you already added the new API to the reference source, re-generating it (after building the source assembly) will update it to be fully qualified and placed in the correct order. This can be done by running the `GenerateReferenceSource` command from the ref directory. +** **Note:** If you already added the new API to the reference source, re-generating it (after building the source assembly) will update it to be fully qualified and placed in the correct order. This can be done by running the `GenerateReferenceAssemblySource` command from the ref directory. ## For System.Runtime These steps can also be applied to some unique assemblies which depend on changes in System.Private.Corelib. (partial facades like System.Memory, for example). -1) Run `dotnet build -c Release /t:GenerateReferenceSource` from the System.Runtime/ref directory. +1) Run `dotnet build -c Release /t:GenerateReferenceAssemblySource` from the System.Runtime/ref directory. 2) Filter out all unrelated changes and extract the changes you care about (ignore certain attributes being removed). Generally, this step is not required for other reference assemblies. diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cc301e7537172..2680982faa6c2 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -18,9 +18,9 @@ https://github.com/dotnet/arcade 8547938aefa24475a04877285553f0b2663ae249 - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index da27adf5e0580..8d84b68f91361 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -60,7 +60,7 @@ 5.0.0-beta.20256.5 5.0.0-beta.20256.5 5.0.0-beta.20256.5 - 5.0.0-beta.20256.5 + 5.0.0-beta.20258.8 5.0.0-beta.20256.5 5.0.0-beta.20256.5 2.5.1-beta.20256.5 diff --git a/eng/outerBuild.targets b/eng/outerBuild.targets index dd546d6bd6f6b..2c529a56aa2f9 100644 --- a/eng/outerBuild.targets +++ b/eng/outerBuild.targets @@ -1,7 +1,7 @@ - + diff --git a/eng/referenceFromRuntime.targets b/eng/referenceFromRuntime.targets index 00d7d54abb80b..34d0eb49199c8 100644 --- a/eng/referenceFromRuntime.targets +++ b/eng/referenceFromRuntime.targets @@ -111,7 +111,7 @@ - + diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index d03b42639c2e6..0efc8a53b0aca 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -154,27 +154,23 @@ - + - <_RefSourceFileOutputPath>$([MSBuild]::NormalizePath('$(MSBuildProjectDirectory)', '..', 'ref', '$(AssemblyName).cs')) <_ExcludeAPIList>$([MSBuild]::NormalizePath('$(MSBuildProjectDirectory)', '..', 'ref', 'ReferenceSourceExcludeApi.txt')) <_ExcludeAttributesList>$(RepositoryEngineeringDir)DefaultGenApiDocIds.txt - <_LicenseHeaderTxtPath>$(RepositoryEngineeringDir)LicenseHeader.txt - - - - <_GenAPICmd>$(_GenAPICommand) - <_GenAPICmd>$(_GenAPICmd) "@(IntermediateAssembly)" - <_GenAPICmd>$(_GenAPICmd) --lib-path "$(RefPath.Trim('\/'))" - <_GenAPICmd>$(_GenAPICmd) --out "$(_RefSourceFileOutputPath)" - <_GenAPICmd>$(_GenAPICmd) --exclude-attributes-list "$(_ExcludeAttributesList)" - <_GenAPICmd Condition="Exists('$(_ExcludeAPIList)')">$(_GenAPICmd) --exclude-api-list "$(_ExcludeAPIList)" - <_GenAPICmd>$(_GenAPICmd) --header-file "$(_LicenseHeaderTxtPath)" - <_GenAPICmd Condition="'$(LangVersion)' != ''">$(_GenAPICmd) --lang-version "$(LangVersion)" + <_LicenseHeaderTxtPath>$(RepositoryEngineeringDir)LicenseHeader.txt + $([MSBuild]::NormalizePath('$(MSBuildProjectDirectory)', '..', 'ref', '$(AssemblyName).cs')) + $(GenAPIAdditionalParameters) --exclude-attributes-list "$(_ExcludeAttributesList)" + $(GenAPIAdditionalParameters) --exclude-api-list "$(_ExcludeAPIList)" + $(GenAPIAdditionalParameters) --header-file "$(_LicenseHeaderTxtPath)" + $(GenAPIAdditionalParameters) --lang-version "$(LangVersion)" + $(GenAPIAdditionalParameters) --follow-type-forwards + - - + + From 039fdf9bd055857d6d0eda42763f2d4e49db8924 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Mon, 11 May 2020 23:37:25 +0200 Subject: [PATCH 113/420] Remove EmbeddedResourceUseDependentUponConvention (#36140) Underlying issue is fixed: https://github.com/microsoft/msbuild/issues/4740 --- Directory.Build.props | 3 --- 1 file changed, 3 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 0d16a8347b40f..e26c8ad29e1fd 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -75,9 +75,6 @@ true - - - false From 941f4514c055a24c949ed0ed0aa2924eee8a2dc3 Mon Sep 17 00:00:00 2001 From: Mitchell Hwang Date: Mon, 11 May 2020 17:57:51 -0400 Subject: [PATCH 114/420] [testing] Rename Prop AppleTestBuilderDir to AppleAppBuilderDir (#36227) Co-authored-by: Mitchell Hwang --- eng/testing/tests.props | 2 +- eng/testing/tests.targets | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/testing/tests.props b/eng/testing/tests.props index 3b9c822c1fb9d..f736c75d4279f 100644 --- a/eng/testing/tests.props +++ b/eng/testing/tests.props @@ -22,7 +22,7 @@ $(NetCoreAppCurrent)-$(MonoConfiguration) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder', '$(MobileHelpersDirSuffix)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder', '$(MobileHelpersDirSuffix)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleTestRunner', '$(MobileHelpersDirSuffix)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', '$(MobileHelpersDirSuffix)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidTestRunner', '$(MobileHelpersDirSuffix)')) diff --git a/eng/testing/tests.targets b/eng/testing/tests.targets index 76352270e8e0b..e8ba7225cb803 100644 --- a/eng/testing/tests.targets +++ b/eng/testing/tests.targets @@ -164,7 +164,7 @@ + AssemblyFile="$(AppleAppBuilderDir)AppleAppBuilder.dll" /> $(OutDir)\Bundle From 0ba41a844ae03bd1b0cfd06e00552be8e4b8f02a Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 11 May 2020 17:02:42 -0500 Subject: [PATCH 115/420] Fix up nint code after latest changes to use compiler nint. (#36220) --- .../Common/src/Interop/OSX/Interop.libobjc.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libraries/Common/src/Interop/OSX/Interop.libobjc.cs b/src/libraries/Common/src/Interop/OSX/Interop.libobjc.cs index 6658d2b4c5d40..d76c59bac334e 100644 --- a/src/libraries/Common/src/Interop/OSX/Interop.libobjc.cs +++ b/src/libraries/Common/src/Interop/OSX/Interop.libobjc.cs @@ -6,7 +6,6 @@ using System; using System.Runtime.InteropServices; -using nint = System.IntPtr; internal static partial class Interop { @@ -45,9 +44,12 @@ internal static Version GetOperatingSystemVersion() { NSOperatingSystemVersion osVersion = get_operatingSystemVersion(processInfo, sel_getUid("operatingSystemVersion")); - major = osVersion.majorVersion.ToInt32(); - minor = osVersion.minorVersion.ToInt32(); - patch = osVersion.patchVersion.ToInt32(); + checked + { + major = (int)osVersion.majorVersion; + minor = (int)osVersion.minorVersion; + patch = (int)osVersion.patchVersion; + } } return new Version(major, minor, patch); From d05a847556b99f7f4725d34484ebb0d4b8fc4f4c Mon Sep 17 00:00:00 2001 From: Youssef Victor <31348972+Youssef1313@users.noreply.github.com> Date: Tue, 12 May 2020 01:34:17 +0200 Subject: [PATCH 116/420] Fix empty ParamName in ArgumentException (#36208) * Update reflectioninvocation.cpp * Update TypeInfoTests.cs * Update EnumConverterTest.cs --- src/coreclr/src/vm/reflectioninvocation.cpp | 5 ++--- .../tests/EnumConverterTest.cs | 2 +- .../System.Private.CoreLib/src/System/RuntimeType.cs | 3 +++ src/libraries/System.Reflection/tests/TypeInfoTests.cs | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/coreclr/src/vm/reflectioninvocation.cpp b/src/coreclr/src/vm/reflectioninvocation.cpp index b604b1a52d913..c530786aa3879 100644 --- a/src/coreclr/src/vm/reflectioninvocation.cpp +++ b/src/coreclr/src/vm/reflectioninvocation.cpp @@ -2396,9 +2396,8 @@ FCIMPL1(Object *, ReflectionEnum::InternalGetEnumUnderlyingType, ReflectClassBas VALIDATEOBJECT(target); TypeHandle th = target->GetType(); - if (!th.IsEnum()) - FCThrowArgument(NULL, NULL); - + _ASSERTE(th.IsEnum()); + OBJECTREF result = NULL; HELPER_METHOD_FRAME_BEGIN_RET_0(); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/EnumConverterTest.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/EnumConverterTest.cs index 9e071a1d58799..1ba44811524dc 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/EnumConverterTest.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/EnumConverterTest.cs @@ -109,7 +109,7 @@ public static void ConvertTo_WithContext_Flags() public static void ConvertTo_WithContext_Negative() { AssertExtensions.Throws(null, () => EnumConverterTests.s_someEnumConverter.ConvertTo(TypeConverterTests.s_context, null, 3, typeof(string))); - AssertExtensions.Throws(null, "enumType", () => new EnumConverter(typeof(Enum)).ConvertTo(TypeConverterTests.s_context, null, SomeFlagsEnum.Option1, typeof(string))); + AssertExtensions.Throws("enumType", () => new EnumConverter(typeof(Enum)).ConvertTo(TypeConverterTests.s_context, null, SomeFlagsEnum.Option1, typeof(string))); } [Fact] diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index 010ca6c2ce34f..141826bc10e3c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -237,6 +237,9 @@ public override bool IsEnumDefined(object value) if (value == null) throw new ArgumentNullException(nameof(value)); + if (!IsEnum) + throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); + // Check if both of them are of the same type RuntimeType valueType = (RuntimeType)value.GetType(); diff --git a/src/libraries/System.Reflection/tests/TypeInfoTests.cs b/src/libraries/System.Reflection/tests/TypeInfoTests.cs index 9d6d9fdbb8890..40c484c13381a 100644 --- a/src/libraries/System.Reflection/tests/TypeInfoTests.cs +++ b/src/libraries/System.Reflection/tests/TypeInfoTests.cs @@ -471,10 +471,10 @@ public static void IsEnumDefined(object value, bool expected) } [Fact] - [ActiveIssue("https://github.com/mono/mono/issues/15028", TestRuntimes.Mono)] public void IsEnumDefined_Invalid() { - AssertExtensions.Throws("", () => typeof(NonGenericClassWithNoInterfaces).GetTypeInfo().IsEnumDefined(10)); + AssertExtensions.Throws("enumType", () => typeof(NonGenericClassWithNoInterfaces).GetTypeInfo().IsEnumDefined(10)); + AssertExtensions.Throws("enumType", () => typeof(NonGenericClassWithNoInterfaces).GetTypeInfo().IsEnumDefined("10")); Assert.Throws(() => typeof(IntEnum).GetTypeInfo().IsEnumDefined(null)); Assert.Throws(() => typeof(IntEnum).GetTypeInfo().IsEnumDefined(new NonGenericClassWithNoInterfaces())); } From 0ab835c0b27280b87db4385740107bf878f1c491 Mon Sep 17 00:00:00 2001 From: Simon Nattress Date: Mon, 11 May 2020 16:35:06 -0700 Subject: [PATCH 117/420] Reduce DebugInfoTable size (#36174) The DebugInfoTableNode contains an array of native format vertices that currently are not unified. Many methods have identical debug info blobs so they can be collapsed to save output binary size. For identical debug info blobs, pass the same byte array reference to the native format writer which will unify on the object reference. In the framework composite image for example, 70% of the debug infos are duplicates. Removing the duplicates reduces the composite image size by 5%. --- .../ReadyToRun/DebugInfoTableNode.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugInfoTableNode.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugInfoTableNode.cs index 31fd6ba9570e1..31540b3d302ae 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugInfoTableNode.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugInfoTableNode.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using System.IO; using Internal.JitInterface; @@ -81,6 +82,8 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) VertexArray vertexArray = new VertexArray(section); section.Place(vertexArray); + Dictionary blobCache = new Dictionary(ByteArrayComparer.Instance); + foreach (MethodWithGCInfo method in factory.EnumerateCompiledMethods()) { MemoryStream methodDebugBlob = new MemoryStream(); @@ -105,8 +108,12 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) methodDebugBlob.Write(vars, 0, vars.Length); } - BlobVertex debugBlob = new BlobVertex(methodDebugBlob.ToArray()); - + byte[] debugBlobArrayKey = methodDebugBlob.ToArray(); + if (!blobCache.TryGetValue(debugBlobArrayKey, out BlobVertex debugBlob)) + { + debugBlob = new BlobVertex(methodDebugBlob.ToArray()); + blobCache.Add(debugBlobArrayKey, debugBlob); + } vertexArray.Set(factory.RuntimeFunctionsTable.GetIndex(method), new DebugInfoVertex(debugBlob)); } From eb63af57302f0e31a5fa565bbf89cdfdcd6f4952 Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Mon, 11 May 2020 17:06:54 -0700 Subject: [PATCH 118/420] unify repeating code --- .../Native/Unix/Common/pal_error_common.h | 323 +++++++++++++++ .../Native/Unix/Common/pal_io_common.h | 189 +++++++++ .../Unix/Common/pal_networking_common.h | 47 +++ .../Unix/System.IO.Ports.Native/pal_serial.c | 373 +----------------- .../Unix/System.IO.Ports.Native/pal_serial.h | 145 +------ .../Native/Unix/System.Native/pal_errno.c | 194 +-------- .../Native/Unix/System.Native/pal_errno.h | 122 +----- .../Native/Unix/System.Native/pal_io.c | 146 +------ .../Native/Unix/System.Native/pal_io.h | 25 +- .../Unix/System.Native/pal_networking.c | 25 +- .../Unix/System.Native/pal_networking.h | 13 +- 11 files changed, 574 insertions(+), 1028 deletions(-) create mode 100644 src/libraries/Native/Unix/Common/pal_error_common.h create mode 100644 src/libraries/Native/Unix/Common/pal_io_common.h create mode 100644 src/libraries/Native/Unix/Common/pal_networking_common.h diff --git a/src/libraries/Native/Unix/Common/pal_error_common.h b/src/libraries/Native/Unix/Common/pal_error_common.h new file mode 100644 index 0000000000000..d45bc21775ecb --- /dev/null +++ b/src/libraries/Native/Unix/Common/pal_error_common.h @@ -0,0 +1,323 @@ +// 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. + +#pragma once + +#include "pal_compiler.h" +#include "pal_types.h" +#include + +// ENODATA is not defined in FreeBSD 10.3 but is defined in 11.0 +#if defined(__FreeBSD__) & !defined(ENODATA) +#define ENODATA ENOATTR +#endif + +/** + * Error codes returned via ConvertErrno. + * + * Only the names (without the PAL_ prefix) are specified by POSIX. + * + * The values chosen below are simply assigned arbitrarily (originally + * in alphabetical order they appear in the spec, but they can't change so + * add new values to the end!). + * + * Also, the values chosen are deliberately outside the range of + * typical UNIX errnos (small numbers), HRESULTs (negative for errors) + * and Win32 errors (0x0000 - 0xFFFF). This isn't required for + * correctness, but may help debug a caller that is interpreting a raw + * int incorrectly. + * + * Wherever the spec says "x may be the same value as y", we do use + * the same value so that callers cannot not take a dependency on + * being able to distinguish between them. + */ +typedef enum +{ + Error_SUCCESS = 0, + + Error_E2BIG = 0x10001, // Argument list too long. + Error_EACCES = 0x10002, // Permission denied. + Error_EADDRINUSE = 0x10003, // Address in use. + Error_EADDRNOTAVAIL = 0x10004, // Address not available. + Error_EAFNOSUPPORT = 0x10005, // Address family not supported. + Error_EAGAIN = 0x10006, // Resource unavailable, try again (same value as EWOULDBLOCK), + Error_EALREADY = 0x10007, // Connection already in progress. + Error_EBADF = 0x10008, // Bad file descriptor. + Error_EBADMSG = 0x10009, // Bad message. + Error_EBUSY = 0x1000A, // Device or resource busy. + Error_ECANCELED = 0x1000B, // Operation canceled. + Error_ECHILD = 0x1000C, // No child processes. + Error_ECONNABORTED = 0x1000D, // Connection aborted. + Error_ECONNREFUSED = 0x1000E, // Connection refused. + Error_ECONNRESET = 0x1000F, // Connection reset. + Error_EDEADLK = 0x10010, // Resource deadlock would occur. + Error_EDESTADDRREQ = 0x10011, // Destination address required. + Error_EDOM = 0x10012, // Mathematics argument out of domain of function. + Error_EDQUOT = 0x10013, // Reserved. + Error_EEXIST = 0x10014, // File exists. + Error_EFAULT = 0x10015, // Bad address. + Error_EFBIG = 0x10016, // File too large. + Error_EHOSTUNREACH = 0x10017, // Host is unreachable. + Error_EIDRM = 0x10018, // Identifier removed. + Error_EILSEQ = 0x10019, // Illegal byte sequence. + Error_EINPROGRESS = 0x1001A, // Operation in progress. + Error_EINTR = 0x1001B, // Interrupted function. + Error_EINVAL = 0x1001C, // Invalid argument. + Error_EIO = 0x1001D, // I/O error. + Error_EISCONN = 0x1001E, // Socket is connected. + Error_EISDIR = 0x1001F, // Is a directory. + Error_ELOOP = 0x10020, // Too many levels of symbolic links. + Error_EMFILE = 0x10021, // File descriptor value too large. + Error_EMLINK = 0x10022, // Too many links. + Error_EMSGSIZE = 0x10023, // Message too large. + Error_EMULTIHOP = 0x10024, // Reserved. + Error_ENAMETOOLONG = 0x10025, // Filename too long. + Error_ENETDOWN = 0x10026, // Network is down. + Error_ENETRESET = 0x10027, // Connection aborted by network. + Error_ENETUNREACH = 0x10028, // Network unreachable. + Error_ENFILE = 0x10029, // Too many files open in system. + Error_ENOBUFS = 0x1002A, // No buffer space available. + Error_ENODEV = 0x1002C, // No such device. + Error_ENOENT = 0x1002D, // No such file or directory. + Error_ENOEXEC = 0x1002E, // Executable file format error. + Error_ENOLCK = 0x1002F, // No locks available. + Error_ENOLINK = 0x10030, // Reserved. + Error_ENOMEM = 0x10031, // Not enough space. + Error_ENOMSG = 0x10032, // No message of the desired type. + Error_ENOPROTOOPT = 0x10033, // Protocol not available. + Error_ENOSPC = 0x10034, // No space left on device. + Error_ENOSYS = 0x10037, // Function not supported. + Error_ENOTCONN = 0x10038, // The socket is not connected. + Error_ENOTDIR = 0x10039, // Not a directory or a symbolic link to a directory. + Error_ENOTEMPTY = 0x1003A, // Directory not empty. + Error_ENOTRECOVERABLE = 0x1003B, // State not recoverable. + Error_ENOTSOCK = 0x1003C, // Not a socket. + Error_ENOTSUP = 0x1003D, // Not supported (same value as EOPNOTSUP). + Error_ENOTTY = 0x1003E, // Inappropriate I/O control operation. + Error_ENXIO = 0x1003F, // No such device or address. + Error_EOVERFLOW = 0x10040, // Value too large to be stored in data type. + Error_EOWNERDEAD = 0x10041, // Previous owner died. + Error_EPERM = 0x10042, // Operation not permitted. + Error_EPIPE = 0x10043, // Broken pipe. + Error_EPROTO = 0x10044, // Protocol error. + Error_EPROTONOSUPPORT = 0x10045, // Protocol not supported. + Error_EPROTOTYPE = 0x10046, // Protocol wrong type for socket. + Error_ERANGE = 0x10047, // Result too large. + Error_EROFS = 0x10048, // Read-only file system. + Error_ESPIPE = 0x10049, // Invalid seek. + Error_ESRCH = 0x1004A, // No such process. + Error_ESTALE = 0x1004B, // Reserved. + Error_ETIMEDOUT = 0x1004D, // Connection timed out. + Error_ETXTBSY = 0x1004E, // Text file busy. + Error_EXDEV = 0x1004F, // Cross-device link. + Error_ESOCKTNOSUPPORT = 0x1005E, // Socket type not supported. + Error_EPFNOSUPPORT = 0x10060, // Protocol family not supported. + Error_ESHUTDOWN = 0x1006C, // Socket shutdown. + Error_EHOSTDOWN = 0x10070, // Host is down. + Error_ENODATA = 0x10071, // No data available. + + // Error codes to track errors beyond kernel. + Error_EHOSTNOTFOUND = 0x20001, // Name lookup failed. + + // POSIX permits these to have the same value and we make them + // always equal so that we cannot introduce a dependency on + // distinguishing between them that would not work on all + // platforms. + Error_EOPNOTSUPP = Error_ENOTSUP, // Operation not supported on socket + Error_EWOULDBLOCK = Error_EAGAIN, // Operation would block + + // This one is not part of POSIX, but is a catch-all for the case + // where we cannot convert the raw errno value to something above. + Error_ENONSTANDARD = 0x1FFFF, +} Error; + +inline static int32_t ConvertErrorPlatformToPal(int32_t platformErrno) +{ + switch (platformErrno) + { + case 0: + return Error_SUCCESS; + case E2BIG: + return Error_E2BIG; + case EACCES: + return Error_EACCES; + case EADDRINUSE: + return Error_EADDRINUSE; + case EADDRNOTAVAIL: + return Error_EADDRNOTAVAIL; + case EAFNOSUPPORT: + return Error_EAFNOSUPPORT; + case EAGAIN: + return Error_EAGAIN; + case EALREADY: + return Error_EALREADY; + case EBADF: + return Error_EBADF; + case EBADMSG: + return Error_EBADMSG; + case EBUSY: + return Error_EBUSY; + case ECANCELED: + return Error_ECANCELED; + case ECHILD: + return Error_ECHILD; + case ECONNABORTED: + return Error_ECONNABORTED; + case ECONNREFUSED: + return Error_ECONNREFUSED; + case ECONNRESET: + return Error_ECONNRESET; + case EDEADLK: + return Error_EDEADLK; + case EDESTADDRREQ: + return Error_EDESTADDRREQ; + case EDOM: + return Error_EDOM; + case EDQUOT: + return Error_EDQUOT; + case EEXIST: + return Error_EEXIST; + case EFAULT: + return Error_EFAULT; + case EFBIG: + return Error_EFBIG; + case EHOSTUNREACH: + return Error_EHOSTUNREACH; + case EIDRM: + return Error_EIDRM; + case EILSEQ: + return Error_EILSEQ; + case EINPROGRESS: + return Error_EINPROGRESS; + case EINTR: + return Error_EINTR; + case EINVAL: + return Error_EINVAL; + case EIO: + return Error_EIO; + case EISCONN: + return Error_EISCONN; + case EISDIR: + return Error_EISDIR; + case ELOOP: + return Error_ELOOP; + case EMFILE: + return Error_EMFILE; + case EMLINK: + return Error_EMLINK; + case EMSGSIZE: + return Error_EMSGSIZE; + case EMULTIHOP: + return Error_EMULTIHOP; + case ENAMETOOLONG: + return Error_ENAMETOOLONG; + case ENETDOWN: + return Error_ENETDOWN; + case ENETRESET: + return Error_ENETRESET; + case ENETUNREACH: + return Error_ENETUNREACH; + case ENFILE: + return Error_ENFILE; + case ENOBUFS: + return Error_ENOBUFS; + case ENODEV: + return Error_ENODEV; + case ENOENT: + return Error_ENOENT; + case ENOEXEC: + return Error_ENOEXEC; + case ENOLCK: + return Error_ENOLCK; + case ENOLINK: + return Error_ENOLINK; + case ENOMEM: + return Error_ENOMEM; + case ENOMSG: + return Error_ENOMSG; + case ENOPROTOOPT: + return Error_ENOPROTOOPT; + case ENOSPC: + return Error_ENOSPC; + case ENOSYS: + return Error_ENOSYS; + case ENOTCONN: + return Error_ENOTCONN; + case ENOTDIR: + return Error_ENOTDIR; +#if ENOTEMPTY != EEXIST // AIX defines this + case ENOTEMPTY: + return Error_ENOTEMPTY; +#endif +#ifdef ENOTRECOVERABLE // not available in NetBSD + case ENOTRECOVERABLE: + return Error_ENOTRECOVERABLE; +#endif + case ENOTSOCK: + return Error_ENOTSOCK; + case ENOTSUP: + return Error_ENOTSUP; + case ENOTTY: + return Error_ENOTTY; + case ENXIO: + return Error_ENXIO; + case EOVERFLOW: + return Error_EOVERFLOW; +#ifdef EOWNERDEAD // not available in NetBSD + case EOWNERDEAD: + return Error_EOWNERDEAD; +#endif + case EPERM: + return Error_EPERM; + case EPIPE: + return Error_EPIPE; + case EPROTO: + return Error_EPROTO; + case EPROTONOSUPPORT: + return Error_EPROTONOSUPPORT; + case EPROTOTYPE: + return Error_EPROTOTYPE; + case ERANGE: + return Error_ERANGE; + case EROFS: + return Error_EROFS; + case ESPIPE: + return Error_ESPIPE; + case ESRCH: + return Error_ESRCH; + case ESTALE: + return Error_ESTALE; + case ETIMEDOUT: + return Error_ETIMEDOUT; + case ETXTBSY: + return Error_ETXTBSY; + case EXDEV: + return Error_EXDEV; +#ifdef ESOCKTNOSUPPORT + case ESOCKTNOSUPPORT: + return Error_ESOCKTNOSUPPORT; +#endif + case EPFNOSUPPORT: + return Error_EPFNOSUPPORT; + case ESHUTDOWN: + return Error_ESHUTDOWN; + case EHOSTDOWN: + return Error_EHOSTDOWN; + case ENODATA: + return Error_ENODATA; + +// #if because these will trigger duplicate case label warnings when +// they have the same value, which is permitted by POSIX and common. +#if EOPNOTSUPP != ENOTSUP + case EOPNOTSUPP: + return Error_EOPNOTSUPP; +#endif +#if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: + return Error_EWOULDBLOCK; +#endif + } + + return Error_ENONSTANDARD; +} diff --git a/src/libraries/Native/Unix/Common/pal_io_common.h b/src/libraries/Native/Unix/Common/pal_io_common.h new file mode 100644 index 0000000000000..15bf1423aa327 --- /dev/null +++ b/src/libraries/Native/Unix/Common/pal_io_common.h @@ -0,0 +1,189 @@ +// 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. + +#pragma once + +#include +#include +#include +#include +#include + +/** + * Our intermediate pollfd struct to normalize the data types + */ +typedef struct +{ + int32_t FileDescriptor; // The file descriptor to poll + int16_t Events; // The events to poll for + int16_t TriggeredEvents; // The events that triggered the poll +} PollEvent; + +/** + * Constants passed to and from poll describing what to poll for and what + * kind of data was received from poll. + */ +typedef enum +{ + PAL_POLLIN = 0x0001, /* non-urgent readable data available */ + PAL_POLLPRI = 0x0002, /* urgent readable data available */ + PAL_POLLOUT = 0x0004, /* data can be written without blocked */ + PAL_POLLERR = 0x0008, /* an error occurred */ + PAL_POLLHUP = 0x0010, /* the file descriptor hung up */ + PAL_POLLNVAL = 0x0020, /* the requested events were invalid */ +} PollEvents; + +inline static int32_t Common_Read(intptr_t fd, void* buffer, int32_t bufferSize) +{ + assert(buffer != NULL || bufferSize == 0); + assert(bufferSize >= 0); + + if (bufferSize < 0) + { + errno = EINVAL; + return -1; + } + + ssize_t count; + while ((count = read(ToFileDescriptor(fd), buffer, (uint32_t)bufferSize)) < 0 && errno == EINTR); + + assert(count >= -1 && count <= bufferSize); + return (int32_t)count; +} + +inline static int32_t Common_Write(intptr_t fd, const void* buffer, int32_t bufferSize) +{ + assert(buffer != NULL || bufferSize == 0); + assert(bufferSize >= 0); + + if (bufferSize < 0) + { + errno = ERANGE; + return -1; + } + + ssize_t count; + while ((count = write(ToFileDescriptor(fd), buffer, (uint32_t)bufferSize)) < 0 && errno == EINTR); + + assert(count >= -1 && count <= bufferSize); + return (int32_t)count; +} + +inline static int32_t Common_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t milliseconds, uint32_t* triggered) +{ + if (pollEvents == NULL || triggered == NULL) + { + return Error_EFAULT; + } + + if (milliseconds < -1) + { + return Error_EINVAL; + } + + struct pollfd stackBuffer[(uint32_t)(2048/sizeof(struct pollfd))]; + int useStackBuffer = eventCount <= ARRAY_SIZE(stackBuffer); + struct pollfd* pollfds = NULL; + if (useStackBuffer) + { + pollfds = &stackBuffer[0]; + } + else + { + pollfds = calloc(eventCount, sizeof(*pollfds)); + if (pollfds == NULL) + { + return Error_ENOMEM; + } + } + + for (uint32_t i = 0; i < eventCount; i++) + { + const PollEvent* event = &pollEvents[i]; + pollfds[i].fd = event->FileDescriptor; + // we need to do this for platforms like AIX where PAL_POLL* doesn't + // match up to their reality; this is PollEvent -> system polling + switch (event->Events) + { + case PAL_POLLIN: + pollfds[i].events = POLLIN; + break; + case PAL_POLLPRI: + pollfds[i].events = POLLPRI; + break; + case PAL_POLLOUT: + pollfds[i].events = POLLOUT; + break; + case PAL_POLLERR: + pollfds[i].events = POLLERR; + break; + case PAL_POLLHUP: + pollfds[i].events = POLLHUP; + break; + case PAL_POLLNVAL: + pollfds[i].events = POLLNVAL; + break; + default: + pollfds[i].events = event->Events; + break; + } + pollfds[i].revents = 0; + } + + int rv; + while ((rv = poll(pollfds, (nfds_t)eventCount, milliseconds)) < 0 && errno == EINTR); + + if (rv < 0) + { + if (!useStackBuffer) + { + free(pollfds); + } + + *triggered = 0; + return ConvertErrorPlatformToPal(errno); + } + + for (uint32_t i = 0; i < eventCount; i++) + { + const struct pollfd* pfd = &pollfds[i]; + assert(pfd->fd == pollEvents[i].FileDescriptor); + assert(pfd->events == pollEvents[i].Events); + + // same as the other switch, just system -> PollEvent + switch (pfd->revents) + { + case POLLIN: + pollEvents[i].TriggeredEvents = PAL_POLLIN; + break; + case POLLPRI: + pollEvents[i].TriggeredEvents = PAL_POLLPRI; + break; + case POLLOUT: + pollEvents[i].TriggeredEvents = PAL_POLLOUT; + break; + case POLLERR: + pollEvents[i].TriggeredEvents = PAL_POLLERR; + break; + case POLLHUP: + pollEvents[i].TriggeredEvents = PAL_POLLHUP; + break; + case POLLNVAL: + pollEvents[i].TriggeredEvents = PAL_POLLNVAL; + break; + default: + pollEvents[i].TriggeredEvents = (int16_t)pfd->revents; + break; + } + } + + *triggered = (uint32_t)rv; + + if (!useStackBuffer) + { + free(pollfds); + } + + return Error_SUCCESS; +} diff --git a/src/libraries/Native/Unix/Common/pal_networking_common.h b/src/libraries/Native/Unix/Common/pal_networking_common.h new file mode 100644 index 0000000000000..353862cd7ce0d --- /dev/null +++ b/src/libraries/Native/Unix/Common/pal_networking_common.h @@ -0,0 +1,47 @@ +// 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. + +#pragma once + +#include +#include + +/* + * Socket shutdown modes. + * + * NOTE: these values are taken from System.Net.SocketShutdown. + */ +typedef enum +{ + SocketShutdown_SHUT_READ = 0, // SHUT_RD + SocketShutdown_SHUT_WRITE = 1, // SHUT_WR + SocketShutdown_SHUT_BOTH = 2, // SHUT_RDWR +} SockerShutdown; + +inline static int32_t Common_Shutdown(intptr_t socket, int32_t socketShutdown) +{ + int fd = ToFileDescriptor(socket); + + int how; + switch (socketShutdown) + { + case SocketShutdown_SHUT_READ: + how = SHUT_RD; + break; + + case SocketShutdown_SHUT_WRITE: + how = SHUT_WR; + break; + + case SocketShutdown_SHUT_BOTH: + how = SHUT_RDWR; + break; + + default: + return Error_EINVAL; + } + + int err = shutdown(fd, how); + return err == 0 ? Error_SUCCESS : ConvertErrorPlatformToPal(errno); +} diff --git a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c index ac243fd29eaa2..9eceb7e6b11ea 100644 --- a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c +++ b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c @@ -10,9 +10,9 @@ #include #include #include -#include #include #include +#include // ENODATA is not defined in FreeBSD 10.3 but is defined in 11.0 #if defined(__FreeBSD__) & !defined(ENODATA) @@ -53,385 +53,22 @@ int SystemIoPortsNative_SerialPortClose(intptr_t handle) return close(fd); } -int32_t ConvertErrorPlatformToPal(int32_t platformErrno) -{ - switch (platformErrno) - { - case 0: - return Error_SUCCESS; - case E2BIG: - return Error_E2BIG; - case EACCES: - return Error_EACCES; - case EADDRINUSE: - return Error_EADDRINUSE; - case EADDRNOTAVAIL: - return Error_EADDRNOTAVAIL; - case EAFNOSUPPORT: - return Error_EAFNOSUPPORT; - case EAGAIN: - return Error_EAGAIN; - case EALREADY: - return Error_EALREADY; - case EBADF: - return Error_EBADF; - case EBADMSG: - return Error_EBADMSG; - case EBUSY: - return Error_EBUSY; - case ECANCELED: - return Error_ECANCELED; - case ECHILD: - return Error_ECHILD; - case ECONNABORTED: - return Error_ECONNABORTED; - case ECONNREFUSED: - return Error_ECONNREFUSED; - case ECONNRESET: - return Error_ECONNRESET; - case EDEADLK: - return Error_EDEADLK; - case EDESTADDRREQ: - return Error_EDESTADDRREQ; - case EDOM: - return Error_EDOM; - case EDQUOT: - return Error_EDQUOT; - case EEXIST: - return Error_EEXIST; - case EFAULT: - return Error_EFAULT; - case EFBIG: - return Error_EFBIG; - case EHOSTUNREACH: - return Error_EHOSTUNREACH; - case EIDRM: - return Error_EIDRM; - case EILSEQ: - return Error_EILSEQ; - case EINPROGRESS: - return Error_EINPROGRESS; - case EINTR: - return Error_EINTR; - case EINVAL: - return Error_EINVAL; - case EIO: - return Error_EIO; - case EISCONN: - return Error_EISCONN; - case EISDIR: - return Error_EISDIR; - case ELOOP: - return Error_ELOOP; - case EMFILE: - return Error_EMFILE; - case EMLINK: - return Error_EMLINK; - case EMSGSIZE: - return Error_EMSGSIZE; - case EMULTIHOP: - return Error_EMULTIHOP; - case ENAMETOOLONG: - return Error_ENAMETOOLONG; - case ENETDOWN: - return Error_ENETDOWN; - case ENETRESET: - return Error_ENETRESET; - case ENETUNREACH: - return Error_ENETUNREACH; - case ENFILE: - return Error_ENFILE; - case ENOBUFS: - return Error_ENOBUFS; - case ENODEV: - return Error_ENODEV; - case ENOENT: - return Error_ENOENT; - case ENOEXEC: - return Error_ENOEXEC; - case ENOLCK: - return Error_ENOLCK; - case ENOLINK: - return Error_ENOLINK; - case ENOMEM: - return Error_ENOMEM; - case ENOMSG: - return Error_ENOMSG; - case ENOPROTOOPT: - return Error_ENOPROTOOPT; - case ENOSPC: - return Error_ENOSPC; - case ENOSYS: - return Error_ENOSYS; - case ENOTCONN: - return Error_ENOTCONN; - case ENOTDIR: - return Error_ENOTDIR; -#if ENOTEMPTY != EEXIST // AIX defines this - case ENOTEMPTY: - return Error_ENOTEMPTY; -#endif -#ifdef ENOTRECOVERABLE // not available in NetBSD - case ENOTRECOVERABLE: - return Error_ENOTRECOVERABLE; -#endif - case ENOTSOCK: - return Error_ENOTSOCK; - case ENOTSUP: - return Error_ENOTSUP; - case ENOTTY: - return Error_ENOTTY; - case ENXIO: - return Error_ENXIO; - case EOVERFLOW: - return Error_EOVERFLOW; -#ifdef EOWNERDEAD // not available in NetBSD - case EOWNERDEAD: - return Error_EOWNERDEAD; -#endif - case EPERM: - return Error_EPERM; - case EPIPE: - return Error_EPIPE; - case EPROTO: - return Error_EPROTO; - case EPROTONOSUPPORT: - return Error_EPROTONOSUPPORT; - case EPROTOTYPE: - return Error_EPROTOTYPE; - case ERANGE: - return Error_ERANGE; - case EROFS: - return Error_EROFS; - case ESPIPE: - return Error_ESPIPE; - case ESRCH: - return Error_ESRCH; - case ESTALE: - return Error_ESTALE; - case ETIMEDOUT: - return Error_ETIMEDOUT; - case ETXTBSY: - return Error_ETXTBSY; - case EXDEV: - return Error_EXDEV; -#ifdef ESOCKTNOSUPPORT - case ESOCKTNOSUPPORT: - return Error_ESOCKTNOSUPPORT; -#endif - case EPFNOSUPPORT: - return Error_EPFNOSUPPORT; - case ESHUTDOWN: - return Error_ESHUTDOWN; - case EHOSTDOWN: - return Error_EHOSTDOWN; - case ENODATA: - return Error_ENODATA; - -// #if because these will trigger duplicate case label warnings when -// they have the same value, which is permitted by POSIX and common. -#if EOPNOTSUPP != ENOTSUP - case EOPNOTSUPP: - return Error_EOPNOTSUPP; -#endif -#if EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: - return Error_EWOULDBLOCK; -#endif - } - - return Error_ENONSTANDARD; -} - int32_t SystemIoPortsNative_Read(intptr_t fd, void* buffer, int32_t bufferSize) { - assert(buffer != NULL || bufferSize == 0); - assert(bufferSize >= 0); - - if (bufferSize < 0) - { - errno = EINVAL; - return -1; - } - - ssize_t count; - while ((count = read(ToFileDescriptor(fd), buffer, (uint32_t)bufferSize)) < 0 && errno == EINTR); - - assert(count >= -1 && count <= bufferSize); - return (int32_t)count; + return Common_Read(fd, buffer, bufferSize); } int32_t SystemIoPortsNative_Write(intptr_t fd, const void* buffer, int32_t bufferSize) { - assert(buffer != NULL || bufferSize == 0); - assert(bufferSize >= 0); - - if (bufferSize < 0) - { - errno = ERANGE; - return -1; - } - - ssize_t count; - while ((count = write(ToFileDescriptor(fd), buffer, (uint32_t)bufferSize)) < 0 && errno == EINTR); - - assert(count >= -1 && count <= bufferSize); - return (int32_t)count; + return Common_Write(fd, buffer, bufferSize); } int32_t SystemIoPortsNative_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t milliseconds, uint32_t* triggered) { - if (pollEvents == NULL || triggered == NULL) - { - return Error_EFAULT; - } - - if (milliseconds < -1) - { - return Error_EINVAL; - } - - struct pollfd stackBuffer[(uint32_t)(2048/sizeof(struct pollfd))]; - int useStackBuffer = eventCount <= ARRAY_SIZE(stackBuffer); - struct pollfd* pollfds = NULL; - if (useStackBuffer) - { - pollfds = &stackBuffer[0]; - } - else - { - pollfds = calloc(eventCount, sizeof(*pollfds)); - if (pollfds == NULL) - { - return Error_ENOMEM; - } - } - - for (uint32_t i = 0; i < eventCount; i++) - { - const PollEvent* event = &pollEvents[i]; - pollfds[i].fd = event->FileDescriptor; - // we need to do this for platforms like AIX where PAL_POLL* doesn't - // match up to their reality; this is PollEvent -> system polling - switch (event->Events) - { - case PAL_POLLIN: - pollfds[i].events = POLLIN; - break; - case PAL_POLLPRI: - pollfds[i].events = POLLPRI; - break; - case PAL_POLLOUT: - pollfds[i].events = POLLOUT; - break; - case PAL_POLLERR: - pollfds[i].events = POLLERR; - break; - case PAL_POLLHUP: - pollfds[i].events = POLLHUP; - break; - case PAL_POLLNVAL: - pollfds[i].events = POLLNVAL; - break; - default: - pollfds[i].events = event->Events; - break; - } - pollfds[i].revents = 0; - } - - int rv; - while ((rv = poll(pollfds, (nfds_t)eventCount, milliseconds)) < 0 && errno == EINTR); - - if (rv < 0) - { - if (!useStackBuffer) - { - free(pollfds); - } - - *triggered = 0; - return ConvertErrorPlatformToPal(errno); - } - - for (uint32_t i = 0; i < eventCount; i++) - { - const struct pollfd* pfd = &pollfds[i]; - assert(pfd->fd == pollEvents[i].FileDescriptor); - assert(pfd->events == pollEvents[i].Events); - - // same as the other switch, just system -> PollEvent - switch (pfd->revents) - { - case POLLIN: - pollEvents[i].TriggeredEvents = PAL_POLLIN; - break; - case POLLPRI: - pollEvents[i].TriggeredEvents = PAL_POLLPRI; - break; - case POLLOUT: - pollEvents[i].TriggeredEvents = PAL_POLLOUT; - break; - case POLLERR: - pollEvents[i].TriggeredEvents = PAL_POLLERR; - break; - case POLLHUP: - pollEvents[i].TriggeredEvents = PAL_POLLHUP; - break; - case POLLNVAL: - pollEvents[i].TriggeredEvents = PAL_POLLNVAL; - break; - default: - pollEvents[i].TriggeredEvents = (int16_t)pfd->revents; - break; - } - } - - *triggered = (uint32_t)rv; - - if (!useStackBuffer) - { - free(pollfds); - } - - return Error_SUCCESS; + return Common_Poll(pollEvents, eventCount, milliseconds, triggered); } -/* - * Socket shutdown modes. - * - * NOTE: these values are taken from System.Net.SocketShutdown. - */ -typedef enum -{ - SocketShutdown_SHUT_READ = 0, // SHUT_RD - SocketShutdown_SHUT_WRITE = 1, // SHUT_WR - SocketShutdown_SHUT_BOTH = 2, // SHUT_RDWR -} SocketShutdown; - int32_t SystemIoPortsNative_Shutdown(intptr_t socket, int32_t socketShutdown) { - int fd = ToFileDescriptor(socket); - - int how; - switch (socketShutdown) - { - case SocketShutdown_SHUT_READ: - how = SHUT_RD; - break; - - case SocketShutdown_SHUT_WRITE: - how = SHUT_WR; - break; - - case SocketShutdown_SHUT_BOTH: - how = SHUT_RDWR; - break; - - default: - return Error_EINVAL; - } - - int err = shutdown(fd, how); - return err == 0 ? Error_SUCCESS : ConvertErrorPlatformToPal(errno); + return Common_Shutdown(socket, socketShutdown); } diff --git a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.h b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.h index dd32304e0774f..30a2d244b907b 100644 --- a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.h +++ b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.h @@ -2,18 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#include "pal_types.h" -#include "pal_compiler.h" +#include -/** - * Our intermediate pollfd struct to normalize the data types - */ -typedef struct -{ - int32_t FileDescriptor; // The file descriptor to poll - int16_t Events; // The events to poll for - int16_t TriggeredEvents; // The events that triggered the poll -} PollEvent; PALEXPORT intptr_t SystemIoPortsNative_SerialPortOpen(const char * name); PALEXPORT int SystemIoPortsNative_SerialPortClose(intptr_t fd); @@ -21,136 +11,3 @@ PALEXPORT int32_t SystemIoPortsNative_Read(intptr_t fd, void* buffer, int32_t bu PALEXPORT int32_t SystemIoPortsNative_Write(intptr_t fd, const void* buffer, int32_t bufferSize); PALEXPORT int32_t SystemIoPortsNative_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t milliseconds, uint32_t* triggered); PALEXPORT int32_t SystemIoPortsNative_Shutdown(intptr_t socket, int32_t socketShutdown); - -/** - * Constants passed to and from poll describing what to poll for and what - * kind of data was received from poll. - */ -typedef enum -{ - PAL_POLLIN = 0x0001, /* non-urgent readable data available */ - PAL_POLLPRI = 0x0002, /* urgent readable data available */ - PAL_POLLOUT = 0x0004, /* data can be written without blocked */ - PAL_POLLERR = 0x0008, /* an error occurred */ - PAL_POLLHUP = 0x0010, /* the file descriptor hung up */ - PAL_POLLNVAL = 0x0020, /* the requested events were invalid */ -} PollEvents; - -/** - * Error codes returned via ConvertErrno. - * - * Only the names (without the PAL_ prefix) are specified by POSIX. - * - * The values chosen below are simply assigned arbitrarily (originally - * in alphabetical order they appear in the spec, but they can't change so - * add new values to the end!). - * - * Also, the values chosen are deliberately outside the range of - * typical UNIX errnos (small numbers), HRESULTs (negative for errors) - * and Win32 errors (0x0000 - 0xFFFF). This isn't required for - * correctness, but may help debug a caller that is interpreting a raw - * int incorrectly. - * - * Wherever the spec says "x may be the same value as y", we do use - * the same value so that callers cannot not take a dependency on - * being able to distinguish between them. - */ -typedef enum -{ - Error_SUCCESS = 0, - - Error_E2BIG = 0x10001, // Argument list too long. - Error_EACCES = 0x10002, // Permission denied. - Error_EADDRINUSE = 0x10003, // Address in use. - Error_EADDRNOTAVAIL = 0x10004, // Address not available. - Error_EAFNOSUPPORT = 0x10005, // Address family not supported. - Error_EAGAIN = 0x10006, // Resource unavailable, try again (same value as EWOULDBLOCK), - Error_EALREADY = 0x10007, // Connection already in progress. - Error_EBADF = 0x10008, // Bad file descriptor. - Error_EBADMSG = 0x10009, // Bad message. - Error_EBUSY = 0x1000A, // Device or resource busy. - Error_ECANCELED = 0x1000B, // Operation canceled. - Error_ECHILD = 0x1000C, // No child processes. - Error_ECONNABORTED = 0x1000D, // Connection aborted. - Error_ECONNREFUSED = 0x1000E, // Connection refused. - Error_ECONNRESET = 0x1000F, // Connection reset. - Error_EDEADLK = 0x10010, // Resource deadlock would occur. - Error_EDESTADDRREQ = 0x10011, // Destination address required. - Error_EDOM = 0x10012, // Mathematics argument out of domain of function. - Error_EDQUOT = 0x10013, // Reserved. - Error_EEXIST = 0x10014, // File exists. - Error_EFAULT = 0x10015, // Bad address. - Error_EFBIG = 0x10016, // File too large. - Error_EHOSTUNREACH = 0x10017, // Host is unreachable. - Error_EIDRM = 0x10018, // Identifier removed. - Error_EILSEQ = 0x10019, // Illegal byte sequence. - Error_EINPROGRESS = 0x1001A, // Operation in progress. - Error_EINTR = 0x1001B, // Interrupted function. - Error_EINVAL = 0x1001C, // Invalid argument. - Error_EIO = 0x1001D, // I/O error. - Error_EISCONN = 0x1001E, // Socket is connected. - Error_EISDIR = 0x1001F, // Is a directory. - Error_ELOOP = 0x10020, // Too many levels of symbolic links. - Error_EMFILE = 0x10021, // File descriptor value too large. - Error_EMLINK = 0x10022, // Too many links. - Error_EMSGSIZE = 0x10023, // Message too large. - Error_EMULTIHOP = 0x10024, // Reserved. - Error_ENAMETOOLONG = 0x10025, // Filename too long. - Error_ENETDOWN = 0x10026, // Network is down. - Error_ENETRESET = 0x10027, // Connection aborted by network. - Error_ENETUNREACH = 0x10028, // Network unreachable. - Error_ENFILE = 0x10029, // Too many files open in system. - Error_ENOBUFS = 0x1002A, // No buffer space available. - Error_ENODEV = 0x1002C, // No such device. - Error_ENOENT = 0x1002D, // No such file or directory. - Error_ENOEXEC = 0x1002E, // Executable file format error. - Error_ENOLCK = 0x1002F, // No locks available. - Error_ENOLINK = 0x10030, // Reserved. - Error_ENOMEM = 0x10031, // Not enough space. - Error_ENOMSG = 0x10032, // No message of the desired type. - Error_ENOPROTOOPT = 0x10033, // Protocol not available. - Error_ENOSPC = 0x10034, // No space left on device. - Error_ENOSYS = 0x10037, // Function not supported. - Error_ENOTCONN = 0x10038, // The socket is not connected. - Error_ENOTDIR = 0x10039, // Not a directory or a symbolic link to a directory. - Error_ENOTEMPTY = 0x1003A, // Directory not empty. - Error_ENOTRECOVERABLE = 0x1003B, // State not recoverable. - Error_ENOTSOCK = 0x1003C, // Not a socket. - Error_ENOTSUP = 0x1003D, // Not supported (same value as EOPNOTSUP). - Error_ENOTTY = 0x1003E, // Inappropriate I/O control operation. - Error_ENXIO = 0x1003F, // No such device or address. - Error_EOVERFLOW = 0x10040, // Value too large to be stored in data type. - Error_EOWNERDEAD = 0x10041, // Previous owner died. - Error_EPERM = 0x10042, // Operation not permitted. - Error_EPIPE = 0x10043, // Broken pipe. - Error_EPROTO = 0x10044, // Protocol error. - Error_EPROTONOSUPPORT = 0x10045, // Protocol not supported. - Error_EPROTOTYPE = 0x10046, // Protocol wrong type for socket. - Error_ERANGE = 0x10047, // Result too large. - Error_EROFS = 0x10048, // Read-only file system. - Error_ESPIPE = 0x10049, // Invalid seek. - Error_ESRCH = 0x1004A, // No such process. - Error_ESTALE = 0x1004B, // Reserved. - Error_ETIMEDOUT = 0x1004D, // Connection timed out. - Error_ETXTBSY = 0x1004E, // Text file busy. - Error_EXDEV = 0x1004F, // Cross-device link. - Error_ESOCKTNOSUPPORT = 0x1005E, // Socket type not supported. - Error_EPFNOSUPPORT = 0x10060, // Protocol family not supported. - Error_ESHUTDOWN = 0x1006C, // Socket shutdown. - Error_EHOSTDOWN = 0x10070, // Host is down. - Error_ENODATA = 0x10071, // No data available. - - // Error codes to track errors beyond kernel. - Error_EHOSTNOTFOUND = 0x20001, // Name lookup failed. - - // POSIX permits these to have the same value and we make them - // always equal so that we cannot introduce a dependency on - // distinguishing between them that would not work on all - // platforms. - Error_EOPNOTSUPP = Error_ENOTSUP, // Operation not supported on socket - Error_EWOULDBLOCK = Error_EAGAIN, // Operation would block - - // This one is not part of POSIX, but is a catch-all for the case - // where we cannot convert the raw errno value to something above. - Error_ENONSTANDARD = 0x1FFFF, -} Error; diff --git a/src/libraries/Native/Unix/System.Native/pal_errno.c b/src/libraries/Native/Unix/System.Native/pal_errno.c index d3bfde6d2f97e..9ee754b3a3a8d 100644 --- a/src/libraries/Native/Unix/System.Native/pal_errno.c +++ b/src/libraries/Native/Unix/System.Native/pal_errno.c @@ -6,205 +6,13 @@ #include "pal_errno.h" #include "pal_utilities.h" -#include #include - -// ENODATA is not defined in FreeBSD 10.3 but is defined in 11.0 -#if defined(__FreeBSD__) & !defined(ENODATA) -#define ENODATA ENOATTR -#endif - #include #include int32_t SystemNative_ConvertErrorPlatformToPal(int32_t platformErrno) { - switch (platformErrno) - { - case 0: - return Error_SUCCESS; - case E2BIG: - return Error_E2BIG; - case EACCES: - return Error_EACCES; - case EADDRINUSE: - return Error_EADDRINUSE; - case EADDRNOTAVAIL: - return Error_EADDRNOTAVAIL; - case EAFNOSUPPORT: - return Error_EAFNOSUPPORT; - case EAGAIN: - return Error_EAGAIN; - case EALREADY: - return Error_EALREADY; - case EBADF: - return Error_EBADF; - case EBADMSG: - return Error_EBADMSG; - case EBUSY: - return Error_EBUSY; - case ECANCELED: - return Error_ECANCELED; - case ECHILD: - return Error_ECHILD; - case ECONNABORTED: - return Error_ECONNABORTED; - case ECONNREFUSED: - return Error_ECONNREFUSED; - case ECONNRESET: - return Error_ECONNRESET; - case EDEADLK: - return Error_EDEADLK; - case EDESTADDRREQ: - return Error_EDESTADDRREQ; - case EDOM: - return Error_EDOM; - case EDQUOT: - return Error_EDQUOT; - case EEXIST: - return Error_EEXIST; - case EFAULT: - return Error_EFAULT; - case EFBIG: - return Error_EFBIG; - case EHOSTUNREACH: - return Error_EHOSTUNREACH; - case EIDRM: - return Error_EIDRM; - case EILSEQ: - return Error_EILSEQ; - case EINPROGRESS: - return Error_EINPROGRESS; - case EINTR: - return Error_EINTR; - case EINVAL: - return Error_EINVAL; - case EIO: - return Error_EIO; - case EISCONN: - return Error_EISCONN; - case EISDIR: - return Error_EISDIR; - case ELOOP: - return Error_ELOOP; - case EMFILE: - return Error_EMFILE; - case EMLINK: - return Error_EMLINK; - case EMSGSIZE: - return Error_EMSGSIZE; - case EMULTIHOP: - return Error_EMULTIHOP; - case ENAMETOOLONG: - return Error_ENAMETOOLONG; - case ENETDOWN: - return Error_ENETDOWN; - case ENETRESET: - return Error_ENETRESET; - case ENETUNREACH: - return Error_ENETUNREACH; - case ENFILE: - return Error_ENFILE; - case ENOBUFS: - return Error_ENOBUFS; - case ENODEV: - return Error_ENODEV; - case ENOENT: - return Error_ENOENT; - case ENOEXEC: - return Error_ENOEXEC; - case ENOLCK: - return Error_ENOLCK; - case ENOLINK: - return Error_ENOLINK; - case ENOMEM: - return Error_ENOMEM; - case ENOMSG: - return Error_ENOMSG; - case ENOPROTOOPT: - return Error_ENOPROTOOPT; - case ENOSPC: - return Error_ENOSPC; - case ENOSYS: - return Error_ENOSYS; - case ENOTCONN: - return Error_ENOTCONN; - case ENOTDIR: - return Error_ENOTDIR; -#if ENOTEMPTY != EEXIST // AIX defines this - case ENOTEMPTY: - return Error_ENOTEMPTY; -#endif -#ifdef ENOTRECOVERABLE // not available in NetBSD - case ENOTRECOVERABLE: - return Error_ENOTRECOVERABLE; -#endif - case ENOTSOCK: - return Error_ENOTSOCK; - case ENOTSUP: - return Error_ENOTSUP; - case ENOTTY: - return Error_ENOTTY; - case ENXIO: - return Error_ENXIO; - case EOVERFLOW: - return Error_EOVERFLOW; -#ifdef EOWNERDEAD // not available in NetBSD - case EOWNERDEAD: - return Error_EOWNERDEAD; -#endif - case EPERM: - return Error_EPERM; - case EPIPE: - return Error_EPIPE; - case EPROTO: - return Error_EPROTO; - case EPROTONOSUPPORT: - return Error_EPROTONOSUPPORT; - case EPROTOTYPE: - return Error_EPROTOTYPE; - case ERANGE: - return Error_ERANGE; - case EROFS: - return Error_EROFS; - case ESPIPE: - return Error_ESPIPE; - case ESRCH: - return Error_ESRCH; - case ESTALE: - return Error_ESTALE; - case ETIMEDOUT: - return Error_ETIMEDOUT; - case ETXTBSY: - return Error_ETXTBSY; - case EXDEV: - return Error_EXDEV; -#ifdef ESOCKTNOSUPPORT - case ESOCKTNOSUPPORT: - return Error_ESOCKTNOSUPPORT; -#endif - case EPFNOSUPPORT: - return Error_EPFNOSUPPORT; - case ESHUTDOWN: - return Error_ESHUTDOWN; - case EHOSTDOWN: - return Error_EHOSTDOWN; - case ENODATA: - return Error_ENODATA; - -// #if because these will trigger duplicate case label warnings when -// they have the same value, which is permitted by POSIX and common. -#if EOPNOTSUPP != ENOTSUP - case EOPNOTSUPP: - return Error_EOPNOTSUPP; -#endif -#if EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: - return Error_EWOULDBLOCK; -#endif - } - - return Error_ENONSTANDARD; + return ConvertErrorPlatformToPal(platformErrno); } int32_t SystemNative_ConvertErrorPalToPlatform(int32_t error) diff --git a/src/libraries/Native/Unix/System.Native/pal_errno.h b/src/libraries/Native/Unix/System.Native/pal_errno.h index c4ba9ccd6e508..f73fe707c59fb 100644 --- a/src/libraries/Native/Unix/System.Native/pal_errno.h +++ b/src/libraries/Native/Unix/System.Native/pal_errno.h @@ -4,127 +4,7 @@ #pragma once -#include "pal_compiler.h" -#include "pal_types.h" - -/** - * Error codes returned via ConvertErrno. - * - * Only the names (without the PAL_ prefix) are specified by POSIX. - * - * The values chosen below are simply assigned arbitrarily (originally - * in alphabetical order they appear in the spec, but they can't change so - * add new values to the end!). - * - * Also, the values chosen are deliberately outside the range of - * typical UNIX errnos (small numbers), HRESULTs (negative for errors) - * and Win32 errors (0x0000 - 0xFFFF). This isn't required for - * correctness, but may help debug a caller that is interpreting a raw - * int incorrectly. - * - * Wherever the spec says "x may be the same value as y", we do use - * the same value so that callers cannot not take a dependency on - * being able to distinguish between them. - */ -typedef enum -{ - Error_SUCCESS = 0, - - Error_E2BIG = 0x10001, // Argument list too long. - Error_EACCES = 0x10002, // Permission denied. - Error_EADDRINUSE = 0x10003, // Address in use. - Error_EADDRNOTAVAIL = 0x10004, // Address not available. - Error_EAFNOSUPPORT = 0x10005, // Address family not supported. - Error_EAGAIN = 0x10006, // Resource unavailable, try again (same value as EWOULDBLOCK), - Error_EALREADY = 0x10007, // Connection already in progress. - Error_EBADF = 0x10008, // Bad file descriptor. - Error_EBADMSG = 0x10009, // Bad message. - Error_EBUSY = 0x1000A, // Device or resource busy. - Error_ECANCELED = 0x1000B, // Operation canceled. - Error_ECHILD = 0x1000C, // No child processes. - Error_ECONNABORTED = 0x1000D, // Connection aborted. - Error_ECONNREFUSED = 0x1000E, // Connection refused. - Error_ECONNRESET = 0x1000F, // Connection reset. - Error_EDEADLK = 0x10010, // Resource deadlock would occur. - Error_EDESTADDRREQ = 0x10011, // Destination address required. - Error_EDOM = 0x10012, // Mathematics argument out of domain of function. - Error_EDQUOT = 0x10013, // Reserved. - Error_EEXIST = 0x10014, // File exists. - Error_EFAULT = 0x10015, // Bad address. - Error_EFBIG = 0x10016, // File too large. - Error_EHOSTUNREACH = 0x10017, // Host is unreachable. - Error_EIDRM = 0x10018, // Identifier removed. - Error_EILSEQ = 0x10019, // Illegal byte sequence. - Error_EINPROGRESS = 0x1001A, // Operation in progress. - Error_EINTR = 0x1001B, // Interrupted function. - Error_EINVAL = 0x1001C, // Invalid argument. - Error_EIO = 0x1001D, // I/O error. - Error_EISCONN = 0x1001E, // Socket is connected. - Error_EISDIR = 0x1001F, // Is a directory. - Error_ELOOP = 0x10020, // Too many levels of symbolic links. - Error_EMFILE = 0x10021, // File descriptor value too large. - Error_EMLINK = 0x10022, // Too many links. - Error_EMSGSIZE = 0x10023, // Message too large. - Error_EMULTIHOP = 0x10024, // Reserved. - Error_ENAMETOOLONG = 0x10025, // Filename too long. - Error_ENETDOWN = 0x10026, // Network is down. - Error_ENETRESET = 0x10027, // Connection aborted by network. - Error_ENETUNREACH = 0x10028, // Network unreachable. - Error_ENFILE = 0x10029, // Too many files open in system. - Error_ENOBUFS = 0x1002A, // No buffer space available. - Error_ENODEV = 0x1002C, // No such device. - Error_ENOENT = 0x1002D, // No such file or directory. - Error_ENOEXEC = 0x1002E, // Executable file format error. - Error_ENOLCK = 0x1002F, // No locks available. - Error_ENOLINK = 0x10030, // Reserved. - Error_ENOMEM = 0x10031, // Not enough space. - Error_ENOMSG = 0x10032, // No message of the desired type. - Error_ENOPROTOOPT = 0x10033, // Protocol not available. - Error_ENOSPC = 0x10034, // No space left on device. - Error_ENOSYS = 0x10037, // Function not supported. - Error_ENOTCONN = 0x10038, // The socket is not connected. - Error_ENOTDIR = 0x10039, // Not a directory or a symbolic link to a directory. - Error_ENOTEMPTY = 0x1003A, // Directory not empty. - Error_ENOTRECOVERABLE = 0x1003B, // State not recoverable. - Error_ENOTSOCK = 0x1003C, // Not a socket. - Error_ENOTSUP = 0x1003D, // Not supported (same value as EOPNOTSUP). - Error_ENOTTY = 0x1003E, // Inappropriate I/O control operation. - Error_ENXIO = 0x1003F, // No such device or address. - Error_EOVERFLOW = 0x10040, // Value too large to be stored in data type. - Error_EOWNERDEAD = 0x10041, // Previous owner died. - Error_EPERM = 0x10042, // Operation not permitted. - Error_EPIPE = 0x10043, // Broken pipe. - Error_EPROTO = 0x10044, // Protocol error. - Error_EPROTONOSUPPORT = 0x10045, // Protocol not supported. - Error_EPROTOTYPE = 0x10046, // Protocol wrong type for socket. - Error_ERANGE = 0x10047, // Result too large. - Error_EROFS = 0x10048, // Read-only file system. - Error_ESPIPE = 0x10049, // Invalid seek. - Error_ESRCH = 0x1004A, // No such process. - Error_ESTALE = 0x1004B, // Reserved. - Error_ETIMEDOUT = 0x1004D, // Connection timed out. - Error_ETXTBSY = 0x1004E, // Text file busy. - Error_EXDEV = 0x1004F, // Cross-device link. - Error_ESOCKTNOSUPPORT = 0x1005E, // Socket type not supported. - Error_EPFNOSUPPORT = 0x10060, // Protocol family not supported. - Error_ESHUTDOWN = 0x1006C, // Socket shutdown. - Error_EHOSTDOWN = 0x10070, // Host is down. - Error_ENODATA = 0x10071, // No data available. - - // Error codes to track errors beyond kernel. - Error_EHOSTNOTFOUND = 0x20001, // Name lookup failed. - - // POSIX permits these to have the same value and we make them - // always equal so that we cannot introduce a dependency on - // distinguishing between them that would not work on all - // platforms. - Error_EOPNOTSUPP = Error_ENOTSUP, // Operation not supported on socket - Error_EWOULDBLOCK = Error_EAGAIN, // Operation would block - - // This one is not part of POSIX, but is a catch-all for the case - // where we cannot convert the raw errno value to something above. - Error_ENONSTANDARD = 0x1FFFF, -} Error; +#include /** * Converts the given raw numeric value obtained via errno -> diff --git a/src/libraries/Native/Unix/System.Native/pal_io.c b/src/libraries/Native/Unix/System.Native/pal_io.c index 4c5af27593cb2..2e441c3efe1e5 100644 --- a/src/libraries/Native/Unix/System.Native/pal_io.c +++ b/src/libraries/Native/Unix/System.Native/pal_io.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -921,120 +920,7 @@ int32_t SystemNative_FTruncate(intptr_t fd, int64_t length) int32_t SystemNative_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t milliseconds, uint32_t* triggered) { - if (pollEvents == NULL || triggered == NULL) - { - return Error_EFAULT; - } - - if (milliseconds < -1) - { - return Error_EINVAL; - } - - struct pollfd stackBuffer[(uint32_t)(2048/sizeof(struct pollfd))]; - int useStackBuffer = eventCount <= ARRAY_SIZE(stackBuffer); - struct pollfd* pollfds = NULL; - if (useStackBuffer) - { - pollfds = &stackBuffer[0]; - } - else - { - pollfds = calloc(eventCount, sizeof(*pollfds)); - if (pollfds == NULL) - { - return Error_ENOMEM; - } - } - - for (uint32_t i = 0; i < eventCount; i++) - { - const PollEvent* event = &pollEvents[i]; - pollfds[i].fd = event->FileDescriptor; - // we need to do this for platforms like AIX where PAL_POLL* doesn't - // match up to their reality; this is PollEvent -> system polling - switch (event->Events) - { - case PAL_POLLIN: - pollfds[i].events = POLLIN; - break; - case PAL_POLLPRI: - pollfds[i].events = POLLPRI; - break; - case PAL_POLLOUT: - pollfds[i].events = POLLOUT; - break; - case PAL_POLLERR: - pollfds[i].events = POLLERR; - break; - case PAL_POLLHUP: - pollfds[i].events = POLLHUP; - break; - case PAL_POLLNVAL: - pollfds[i].events = POLLNVAL; - break; - default: - pollfds[i].events = event->Events; - break; - } - pollfds[i].revents = 0; - } - - int rv; - while ((rv = poll(pollfds, (nfds_t)eventCount, milliseconds)) < 0 && errno == EINTR); - - if (rv < 0) - { - if (!useStackBuffer) - { - free(pollfds); - } - - *triggered = 0; - return SystemNative_ConvertErrorPlatformToPal(errno); - } - - for (uint32_t i = 0; i < eventCount; i++) - { - const struct pollfd* pfd = &pollfds[i]; - assert(pfd->fd == pollEvents[i].FileDescriptor); - assert(pfd->events == pollEvents[i].Events); - - // same as the other switch, just system -> PollEvent - switch (pfd->revents) - { - case POLLIN: - pollEvents[i].TriggeredEvents = PAL_POLLIN; - break; - case POLLPRI: - pollEvents[i].TriggeredEvents = PAL_POLLPRI; - break; - case POLLOUT: - pollEvents[i].TriggeredEvents = PAL_POLLOUT; - break; - case POLLERR: - pollEvents[i].TriggeredEvents = PAL_POLLERR; - break; - case POLLHUP: - pollEvents[i].TriggeredEvents = PAL_POLLHUP; - break; - case POLLNVAL: - pollEvents[i].TriggeredEvents = PAL_POLLNVAL; - break; - default: - pollEvents[i].TriggeredEvents = (int16_t)pfd->revents; - break; - } - } - - *triggered = (uint32_t)rv; - - if (!useStackBuffer) - { - free(pollfds); - } - - return Error_SUCCESS; + return Common_Poll(pollEvents, eventCount, milliseconds, triggered); } int32_t SystemNative_PosixFAdvise(intptr_t fd, int64_t offset, int64_t length, int32_t advice) @@ -1085,20 +971,7 @@ char* SystemNative_GetLine(FILE* stream) int32_t SystemNative_Read(intptr_t fd, void* buffer, int32_t bufferSize) { - assert(buffer != NULL || bufferSize == 0); - assert(bufferSize >= 0); - - if (bufferSize < 0) - { - errno = EINVAL; - return -1; - } - - ssize_t count; - while ((count = read(ToFileDescriptor(fd), buffer, (uint32_t)bufferSize)) < 0 && errno == EINTR); - - assert(count >= -1 && count <= bufferSize); - return (int32_t)count; + return Common_Read(fd, buffer, bufferSize); } int32_t SystemNative_ReadLink(const char* path, char* buffer, int32_t bufferSize) @@ -1139,20 +1012,7 @@ void SystemNative_Sync(void) int32_t SystemNative_Write(intptr_t fd, const void* buffer, int32_t bufferSize) { - assert(buffer != NULL || bufferSize == 0); - assert(bufferSize >= 0); - - if (bufferSize < 0) - { - errno = ERANGE; - return -1; - } - - ssize_t count; - while ((count = write(ToFileDescriptor(fd), buffer, (uint32_t)bufferSize)) < 0 && errno == EINTR); - - assert(count >= -1 && count <= bufferSize); - return (int32_t)count; + return Common_Write(fd, buffer, bufferSize); } // Read all data from inFd and write it to outFd diff --git a/src/libraries/Native/Unix/System.Native/pal_io.h b/src/libraries/Native/Unix/System.Native/pal_io.h index 9f68aa3d62f9e..3c7384b50f16a 100644 --- a/src/libraries/Native/Unix/System.Native/pal_io.h +++ b/src/libraries/Native/Unix/System.Native/pal_io.h @@ -11,6 +11,7 @@ #include #include #include +#include /** * File status returned by Stat or FStat. @@ -259,20 +260,6 @@ typedef enum PAL_SC_PAGESIZE = 2, // Size of a page in bytes } SysConfName; -/** - * Constants passed to and from poll describing what to poll for and what - * kind of data was received from poll. - */ -typedef enum -{ - PAL_POLLIN = 0x0001, /* non-urgent readable data available */ - PAL_POLLPRI = 0x0002, /* urgent readable data available */ - PAL_POLLOUT = 0x0004, /* data can be written without blocked */ - PAL_POLLERR = 0x0008, /* an error occurred */ - PAL_POLLHUP = 0x0010, /* the file descriptor hung up */ - PAL_POLLNVAL = 0x0020, /* the requested events were invalid */ -} PollEvents; - /** * Constants passed to posix_advise to give hints to the kernel about the type of I/O * operations that will occur. @@ -297,16 +284,6 @@ typedef struct int32_t InodeType; // The inode type as described in the NodeType enum } DirectoryEntry; -/** - * Our intermediate pollfd struct to normalize the data types - */ -typedef struct -{ - int32_t FileDescriptor; // The file descriptor to poll - int16_t Events; // The events to poll for - int16_t TriggeredEvents; // The events that triggered the poll -} PollEvent; - /** * Constants passed in the mask argument of INotifyAddWatch which identify inotify events. */ diff --git a/src/libraries/Native/Unix/System.Native/pal_networking.c b/src/libraries/Native/Unix/System.Native/pal_networking.c index 47d4273f6dc50..319b5000c46a0 100644 --- a/src/libraries/Native/Unix/System.Native/pal_networking.c +++ b/src/libraries/Native/Unix/System.Native/pal_networking.c @@ -7,6 +7,7 @@ #include "pal_io.h" #include "pal_safecrt.h" #include "pal_utilities.h" +#include #include #include @@ -1566,29 +1567,7 @@ int32_t SystemNative_Listen(intptr_t socket, int32_t backlog) int32_t SystemNative_Shutdown(intptr_t socket, int32_t socketShutdown) { - int fd = ToFileDescriptor(socket); - - int how; - switch (socketShutdown) - { - case SocketShutdown_SHUT_READ: - how = SHUT_RD; - break; - - case SocketShutdown_SHUT_WRITE: - how = SHUT_WR; - break; - - case SocketShutdown_SHUT_BOTH: - how = SHUT_RDWR; - break; - - default: - return Error_EINVAL; - } - - int err = shutdown(fd, how); - return err == 0 ? Error_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); + return Common_Shutdown(socket, socketShutdown); } int32_t SystemNative_GetSocketErrorOption(intptr_t socket, int32_t* error) diff --git a/src/libraries/Native/Unix/System.Native/pal_networking.h b/src/libraries/Native/Unix/System.Native/pal_networking.h index 8d228c9f1bac4..4cd3ca922ea52 100644 --- a/src/libraries/Native/Unix/System.Native/pal_networking.h +++ b/src/libraries/Native/Unix/System.Native/pal_networking.h @@ -7,6 +7,7 @@ #include "pal_compiler.h" #include "pal_types.h" #include "pal_errno.h" +#include /** * These error values are different on every platform so make a @@ -111,18 +112,6 @@ typedef enum MulticastOption_MULTICAST_IF = 2 // IP_MULTICAST_IF } MulticastOption; -/* - * Socket shutdown modes. - * - * NOTE: these values are taken from System.Net.SocketShutdown. - */ -typedef enum -{ - SocketShutdown_SHUT_READ = 0, // SHUT_RD - SocketShutdown_SHUT_WRITE = 1, // SHUT_WR - SocketShutdown_SHUT_BOTH = 2, // SHUT_RDWR -} SockerShutdown; - /* * Socket option levels. * From a07068ae625c3bfffc2459d7e5aaa738cc6efc96 Mon Sep 17 00:00:00 2001 From: Anirudh Agnihotry Date: Mon, 11 May 2020 17:56:45 -0700 Subject: [PATCH 119/420] update branding to preview6 (#36247) --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 8d84b68f91361..dca797f403a22 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,7 +7,7 @@ 0 0 preview - 5 + 6 $(MajorVersion).$(MinorVersion).0.0 From facdc3673fdc564440394d7cce72942f10bb3a4e Mon Sep 17 00:00:00 2001 From: Youssef Victor <31348972+Youssef1313@users.noreply.github.com> Date: Tue, 12 May 2020 03:12:22 +0200 Subject: [PATCH 120/420] Delete outdated todo comment (#36224) --- .../System.Runtime.Numerics/src/System/Numerics/BigInteger.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs index 123453cdfaf21..494b0531dcb36 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs @@ -1477,7 +1477,7 @@ public string ToString(string? format, IFormatProvider? provider) return BigNumber.FormatBigInteger(this, format, NumberFormatInfo.GetInstance(provider)); } - public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = null) // TODO: change format to ReadOnlySpan + public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = null) { return BigNumber.TryFormatBigInteger(this, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten); } From 6a48efaaf9ee549a9d5f52ad5a74eacf5de20c62 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 11 May 2020 18:32:04 -0700 Subject: [PATCH 121/420] [ARM64] Implement Duplicate and DuplicateSelectedScalar (#36144) * Adding support for DuplicateToVector64 and DuplicateToVector128 to Arm.AdvSimd and Arm.AdvSimd.Arm64 * Adding tests for DuplicateToVector64 and DuplicateToVector128 * Adding support for DuplicateSelectedScalarToVector64 and DuplicateSelectedScalarToVector128 to Arm.AdvSimd and Arm.AdvSimd.Arm64 * Adding tests for DuplicateSelectedScalarToVector64 and DuplicateSelectedScalarToVector128 * Regenerating tests for the newly added HWIntrinsics * Ensure parentheses exist * Removing the AdvSimd.Arm64 hwintrinsiclist entry for DuplicateToVector64 * Removing the rest of the NI_AdvSimd_arm64_DuplicateToVector64 usages and clarifying a comment * Moving break outside the braces for consistency * Removing another Arm64.DuplicateToVector64 * Removing the AdvSimd.Arm64.DuplicateToVector64 tests * Adding tests covering DuplicateToVector64/DuplicateToVector128 immediate inputs * Regenerating the ARM64 HWIntrinsic tests * Fixing the DuplicateToVector immediate tests * Regenerating the DuplicateToVector immediate tests --- src/coreclr/src/jit/emitarm64.cpp | 10 +- src/coreclr/src/jit/hwintrinsicarm64.cpp | 3 + .../src/jit/hwintrinsiccodegenarm64.cpp | 64 ++- src/coreclr/src/jit/hwintrinsiclistarm64.h | 6 + src/coreclr/src/jit/lowerarmarch.cpp | 7 + src/coreclr/src/jit/lsraarm64.cpp | 3 + .../Arm/AdvSimd.Arm64/AdvSimd.Arm64_r.csproj | 9 + .../Arm/AdvSimd.Arm64/AdvSimd.Arm64_ro.csproj | 9 + ...SelectedScalarToVector128.V128.Double.1.cs | 506 ++++++++++++++++++ ...eSelectedScalarToVector128.V128.Int64.1.cs | 506 ++++++++++++++++++ ...SelectedScalarToVector128.V128.UInt64.1.cs | 506 ++++++++++++++++++ .../DuplicateToVector128.Double.31.cs | 185 +++++++ .../DuplicateToVector128.Double.cs | 300 +++++++++++ .../DuplicateToVector128.Int64.31.cs | 185 +++++++ .../DuplicateToVector128.Int64.cs | 300 +++++++++++ .../DuplicateToVector128.UInt64.31.cs | 185 +++++++ .../DuplicateToVector128.UInt64.cs | 300 +++++++++++ .../AdvSimd.Arm64/Program.AdvSimd.Arm64.cs | 9 + .../Arm/AdvSimd/AdvSimd_r.csproj | 56 ++ .../Arm/AdvSimd/AdvSimd_ro.csproj | 56 ++ ...teSelectedScalarToVector128.V128.Byte.8.cs | 506 ++++++++++++++++++ ...eSelectedScalarToVector128.V128.Int16.4.cs | 506 ++++++++++++++++++ ...eSelectedScalarToVector128.V128.Int32.2.cs | 506 ++++++++++++++++++ ...eSelectedScalarToVector128.V128.SByte.8.cs | 506 ++++++++++++++++++ ...SelectedScalarToVector128.V128.Single.2.cs | 506 ++++++++++++++++++ ...SelectedScalarToVector128.V128.UInt16.4.cs | 506 ++++++++++++++++++ ...SelectedScalarToVector128.V128.UInt32.2.cs | 506 ++++++++++++++++++ ...ateSelectedScalarToVector128.V64.Byte.1.cs | 506 ++++++++++++++++++ ...teSelectedScalarToVector128.V64.Int16.1.cs | 506 ++++++++++++++++++ ...teSelectedScalarToVector128.V64.Int32.1.cs | 506 ++++++++++++++++++ ...teSelectedScalarToVector128.V64.SByte.1.cs | 506 ++++++++++++++++++ ...eSelectedScalarToVector128.V64.Single.1.cs | 506 ++++++++++++++++++ ...eSelectedScalarToVector128.V64.UInt16.1.cs | 506 ++++++++++++++++++ ...eSelectedScalarToVector128.V64.UInt32.1.cs | 506 ++++++++++++++++++ ...ateSelectedScalarToVector64.V128.Byte.8.cs | 506 ++++++++++++++++++ ...teSelectedScalarToVector64.V128.Int16.4.cs | 506 ++++++++++++++++++ ...teSelectedScalarToVector64.V128.Int32.2.cs | 506 ++++++++++++++++++ ...teSelectedScalarToVector64.V128.SByte.8.cs | 506 ++++++++++++++++++ ...eSelectedScalarToVector64.V128.Single.2.cs | 506 ++++++++++++++++++ ...eSelectedScalarToVector64.V128.UInt16.4.cs | 506 ++++++++++++++++++ ...eSelectedScalarToVector64.V128.UInt32.2.cs | 506 ++++++++++++++++++ ...cateSelectedScalarToVector64.V64.Byte.1.cs | 506 ++++++++++++++++++ ...ateSelectedScalarToVector64.V64.Int16.1.cs | 506 ++++++++++++++++++ ...ateSelectedScalarToVector64.V64.Int32.1.cs | 506 ++++++++++++++++++ ...ateSelectedScalarToVector64.V64.SByte.1.cs | 506 ++++++++++++++++++ ...teSelectedScalarToVector64.V64.Single.1.cs | 506 ++++++++++++++++++ ...teSelectedScalarToVector64.V64.UInt16.1.cs | 506 ++++++++++++++++++ ...teSelectedScalarToVector64.V64.UInt32.1.cs | 506 ++++++++++++++++++ .../AdvSimd/DuplicateToVector128.Byte.31.cs | 185 +++++++ .../Arm/AdvSimd/DuplicateToVector128.Byte.cs | 300 +++++++++++ .../AdvSimd/DuplicateToVector128.Int16.31.cs | 185 +++++++ .../Arm/AdvSimd/DuplicateToVector128.Int16.cs | 300 +++++++++++ .../AdvSimd/DuplicateToVector128.Int32.31.cs | 185 +++++++ .../Arm/AdvSimd/DuplicateToVector128.Int32.cs | 300 +++++++++++ .../AdvSimd/DuplicateToVector128.SByte.31.cs | 185 +++++++ .../Arm/AdvSimd/DuplicateToVector128.SByte.cs | 300 +++++++++++ .../AdvSimd/DuplicateToVector128.Single.31.cs | 185 +++++++ .../AdvSimd/DuplicateToVector128.Single.cs | 300 +++++++++++ .../AdvSimd/DuplicateToVector128.UInt16.31.cs | 185 +++++++ .../AdvSimd/DuplicateToVector128.UInt16.cs | 300 +++++++++++ .../AdvSimd/DuplicateToVector128.UInt32.31.cs | 185 +++++++ .../AdvSimd/DuplicateToVector128.UInt32.cs | 300 +++++++++++ .../AdvSimd/DuplicateToVector64.Byte.31.cs | 185 +++++++ .../Arm/AdvSimd/DuplicateToVector64.Byte.cs | 300 +++++++++++ .../AdvSimd/DuplicateToVector64.Int16.31.cs | 185 +++++++ .../Arm/AdvSimd/DuplicateToVector64.Int16.cs | 300 +++++++++++ .../AdvSimd/DuplicateToVector64.Int32.31.cs | 185 +++++++ .../Arm/AdvSimd/DuplicateToVector64.Int32.cs | 300 +++++++++++ .../AdvSimd/DuplicateToVector64.SByte.31.cs | 185 +++++++ .../Arm/AdvSimd/DuplicateToVector64.SByte.cs | 300 +++++++++++ .../AdvSimd/DuplicateToVector64.Single.31.cs | 185 +++++++ .../Arm/AdvSimd/DuplicateToVector64.Single.cs | 300 +++++++++++ .../AdvSimd/DuplicateToVector64.UInt16.31.cs | 185 +++++++ .../Arm/AdvSimd/DuplicateToVector64.UInt16.cs | 300 +++++++++++ .../AdvSimd/DuplicateToVector64.UInt32.31.cs | 185 +++++++ .../Arm/AdvSimd/DuplicateToVector64.UInt32.cs | 300 +++++++++++ .../Arm/AdvSimd/Program.AdvSimd.cs | 56 ++ .../Arm/Shared/GenerateTests.csx | 69 ++- .../Arm/Shared/_ImmOpTestTemplate.template | 171 ++++++ .../Shared/_ImmUnaryOpTestTemplate.template | 492 +++++++++++++++++ .../_UnaryOpScalarTestTemplate.template | 286 ++++++++++ .../Arm/AdvSimd.PlatformNotSupported.cs | 330 ++++++++++++ .../System/Runtime/Intrinsics/Arm/AdvSimd.cs | 330 ++++++++++++ .../System.Runtime.Intrinsics.Experimental.cs | 48 ++ 84 files changed, 25927 insertions(+), 18 deletions(-) create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Double.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.UInt64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Double.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Double.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Int64.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.UInt64.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.UInt64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Byte.8.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int16.4.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int32.2.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.SByte.8.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Single.2.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt16.4.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt32.2.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Single.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Byte.8.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int16.4.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int32.2.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.SByte.8.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Single.2.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt16.4.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt32.2.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Single.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Byte.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int16.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int32.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.SByte.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Single.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Single.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt16.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt32.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Byte.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int16.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int32.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.SByte.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Single.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Single.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt16.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt32.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmOpTestTemplate.template create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmUnaryOpTestTemplate.template create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_UnaryOpScalarTestTemplate.template diff --git a/src/coreclr/src/jit/emitarm64.cpp b/src/coreclr/src/jit/emitarm64.cpp index 0d3eaba955931..81bca4118a9ff 100644 --- a/src/coreclr/src/jit/emitarm64.cpp +++ b/src/coreclr/src/jit/emitarm64.cpp @@ -649,12 +649,13 @@ void emitter::emitInsSanityCheck(instrDesc* id) break; case IF_DV_2D: // DV_2D .Q.........iiiii ......nnnnnddddd Vd Vn[] (dup - vector) + ins = id->idIns(); datasize = id->idOpSize(); assert(isValidVectorDatasize(datasize)); assert(isValidArrangement(datasize, id->idInsOpt())); elemsize = optGetElemsize(id->idInsOpt()); index = emitGetInsSC(id); - assert(isValidVectorIndex(datasize, elemsize, index)); + assert((ins == INS_dup) || isValidVectorIndex(datasize, elemsize, index)); assert(isVectorRegister(id->idReg1())); assert(isVectorRegister(id->idReg2())); break; @@ -5031,12 +5032,17 @@ void emitter::emitIns_R_R_I( { if (insOptsAnyArrangement(opt)) { + // The size and opt were modified to be based on the + // return type but the immediate is based on the operand + // which can be of a larger size. As such, we don't + // assert the index is valid here and instead do it in + // codegen. + // Vector operation assert(isValidVectorDatasize(size)); assert(isValidArrangement(size, opt)); elemsize = optGetElemsize(opt); assert(isValidVectorElemsize(elemsize)); - assert(isValidVectorIndex(size, elemsize, imm)); assert(opt != INS_OPTS_1D); // Reserved encoding fmt = IF_DV_2D; break; diff --git a/src/coreclr/src/jit/hwintrinsicarm64.cpp b/src/coreclr/src/jit/hwintrinsicarm64.cpp index 85c734d97bb31..45efb8a68a58b 100644 --- a/src/coreclr/src/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/src/jit/hwintrinsicarm64.cpp @@ -200,10 +200,13 @@ int HWIntrinsicInfo::lookupImmUpperBound(NamedIntrinsic intrinsic, int simdSize, { switch (intrinsic) { + case NI_AdvSimd_DuplicateSelectedScalarToVector64: + case NI_AdvSimd_DuplicateSelectedScalarToVector128: case NI_AdvSimd_Extract: case NI_AdvSimd_ExtractVector128: case NI_AdvSimd_ExtractVector64: case NI_AdvSimd_Insert: + case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128: immUpperBound = Compiler::getSIMDVectorLength(simdSize, baseType); break; diff --git a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp index fafbf06489728..71ac68f759ce8 100644 --- a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp @@ -430,6 +430,35 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GetEmitter()->emitIns_R_R(ins, emitSize, op2Reg, op1Reg, opt); break; + case NI_AdvSimd_DuplicateSelectedScalarToVector64: + case NI_AdvSimd_DuplicateSelectedScalarToVector128: + case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128: + { + HWIntrinsicImmOpHelper helper(this, intrin.op2, node); + + // Prior to codegen, the emitSize is based on node->gtSIMDSize which + // tracks the size of the first operand and is used to tell if the index + // is in range. However, when actually emitting it needs to be the size + // of the return and the size of the operand is interpreted based on the + // index value. + + assert( + GetEmitter()->isValidVectorIndex(emitSize, GetEmitter()->optGetElemsize(opt), helper.ImmValue())); + + emitSize = emitActualTypeSize(node->gtType); + opt = genGetSimdInsOpt(emitSize, intrin.baseType); + + for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) + { + const int elementIndex = helper.ImmValue(); + + assert(opt != INS_OPTS_NONE); + GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, op1Reg, elementIndex, opt); + } + + break; + } + case NI_AdvSimd_Extract: { HWIntrinsicImmOpHelper helper(this, intrin.op2, node); @@ -556,28 +585,33 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Vector64_Create: case NI_Vector128_Create: - if (intrin.op1->isContainedFltOrDblImmed()) - { - const double dataValue = intrin.op1->AsDblCon()->gtDconVal; - GetEmitter()->emitIns_R_F(INS_fmov, emitSize, targetReg, dataValue, opt); - } - else if (varTypeIsFloating(intrin.baseType)) - { - GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, op1Reg, 0, opt); - } - else + case NI_AdvSimd_DuplicateToVector64: + case NI_AdvSimd_DuplicateToVector128: + case NI_AdvSimd_Arm64_DuplicateToVector128: + { + if (varTypeIsFloating(intrin.baseType)) { - if (intrin.op1->isContainedIntOrIImmed()) + if (intrin.op1->isContainedFltOrDblImmed()) { - const ssize_t dataValue = intrin.op1->AsIntCon()->gtIconVal; - GetEmitter()->emitIns_R_I(INS_movi, emitSize, targetReg, dataValue, opt); + const double dataValue = intrin.op1->AsDblCon()->gtDconVal; + GetEmitter()->emitIns_R_F(INS_fmov, emitSize, targetReg, dataValue, opt); } else { - GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg, opt); + GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, op1Reg, 0, opt); } } - break; + else if (intrin.op1->isContainedIntOrIImmed()) + { + const ssize_t dataValue = intrin.op1->AsIntCon()->gtIconVal; + GetEmitter()->emitIns_R_I(INS_movi, emitSize, targetReg, dataValue, opt); + } + else + { + GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg, opt); + } + } + break; default: unreached(); diff --git a/src/coreclr/src/jit/hwintrinsiclistarm64.h b/src/coreclr/src/jit/hwintrinsiclistarm64.h index ec39efddb4441..f798a17d26e42 100644 --- a/src/coreclr/src/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/src/jit/hwintrinsiclistarm64.h @@ -93,6 +93,10 @@ HARDWARE_INTRINSIC(AdvSimd, CompareLessThan, - HARDWARE_INTRINSIC(AdvSimd, CompareLessThanOrEqual, -1, 2, {INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_invalid, INS_invalid, INS_fcmge, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AdvSimd, CompareTest, -1, 2, {INS_cmtst, INS_cmtst, INS_cmtst, INS_cmtst, INS_cmtst, INS_cmtst, INS_invalid, INS_invalid, INS_cmtst, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AdvSimd, DivideScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fdiv, INS_fdiv}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, DuplicateSelectedScalarToVector64, -1, 2, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, DuplicateSelectedScalarToVector128, -1, 2, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, DuplicateToVector64, 8, 1, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, DuplicateToVector128, 16, 1, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AdvSimd, Extract, -1, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AdvSimd, ExtractAndNarrowHigh, 16, 2, {INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(AdvSimd, ExtractAndNarrowLow, 8, 1, {INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) @@ -192,6 +196,8 @@ HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareLessThanScalar, HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareTest, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmtst, INS_cmtst, INS_invalid, INS_cmtst}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareTestScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmtst, INS_cmtst, INS_invalid, INS_cmtst}, HW_Category_SIMDScalar, HW_Flag_Commutative) HARDWARE_INTRINSIC(AdvSimd_Arm64, Divide, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fdiv, INS_fdiv}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, DuplicateSelectedScalarToVector128, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_dup, INS_dup, INS_invalid, INS_dup}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, DuplicateToVector128, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_dup, INS_dup, INS_invalid, INS_dup}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AdvSimd_Arm64, FusedMultiplyAdd, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmla}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(AdvSimd_Arm64, FusedMultiplySubtract, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmls}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(AdvSimd_Arm64, Max, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmax}, HW_Category_SimpleSIMD, HW_Flag_Commutative) diff --git a/src/coreclr/src/jit/lowerarmarch.cpp b/src/coreclr/src/jit/lowerarmarch.cpp index 87639a0fdfd8f..7b7706e9b1caa 100644 --- a/src/coreclr/src/jit/lowerarmarch.cpp +++ b/src/coreclr/src/jit/lowerarmarch.cpp @@ -896,7 +896,10 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) switch (intrin.id) { + case NI_AdvSimd_DuplicateSelectedScalarToVector64: + case NI_AdvSimd_DuplicateSelectedScalarToVector128: case NI_AdvSimd_Extract: + case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128: if (intrin.op2->IsCnsIntOrI()) { MakeSrcContained(node, intrin.op2); @@ -934,6 +937,9 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Vector128_Create: case NI_Vector64_CreateScalarUnsafe: case NI_Vector128_CreateScalarUnsafe: + case NI_AdvSimd_DuplicateToVector64: + case NI_AdvSimd_DuplicateToVector128: + case NI_AdvSimd_Arm64_DuplicateToVector128: if (intrin.op1->IsCnsIntOrI()) { const ssize_t dataValue = intrin.op1->AsIntCon()->gtIconVal; @@ -955,6 +961,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) } } break; + default: unreached(); } diff --git a/src/coreclr/src/jit/lsraarm64.cpp b/src/coreclr/src/jit/lsraarm64.cpp index 6b7e6116e3f45..c69a6cfab03cd 100644 --- a/src/coreclr/src/jit/lsraarm64.cpp +++ b/src/coreclr/src/jit/lsraarm64.cpp @@ -1015,8 +1015,11 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) switch (intrin.id) { + case NI_AdvSimd_DuplicateSelectedScalarToVector64: + case NI_AdvSimd_DuplicateSelectedScalarToVector128: case NI_AdvSimd_Extract: case NI_AdvSimd_Insert: + case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128: needBranchTargetReg = !intrin.op2->isContainedIntOrIImmed(); break; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_r.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_r.csproj index 3981b99a07c19..81b0fa0de4f7b 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_r.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_r.csproj @@ -101,6 +101,15 @@ + + + + + + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_ro.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_ro.csproj index 7b44b6ca06304..1fed9e48643cf 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_ro.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_ro.csproj @@ -101,6 +101,15 @@ + + + + + + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Double.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Double.1.cs new file mode 100644 index 0000000000000..3de99be40433b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Double.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V128_Double_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Double_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Double_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Double[] inArray, Double[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Double_1 testClass) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Double_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Double*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Double); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Double); + + private static Double[] _data = new Double[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Double_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Double_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); } + _dataTable = new DataTable(_data, new Double[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Double*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Double*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Double*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Double*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Double_1(); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Double_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Double*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Double*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Double*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Double[] inArray = new Double[Op1ElementCount]; + Double[] outArray = new Double[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Double[] inArray = new Double[Op1ElementCount]; + Double[] outArray = new Double[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.DuplicateSelectedScalarToVector128)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Int64.1.cs new file mode 100644 index 0000000000000..e45da2e0c8e52 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Int64.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V128_Int64_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int64_1 testClass) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int64_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int64_1(); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int64_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.DuplicateSelectedScalarToVector128)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.UInt64.1.cs new file mode 100644 index 0000000000000..662352e5de00e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.UInt64.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V128_UInt64_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt64_1 testClass) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt64_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt64_1(); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt64_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.DuplicateSelectedScalarToVector128)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Double.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Double.31.cs new file mode 100644 index 0000000000000..25a9c6fb883a3 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Double.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_Double_31() + { + var test = new ImmOpTest__DuplicateToVector128_Double_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector128_Double_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Double[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Double); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector128_Double_31() + { + Succeeded = true; + + _dataTable = new DataTable(new Double[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.Arm64.DuplicateToVector128( + (Double)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.DuplicateToVector128), new Type[] { typeof(Double) }) + .Invoke(null, new object[] { + (Double)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + Double[] outArray = new Double[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(Double[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.DuplicateToVector128)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Double.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Double.cs new file mode 100644 index 0000000000000..f500029f5dafe --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Double.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_Double() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector128_Double(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector128_Double + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Double[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Double _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetDouble(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector128_Double testClass) + { + var result = AdvSimd.Arm64.DuplicateToVector128(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Double); + + private static Double _data; + + private static Double _clsVar; + + private Double _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector128_Double() + { + _clsVar = TestLibrary.Generator.GetDouble(); + } + + public DuplicateUnaryOpTest__DuplicateToVector128_Double() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetDouble(); + _data = TestLibrary.Generator.GetDouble(); + + _dataTable = new DataTable(new Double[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.DuplicateToVector128( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.DuplicateToVector128), new Type[] { typeof(Double) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.DuplicateToVector128( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.Arm64.DuplicateToVector128(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector128_Double(); + var result = AdvSimd.Arm64.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.DuplicateToVector128(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Double data, void* result, [CallerMemberName] string method = "") + { + Double[] outArray = new Double[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(Double data, Double[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.DuplicateToVector128)}(Double): DuplicateToVector128 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Int64.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Int64.31.cs new file mode 100644 index 0000000000000..cc3b5e8168d0c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Int64.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_Int64_31() + { + var test = new ImmOpTest__DuplicateToVector128_Int64_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector128_Int64_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector128_Int64_31() + { + Succeeded = true; + + _dataTable = new DataTable(new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.Arm64.DuplicateToVector128( + (Int64)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.DuplicateToVector128), new Type[] { typeof(Int64) }) + .Invoke(null, new object[] { + (Int64)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + Int64[] outArray = new Int64[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.DuplicateToVector128)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Int64.cs new file mode 100644 index 0000000000000..11dd759214131 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.Int64.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_Int64() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector128_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector128_Int64 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Int64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetInt64(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector128_Int64 testClass) + { + var result = AdvSimd.Arm64.DuplicateToVector128(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64 _data; + + private static Int64 _clsVar; + + private Int64 _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector128_Int64() + { + _clsVar = TestLibrary.Generator.GetInt64(); + } + + public DuplicateUnaryOpTest__DuplicateToVector128_Int64() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetInt64(); + _data = TestLibrary.Generator.GetInt64(); + + _dataTable = new DataTable(new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.DuplicateToVector128( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.DuplicateToVector128), new Type[] { typeof(Int64) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.DuplicateToVector128( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.Arm64.DuplicateToVector128(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector128_Int64(); + var result = AdvSimd.Arm64.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.DuplicateToVector128(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Int64 data, void* result, [CallerMemberName] string method = "") + { + Int64[] outArray = new Int64[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(Int64 data, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.DuplicateToVector128)}(Int64): DuplicateToVector128 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.UInt64.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.UInt64.31.cs new file mode 100644 index 0000000000000..d1ebd0dd1ae65 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.UInt64.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_UInt64_31() + { + var test = new ImmOpTest__DuplicateToVector128_UInt64_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector128_UInt64_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector128_UInt64_31() + { + Succeeded = true; + + _dataTable = new DataTable(new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.Arm64.DuplicateToVector128( + (UInt64)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.DuplicateToVector128), new Type[] { typeof(UInt64) }) + .Invoke(null, new object[] { + (UInt64)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + UInt64[] outArray = new UInt64[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.DuplicateToVector128)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.UInt64.cs new file mode 100644 index 0000000000000..58788479dbfd7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateToVector128.UInt64.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_UInt64() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector128_UInt64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector128_UInt64 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public UInt64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetUInt64(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector128_UInt64 testClass) + { + var result = AdvSimd.Arm64.DuplicateToVector128(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64 _data; + + private static UInt64 _clsVar; + + private UInt64 _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector128_UInt64() + { + _clsVar = TestLibrary.Generator.GetUInt64(); + } + + public DuplicateUnaryOpTest__DuplicateToVector128_UInt64() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetUInt64(); + _data = TestLibrary.Generator.GetUInt64(); + + _dataTable = new DataTable(new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.DuplicateToVector128( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.DuplicateToVector128), new Type[] { typeof(UInt64) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.DuplicateToVector128( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.Arm64.DuplicateToVector128(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector128_UInt64(); + var result = AdvSimd.Arm64.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.DuplicateToVector128(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(UInt64 data, void* result, [CallerMemberName] string method = "") + { + UInt64[] outArray = new UInt64[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(UInt64 data, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.DuplicateToVector128)}(UInt64): DuplicateToVector128 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64.cs index 0b0f843a2b45c..3ef5be975b4b2 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64.cs @@ -105,6 +105,15 @@ static Program() ["Divide.Vector64.Single"] = Divide_Vector64_Single, ["Divide.Vector128.Double"] = Divide_Vector128_Double, ["Divide.Vector128.Single"] = Divide_Vector128_Single, + ["DuplicateSelectedScalarToVector128.V128.Double.1"] = DuplicateSelectedScalarToVector128_V128_Double_1, + ["DuplicateSelectedScalarToVector128.V128.Int64.1"] = DuplicateSelectedScalarToVector128_V128_Int64_1, + ["DuplicateSelectedScalarToVector128.V128.UInt64.1"] = DuplicateSelectedScalarToVector128_V128_UInt64_1, + ["DuplicateToVector128.Double"] = DuplicateToVector128_Double, + ["DuplicateToVector128.Double.31"] = DuplicateToVector128_Double_31, + ["DuplicateToVector128.Int64"] = DuplicateToVector128_Int64, + ["DuplicateToVector128.Int64.31"] = DuplicateToVector128_Int64_31, + ["DuplicateToVector128.UInt64"] = DuplicateToVector128_UInt64, + ["DuplicateToVector128.UInt64.31"] = DuplicateToVector128_UInt64_31, ["FusedMultiplyAdd.Vector128.Double"] = FusedMultiplyAdd_Vector128_Double, ["FusedMultiplySubtract.Vector128.Double"] = FusedMultiplySubtract_Vector128_Double, ["Max.Vector128.Double"] = Max_Vector128_Double, diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj index e31d1407a1671..a1c2428103019 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj @@ -337,6 +337,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj index 22e73f0c0be11..c15b086b93c63 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj @@ -337,6 +337,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Byte.8.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Byte.8.cs new file mode 100644 index 0000000000000..f15b8ac49234e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Byte.8.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V128_Byte_8() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Byte_8(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Byte_8 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Byte_8 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 8); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Byte_8 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Byte*)(pFld)), + 8 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Byte_8() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Byte_8() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)8 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + (byte)8 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Byte*)(pClsVar)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Byte_8(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Byte_8(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Byte*)(pFld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Byte*)(pFld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Byte*)(&test._fld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[8]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[8]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector128, 8): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int16.4.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int16.4.cs new file mode 100644 index 0000000000000..8765c46f43a3f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int16.4.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V128_Int16_4() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int16_4(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int16_4 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int16_4 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 4); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int16_4 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int16*)(pFld)), + 4 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int16_4() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int16_4() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)4 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)4 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int16_4(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int16_4(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int16*)(pFld)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int16*)(pFld)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[4]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[4]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector128, 4): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int32.2.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int32.2.cs new file mode 100644 index 0000000000000..aaa7c39fae2dd --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int32.2.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V128_Int32_2() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int32_2(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int32_2 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int32_2 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int32_2 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int32*)(pFld)), + 2 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int32_2() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int32_2() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)2 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)2 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int32_2(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Int32_2(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int32*)(pFld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int32*)(pFld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[2]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[2]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector128, 2): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.SByte.8.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.SByte.8.cs new file mode 100644 index 0000000000000..b0309d47d6bf1 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.SByte.8.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V128_SByte_8() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_SByte_8(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_SByte_8 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_SByte_8 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 8); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_SByte_8 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((SByte*)(pFld)), + 8 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_SByte_8() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_SByte_8() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)8 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)8 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((SByte*)(pClsVar)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_SByte_8(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_SByte_8(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((SByte*)(pFld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((SByte*)(pFld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((SByte*)(&test._fld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[8]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[8]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector128, 8): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Single.2.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Single.2.cs new file mode 100644 index 0000000000000..ba32b9e060cea --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Single.2.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V128_Single_2() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Single_2(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Single_2 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Single[] inArray, Single[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Single_2 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Single_2 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Single*)(pFld)), + 2 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Single); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Single); + + private static Single[] _data = new Single[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Single_2() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Single_2() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + _dataTable = new DataTable(_data, new Single[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Single*)(_dataTable.inArrayPtr)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)2 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Single*)(_dataTable.inArrayPtr)), + (byte)2 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Single*)(pClsVar)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Single*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Single_2(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_Single_2(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Single*)(pFld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Single*)(pFld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((Single*)(&test._fld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Single[] inArray = new Single[Op1ElementCount]; + Single[] outArray = new Single[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Single[] inArray = new Single[Op1ElementCount]; + Single[] outArray = new Single[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[2]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[2]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector128, 2): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt16.4.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt16.4.cs new file mode 100644 index 0000000000000..dffc8bb44d774 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt16.4.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V128_UInt16_4() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt16_4(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt16_4 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt16_4 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 4); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt16_4 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 4 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt16_4() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt16_4() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)4 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)4 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt16*)(pClsVar)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt16_4(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt16_4(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt16*)(&test._fld)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[4]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[4]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector128, 4): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt32.2.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt32.2.cs new file mode 100644 index 0000000000000..d69e9052b2fc3 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt32.2.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V128_UInt32_2() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt32_2(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt32_2 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt32_2 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt32_2 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 2 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt32_2() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt32_2() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)2 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)2 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt32*)(pClsVar)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt32_2(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V128_UInt32_2(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector128((UInt32*)(&test._fld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[2]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[2]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector128, 2): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Byte.1.cs new file mode 100644 index 0000000000000..cf194dad18516 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Byte.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V64_Byte_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Byte_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Byte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Byte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Byte_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Byte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Byte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int16.1.cs new file mode 100644 index 0000000000000..791ebe4c671e0 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int16.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V64_Int16_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int16_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int16_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int32.1.cs new file mode 100644 index 0000000000000..bf54562526a25 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int32.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V64_Int32_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int32_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int32_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Int32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.SByte.1.cs new file mode 100644 index 0000000000000..6c837d1d8f684 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.SByte.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V64_SByte_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_SByte_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_SByte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_SByte_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_SByte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Single.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Single.1.cs new file mode 100644 index 0000000000000..c1700350e048d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Single.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V64_Single_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Single_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Single_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Single[] inArray, Single[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Single_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Single_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Single*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Single); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Single); + + private static Single[] _data = new Single[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Single_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Single_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + _dataTable = new DataTable(_data, new Single[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Single*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Single*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Single*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Single*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Single_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_Single_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Single*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Single*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((Single*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Single[] inArray = new Single[Op1ElementCount]; + Single[] outArray = new Single[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Single[] inArray = new Single[Op1ElementCount]; + Single[] outArray = new Single[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt16.1.cs new file mode 100644 index 0000000000000..6cea89d585e46 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt16.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V64_UInt16_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt16_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt16_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt32.1.cs new file mode 100644 index 0000000000000..015062711019c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt32.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector128_V64_UInt32_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt32_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector128), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector128(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt32_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector128_V64_UInt32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector128(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector128( + AdvSimd.LoadVector64((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector128)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Byte.8.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Byte.8.cs new file mode 100644 index 0000000000000..1742b87a96d55 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Byte.8.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V128_Byte_8() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Byte_8(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Byte_8 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Byte_8 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 8); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Byte_8 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Byte*)(pFld)), + 8 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Byte_8() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Byte_8() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)8 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + (byte)8 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Byte*)(pClsVar)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Byte_8(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Byte_8(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Byte*)(pFld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Byte*)(pFld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Byte*)(&test._fld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[8]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[8]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector128, 8): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int16.4.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int16.4.cs new file mode 100644 index 0000000000000..37f41d0b040a9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int16.4.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V128_Int16_4() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int16_4(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int16_4 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int16_4 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 4); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int16_4 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Int16*)(pFld)), + 4 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int16_4() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int16_4() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)4 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)4 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int16_4(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int16_4(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Int16*)(pFld)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Int16*)(pFld)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[4]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[4]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector128, 4): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int32.2.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int32.2.cs new file mode 100644 index 0000000000000..2e65fe0387f25 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int32.2.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V128_Int32_2() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int32_2(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int32_2 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int32_2 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int32_2 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Int32*)(pFld)), + 2 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int32_2() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int32_2() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)2 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)2 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int32_2(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Int32_2(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Int32*)(pFld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Int32*)(pFld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[2]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[2]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector128, 2): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.SByte.8.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.SByte.8.cs new file mode 100644 index 0000000000000..1e06e79d7fd17 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.SByte.8.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V128_SByte_8() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_SByte_8(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_SByte_8 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_SByte_8 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 8); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_SByte_8 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((SByte*)(pFld)), + 8 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_SByte_8() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_SByte_8() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)8 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)8 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((SByte*)(pClsVar)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_SByte_8(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_SByte_8(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((SByte*)(pFld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((SByte*)(pFld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((SByte*)(&test._fld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[8]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[8]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector128, 8): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Single.2.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Single.2.cs new file mode 100644 index 0000000000000..78acaf5c71a13 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Single.2.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V128_Single_2() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Single_2(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Single_2 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Single[] inArray, Single[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Single_2 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Single_2 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Single*)(pFld)), + 2 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Single); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Single); + + private static Single[] _data = new Single[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Single_2() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Single_2() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + _dataTable = new DataTable(_data, new Single[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Single*)(_dataTable.inArrayPtr)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)2 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Single*)(_dataTable.inArrayPtr)), + (byte)2 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Single*)(pClsVar)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Single*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Single_2(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_Single_2(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Single*)(pFld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Single*)(pFld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((Single*)(&test._fld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Single[] inArray = new Single[Op1ElementCount]; + Single[] outArray = new Single[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Single[] inArray = new Single[Op1ElementCount]; + Single[] outArray = new Single[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[2]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[2]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector128, 2): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt16.4.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt16.4.cs new file mode 100644 index 0000000000000..bccbfcc568194 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt16.4.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V128_UInt16_4() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt16_4(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt16_4 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt16_4 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 4); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt16_4 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 4 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt16_4() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt16_4() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)4 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)4 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((UInt16*)(pClsVar)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt16_4(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt16_4(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 4); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((UInt16*)(&test._fld)), + 4 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[4]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[4]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector128, 4): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt32.2.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt32.2.cs new file mode 100644 index 0000000000000..c996ec79f20dd --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt32.2.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V128_UInt32_2() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt32_2(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt32_2 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt32_2 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt32_2 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 2 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt32_2() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt32_2() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)2 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)2 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((UInt32*)(pClsVar)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt32_2(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V128_UInt32_2(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector128((UInt32*)(&test._fld)), + 2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[2]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[2]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector128, 2): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Byte.1.cs new file mode 100644 index 0000000000000..c00b1017bc64d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Byte.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V64_Byte_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Byte_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Byte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Byte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Byte_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Byte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Byte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int16.1.cs new file mode 100644 index 0000000000000..916e8c9301cec --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int16.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V64_Int16_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int16_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int16_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int32.1.cs new file mode 100644 index 0000000000000..feea52b04ec89 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int32.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V64_Int32_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int32_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int32_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Int32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.SByte.1.cs new file mode 100644 index 0000000000000..70d504eaf1649 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.SByte.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V64_SByte_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_SByte_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_SByte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_SByte_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_SByte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Single.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Single.1.cs new file mode 100644 index 0000000000000..4c16760a53829 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Single.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V64_Single_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Single_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Single_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Single[] inArray, Single[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Single_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Single_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Single*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Single); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Single); + + private static Single[] _data = new Single[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Single_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Single_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); } + _dataTable = new DataTable(_data, new Single[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Single*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Single*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Single*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Single*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Single_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_Single_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Single*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Single*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((Single*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Single[] inArray = new Single[Op1ElementCount]; + Single[] outArray = new Single[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Single[] inArray = new Single[Op1ElementCount]; + Single[] outArray = new Single[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt16.1.cs new file mode 100644 index 0000000000000..809df830e91ba --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt16.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V64_UInt16_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt16_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt16_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt32.1.cs new file mode 100644 index 0000000000000..67852ad55787d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt32.1.cs @@ -0,0 +1,506 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateSelectedScalarToVector64_V64_UInt32_1() + { + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt32_1 testClass) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateSelectedScalarToVector64), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.DuplicateSelectedScalarToVector64(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt32_1(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__DuplicateSelectedScalarToVector64_V64_UInt32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateSelectedScalarToVector64(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateSelectedScalarToVector64( + AdvSimd.LoadVector64((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != firstOp[1]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != firstOp[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateSelectedScalarToVector64)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Byte.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Byte.31.cs new file mode 100644 index 0000000000000..aa12893fa2fb7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Byte.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_Byte_31() + { + var test = new ImmOpTest__DuplicateToVector128_Byte_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector128_Byte_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector128_Byte_31() + { + Succeeded = true; + + _dataTable = new DataTable(new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector128( + (Byte)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(Byte) }) + .Invoke(null, new object[] { + (Byte)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + Byte[] outArray = new Byte[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Byte.cs new file mode 100644 index 0000000000000..5c60e82afd1e2 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Byte.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_Byte() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector128_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector128_Byte + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Byte _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetByte(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector128_Byte testClass) + { + var result = AdvSimd.DuplicateToVector128(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte _data; + + private static Byte _clsVar; + + private Byte _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector128_Byte() + { + _clsVar = TestLibrary.Generator.GetByte(); + } + + public DuplicateUnaryOpTest__DuplicateToVector128_Byte() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetByte(); + _data = TestLibrary.Generator.GetByte(); + + _dataTable = new DataTable(new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector128( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(Byte) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector128( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector128(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector128_Byte(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector128(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Byte data, void* result, [CallerMemberName] string method = "") + { + Byte[] outArray = new Byte[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(Byte data, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(Byte): DuplicateToVector128 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int16.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int16.31.cs new file mode 100644 index 0000000000000..7173c618131ea --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int16.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_Int16_31() + { + var test = new ImmOpTest__DuplicateToVector128_Int16_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector128_Int16_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector128_Int16_31() + { + Succeeded = true; + + _dataTable = new DataTable(new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector128( + (Int16)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(Int16) }) + .Invoke(null, new object[] { + (Int16)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + Int16[] outArray = new Int16[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int16.cs new file mode 100644 index 0000000000000..510d61858ff05 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int16.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_Int16() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector128_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector128_Int16 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Int16 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetInt16(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector128_Int16 testClass) + { + var result = AdvSimd.DuplicateToVector128(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16 _data; + + private static Int16 _clsVar; + + private Int16 _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector128_Int16() + { + _clsVar = TestLibrary.Generator.GetInt16(); + } + + public DuplicateUnaryOpTest__DuplicateToVector128_Int16() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetInt16(); + _data = TestLibrary.Generator.GetInt16(); + + _dataTable = new DataTable(new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector128( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(Int16) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector128( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector128(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector128_Int16(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector128(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Int16 data, void* result, [CallerMemberName] string method = "") + { + Int16[] outArray = new Int16[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(Int16 data, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(Int16): DuplicateToVector128 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int32.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int32.31.cs new file mode 100644 index 0000000000000..b12495ff11aed --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int32.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_Int32_31() + { + var test = new ImmOpTest__DuplicateToVector128_Int32_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector128_Int32_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector128_Int32_31() + { + Succeeded = true; + + _dataTable = new DataTable(new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector128( + (Int32)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(Int32) }) + .Invoke(null, new object[] { + (Int32)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + Int32[] outArray = new Int32[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int32.cs new file mode 100644 index 0000000000000..77967e2777f32 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Int32.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_Int32() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector128_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector128_Int32 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Int32 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetInt32(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector128_Int32 testClass) + { + var result = AdvSimd.DuplicateToVector128(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32 _data; + + private static Int32 _clsVar; + + private Int32 _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector128_Int32() + { + _clsVar = TestLibrary.Generator.GetInt32(); + } + + public DuplicateUnaryOpTest__DuplicateToVector128_Int32() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetInt32(); + _data = TestLibrary.Generator.GetInt32(); + + _dataTable = new DataTable(new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector128( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(Int32) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector128( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector128(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector128_Int32(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector128(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Int32 data, void* result, [CallerMemberName] string method = "") + { + Int32[] outArray = new Int32[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(Int32 data, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(Int32): DuplicateToVector128 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.SByte.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.SByte.31.cs new file mode 100644 index 0000000000000..824cd8968dd8c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.SByte.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_SByte_31() + { + var test = new ImmOpTest__DuplicateToVector128_SByte_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector128_SByte_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector128_SByte_31() + { + Succeeded = true; + + _dataTable = new DataTable(new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector128( + (SByte)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(SByte) }) + .Invoke(null, new object[] { + (SByte)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + SByte[] outArray = new SByte[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.SByte.cs new file mode 100644 index 0000000000000..183ad0bc2041c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.SByte.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_SByte() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector128_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector128_SByte + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public SByte _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetSByte(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector128_SByte testClass) + { + var result = AdvSimd.DuplicateToVector128(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte _data; + + private static SByte _clsVar; + + private SByte _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector128_SByte() + { + _clsVar = TestLibrary.Generator.GetSByte(); + } + + public DuplicateUnaryOpTest__DuplicateToVector128_SByte() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetSByte(); + _data = TestLibrary.Generator.GetSByte(); + + _dataTable = new DataTable(new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector128( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(SByte) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector128( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector128(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector128_SByte(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector128(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(SByte data, void* result, [CallerMemberName] string method = "") + { + SByte[] outArray = new SByte[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(SByte data, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(SByte): DuplicateToVector128 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Single.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Single.31.cs new file mode 100644 index 0000000000000..9685545397d5d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Single.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_Single_31() + { + var test = new ImmOpTest__DuplicateToVector128_Single_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector128_Single_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Single[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Single); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector128_Single_31() + { + Succeeded = true; + + _dataTable = new DataTable(new Single[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector128( + (Single)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(Single) }) + .Invoke(null, new object[] { + (Single)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + Single[] outArray = new Single[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(Single[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Single.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Single.cs new file mode 100644 index 0000000000000..caad761f6f97d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.Single.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_Single() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector128_Single(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector128_Single + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Single[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Single _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetSingle(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector128_Single testClass) + { + var result = AdvSimd.DuplicateToVector128(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Single); + + private static Single _data; + + private static Single _clsVar; + + private Single _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector128_Single() + { + _clsVar = TestLibrary.Generator.GetSingle(); + } + + public DuplicateUnaryOpTest__DuplicateToVector128_Single() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetSingle(); + _data = TestLibrary.Generator.GetSingle(); + + _dataTable = new DataTable(new Single[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector128( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(Single) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector128( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector128(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector128_Single(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector128(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Single data, void* result, [CallerMemberName] string method = "") + { + Single[] outArray = new Single[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(Single data, Single[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(Single): DuplicateToVector128 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt16.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt16.31.cs new file mode 100644 index 0000000000000..2bfa725584af9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt16.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_UInt16_31() + { + var test = new ImmOpTest__DuplicateToVector128_UInt16_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector128_UInt16_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector128_UInt16_31() + { + Succeeded = true; + + _dataTable = new DataTable(new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector128( + (UInt16)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(UInt16) }) + .Invoke(null, new object[] { + (UInt16)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + UInt16[] outArray = new UInt16[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt16.cs new file mode 100644 index 0000000000000..5f4e3097fc90a --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt16.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_UInt16() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector128_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector128_UInt16 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public UInt16 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetUInt16(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector128_UInt16 testClass) + { + var result = AdvSimd.DuplicateToVector128(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16 _data; + + private static UInt16 _clsVar; + + private UInt16 _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector128_UInt16() + { + _clsVar = TestLibrary.Generator.GetUInt16(); + } + + public DuplicateUnaryOpTest__DuplicateToVector128_UInt16() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetUInt16(); + _data = TestLibrary.Generator.GetUInt16(); + + _dataTable = new DataTable(new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector128( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(UInt16) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector128( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector128(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector128_UInt16(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector128(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(UInt16 data, void* result, [CallerMemberName] string method = "") + { + UInt16[] outArray = new UInt16[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(UInt16 data, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(UInt16): DuplicateToVector128 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt32.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt32.31.cs new file mode 100644 index 0000000000000..c3ade1c04fd54 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt32.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_UInt32_31() + { + var test = new ImmOpTest__DuplicateToVector128_UInt32_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector128_UInt32_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector128_UInt32_31() + { + Succeeded = true; + + _dataTable = new DataTable(new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector128( + (UInt32)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(UInt32) }) + .Invoke(null, new object[] { + (UInt32)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + UInt32[] outArray = new UInt32[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt32.cs new file mode 100644 index 0000000000000..2d58f8f2e3fcb --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector128.UInt32.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector128_UInt32() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector128_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector128_UInt32 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public UInt32 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetUInt32(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector128_UInt32 testClass) + { + var result = AdvSimd.DuplicateToVector128(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32 _data; + + private static UInt32 _clsVar; + + private UInt32 _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector128_UInt32() + { + _clsVar = TestLibrary.Generator.GetUInt32(); + } + + public DuplicateUnaryOpTest__DuplicateToVector128_UInt32() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetUInt32(); + _data = TestLibrary.Generator.GetUInt32(); + + _dataTable = new DataTable(new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector128( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector128), new Type[] { typeof(UInt32) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector128( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector128(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector128_UInt32(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector128(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector128(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(UInt32 data, void* result, [CallerMemberName] string method = "") + { + UInt32[] outArray = new UInt32[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(UInt32 data, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector128)}(UInt32): DuplicateToVector128 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Byte.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Byte.31.cs new file mode 100644 index 0000000000000..44c3abb84eb06 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Byte.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_Byte_31() + { + var test = new ImmOpTest__DuplicateToVector64_Byte_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector64_Byte_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector64_Byte_31() + { + Succeeded = true; + + _dataTable = new DataTable(new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector64( + (Byte)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(Byte) }) + .Invoke(null, new object[] { + (Byte)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + Byte[] outArray = new Byte[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Byte.cs new file mode 100644 index 0000000000000..c519918584cce --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Byte.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_Byte() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector64_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector64_Byte + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Byte _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetByte(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector64_Byte testClass) + { + var result = AdvSimd.DuplicateToVector64(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte _data; + + private static Byte _clsVar; + + private Byte _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector64_Byte() + { + _clsVar = TestLibrary.Generator.GetByte(); + } + + public DuplicateUnaryOpTest__DuplicateToVector64_Byte() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetByte(); + _data = TestLibrary.Generator.GetByte(); + + _dataTable = new DataTable(new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector64( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(Byte) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector64( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector64(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector64_Byte(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector64(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Byte data, void* result, [CallerMemberName] string method = "") + { + Byte[] outArray = new Byte[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(Byte data, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(Byte): DuplicateToVector64 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int16.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int16.31.cs new file mode 100644 index 0000000000000..7a84cc8afac97 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int16.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_Int16_31() + { + var test = new ImmOpTest__DuplicateToVector64_Int16_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector64_Int16_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector64_Int16_31() + { + Succeeded = true; + + _dataTable = new DataTable(new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector64( + (Int16)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(Int16) }) + .Invoke(null, new object[] { + (Int16)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + Int16[] outArray = new Int16[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int16.cs new file mode 100644 index 0000000000000..c5e95a8ee07f1 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int16.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_Int16() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector64_Int16 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Int16 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetInt16(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector64_Int16 testClass) + { + var result = AdvSimd.DuplicateToVector64(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16 _data; + + private static Int16 _clsVar; + + private Int16 _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector64_Int16() + { + _clsVar = TestLibrary.Generator.GetInt16(); + } + + public DuplicateUnaryOpTest__DuplicateToVector64_Int16() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetInt16(); + _data = TestLibrary.Generator.GetInt16(); + + _dataTable = new DataTable(new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector64( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(Int16) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector64( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector64(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector64_Int16(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector64(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Int16 data, void* result, [CallerMemberName] string method = "") + { + Int16[] outArray = new Int16[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(Int16 data, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(Int16): DuplicateToVector64 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int32.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int32.31.cs new file mode 100644 index 0000000000000..beb6d1b62ac6b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int32.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_Int32_31() + { + var test = new ImmOpTest__DuplicateToVector64_Int32_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector64_Int32_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector64_Int32_31() + { + Succeeded = true; + + _dataTable = new DataTable(new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector64( + (Int32)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(Int32) }) + .Invoke(null, new object[] { + (Int32)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + Int32[] outArray = new Int32[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int32.cs new file mode 100644 index 0000000000000..4045059208899 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Int32.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_Int32() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector64_Int32 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Int32 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetInt32(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector64_Int32 testClass) + { + var result = AdvSimd.DuplicateToVector64(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32 _data; + + private static Int32 _clsVar; + + private Int32 _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector64_Int32() + { + _clsVar = TestLibrary.Generator.GetInt32(); + } + + public DuplicateUnaryOpTest__DuplicateToVector64_Int32() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetInt32(); + _data = TestLibrary.Generator.GetInt32(); + + _dataTable = new DataTable(new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector64( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(Int32) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector64( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector64(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector64_Int32(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector64(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Int32 data, void* result, [CallerMemberName] string method = "") + { + Int32[] outArray = new Int32[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(Int32 data, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(Int32): DuplicateToVector64 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.SByte.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.SByte.31.cs new file mode 100644 index 0000000000000..1d0a5e7dcac31 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.SByte.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_SByte_31() + { + var test = new ImmOpTest__DuplicateToVector64_SByte_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector64_SByte_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector64_SByte_31() + { + Succeeded = true; + + _dataTable = new DataTable(new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector64( + (SByte)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(SByte) }) + .Invoke(null, new object[] { + (SByte)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + SByte[] outArray = new SByte[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.SByte.cs new file mode 100644 index 0000000000000..98f2458c5a9cd --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.SByte.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_SByte() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector64_SByte + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public SByte _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetSByte(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector64_SByte testClass) + { + var result = AdvSimd.DuplicateToVector64(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte _data; + + private static SByte _clsVar; + + private SByte _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector64_SByte() + { + _clsVar = TestLibrary.Generator.GetSByte(); + } + + public DuplicateUnaryOpTest__DuplicateToVector64_SByte() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetSByte(); + _data = TestLibrary.Generator.GetSByte(); + + _dataTable = new DataTable(new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector64( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(SByte) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector64( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector64(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector64_SByte(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector64(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(SByte data, void* result, [CallerMemberName] string method = "") + { + SByte[] outArray = new SByte[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(SByte data, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(SByte): DuplicateToVector64 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Single.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Single.31.cs new file mode 100644 index 0000000000000..cbfbf0c11ee5a --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Single.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_Single_31() + { + var test = new ImmOpTest__DuplicateToVector64_Single_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector64_Single_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Single[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Single); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector64_Single_31() + { + Succeeded = true; + + _dataTable = new DataTable(new Single[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector64( + (Single)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(Single) }) + .Invoke(null, new object[] { + (Single)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + Single[] outArray = new Single[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(Single[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Single.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Single.cs new file mode 100644 index 0000000000000..44bd66c494854 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.Single.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_Single() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector64_Single(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector64_Single + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Single[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Single _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetSingle(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector64_Single testClass) + { + var result = AdvSimd.DuplicateToVector64(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Single); + + private static Single _data; + + private static Single _clsVar; + + private Single _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector64_Single() + { + _clsVar = TestLibrary.Generator.GetSingle(); + } + + public DuplicateUnaryOpTest__DuplicateToVector64_Single() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetSingle(); + _data = TestLibrary.Generator.GetSingle(); + + _dataTable = new DataTable(new Single[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector64( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(Single) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector64( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector64(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector64_Single(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector64(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Single data, void* result, [CallerMemberName] string method = "") + { + Single[] outArray = new Single[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(Single data, Single[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(Single): DuplicateToVector64 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt16.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt16.31.cs new file mode 100644 index 0000000000000..cf0b6de370ba5 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt16.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_UInt16_31() + { + var test = new ImmOpTest__DuplicateToVector64_UInt16_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector64_UInt16_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector64_UInt16_31() + { + Succeeded = true; + + _dataTable = new DataTable(new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector64( + (UInt16)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(UInt16) }) + .Invoke(null, new object[] { + (UInt16)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + UInt16[] outArray = new UInt16[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt16.cs new file mode 100644 index 0000000000000..e533f462f7466 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt16.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_UInt16() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector64_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector64_UInt16 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public UInt16 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetUInt16(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector64_UInt16 testClass) + { + var result = AdvSimd.DuplicateToVector64(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16 _data; + + private static UInt16 _clsVar; + + private UInt16 _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector64_UInt16() + { + _clsVar = TestLibrary.Generator.GetUInt16(); + } + + public DuplicateUnaryOpTest__DuplicateToVector64_UInt16() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetUInt16(); + _data = TestLibrary.Generator.GetUInt16(); + + _dataTable = new DataTable(new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector64( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(UInt16) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector64( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector64(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector64_UInt16(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector64(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(UInt16 data, void* result, [CallerMemberName] string method = "") + { + UInt16[] outArray = new UInt16[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(UInt16 data, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(UInt16): DuplicateToVector64 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt32.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt32.31.cs new file mode 100644 index 0000000000000..5e4d079535d7a --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt32.31.cs @@ -0,0 +1,185 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_UInt32_31() + { + var test = new ImmOpTest__DuplicateToVector64_UInt32_31(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 ImmOpTest__DuplicateToVector64_UInt32_31 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private DataTable _dataTable; + + public ImmOpTest__DuplicateToVector64_UInt32_31() + { + Succeeded = true; + + _dataTable = new DataTable(new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = AdvSimd.DuplicateToVector64( + (UInt32)31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(UInt32) }) + .Invoke(null, new object[] { + (UInt32)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + UInt32[] outArray = new UInt32[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(outArray, method); + } + + private void ValidateResult(UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != 31) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 31) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt32.cs new file mode 100644 index 0000000000000..402384cf4b01c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateToVector64.UInt32.cs @@ -0,0 +1,300 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void DuplicateToVector64_UInt32() + { + var test = new DuplicateUnaryOpTest__DuplicateToVector64_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 DuplicateUnaryOpTest__DuplicateToVector64_UInt32 + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public UInt32 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = TestLibrary.Generator.GetUInt32(); + return testStruct; + } + + public void RunStructFldScenario(DuplicateUnaryOpTest__DuplicateToVector64_UInt32 testClass) + { + var result = AdvSimd.DuplicateToVector64(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32 _data; + + private static UInt32 _clsVar; + + private UInt32 _fld; + + private DataTable _dataTable; + + static DuplicateUnaryOpTest__DuplicateToVector64_UInt32() + { + _clsVar = TestLibrary.Generator.GetUInt32(); + } + + public DuplicateUnaryOpTest__DuplicateToVector64_UInt32() + { + Succeeded = true; + + _fld = TestLibrary.Generator.GetUInt32(); + _data = TestLibrary.Generator.GetUInt32(); + + _dataTable = new DataTable(new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.DuplicateToVector64( + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.DuplicateToVector64), new Type[] { typeof(UInt32) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.DuplicateToVector64( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned(ref Unsafe.As(ref _data)); + var result = AdvSimd.DuplicateToVector64(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new DuplicateUnaryOpTest__DuplicateToVector64_UInt32(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.DuplicateToVector64(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.DuplicateToVector64(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(UInt32 data, void* result, [CallerMemberName] string method = "") + { + UInt32[] outArray = new UInt32[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult(UInt32 data, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (result[0] != data) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != data) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.DuplicateToVector64)}(UInt32): DuplicateToVector64 failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs index 246f31429980b..f8c35610338ab 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs @@ -341,6 +341,62 @@ static Program() ["CompareTest.Vector128.UInt32"] = CompareTest_Vector128_UInt32, ["DivideScalar.Vector64.Double"] = DivideScalar_Vector64_Double, ["DivideScalar.Vector64.Single"] = DivideScalar_Vector64_Single, + ["DuplicateSelectedScalarToVector64.V64.Byte.1"] = DuplicateSelectedScalarToVector64_V64_Byte_1, + ["DuplicateSelectedScalarToVector64.V64.Int16.1"] = DuplicateSelectedScalarToVector64_V64_Int16_1, + ["DuplicateSelectedScalarToVector64.V64.Int32.1"] = DuplicateSelectedScalarToVector64_V64_Int32_1, + ["DuplicateSelectedScalarToVector64.V64.SByte.1"] = DuplicateSelectedScalarToVector64_V64_SByte_1, + ["DuplicateSelectedScalarToVector64.V64.Single.1"] = DuplicateSelectedScalarToVector64_V64_Single_1, + ["DuplicateSelectedScalarToVector64.V64.UInt16.1"] = DuplicateSelectedScalarToVector64_V64_UInt16_1, + ["DuplicateSelectedScalarToVector64.V64.UInt32.1"] = DuplicateSelectedScalarToVector64_V64_UInt32_1, + ["DuplicateSelectedScalarToVector64.V128.Byte.8"] = DuplicateSelectedScalarToVector64_V128_Byte_8, + ["DuplicateSelectedScalarToVector64.V128.Int16.4"] = DuplicateSelectedScalarToVector64_V128_Int16_4, + ["DuplicateSelectedScalarToVector64.V128.Int32.2"] = DuplicateSelectedScalarToVector64_V128_Int32_2, + ["DuplicateSelectedScalarToVector64.V128.SByte.8"] = DuplicateSelectedScalarToVector64_V128_SByte_8, + ["DuplicateSelectedScalarToVector64.V128.Single.2"] = DuplicateSelectedScalarToVector64_V128_Single_2, + ["DuplicateSelectedScalarToVector64.V128.UInt16.4"] = DuplicateSelectedScalarToVector64_V128_UInt16_4, + ["DuplicateSelectedScalarToVector64.V128.UInt32.2"] = DuplicateSelectedScalarToVector64_V128_UInt32_2, + ["DuplicateSelectedScalarToVector128.V64.Byte.1"] = DuplicateSelectedScalarToVector128_V64_Byte_1, + ["DuplicateSelectedScalarToVector128.V64.Int16.1"] = DuplicateSelectedScalarToVector128_V64_Int16_1, + ["DuplicateSelectedScalarToVector128.V64.Int32.1"] = DuplicateSelectedScalarToVector128_V64_Int32_1, + ["DuplicateSelectedScalarToVector128.V64.SByte.1"] = DuplicateSelectedScalarToVector128_V64_SByte_1, + ["DuplicateSelectedScalarToVector128.V64.Single.1"] = DuplicateSelectedScalarToVector128_V64_Single_1, + ["DuplicateSelectedScalarToVector128.V64.UInt16.1"] = DuplicateSelectedScalarToVector128_V64_UInt16_1, + ["DuplicateSelectedScalarToVector128.V64.UInt32.1"] = DuplicateSelectedScalarToVector128_V64_UInt32_1, + ["DuplicateSelectedScalarToVector128.V128.Byte.8"] = DuplicateSelectedScalarToVector128_V128_Byte_8, + ["DuplicateSelectedScalarToVector128.V128.Int16.4"] = DuplicateSelectedScalarToVector128_V128_Int16_4, + ["DuplicateSelectedScalarToVector128.V128.Int32.2"] = DuplicateSelectedScalarToVector128_V128_Int32_2, + ["DuplicateSelectedScalarToVector128.V128.SByte.8"] = DuplicateSelectedScalarToVector128_V128_SByte_8, + ["DuplicateSelectedScalarToVector128.V128.Single.2"] = DuplicateSelectedScalarToVector128_V128_Single_2, + ["DuplicateSelectedScalarToVector128.V128.UInt16.4"] = DuplicateSelectedScalarToVector128_V128_UInt16_4, + ["DuplicateSelectedScalarToVector128.V128.UInt32.2"] = DuplicateSelectedScalarToVector128_V128_UInt32_2, + ["DuplicateToVector64.Byte"] = DuplicateToVector64_Byte, + ["DuplicateToVector64.Byte.31"] = DuplicateToVector64_Byte_31, + ["DuplicateToVector64.Int16"] = DuplicateToVector64_Int16, + ["DuplicateToVector64.Int16.31"] = DuplicateToVector64_Int16_31, + ["DuplicateToVector64.Int32"] = DuplicateToVector64_Int32, + ["DuplicateToVector64.Int32.31"] = DuplicateToVector64_Int32_31, + ["DuplicateToVector64.SByte"] = DuplicateToVector64_SByte, + ["DuplicateToVector64.SByte.31"] = DuplicateToVector64_SByte_31, + ["DuplicateToVector64.Single"] = DuplicateToVector64_Single, + ["DuplicateToVector64.Single.31"] = DuplicateToVector64_Single_31, + ["DuplicateToVector64.UInt16"] = DuplicateToVector64_UInt16, + ["DuplicateToVector64.UInt16.31"] = DuplicateToVector64_UInt16_31, + ["DuplicateToVector64.UInt32"] = DuplicateToVector64_UInt32, + ["DuplicateToVector64.UInt32.31"] = DuplicateToVector64_UInt32_31, + ["DuplicateToVector128.Byte"] = DuplicateToVector128_Byte, + ["DuplicateToVector128.Byte.31"] = DuplicateToVector128_Byte_31, + ["DuplicateToVector128.Int16"] = DuplicateToVector128_Int16, + ["DuplicateToVector128.Int16.31"] = DuplicateToVector128_Int16_31, + ["DuplicateToVector128.Int32"] = DuplicateToVector128_Int32, + ["DuplicateToVector128.Int32.31"] = DuplicateToVector128_Int32_31, + ["DuplicateToVector128.SByte"] = DuplicateToVector128_SByte, + ["DuplicateToVector128.SByte.31"] = DuplicateToVector128_SByte_31, + ["DuplicateToVector128.Single"] = DuplicateToVector128_Single, + ["DuplicateToVector128.Single.31"] = DuplicateToVector128_Single_31, + ["DuplicateToVector128.UInt16"] = DuplicateToVector128_UInt16, + ["DuplicateToVector128.UInt16.31"] = DuplicateToVector128_UInt16_31, + ["DuplicateToVector128.UInt32"] = DuplicateToVector128_UInt32, + ["DuplicateToVector128.UInt32.31"] = DuplicateToVector128_UInt32_31, ["Extract.Vector64.Byte.1"] = Extract_Vector64_Byte_1, ["Extract.Vector64.Int16.1"] = Extract_Vector64_Int16_1, ["Extract.Vector64.Int32.1"] = Extract_Vector64_Int32_1, diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx index 9130ef1424b3d..c2f17ba406e11 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx @@ -86,6 +86,9 @@ private const string SecureHashOpTest_ValidationLogic = @"{RetBaseType}[] expect private static readonly (string templateFileName, string outputTemplateName, Dictionary templateData)[] Templates = new[] { + ("_UnaryOpScalarTestTemplate.template", "DuplicateTest.template", new Dictionary { ["TemplateName"] = "Duplicate", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_ImmUnaryOpTestTemplate.template", "ImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_ImmOpTestTemplate.template", "ImmOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), ("_BinaryOpTestTemplate.template", "SimpleBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), ("_TernaryOpTestTemplate.template", "VecTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), ("_UnaryOpTestTemplate.template", "SimpleUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), @@ -97,7 +100,6 @@ private static readonly (string templateFileName, string outputTemplateName, Dic ("_UnaryOpTestTemplate.template", "SecureHashUnOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), ("_BinaryOpTestTemplate.template", "SecureHashBinOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }), ("_TernaryOpTestTemplate.template", "SecureHashTernOpTest.template", new Dictionary { ["TemplateName"] = "SecureHash", ["TemplateValidationLogic"] = SecureHashOpTest_ValidationLogic }) - }; private static readonly (string templateFileName, Dictionary templateData)[] AdvSimdInputs = new [] @@ -431,6 +433,62 @@ private static readonly (string templateFileName, Dictionary tem ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "DivideScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DivideScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Divide(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "DivideScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DivideScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_Byte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "8", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "result[i] != firstOp[8]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_Int16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "4", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "result[i] != firstOp[4]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_Int32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_SByte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "8", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "result[i] != firstOp[8]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_Single_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_UInt16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "4", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "result[i] != firstOp[4]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_UInt32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Byte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "8", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "result[i] != firstOp[8]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Int16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "4", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "result[i] != firstOp[4]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Int32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_SByte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "8", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "result[i] != firstOp[8]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Single_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_UInt16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "4", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "result[i] != firstOp[4]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_UInt32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Byte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_SByte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Single_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Byte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_SByte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Single_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), @@ -1023,6 +1081,15 @@ private static readonly (string templateFileName, Dictionary tem ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Divide(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Int64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Double_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int64_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt64_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAdd_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtract_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Max(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmOpTestTemplate.template b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmOpTestTemplate.template new file mode 100644 index 0000000000000..77a6503ac0c0f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmOpTestTemplate.template @@ -0,0 +1,171 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void {TestName}() + { + var test = new {TemplateName}OpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + } + 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 {TemplateName}OpTest__{TestName} + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({RetBaseType}[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + private DataTable _dataTable; + + public {TemplateName}OpTest__{TestName}() + { + Succeeded = true; + + _dataTable = new DataTable(new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario)); + + var result = {Isa}.{Method}( + ({Op1BaseType}){Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}) }) + .Invoke(null, new object[] { + ({Op1BaseType}){Imm} + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + ValidateResult(outArray, method); + } + + private void ValidateResult({RetBaseType}[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + {TemplateValidationLogic} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Imm}): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmUnaryOpTestTemplate.template b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmUnaryOpTestTemplate.template new file mode 100644 index 0000000000000..df6ea9bf70435 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmUnaryOpTestTemplate.template @@ -0,0 +1,492 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void {TestName}() + { + var test = new {TemplateName}UnaryOpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if ({LoadIsa}.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if ({LoadIsa}.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if ({LoadIsa}.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if ({LoadIsa}.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if ({LoadIsa}.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 {TemplateName}UnaryOpTest__{TestName} + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({Op1BaseType}[] inArray, {RetBaseType}[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + return testStruct; + } + + public void RunStructFldScenario({TemplateName}UnaryOpTest__{TestName} testClass) + { + var result = {Isa}.{Method}(_fld, {Imm}); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load({TemplateName}UnaryOpTest__{TestName} testClass) + { + fixed ({Op1VectorType}<{Op1BaseType}>* pFld = &_fld) + { + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld)), + {Imm} + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + private static {Op1BaseType}[] _data = new {Op1BaseType}[Op1ElementCount]; + + private static {Op1VectorType}<{Op1BaseType}> _clsVar; + + private {Op1VectorType}<{Op1BaseType}> _fld; + + private DataTable _dataTable; + + static {TemplateName}UnaryOpTest__{TestName}() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + } + + public {TemplateName}UnaryOpTest__{TestName}() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; } + _dataTable = new DataTable(_data, new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr), + (byte){Imm} + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof(byte) }) + .Invoke(null, new object[] { + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)), + (byte){Imm} + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = {Isa}.{Method}( + _clsVar, + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed ({Op1VectorType}<{Op1BaseType}>* pClsVar = &_clsVar) + { + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pClsVar)), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr); + var result = {Isa}.{Method}(firstOp, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)); + var result = {Isa}.{Method}(firstOp, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new {TemplateName}UnaryOpTest__{TestName}(); + var result = {Isa}.{Method}(test._fld, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new {TemplateName}UnaryOpTest__{TestName}(); + + fixed ({Op1VectorType}<{Op1BaseType}>* pFld = &test._fld) + { + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld)), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed ({Op1VectorType}<{Op1BaseType}>* pFld = &_fld) + { + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld)), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(&test._fld)), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult({Op1VectorType}<{Op1BaseType}> firstOp, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult({Op1BaseType}[] firstOp, {RetBaseType}[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + {TemplateValidationLogic} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Imm}): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_UnaryOpScalarTestTemplate.template b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_UnaryOpScalarTestTemplate.template new file mode 100644 index 0000000000000..b80651df1c8e3 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_UnaryOpScalarTestTemplate.template @@ -0,0 +1,286 @@ +// 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\Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void {TestName}() + { + var test = new {TemplateName}UnaryOpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead(); + + // Validates calling via reflection works, using Unsafe.ReadUnaligned + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.ReadUnaligned + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 {TemplateName}UnaryOpTest__{TestName} + { + private struct DataTable + { + private byte[] outArray; + + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({RetBaseType}[] outArray, int alignment) + { + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.outArray = new byte[alignment * 2]; + + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + } + + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op1BaseType} _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + testStruct._fld = {NextValueOp1}; + return testStruct; + } + + public void RunStructFldScenario({TemplateName}UnaryOpTest__{TestName} testClass) + { + var result = {Isa}.{Method}(_fld); + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + private static {Op1BaseType} _data; + + private static {Op1BaseType} _clsVar; + + private {Op1BaseType} _fld; + + private DataTable _dataTable; + + static {TemplateName}UnaryOpTest__{TestName}() + { + _clsVar = {NextValueOp1}; + } + + public {TemplateName}UnaryOpTest__{TestName}() + { + Succeeded = true; + + _fld = {NextValueOp1}; + _data = {NextValueOp1}; + + _dataTable = new DataTable(new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = {Isa}.{Method}( + Unsafe.ReadUnaligned<{Op1BaseType}>(ref Unsafe.As<{Op1BaseType}, byte>(ref _data)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}) }) + .Invoke(null, new object[] { + Unsafe.ReadUnaligned<{Op1BaseType}>(ref Unsafe.As<{Op1BaseType}, byte>(ref _data)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_data, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = {Isa}.{Method}( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var data = Unsafe.ReadUnaligned<{Op1BaseType}>(ref Unsafe.As<{Op1BaseType}, byte>(ref _data)); + var result = {Isa}.{Method}(data); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(data, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new {TemplateName}UnaryOpTest__{TestName}(); + var result = {Isa}.{Method}(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult({Op1BaseType} data, void* result, [CallerMemberName] string method = "") + { + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + ValidateResult(data, outArray, method); + } + + private void ValidateResult({Op1BaseType} data, {RetBaseType}[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + {TemplateValidationLogic} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1BaseType}): {Method} failed:"); + TestLibrary.TestFramework.LogInformation($" data: {data}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs index d480608fcf2be..f5ffb5d6236da 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs @@ -640,6 +640,42 @@ public new abstract class Arm64 : ArmBase.Arm64 /// public static Vector128 Divide(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + /// + /// float64x2_t vdupq_laneq_f64 (float64x2_t vec, const int lane) + /// A64: DUP Vd.2D, Vn.D[index] + /// + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// int64x2_t vdupq_laneq_s64 (int64x2_t vec, const int lane) + /// A64: DUP Vd.2D, Vn.D[index] + /// + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vdupq_laneq_u64 (uint64x2_t vec, const int lane) + /// A64: DUP Vd.2D, Vn.D[index] + /// + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// float64x2_t vdupq_n_f64 (float64_t value) + /// A64: DUP Vd.2D, Vn.D[0] + /// + public static Vector128 DuplicateToVector128(double value) { throw new PlatformNotSupportedException(); } + + /// + /// int64x2_t vdupq_n_s64 (int64_t value) + /// A64: DUP Vd.2D, Rn + /// + public static Vector128 DuplicateToVector128(long value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vdupq_n_s64 (uint64_t value) + /// A64: DUP Vd.2D, Rn + /// + public static Vector128 DuplicateToVector128(ulong value) { throw new PlatformNotSupportedException(); } + /// /// float64x2_t vfmaq_f64 (float64x2_t a, float64x2_t b, float64x2_t c) /// A64: FMLA Vd.2D, Vn.2D, Vm.2D @@ -4201,6 +4237,300 @@ public new abstract class Arm64 : ArmBase.Arm64 /// public static Vector64 DivideScalar(Vector64 left, Vector64 right) { throw new PlatformNotSupportedException(); } + /// + /// uint8x8_t vdup_lane_u8 (uint8x8_t vec, const int lane) + /// A32: VDUP.8 Dd, Dm[index] + /// A64: DUP Vd.8B, Vn.B[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vdup_lane_s16 (int16x4_t vec, const int lane) + /// A32: VDUP.16 Dd, Dm[index] + /// A64: DUP Vd.4H, Vn.H[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vdup_lane_s32 (int32x2_t vec, const int lane) + /// A32: VDUP.32 Dd, Dm[index] + /// A64: DUP Vd.2S, Vn.S[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// float32x2_t vdup_lane_f32 (float32x2_t vec, const int lane) + /// A32: VDUP.32 Dd, Dm[index] + /// A64: DUP Vd.2S, Vn.S[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vdup_lane_s8 (int8x8_t vec, const int lane) + /// A32: VDUP.8 Dd, Dm[index] + /// A64: DUP Vd.8B, Vn.B[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vdup_lane_u16 (uint16x4_t vec, const int lane) + /// A32: VDUP.16 Dd, Dm[index] + /// A64: DUP Vd.4H, Vn.H[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vdup_lane_u32 (uint32x2_t vec, const int lane) + /// A32: VDUP.32 Dd, Dm[index] + /// A64: DUP Vd.2S, Vn.S[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vdup_laneq_u8 (uint8x16_t vec, const int lane) + /// A32: VDUP.8 Dd, Dm[index] + /// A64: DUP Vd.8B, Vn.B[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vdup_laneq_s16 (int16x8_t vec, const int lane) + /// A32: VDUP.16 Dd, Dm[index] + /// A64: DUP Vd.4H, Vn.H[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vdup_laneq_s32 (int32x4_t vec, const int lane) + /// A32: VDUP.32 Dd, Dm[index] + /// A64: DUP Vd.2S, Vn.S[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// float32x2_t vdup_laneq_f32 (float32x4_t vec, const int lane) + /// A32: VDUP.32 Dd, Dm[index] + /// A64: DUP Vd.2S, Vn.S[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vdup_laneq_s8 (int8x16_t vec, const int lane) + /// A32: VDUP.8 Dd, Dm[index] + /// A64: DUP Vd.8B, Vn.B[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vdup_laneq_u16 (uint16x8_t vec, const int lane) + /// A32: VDUP.16 Dd, Dm[index] + /// A64: DUP Vd.4H, Vn.H[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vdup_laneq_u32 (uint32x4_t vec, const int lane) + /// A32: VDUP.32 Dd, Dm[index] + /// A64: DUP Vd.2S, Vn.S[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vdupq_lane_u8 (uint8x8_t vec, const int lane) + /// A32: VDUP.8 Qd, Dm[index] + /// A64: DUP Vd.16B, Vn.B[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vdupq_lane_s16 (int16x4_t vec, const int lane) + /// A32: VDUP.16 Qd, Dm[index] + /// A64: DUP Vd.8H, Vn.H[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vdupq_lane_s32 (int32x2_t vec, const int lane) + /// A32: VDUP.32 Qd, Dm[index] + /// A64: DUP Vd.4S, Vn.S[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// float32x4_t vdupq_lane_f32 (float32x2_t vec, const int lane) + /// A32: VDUP.32 Qd, Dm[index] + /// A64: DUP Vd.4S, Vn.S[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vdupq_lane_s8 (int8x8_t vec, const int lane) + /// A32: VDUP.8 Qd, Dm[index] + /// A64: DUP Vd.16B, Vn.B[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vdupq_lane_u16 (uint16x4_t vec, const int lane) + /// A32: VDUP.16 Qd, Dm[index] + /// A64: DUP Vd.8H, Vn.H[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vdupq_lane_u32 (uint32x2_t vec, const int lane) + /// A32: VDUP.32 Qd, Dm[index] + /// A64: DUP Vd.4S, Vn.S[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vdupq_lane_u8 (uint8x16_t vec, const int lane) + /// A32: VDUP.8 Qd, Dm[index] + /// A64: DUP Vd.16B, Vn.B[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vdupq_lane_s16 (int16x8_t vec, const int lane) + /// A32: VDUP.16 Qd, Dm[index] + /// A64: DUP Vd.8H, Vn.H[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vdupq_lane_s32 (int32x4_t vec, const int lane) + /// A32: VDUP.32 Qd, Dm[index] + /// A64: DUP Vd.4S, Vn.S[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// float32x4_t vdupq_lane_f32 (float32x4_t vec, const int lane) + /// A32: VDUP.32 Qd, Dm[index] + /// A64: DUP Vd.4S, Vn.S[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vdupq_lane_s8 (int8x16_t vec, const int lane) + /// A32: VDUP.8 Qd, Dm[index] + /// A64: DUP Vd.16B, Vn.B[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vdupq_lane_u16 (uint16x8_t vec, const int lane) + /// A32: VDUP.16 Qd, Dm[index] + /// A64: DUP Vd.8H, Vn.H[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vdupq_lane_u32 (uint32x4_t vec, const int lane) + /// A32: VDUP.32 Qd, Dm[index] + /// A64: DUP Vd.4S, Vn.S[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vdup_n_u8 (uint8_t value) + /// A32: VDUP.8 Dd, Rt + /// A64: DUP Vd.8B, Rn + /// + public static Vector64 DuplicateToVector64(byte value) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vdup_n_s16 (int16_t value) + /// A32: VDUP.16 Dd, Rt + /// A64: DUP Vd.4H, Rn + /// + public static Vector64 DuplicateToVector64(short value) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vdup_n_s32 (int32_t value) + /// A32: VDUP.32 Dd, Rt + /// A64: DUP Vd.2S, Rn + /// + public static Vector64 DuplicateToVector64(int value) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vdup_n_s8 (int8_t value) + /// A32: VDUP.8 Dd, Rt + /// A64: DUP Vd.8B, Rn + /// + public static Vector64 DuplicateToVector64(sbyte value) { throw new PlatformNotSupportedException(); } + + /// + /// float32x2_t vdup_n_f32 (float32_t value) + /// A32: VDUP Dd, Dm[0] + /// A64: DUP Vd.2S, Vn.S[0] + /// + public static Vector64 DuplicateToVector64(float value) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vdup_n_u16 (uint16_t value) + /// A32: VDUP.16 Dd, Rt + /// A64: DUP Vd.4H, Rn + /// + public static Vector64 DuplicateToVector64(ushort value) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vdup_n_u32 (uint32_t value) + /// A32: VDUP.32 Dd, Rt + /// A64: DUP Vd.2S, Rn + /// + public static Vector64 DuplicateToVector64(uint value) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vdupq_n_u8 (uint8_t value) + /// A32: VDUP.8 Qd, Rt + /// A64: DUP Vd.16B, Rn + /// + public static Vector128 DuplicateToVector128(byte value) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vdupq_n_s16 (int16_t value) + /// A32: VDUP.16 Qd, Rt + /// A64: DUP Vd.8H, Rn + /// + public static Vector128 DuplicateToVector128(short value) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vdupq_n_s32 (int32_t value) + /// A32: VDUP.32 Qd, Rt + /// A64: DUP Vd.4S, Rn + /// + public static Vector128 DuplicateToVector128(int value) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vdupq_n_s8 (int8_t value) + /// A32: VDUP.8 Qd, Rt + /// A64: DUP Vd.16B, Rn + /// + public static Vector128 DuplicateToVector128(sbyte value) { throw new PlatformNotSupportedException(); } + + /// + /// float32x4_t vdupq_n_f32 (float32_t value) + /// A32: VDUP Qd, Dm[0] + /// A64: DUP Vd.4S, Vn.S[0] + /// + public static Vector128 DuplicateToVector128(float value) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vdupq_n_u16 (uint16_t value) + /// A32: VDUP.16 Qd, Rt + /// A64: DUP Vd.8H, Rn + /// + public static Vector128 DuplicateToVector128(ushort value) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vdupq_n_u32 (uint32_t value) + /// A32: VDUP.32 Qd, Rt + /// A64: DUP Vd.4S, Rn + /// + public static Vector128 DuplicateToVector128(uint value) { throw new PlatformNotSupportedException(); } + /// /// uint8_t vget_lane_u8 (uint8x8_t v, const int lane) /// A32: VMOV.U8 Rt, Dn[lane] diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs index f5432dd94ac2b..33d80a65510c7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs @@ -642,6 +642,42 @@ public new abstract class Arm64 : ArmBase.Arm64 /// public static Vector128 Divide(Vector128 left, Vector128 right) => Divide(left, right); + /// + /// float64x2_t vdupq_laneq_f64 (float64x2_t vec, const int lane) + /// A64: DUP Vd.2D, Vn.D[index] + /// + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) => DuplicateSelectedScalarToVector128(value, index); + + /// + /// int64x2_t vdupq_laneq_s64 (int64x2_t vec, const int lane) + /// A64: DUP Vd.2D, Vn.D[index] + /// + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) => DuplicateSelectedScalarToVector128(value, index); + + /// + /// uint64x2_t vdupq_laneq_u64 (uint64x2_t vec, const int lane) + /// A64: DUP Vd.2D, Vn.D[index] + /// + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) => DuplicateSelectedScalarToVector128(value, index); + + /// + /// float64x2_t vdupq_n_f64 (float64_t value) + /// A64: DUP Vd.2D, Vn.D[0] + /// + public static Vector128 DuplicateToVector128(double value) => DuplicateToVector128(value); + + /// + /// int64x2_t vdupq_n_s64 (int64_t value) + /// A64: DUP Vd.2D, Rn + /// + public static Vector128 DuplicateToVector128(long value) => DuplicateToVector128(value); + + /// + /// uint64x2_t vdupq_n_s64 (uint64_t value) + /// A64: DUP Vd.2D, Rn + /// + public static Vector128 DuplicateToVector128(ulong value) => DuplicateToVector128(value); + /// /// float64x2_t vfmaq_f64 (float64x2_t a, float64x2_t b, float64x2_t c) /// A64: FMLA Vd.2D, Vn.2D, Vm.2D @@ -4203,6 +4239,300 @@ public new abstract class Arm64 : ArmBase.Arm64 /// public static Vector64 DivideScalar(Vector64 left, Vector64 right) => DivideScalar(left, right); + /// + /// uint8x8_t vdup_lane_u8 (uint8x8_t vec, const int lane) + /// A32: VDUP.8 Dd, Dm[index] + /// A64: DUP Vd.8B, Vn.B[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// int16x4_t vdup_lane_s16 (int16x4_t vec, const int lane) + /// A32: VDUP.16 Dd, Dm[index] + /// A64: DUP Vd.4H, Vn.H[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// int32x2_t vdup_lane_s32 (int32x2_t vec, const int lane) + /// A32: VDUP.32 Dd, Dm[index] + /// A64: DUP Vd.2S, Vn.S[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// float32x2_t vdup_lane_f32 (float32x2_t vec, const int lane) + /// A32: VDUP.32 Dd, Dm[index] + /// A64: DUP Vd.2S, Vn.S[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// int8x8_t vdup_lane_s8 (int8x8_t vec, const int lane) + /// A32: VDUP.8 Dd, Dm[index] + /// A64: DUP Vd.8B, Vn.B[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// uint16x4_t vdup_lane_u16 (uint16x4_t vec, const int lane) + /// A32: VDUP.16 Dd, Dm[index] + /// A64: DUP Vd.4H, Vn.H[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// uint32x2_t vdup_lane_u32 (uint32x2_t vec, const int lane) + /// A32: VDUP.32 Dd, Dm[index] + /// A64: DUP Vd.2S, Vn.S[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector64 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// uint8x8_t vdup_laneq_u8 (uint8x16_t vec, const int lane) + /// A32: VDUP.8 Dd, Dm[index] + /// A64: DUP Vd.8B, Vn.B[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// int16x4_t vdup_laneq_s16 (int16x8_t vec, const int lane) + /// A32: VDUP.16 Dd, Dm[index] + /// A64: DUP Vd.4H, Vn.H[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// int32x2_t vdup_laneq_s32 (int32x4_t vec, const int lane) + /// A32: VDUP.32 Dd, Dm[index] + /// A64: DUP Vd.2S, Vn.S[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// float32x2_t vdup_laneq_f32 (float32x4_t vec, const int lane) + /// A32: VDUP.32 Dd, Dm[index] + /// A64: DUP Vd.2S, Vn.S[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// int8x8_t vdup_laneq_s8 (int8x16_t vec, const int lane) + /// A32: VDUP.8 Dd, Dm[index] + /// A64: DUP Vd.8B, Vn.B[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// uint16x4_t vdup_laneq_u16 (uint16x8_t vec, const int lane) + /// A32: VDUP.16 Dd, Dm[index] + /// A64: DUP Vd.4H, Vn.H[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// uint32x2_t vdup_laneq_u32 (uint32x4_t vec, const int lane) + /// A32: VDUP.32 Dd, Dm[index] + /// A64: DUP Vd.2S, Vn.S[index] + /// + public static Vector64 DuplicateSelectedScalarToVector64(Vector128 value, byte index)=> DuplicateSelectedScalarToVector64(value, index); + + /// + /// uint8x16_t vdupq_lane_u8 (uint8x8_t vec, const int lane) + /// A32: VDUP.8 Qd, Dm[index] + /// A64: DUP Vd.16B, Vn.B[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// int16x8_t vdupq_lane_s16 (int16x4_t vec, const int lane) + /// A32: VDUP.16 Qd, Dm[index] + /// A64: DUP Vd.8H, Vn.H[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// int32x4_t vdupq_lane_s32 (int32x2_t vec, const int lane) + /// A32: VDUP.32 Qd, Dm[index] + /// A64: DUP Vd.4S, Vn.S[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// float32x4_t vdupq_lane_f32 (float32x2_t vec, const int lane) + /// A32: VDUP.32 Qd, Dm[index] + /// A64: DUP Vd.4S, Vn.S[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// int8x16_t vdupq_lane_s8 (int8x8_t vec, const int lane) + /// A32: VDUP.8 Qd, Dm[index] + /// A64: DUP Vd.16B, Vn.B[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// uint16x8_t vdupq_lane_u16 (uint16x4_t vec, const int lane) + /// A32: VDUP.16 Qd, Dm[index] + /// A64: DUP Vd.8H, Vn.H[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// uint32x4_t vdupq_lane_u32 (uint32x2_t vec, const int lane) + /// A32: VDUP.32 Qd, Dm[index] + /// A64: DUP Vd.4S, Vn.S[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector64 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// uint8x16_t vdupq_lane_u8 (uint8x16_t vec, const int lane) + /// A32: VDUP.8 Qd, Dm[index] + /// A64: DUP Vd.16B, Vn.B[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// int16x8_t vdupq_lane_s16 (int16x8_t vec, const int lane) + /// A32: VDUP.16 Qd, Dm[index] + /// A64: DUP Vd.8H, Vn.H[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// int32x4_t vdupq_lane_s32 (int32x4_t vec, const int lane) + /// A32: VDUP.32 Qd, Dm[index] + /// A64: DUP Vd.4S, Vn.S[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// float32x4_t vdupq_lane_f32 (float32x4_t vec, const int lane) + /// A32: VDUP.32 Qd, Dm[index] + /// A64: DUP Vd.4S, Vn.S[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// int8x16_t vdupq_lane_s8 (int8x16_t vec, const int lane) + /// A32: VDUP.8 Qd, Dm[index] + /// A64: DUP Vd.16B, Vn.B[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// uint16x8_t vdupq_lane_u16 (uint16x8_t vec, const int lane) + /// A32: VDUP.16 Qd, Dm[index] + /// A64: DUP Vd.8H, Vn.H[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// uint32x4_t vdupq_lane_u32 (uint32x4_t vec, const int lane) + /// A32: VDUP.32 Qd, Dm[index] + /// A64: DUP Vd.4S, Vn.S[index] + /// + public static Vector128 DuplicateSelectedScalarToVector128(Vector128 value, byte index)=> DuplicateSelectedScalarToVector128(value, index); + + /// + /// uint8x8_t vdup_n_u8 (uint8_t value) + /// A32: VDUP.8 Dd, Rt + /// A64: DUP Vd.8B, Rn + /// + public static Vector64 DuplicateToVector64(byte value) => DuplicateToVector64(value); + + /// + /// int16x4_t vdup_n_s16 (int16_t value) + /// A32: VDUP.16 Dd, Rt + /// A64: DUP Vd.4H, Rn + /// + public static Vector64 DuplicateToVector64(short value) => DuplicateToVector64(value); + + /// + /// int32x2_t vdup_n_s32 (int32_t value) + /// A32: VDUP.32 Dd, Rt + /// A64: DUP Vd.2S, Rn + /// + public static Vector64 DuplicateToVector64(int value) => DuplicateToVector64(value); + + /// + /// int8x8_t vdup_n_s8 (int8_t value) + /// A32: VDUP.8 Dd, Rt + /// A64: DUP Vd.8B, Rn + /// + public static Vector64 DuplicateToVector64(sbyte value) => DuplicateToVector64(value); + + /// + /// float32x2_t vdup_n_f32 (float32_t value) + /// A32: VDUP Dd, Dm[0] + /// A64: DUP Vd.2S, Vn.S[0] + /// + public static Vector64 DuplicateToVector64(float value) => DuplicateToVector64(value); + + /// + /// uint16x4_t vdup_n_u16 (uint16_t value) + /// A32: VDUP.16 Dd, Rt + /// A64: DUP Vd.4H, Rn + /// + public static Vector64 DuplicateToVector64(ushort value) => DuplicateToVector64(value); + + /// + /// uint32x2_t vdup_n_u32 (uint32_t value) + /// A32: VDUP.32 Dd, Rt + /// A64: DUP Vd.2S, Rn + /// + public static Vector64 DuplicateToVector64(uint value) => DuplicateToVector64(value); + + /// + /// uint8x16_t vdupq_n_u8 (uint8_t value) + /// A32: VDUP.8 Qd, Rt + /// A64: DUP Vd.16B, Rn + /// + public static Vector128 DuplicateToVector128(byte value) => DuplicateToVector128(value); + + /// + /// int16x8_t vdupq_n_s16 (int16_t value) + /// A32: VDUP.16 Qd, Rt + /// A64: DUP Vd.8H, Rn + /// + public static Vector128 DuplicateToVector128(short value) => DuplicateToVector128(value); + + /// + /// int32x4_t vdupq_n_s32 (int32_t value) + /// A32: VDUP.32 Qd, Rt + /// A64: DUP Vd.4S, Rn + /// + public static Vector128 DuplicateToVector128(int value) => DuplicateToVector128(value); + + /// + /// int8x16_t vdupq_n_s8 (int8_t value) + /// A32: VDUP.8 Qd, Rt + /// A64: DUP Vd.16B, Rn + /// + public static Vector128 DuplicateToVector128(sbyte value) => DuplicateToVector128(value); + + /// + /// float32x4_t vdupq_n_f32 (float32_t value) + /// A32: VDUP Qd, Dm[0] + /// A64: DUP Vd.4S, Vn.S[0] + /// + public static Vector128 DuplicateToVector128(float value) => DuplicateToVector128(value); + + /// + /// uint16x8_t vdupq_n_u16 (uint16_t value) + /// A32: VDUP.16 Qd, Rt + /// A64: DUP Vd.8H, Rn + /// + public static Vector128 DuplicateToVector128(ushort value) => DuplicateToVector128(value); + + /// + /// uint32x4_t vdupq_n_u32 (uint32_t value) + /// A32: VDUP.32 Qd, Rt + /// A64: DUP Vd.4S, Rn + /// + public static Vector128 DuplicateToVector128(uint value) => DuplicateToVector128(value); + /// /// uint8_t vget_lane_u8 (uint8x8_t v, const int lane) /// A32: VMOV.U8 Rt, Dn[lane] diff --git a/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs b/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs index dee537db82298..addbcf945c048 100644 --- a/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs +++ b/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs @@ -341,6 +341,48 @@ public abstract partial class AdvSimd : System.Runtime.Intrinsics.Arm.ArmBase public static System.Runtime.Intrinsics.Vector64 CompareTest(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 DivideScalar(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 DivideScalar(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(byte value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(short value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(int value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(sbyte value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(float value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(ushort value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(uint value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(byte value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(short value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(int value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(sbyte value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(float value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(ushort value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(uint value) { throw null; } public static byte Extract(System.Runtime.Intrinsics.Vector128 vector, byte index) { throw null; } public static double Extract(System.Runtime.Intrinsics.Vector128 vector, byte index) { throw null; } public static short Extract(System.Runtime.Intrinsics.Vector128 vector, byte index) { throw null; } @@ -933,6 +975,12 @@ public new abstract partial class Arm64 : System.Runtime.Intrinsics.Arm.ArmBase. public static System.Runtime.Intrinsics.Vector128 Divide(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 Divide(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Divide(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(double value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(long value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(ulong value) { throw null; } public static System.Runtime.Intrinsics.Vector128 FusedMultiplyAdd(System.Runtime.Intrinsics.Vector128 acc, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 FusedMultiplySubtract(System.Runtime.Intrinsics.Vector128 acc, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 Max(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } From 751a10e5089d9be467d0dccc5856e2beb5f1eca8 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Mon, 11 May 2020 18:48:54 -0700 Subject: [PATCH 122/420] disable ServerAsyncAuthenticate_MismatchProtocols_Fails again (#36250) --- .../tests/FunctionalTests/ServerAsyncAuthenticateTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs index 28ff72a1f0563..bc58e68aa5eba 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs @@ -44,6 +44,7 @@ public async Task ServerAsyncAuthenticate_EachSupportedProtocol_Success(SslProto [Theory] [MemberData(nameof(ProtocolMismatchData))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/36192", TestPlatforms.AnyUnix)] public async Task ServerAsyncAuthenticate_MismatchProtocols_Fails( SslProtocols serverProtocol, SslProtocols clientProtocol, From 0cb7b8236abef0b95756febb0c5799932715c5ba Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 11 May 2020 22:18:17 -0700 Subject: [PATCH 123/420] Handle struct marshal stubs in ILStubManager::TraceManager. (#36249) Fixes #36248 --- src/coreclr/src/vm/stubmgr.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/coreclr/src/vm/stubmgr.cpp b/src/coreclr/src/vm/stubmgr.cpp index 2ff9311167a9d..12cbd4831f5ee 100644 --- a/src/coreclr/src/vm/stubmgr.cpp +++ b/src/coreclr/src/vm/stubmgr.cpp @@ -1844,6 +1844,12 @@ BOOL ILStubManager::TraceManager(Thread *thread, trace->InitForUnmanaged(target); } #endif // FEATURE_COMINTEROP + else if (pStubMD->IsStructMarshalStub()) + { + // There's no "target" for struct marshalling stubs + // so we have nowhere to tell the debugger to move the breakpoint. + return FALSE; + } else { // This is either direct forward P/Invoke or a CLR-to-COM call, the argument is MD From 1149f02fad6436851cfed067c7e43daf04c67939 Mon Sep 17 00:00:00 2001 From: Koundinya Veluri Date: Mon, 27 Apr 2020 16:30:06 -0700 Subject: [PATCH 124/420] Fix Unix named mutex crash during some race conditions Below when I refer to "mutex" I'm referring to the underlying mutex object, not an instance of the `Mutex` class. - When the last reference to a mutex is closed while the lock is held by some thread and a pthread mutex is used, the mutex was attempted to be destroyed but that has undefined behavior - There doesn't seem to be a way to behave exactly like on Windows for this corner case, where the mutex is destroyed when the last reference to it is released, regardless of which process has the mutex locked and which process releases the last reference to it (they could be two different processes), including in cases of abrupt shutdown - For this corner case I settled on what seems like a decent solution and compatible with older runtimes: - When a process releases its last reference to the mutex - If that mutex is locked by the same thread, the lock is abandoned and the process no longer references the mutex - If that mutex is locked by a different thread, the lifetime of the mutex is extended with an implicit ref. The implicit ref prevents this or other processes from attempting to destroy the mutex while it is locked. The implicit ref is removed in either of these cases: - The mutex gets another reference from within the same process - The thread that owns the lock exits and abandons the mutex, at which point that would be the last reference to the mutex and the process would not reference the mutex anymore - The implementation based on file locks is less restricted, but for consistency that implementation also follows the same behavior - There was also a race between an exiting thread abandoning one of its locked named mutexes and another thread releasing the last reference to it, fixed by using the creation/deletion process lock to synchronize Fix for https://github.com/dotnet/runtime/issues/34271 in master Closes https://github.com/dotnet/runtime/issues/28449 - probably doesn't fix the issue, but trying to enable it to see if it continues to fail --- src/coreclr/src/pal/src/include/pal/mutex.hpp | 13 +- .../src/pal/src/include/pal/sharedmemory.h | 7 +- .../src/pal/src/include/pal/synchobjects.hpp | 2 +- .../src/pal/src/sharedmemory/sharedmemory.cpp | 23 ++- .../src/pal/src/synchmgr/synchmanager.cpp | 65 ++++-- src/coreclr/src/pal/src/synchobj/mutex.cpp | 91 +++++++-- .../threading/NamedMutex/test1/namedmutex.cpp | 193 ++++++++++++++++-- .../System.Threading/tests/MutexTests.cs | 157 +++++++++++--- 8 files changed, 462 insertions(+), 89 deletions(-) diff --git a/src/coreclr/src/pal/src/include/pal/mutex.hpp b/src/coreclr/src/pal/src/include/pal/mutex.hpp index 8aa9a53bdafc2..d5f6cef009537 100644 --- a/src/coreclr/src/pal/src/include/pal/mutex.hpp +++ b/src/coreclr/src/pal/src/include/pal/mutex.hpp @@ -146,7 +146,6 @@ class NamedMutexProcessData : public SharedMemoryProcessDataBase private: SharedMemoryProcessDataHeader *m_processDataHeader; - NamedMutexSharedData *m_sharedData; SIZE_T m_lockCount; #if !NAMED_MUTEX_USE_PTHREAD_MUTEX HANDLE m_processLockHandle; @@ -154,6 +153,7 @@ class NamedMutexProcessData : public SharedMemoryProcessDataBase #endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX CorUnix::CPalThread *m_lockOwnerThread; NamedMutexProcessData *m_nextInThreadOwnedNamedMutexList; + bool m_hasRefFromLockOwnerThread; public: static SharedMemoryProcessDataHeader *CreateOrOpen(LPCSTR name, bool acquireLockIfCreated, bool *createdRef); @@ -169,8 +169,19 @@ class NamedMutexProcessData : public SharedMemoryProcessDataBase int sharedLockFileDescriptor #endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX ); + +public: + virtual bool CanClose() const override; + virtual bool HasImplicitRef() const override; + virtual void SetHasImplicitRef(bool value) override; virtual void Close(bool isAbruptShutdown, bool releaseSharedData) override; +public: + bool IsLockOwnedByCurrentThread() const + { + return GetSharedData()->IsLockOwnedByCurrentThread(); + } + private: NamedMutexSharedData *GetSharedData() const; void SetLockOwnerThread(CorUnix::CPalThread *lockOwnerThread); diff --git a/src/coreclr/src/pal/src/include/pal/sharedmemory.h b/src/coreclr/src/pal/src/include/pal/sharedmemory.h index 74e1cd4aedc39..ff64e20b5aa74 100644 --- a/src/coreclr/src/pal/src/include/pal/sharedmemory.h +++ b/src/coreclr/src/pal/src/include/pal/sharedmemory.h @@ -188,9 +188,10 @@ class SharedMemorySharedDataHeader class SharedMemoryProcessDataBase { public: - virtual void Close(bool isAbruptShutdown, bool releaseSharedData) - { - } + virtual bool CanClose() const = 0; + virtual bool HasImplicitRef() const = 0; + virtual void SetHasImplicitRef(bool value) = 0; + virtual void Close(bool isAbruptShutdown, bool releaseSharedData) = 0; virtual ~SharedMemoryProcessDataBase() { diff --git a/src/coreclr/src/pal/src/include/pal/synchobjects.hpp b/src/coreclr/src/pal/src/include/pal/synchobjects.hpp index 66d4710acb24b..ab51a005bae06 100644 --- a/src/coreclr/src/pal/src/include/pal/synchobjects.hpp +++ b/src/coreclr/src/pal/src/include/pal/synchobjects.hpp @@ -118,7 +118,6 @@ namespace CorUnix Volatile m_lSharedSynchLockCount; LIST_ENTRY m_leOwnedObjsList; - CRITICAL_SECTION m_ownedNamedMutexListLock; NamedMutexProcessData *m_ownedNamedMutexListHead; ThreadNativeWaitData m_tnwdNativeData; @@ -178,6 +177,7 @@ namespace CorUnix void RemoveOwnedNamedMutex(NamedMutexProcessData *processData); NamedMutexProcessData *RemoveFirstOwnedNamedMutex(); bool OwnsNamedMutex(NamedMutexProcessData *processData); + bool OwnsAnyNamedMutex() const; // The following methods provide access to the native wait lock for // those implementations that need a lock to protect the support for diff --git a/src/coreclr/src/pal/src/sharedmemory/sharedmemory.cpp b/src/coreclr/src/pal/src/sharedmemory/sharedmemory.cpp index 619fae0852826..d61b92c939fd0 100644 --- a/src/coreclr/src/pal/src/sharedmemory/sharedmemory.cpp +++ b/src/coreclr/src/pal/src/sharedmemory/sharedmemory.cpp @@ -878,6 +878,7 @@ void SharedMemoryProcessDataHeader::Close() // nonzero, don't clean up any object or global process-local state. if (m_refCount == 0) { + _ASSERTE(m_data == nullptr || m_data->CanClose()); SharedMemoryManager::RemoveProcessDataHeader(this); } @@ -1015,7 +1016,12 @@ void SharedMemoryProcessDataHeader::IncRefCount() _ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired()); _ASSERTE(m_refCount != 0); - ++m_refCount; + if (++m_refCount == 2 && m_data != nullptr && m_data->HasImplicitRef()) + { + // The synchronization object got an explicit ref that will govern its lifetime, remove the implicit ref + --m_refCount; + m_data->SetHasImplicitRef(false); + } } void SharedMemoryProcessDataHeader::DecRefCount() @@ -1023,10 +1029,21 @@ void SharedMemoryProcessDataHeader::DecRefCount() _ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired()); _ASSERTE(m_refCount != 0); - if (--m_refCount == 0) + if (--m_refCount != 0) + { + return; + } + + if (m_data != nullptr && !m_data->CanClose()) { - InternalDelete(this); + // Extend the lifetime of the synchronization object. The process data object is responsible for removing this extra ref + // when the synchronization object transitions into a state where it can be closed. + ++m_refCount; + m_data->SetHasImplicitRef(true); + return; } + + InternalDelete(this); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/src/pal/src/synchmgr/synchmanager.cpp b/src/coreclr/src/pal/src/synchmgr/synchmanager.cpp index 9d868c00e09f9..52b8843889d23 100644 --- a/src/coreclr/src/pal/src/synchmgr/synchmanager.cpp +++ b/src/coreclr/src/pal/src/synchmgr/synchmanager.cpp @@ -568,6 +568,17 @@ namespace CorUnix CThreadSynchronizationInfo * pSynchInfo = &pthrTarget->synchronizationInfo; CPalSynchronizationManager * pSynchManager = GetInstance(); + // The shared memory manager's process lock is acquired before calling into some PAL synchronization primitives that may + // take the PAL synchronization manager's synch lock (acquired below). For example, when using a file lock + // implementation for a named mutex (see NamedMutexProcessData::NamedMutexProcessData()), under the shared memory + // manager's process lock, CreateMutex is called, which acquires the PAL synchronization manager's synch lock. The same + // lock order needs to be maintained here to avoid a deadlock. + bool abandonNamedMutexes = pSynchInfo->OwnsAnyNamedMutex(); + if (abandonNamedMutexes) + { + SharedMemoryManager::AcquireCreationDeletionProcessLock(); + } + // Local lock AcquireLocalSynchLock(pthrCurrent); @@ -610,15 +621,18 @@ namespace CorUnix pSynchManager->m_cacheOwnedObjectsListNodes.Add(pthrCurrent, poolnItem); } - // Abandon owned named mutexes - while (true) + if (abandonNamedMutexes) { - NamedMutexProcessData *processData = pSynchInfo->RemoveFirstOwnedNamedMutex(); - if (processData == nullptr) + // Abandon owned named mutexes + while (true) { - break; + NamedMutexProcessData *processData = pSynchInfo->RemoveFirstOwnedNamedMutex(); + if (processData == nullptr) + { + break; + } + processData->Abandon(); } - processData->Abandon(); } if (pthrTarget != pthrCurrent) @@ -660,6 +674,12 @@ namespace CorUnix } ReleaseLocalSynchLock(pthrCurrent); + + if (abandonNamedMutexes) + { + SharedMemoryManager::ReleaseCreationDeletionProcessLock(); + } + DiscardAllPendingAPCs(pthrCurrent, pthrTarget); return palErr; @@ -4036,7 +4056,6 @@ namespace CorUnix m_ownedNamedMutexListHead(nullptr) { InitializeListHead(&m_leOwnedObjsList); - InitializeCriticalSection(&m_ownedNamedMutexListLock); #ifdef SYNCHMGR_SUSPENSION_SAFE_CONDITION_SIGNALING m_lPendingSignalingCount = 0; @@ -4046,7 +4065,6 @@ namespace CorUnix CThreadSynchronizationInfo::~CThreadSynchronizationInfo() { - DeleteCriticalSection(&m_ownedNamedMutexListLock); if (NULL != m_shridWaitAwakened) { free(m_shridWaitAwakened); @@ -4283,20 +4301,21 @@ namespace CorUnix void CThreadSynchronizationInfo::AddOwnedNamedMutex(NamedMutexProcessData *processData) { + _ASSERTE(this == &GetCurrentPalThread()->synchronizationInfo); _ASSERTE(processData != nullptr); + _ASSERTE(processData->IsLockOwnedByCurrentThread()); _ASSERTE(processData->GetNextInThreadOwnedNamedMutexList() == nullptr); - EnterCriticalSection(&m_ownedNamedMutexListLock); processData->SetNextInThreadOwnedNamedMutexList(m_ownedNamedMutexListHead); m_ownedNamedMutexListHead = processData; - LeaveCriticalSection(&m_ownedNamedMutexListLock); } void CThreadSynchronizationInfo::RemoveOwnedNamedMutex(NamedMutexProcessData *processData) { + _ASSERTE(this == &GetCurrentPalThread()->synchronizationInfo); _ASSERTE(processData != nullptr); + _ASSERTE(processData->IsLockOwnedByCurrentThread()); - EnterCriticalSection(&m_ownedNamedMutexListLock); if (m_ownedNamedMutexListHead == processData) { m_ownedNamedMutexListHead = processData->GetNextInThreadOwnedNamedMutexList(); @@ -4321,38 +4340,44 @@ namespace CorUnix } _ASSERTE(found); } - LeaveCriticalSection(&m_ownedNamedMutexListLock); } NamedMutexProcessData *CThreadSynchronizationInfo::RemoveFirstOwnedNamedMutex() { - EnterCriticalSection(&m_ownedNamedMutexListLock); + _ASSERTE(this == &GetCurrentPalThread()->synchronizationInfo); + NamedMutexProcessData *processData = m_ownedNamedMutexListHead; if (processData != nullptr) { + _ASSERTE(processData->IsLockOwnedByCurrentThread()); m_ownedNamedMutexListHead = processData->GetNextInThreadOwnedNamedMutexList(); processData->SetNextInThreadOwnedNamedMutexList(nullptr); } - LeaveCriticalSection(&m_ownedNamedMutexListLock); return processData; } bool CThreadSynchronizationInfo::OwnsNamedMutex(NamedMutexProcessData *processData) { - EnterCriticalSection(&m_ownedNamedMutexListLock); - bool found = false; + _ASSERTE(this == &GetCurrentPalThread()->synchronizationInfo); + for (NamedMutexProcessData *current = m_ownedNamedMutexListHead; current != nullptr; current = current->GetNextInThreadOwnedNamedMutexList()) { + _ASSERTE(current->IsLockOwnedByCurrentThread()); if (current == processData) { - found = true; - break; + return true; } } - LeaveCriticalSection(&m_ownedNamedMutexListLock); - return found; + + return false; + } + + bool CThreadSynchronizationInfo::OwnsAnyNamedMutex() const + { + _ASSERTE(this == &GetCurrentPalThread()->synchronizationInfo); + return m_ownedNamedMutexListHead != nullptr; } #if SYNCHMGR_SUSPENSION_SAFE_CONDITION_SIGNALING diff --git a/src/coreclr/src/pal/src/synchobj/mutex.cpp b/src/coreclr/src/pal/src/synchobj/mutex.cpp index a4bb340a436a9..6c90ab475e721 100644 --- a/src/coreclr/src/pal/src/synchobj/mutex.cpp +++ b/src/coreclr/src/pal/src/synchobj/mutex.cpp @@ -1247,7 +1247,8 @@ NamedMutexProcessData::NamedMutexProcessData( m_sharedLockFileDescriptor(sharedLockFileDescriptor), #endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX m_lockOwnerThread(nullptr), - m_nextInThreadOwnedNamedMutexList(nullptr) + m_nextInThreadOwnedNamedMutexList(nullptr), + m_hasRefFromLockOwnerThread(false) { _ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired()); _ASSERTE(processDataHeader != nullptr); @@ -1263,6 +1264,39 @@ NamedMutexProcessData::NamedMutexProcessData( #endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX } +bool NamedMutexProcessData::CanClose() const +{ + _ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired()); + + // When using a pthread robust mutex, the mutex may only be unlocked and destroyed by the thread that owns the lock. When + // using file locks, even though any thread could release that lock, the behavior is kept consistent to the more + // conservative case. If the last handle to the mutex is closed when a different thread owns the lock, the mutex cannot be + // closed. Due to these limitations, the behavior in this corner case is necessarily different from Windows. The caller will + // extend the lifetime of the mutex and will call OnLifetimeExtendedDueToCannotClose() shortly. + return m_lockOwnerThread == nullptr || m_lockOwnerThread == GetCurrentPalThread(); +} + +bool NamedMutexProcessData::HasImplicitRef() const +{ + _ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired()); + return m_hasRefFromLockOwnerThread; +} + +void NamedMutexProcessData::SetHasImplicitRef(bool value) +{ + _ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired()); + _ASSERTE(m_hasRefFromLockOwnerThread != value); + _ASSERTE(!value || !CanClose()); + + // If value == true: + // The mutex could not be closed and the caller extended the lifetime of the mutex. Record that the lock owner thread + // should release the ref when the lock is released on that thread. + // Else: + // The mutex has an implicit ref and got the first explicit reference from this process. Remove the implicit ref from the + // lock owner thread. + m_hasRefFromLockOwnerThread = value; +} + void NamedMutexProcessData::Close(bool isAbruptShutdown, bool releaseSharedData) { _ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired()); @@ -1272,20 +1306,23 @@ void NamedMutexProcessData::Close(bool isAbruptShutdown, bool releaseSharedData) // active references to the mutex. So when shutting down abruptly, don't clean up any object or global process-local state. if (!isAbruptShutdown) { + _ASSERTE(CanClose()); + _ASSERTE(!m_hasRefFromLockOwnerThread); + CPalThread *lockOwnerThread = m_lockOwnerThread; - if (lockOwnerThread != nullptr) + if (lockOwnerThread == GetCurrentPalThread()) { - // The mutex was not released before it was closed. If the lock is owned by the current thread, abandon the mutex. - // In both cases, clean up the owner thread's list of owned mutexes. + // The mutex was not released before the last handle to it from this process was closed on the lock-owning thread. + // Another process may still have a handle to the mutex, but since it appears as though this process would not be + // releasing the mutex, abandon the mutex. The only way for this process to otherwise release the mutex is to open + // another handle to it and release the lock on the same thread, which would be incorrect-looking code. The behavior + // in this corner case is different from Windows. lockOwnerThread->synchronizationInfo.RemoveOwnedNamedMutex(this); - if (lockOwnerThread == GetCurrentPalThread()) - { - Abandon(); - } - else - { - m_lockOwnerThread = nullptr; - } + Abandon(); + } + else + { + _ASSERTE(lockOwnerThread == nullptr); } if (releaseSharedData) @@ -1337,18 +1374,20 @@ NamedMutexSharedData *NamedMutexProcessData::GetSharedData() const void NamedMutexProcessData::SetLockOwnerThread(CorUnix::CPalThread *lockOwnerThread) { _ASSERTE(lockOwnerThread == nullptr || lockOwnerThread == GetCurrentPalThread()); - _ASSERTE(GetSharedData()->IsLockOwnedByCurrentThread()); + _ASSERTE(IsLockOwnedByCurrentThread()); m_lockOwnerThread = lockOwnerThread; } NamedMutexProcessData *NamedMutexProcessData::GetNextInThreadOwnedNamedMutexList() const { + _ASSERTE(IsLockOwnedByCurrentThread()); return m_nextInThreadOwnedNamedMutexList; } void NamedMutexProcessData::SetNextInThreadOwnedNamedMutexList(NamedMutexProcessData *next) { + _ASSERTE(IsLockOwnedByCurrentThread()); m_nextInThreadOwnedNamedMutexList = next; } @@ -1367,7 +1406,7 @@ MutexTryAcquireLockResult NamedMutexProcessData::TryAcquireLock(DWORD timeoutMil // at the appropriate time, see ReleaseLock(). if (m_lockCount != 0) { - _ASSERTE(sharedData->IsLockOwnedByCurrentThread()); // otherwise, this thread would not have acquired the lock + _ASSERTE(IsLockOwnedByCurrentThread()); // otherwise, this thread would not have acquired the lock _ASSERTE(GetCurrentPalThread()->synchronizationInfo.OwnsNamedMutex(this)); if (m_lockCount + 1 < m_lockCount) @@ -1442,7 +1481,7 @@ MutexTryAcquireLockResult NamedMutexProcessData::TryAcquireLock(DWORD timeoutMil // Check if it's a recursive lock attempt if (m_lockCount != 0) { - _ASSERTE(sharedData->IsLockOwnedByCurrentThread()); // otherwise, this thread would not have acquired the process lock + _ASSERTE(IsLockOwnedByCurrentThread()); // otherwise, this thread would not have acquired the process lock _ASSERTE(GetCurrentPalThread()->synchronizationInfo.OwnsNamedMutex(this)); if (m_lockCount + 1 < m_lockCount) @@ -1565,12 +1604,13 @@ MutexTryAcquireLockResult NamedMutexProcessData::TryAcquireLock(DWORD timeoutMil void NamedMutexProcessData::ReleaseLock() { - if (!GetSharedData()->IsLockOwnedByCurrentThread()) + if (!IsLockOwnedByCurrentThread()) { throw SharedMemoryException(static_cast(NamedMutexError::ThreadHasNotAcquiredMutex)); } _ASSERTE(GetCurrentPalThread()->synchronizationInfo.OwnsNamedMutex(this)); + _ASSERTE(!m_hasRefFromLockOwnerThread); _ASSERTE(m_lockCount != 0); --m_lockCount; @@ -1586,23 +1626,36 @@ void NamedMutexProcessData::ReleaseLock() void NamedMutexProcessData::Abandon() { + _ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired()); + NamedMutexSharedData *sharedData = GetSharedData(); - _ASSERTE(sharedData->IsLockOwnedByCurrentThread()); + _ASSERTE(IsLockOwnedByCurrentThread()); _ASSERTE(m_lockCount != 0); + bool hasRefFromLockOwnerThread = m_hasRefFromLockOwnerThread; + if (hasRefFromLockOwnerThread) + { + m_hasRefFromLockOwnerThread = false; + } + sharedData->SetIsAbandoned(true); m_lockCount = 0; SetLockOwnerThread(nullptr); ActuallyReleaseLock(); + + if (hasRefFromLockOwnerThread) + { + m_processDataHeader->DecRefCount(); + } } void NamedMutexProcessData::ActuallyReleaseLock() { - NamedMutexSharedData *sharedData = GetSharedData(); - _ASSERTE(sharedData->IsLockOwnedByCurrentThread()); + _ASSERTE(IsLockOwnedByCurrentThread()); _ASSERTE(!GetCurrentPalThread()->synchronizationInfo.OwnsNamedMutex(this)); _ASSERTE(m_lockCount == 0); + NamedMutexSharedData *sharedData = GetSharedData(); sharedData->ClearLockOwner(); #if NAMED_MUTEX_USE_PTHREAD_MUTEX diff --git a/src/coreclr/src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp b/src/coreclr/src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp index 6635d76a80a07..761bb47b5c6be 100644 --- a/src/coreclr/src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp +++ b/src/coreclr/src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp @@ -60,9 +60,12 @@ extern bool WriteHeaderInfo(const char *path, char sharedMemoryType, char versio { \ if (!g_isParent) \ { \ - Trace("Child process: "); \ + Trace("'paltest_namedmutex_test1' child process failed at line %u. Expression: " #expression "\n", __LINE__); \ + } \ + else \ + { \ + Trace("'paltest_namedmutex_test1' failed at line %u. Expression: " #expression "\n", __LINE__); \ } \ - Trace("'paltest_namedmutex_test1' failed at line %u. Expression: " #expression "\n", __LINE__); \ fflush(stdout); \ return false; \ } \ @@ -516,7 +519,7 @@ bool MutualExclusionTests_Parent() TestAssert(WaitForSingleObject(m, static_cast(-1)) == WAIT_OBJECT_0); // lock the mutex with no timeout and release TestAssert(m.Release()); - UninitializeParent(testName, parentEvents); + TestAssert(UninitializeParent(testName, parentEvents)); return true; } @@ -539,7 +542,7 @@ DWORD PALAPI MutualExclusionTests_Child(void *arg = nullptr) TestAssert(m.Release()); // release the lock } - UninitializeChild(childRunningEvent, parentEvents, childEvents); + TestAssert(UninitializeChild(childRunningEvent, parentEvents, childEvents)); return 0; } @@ -622,7 +625,7 @@ bool LifetimeTests_Parent() TestAssert(YieldToChild(parentEvents, childEvents, ei)); // child closes second reference TestAssert(!TestFileExists(BuildGlobalShmFilePath(testName, name, NamePrefix))); - UninitializeParent(testName, parentEvents); + TestAssert(UninitializeParent(testName, parentEvents)); return true; } @@ -653,7 +656,7 @@ DWORD PALAPI LifetimeTests_Child(void *arg = nullptr) TestAssert(YieldToParent(parentEvents, childEvents, ei)); // parent verifies } - UninitializeChild(childRunningEvent, parentEvents, childEvents); + TestAssert(UninitializeChild(childRunningEvent, parentEvents, childEvents)); return 0; } @@ -702,11 +705,11 @@ bool AbandonTests_Parent() TestAssert(parentEvents[1].Release()); // child sleeps for short duration and abandons the mutex TestAssert(WaitForSingleObject(m, FailTimeoutMilliseconds) == WAIT_ABANDONED_0); // attempt to lock and see abandoned mutex - UninitializeParent(testName, parentEvents, false /* releaseParentEvents */); // parent events are released above + TestAssert(UninitializeParent(testName, parentEvents, false /* releaseParentEvents */)); // parent events are released above } // Verify that the mutex lock is owned by this thread, by starting a new thread and trying to lock it - StartThread(AbandonTests_Child_TryLock); + TestAssert(StartThread(AbandonTests_Child_TryLock)); { AutoCloseMutexHandle parentEvents[2], childEvents[2]; TestAssert(InitializeParent(testName, parentEvents, childEvents)); @@ -714,11 +717,11 @@ bool AbandonTests_Parent() TestAssert(YieldToChild(parentEvents, childEvents, ei)); // child tries to lock mutex - UninitializeParent(testName, parentEvents); + TestAssert(UninitializeParent(testName, parentEvents)); } // Verify that the mutex lock is owned by this thread, by starting a new process and trying to lock it - StartProcess("AbandonTests_Child_TryLock"); + TestAssert(StartProcess("AbandonTests_Child_TryLock")); AutoCloseMutexHandle parentEvents[2], childEvents[2]; TestAssert(InitializeParent(testName, parentEvents, childEvents)); int ei = 0; @@ -730,7 +733,7 @@ bool AbandonTests_Parent() TestAssert(WaitForSingleObject(m, FailTimeoutMilliseconds) == WAIT_OBJECT_0); // lock again to see it's not abandoned anymore TestAssert(m.Release()); - UninitializeParent(testName, parentEvents, false /* releaseParentEvents */); // parent events are released above + TestAssert(UninitializeParent(testName, parentEvents)); // Since the child abandons the mutex, and a child process may not release the file lock on the shared memory file before // indicating completion to the parent, make sure to delete the shared memory file by repeatedly opening/closing the mutex @@ -772,7 +775,7 @@ DWORD PALAPI AbandonTests_Child_GracefulExit_Close(void *arg = nullptr) m.Close(); // close mutex without releasing lock } - UninitializeChild(childRunningEvent, parentEvents, childEvents); + TestAssert(UninitializeChild(childRunningEvent, parentEvents, childEvents)); return 0; } @@ -801,7 +804,7 @@ DWORD AbandonTests_Child_GracefulExit_NoClose(void *arg = nullptr) m.Abandon(); // don't close the mutex } - UninitializeChild(childRunningEvent, parentEvents, childEvents); + TestAssert(UninitializeChild(childRunningEvent, parentEvents, childEvents)); return 0; } @@ -830,7 +833,7 @@ DWORD AbandonTests_Child_AbruptExit(void *arg = nullptr) m.Abandon(); // don't close the mutex } - UninitializeChild(childRunningEvent, parentEvents, childEvents); + TestAssert(UninitializeChild(childRunningEvent, parentEvents, childEvents)); } TestAssert(test_kill(currentPid) == 0); // abandon the mutex abruptly @@ -894,7 +897,7 @@ DWORD AbandonTests_Child_FileLocksNotInherited_Child_AbruptExit(void *arg = null m.Close(); // close mutex without releasing lock (root parent expects the mutex to be abandoned) } - UninitializeChild(childRunningEvent, parentEvents, childEvents); + TestAssert(UninitializeChild(childRunningEvent, parentEvents, childEvents)); return 0; } @@ -917,14 +920,12 @@ DWORD PALAPI AbandonTests_Child_TryLock(void *arg) TestAssert(WaitForSingleObject(m, g_expectedTimeoutMilliseconds) == WAIT_TIMEOUT); } - UninitializeChild(childRunningEvent, parentEvents, childEvents); + TestAssert(UninitializeChild(childRunningEvent, parentEvents, childEvents)); return 0; } bool AbandonTests() { - const char *testName = "AbandonTests"; - // Abandon by graceful exit where the lock owner closes the mutex before releasing it, unblocks a waiter TestAssert(StartThread(AbandonTests_Child_GracefulExit_Close)); TestAssert(AbandonTests_Parent()); @@ -945,6 +946,151 @@ bool AbandonTests() return true; } +bool LockAndCloseWithoutThreadExitTests_Parent_CloseOnSameThread() +{ + const char *testName = "LockAndCloseWithoutThreadExitTests"; + + AutoCloseMutexHandle parentEvents[2], childEvents[2]; + TestAssert(InitializeParent(testName, parentEvents, childEvents)); + int ei = 0; + char name[MaxPathSize]; + AutoCloseMutexHandle m; + + TestCreateMutex(m, BuildName(testName, name, GlobalPrefix, NamePrefix)); + TestAssert(m != nullptr); + + TestAssert(YieldToChild(parentEvents, childEvents, ei)); // child locks mutex and closes second reference to mutex on lock-owner thread + TestAssert(WaitForSingleObject(m, 0) == WAIT_TIMEOUT); // attempt to lock and fail + + TestAssert(YieldToChild(parentEvents, childEvents, ei)); // child closes last reference to mutex on lock-owner thread + TestAssert(WaitForSingleObject(m, 0) == WAIT_ABANDONED_0); // attempt to lock and see abandoned mutex + TestAssert(m.Release()); + + TestAssert(YieldToChild(parentEvents, childEvents, ei)); // child exits + TestAssert(TestFileExists(BuildGlobalShmFilePath(testName, name, NamePrefix))); + m.Close(); + TestAssert(!TestFileExists(BuildGlobalShmFilePath(testName, name, NamePrefix))); + + TestAssert(UninitializeParent(testName, parentEvents)); + return true; +} + +DWORD PALAPI LockAndCloseWithoutThreadExitTests_Child_CloseOnSameThread(void *arg = nullptr) +{ + const char *testName = "LockAndCloseWithoutThreadExitTests"; + + TestAssert(test_getpid() != g_parentPid); // this test needs to run in a separate process + + AutoCloseMutexHandle childRunningEvent, parentEvents[2], childEvents[2]; + TestAssert(InitializeChild(testName, childRunningEvent, parentEvents, childEvents)); + int ei = 0; + char name[MaxPathSize]; + + // ... parent waits for child to lock and close second reference to mutex + AutoCloseMutexHandle m(TestOpenMutex(BuildName(testName, name, GlobalPrefix, NamePrefix))); + TestAssert(m != nullptr); + TestAssert(WaitForSingleObject(m, 0) == WAIT_OBJECT_0); + TestAssert(AutoCloseMutexHandle(TestOpenMutex(BuildName(testName, name, GlobalPrefix, NamePrefix))) != nullptr); + TestAssert(YieldToParent(parentEvents, childEvents, ei)); // parent waits for child to close last reference to mutex + + m.Close(); // close mutex on lock-owner thread without releasing lock + TestAssert(YieldToParent(parentEvents, childEvents, ei)); // parent verifies while this thread is still active + + TestAssert(UninitializeChild(childRunningEvent, parentEvents, childEvents)); + return 0; +} + +DWORD PALAPI LockAndCloseWithoutThreadExitTests_ChildThread_CloseMutex(void *arg); + +bool LockAndCloseWithoutThreadExitTests_Parent_CloseOnDifferentThread() +{ + const char *testName = "LockAndCloseWithoutThreadExitTests"; + + AutoCloseMutexHandle parentEvents[2], childEvents[2]; + TestAssert(InitializeParent(testName, parentEvents, childEvents)); + int ei = 0; + char name[MaxPathSize]; + AutoCloseMutexHandle m; + + TestCreateMutex(m, BuildName(testName, name, GlobalPrefix, NamePrefix)); + TestAssert(m != nullptr); + + TestAssert(YieldToChild(parentEvents, childEvents, ei)); // child locks mutex and closes second reference to mutex on lock-owner thread + TestAssert(WaitForSingleObject(m, 0) == WAIT_TIMEOUT); // attempt to lock and fail + + TestAssert(YieldToChild(parentEvents, childEvents, ei)); // child closes last reference to mutex on non-lock-owner thread + TestAssert(WaitForSingleObject(m, 0) == WAIT_TIMEOUT); // attempt to lock and fail + m.Close(); + m = TestOpenMutex(BuildName(testName, name, GlobalPrefix, NamePrefix)); + TestAssert(m != nullptr); // child has implicit reference to mutex + + TestAssert(YieldToChild(parentEvents, childEvents, ei)); // child closes new reference to mutex on lock-owner thread + TestAssert(WaitForSingleObject(m, 0) == WAIT_ABANDONED_0); // attempt to lock and see abandoned mutex + TestAssert(m.Release()); + + TestAssert(YieldToChild(parentEvents, childEvents, ei)); // child exits + TestAssert(TestFileExists(BuildGlobalShmFilePath(testName, name, NamePrefix))); + m.Close(); + TestAssert(!TestFileExists(BuildGlobalShmFilePath(testName, name, NamePrefix))); + + TestAssert(UninitializeParent(testName, parentEvents)); + return true; +} + +DWORD PALAPI LockAndCloseWithoutThreadExitTests_Child_CloseOnDifferentThread(void *arg = nullptr) +{ + const char *testName = "LockAndCloseWithoutThreadExitTests"; + + TestAssert(test_getpid() != g_parentPid); // this test needs to run in a separate process + + AutoCloseMutexHandle childRunningEvent, parentEvents[2], childEvents[2]; + TestAssert(InitializeChild(testName, childRunningEvent, parentEvents, childEvents)); + int ei = 0; + char name[MaxPathSize]; + + // ... parent waits for child to lock and close second reference to mutex + AutoCloseMutexHandle m(TestOpenMutex(BuildName(testName, name, GlobalPrefix, NamePrefix))); + TestAssert(m != nullptr); + TestAssert(WaitForSingleObject(m, 0) == WAIT_OBJECT_0); + TestAssert(AutoCloseMutexHandle(TestOpenMutex(BuildName(testName, name, GlobalPrefix, NamePrefix))) != nullptr); + TestAssert(YieldToParent(parentEvents, childEvents, ei)); // parent waits for child to close last reference to mutex + + // Close the mutex on a thread that is not the lock-owner thread, without releasing the lock + HANDLE closeMutexThread = nullptr; + TestAssert(StartThread(LockAndCloseWithoutThreadExitTests_ChildThread_CloseMutex, (HANDLE)m, &closeMutexThread)); + TestAssert(closeMutexThread != nullptr); + TestAssert(WaitForSingleObject(closeMutexThread, FailTimeoutMilliseconds) == WAIT_OBJECT_0); + TestAssert(CloseHandle(closeMutexThread)); + m.Abandon(); // mutex is already closed, don't close it again + TestAssert(YieldToParent(parentEvents, childEvents, ei)); // parent verifies while this lock-owner thread is still active + + m = TestOpenMutex(BuildName(testName, name, GlobalPrefix, NamePrefix)); + TestAssert(m != nullptr); + m.Close(); // close mutex on lock-owner thread without releasing lock + TestAssert(YieldToParent(parentEvents, childEvents, ei)); // parent verifies while this thread is still active + + TestAssert(UninitializeChild(childRunningEvent, parentEvents, childEvents)); + return 0; +} + +DWORD PALAPI LockAndCloseWithoutThreadExitTests_ChildThread_CloseMutex(void *arg) +{ + TestAssert(arg != nullptr); + AutoCloseMutexHandle((HANDLE)arg).Close(); + return 0; +} + +bool LockAndCloseWithoutThreadExitTests() +{ + TestAssert(StartProcess("LockAndCloseWithoutThreadExitTests_Child_CloseOnSameThread")); + TestAssert(LockAndCloseWithoutThreadExitTests_Parent_CloseOnSameThread()); + + TestAssert(StartProcess("LockAndCloseWithoutThreadExitTests_Child_CloseOnDifferentThread")); + TestAssert(LockAndCloseWithoutThreadExitTests_Parent_CloseOnDifferentThread()); + + return true; +} + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Test harness @@ -954,7 +1100,8 @@ bool (*const (TestList[]))() = HeaderMismatchTests, MutualExclusionTests, LifetimeTests, - AbandonTests + AbandonTests, + LockAndCloseWithoutThreadExitTests }; bool RunTests() @@ -1125,6 +1272,14 @@ int __cdecl main(int argc, char **argv) { AbandonTests_Child_TryLock(); } + else if (test_strcmp(argv[2], "LockAndCloseWithoutThreadExitTests_Child_CloseOnSameThread") == 0) + { + LockAndCloseWithoutThreadExitTests_Child_CloseOnSameThread(); + } + else if (test_strcmp(argv[2], "LockAndCloseWithoutThreadExitTests_Child_CloseOnDifferentThread") == 0) + { + LockAndCloseWithoutThreadExitTests_Child_CloseOnDifferentThread(); + } ExitProcess(PASS); return PASS; } diff --git a/src/libraries/System.Threading/tests/MutexTests.cs b/src/libraries/System.Threading/tests/MutexTests.cs index 79de3ee2be4f9..e5143a4484446 100644 --- a/src/libraries/System.Threading/tests/MutexTests.cs +++ b/src/libraries/System.Threading/tests/MutexTests.cs @@ -401,39 +401,53 @@ public static IEnumerable CrossProcess_NamedMutex_ProtectedFileAccessA } } - [ActiveIssue("https://github.com/dotnet/runtime/issues/28449")] [Theory] [MemberData(nameof(CrossProcess_NamedMutex_ProtectedFileAccessAtomic_MemberData))] public void CrossProcess_NamedMutex_ProtectedFileAccessAtomic(string prefix) { - ThreadTestHelpers.RunTestInBackgroundThread(() => + string fileName = GetTestFilePath(); + try { - string mutexName = prefix + Guid.NewGuid().ToString("N"); - string fileName = GetTestFilePath(); - - Action otherProcess = (m, f) => + ThreadTestHelpers.RunTestInBackgroundThread(() => { - using (var mutex = Mutex.OpenExisting(m)) - { - mutex.CheckedWait(); - try - { File.WriteAllText(f, "0"); } - finally { mutex.ReleaseMutex(); } + string mutexName = prefix + Guid.NewGuid().ToString("N"); - IncrementValueInFileNTimes(mutex, f, 10); - } - }; + Action otherProcess = (m, f) => + { + using (var mutex = Mutex.OpenExisting(m)) + { + mutex.CheckedWait(); + try + { File.WriteAllText(f, "0"); } + finally { mutex.ReleaseMutex(); } - using (var mutex = new Mutex(false, mutexName)) - using (var remote = RemoteExecutor.Invoke(otherProcess, mutexName, fileName)) - { - SpinWait.SpinUntil(() => File.Exists(fileName), ThreadTestHelpers.UnexpectedTimeoutMilliseconds); + IncrementValueInFileNTimes(mutex, f, 10); + } + }; - IncrementValueInFileNTimes(mutex, fileName, 10); - } + using (var mutex = new Mutex(false, mutexName)) + using (var remote = RemoteExecutor.Invoke(otherProcess, mutexName, fileName)) + { + SpinWait.SpinUntil( + () => + { + mutex.CheckedWait(); + try + { return File.Exists(fileName) && int.TryParse(File.ReadAllText(fileName), out _); } + finally { mutex.ReleaseMutex(); } + }, + ThreadTestHelpers.UnexpectedTimeoutMilliseconds); + + IncrementValueInFileNTimes(mutex, fileName, 10); + } - Assert.Equal(20, int.Parse(File.ReadAllText(fileName))); - }); + Assert.Equal(20, int.Parse(File.ReadAllText(fileName))); + }); + } + catch (Exception ex) when (File.Exists(fileName)) + { + throw new AggregateException($"File contents: {File.ReadAllText(fileName)}", ex); + } } private static void IncrementValueInFileNTimes(Mutex mutex, string fileName, int n) @@ -451,6 +465,103 @@ private static void IncrementValueInFileNTimes(Mutex mutex, string fileName, int } } + [Fact] + public void NamedMutex_ThreadExitDisposeRaceTest() + { + var mutexName = Guid.NewGuid().ToString("N"); + + for (int i = 0; i < 1000; ++i) + { + var m = new Mutex(false, mutexName); + var startParallelTest = new ManualResetEvent(false); + + var t0Ready = new AutoResetEvent(false); + Thread t0 = ThreadTestHelpers.CreateGuardedThread(out Action waitForT0, () => + { + m.CheckedWait(); + t0Ready.Set(); + startParallelTest.CheckedWait(); // after this, exit T0 + }); + t0.IsBackground = true; + + var t1Ready = new AutoResetEvent(false); + Thread t1 = ThreadTestHelpers.CreateGuardedThread(out Action waitForT1, () => + { + using (var m2 = Mutex.OpenExisting(mutexName)) + { + m.Dispose(); + t1Ready.Set(); + startParallelTest.CheckedWait(); // after this, close last handle to named mutex, exit T1 + } + }); + t1.IsBackground = true; + + t0.Start(); + t0Ready.CheckedWait(); // wait for T0 to acquire the mutex + t1.Start(); + t1Ready.CheckedWait(); // wait for T1 to open the existing mutex in a new mutex object and dispose one of the two + + // Release both threads at the same time. T0 will be exiting the thread, perhaps trying to abandon the mutex + // that is still locked by it. In parallel, T1 will be disposing the last mutex instance, which would try to + // destroy the mutex. + startParallelTest.Set(); + waitForT0(); + waitForT1(); + + // Create a new mutex object with the same name and acquire it. There can be a delay between Thread.Join() above + // returning and for T0 to abandon its mutex, keep trying to also verify that the mutex object is actually + // destroyed and created new again. + SpinWait.SpinUntil(() => + { + using (m = new Mutex(true, mutexName, out bool createdNew)) + { + if (createdNew) + { + m.ReleaseMutex(); + } + return createdNew; + } + }); + } + } + + [Fact] + public void NamedMutex_DisposeWhenLockedRaceTest() + { + var mutexName = Guid.NewGuid().ToString("N"); + var mutex2Name = mutexName + "_2"; + + var waitsForThread = new Action[Environment.ProcessorCount]; + for (int i = 0; i < waitsForThread.Length; ++i) + { + var t = ThreadTestHelpers.CreateGuardedThread(out waitsForThread[i], () => + { + for (int i = 0; i < 1000; ++i) + { + // Create or open two mutexes with different names, acquire the lock if created, and dispose without + // releasing the lock. What may occasionally happen is, one thread T0 will acquire the lock, another + // thread T1 will open the same mutex, T0 will dispose its mutex while the lock is held, and T1 will + // then release the last reference to the mutex. On some implementations T1 may not be able to destroy + // the mutex when it is still locked by T0, or there may be potential for races in the sequence. This + // test only looks for errors from race conditions. + using (var mutex = new Mutex(true, mutexName)) + { + } + using (var mutex = new Mutex(true, mutex2Name)) + { + } + } + }); + t.IsBackground = true; + t.Start(); + } + + foreach (var waitForThread in waitsForThread) + { + waitForThread(); + } + } + public static TheoryData GetValidNames() { var names = new TheoryData() { Guid.NewGuid().ToString("N") }; From 5f884ba5fbc95857528b2da5b02c91e1b2b3d567 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Tue, 12 May 2020 16:24:02 +1000 Subject: [PATCH 125/420] Fix vs testing link (#36261) --- docs/workflow/building/libraries/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/workflow/building/libraries/README.md b/docs/workflow/building/libraries/README.md index e790e9997659c..c64f34d705470 100644 --- a/docs/workflow/building/libraries/README.md +++ b/docs/workflow/building/libraries/README.md @@ -205,6 +205,6 @@ If you are working on Windows, and use Visual Studio, you can open individual li ## Running tests -For more details about running tests inside Visual Studio, [go here](../../testing/libraries/testing.md#running-tests-from-visual-studio ) +For more details about running tests inside Visual Studio, [go here](../../testing/visualstudio.md). For more about running tests, read the [running tests](../../testing/libraries/testing.md) document. From 7f042fc22e57f8b762baf0222aa4e6348dea7cbf Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 12 May 2020 03:29:02 -0400 Subject: [PATCH 126/420] Build WASM runtimes (#35566) --- eng/liveBuilds.targets | 2 + .../netcoreapp/src/netcoreapp.depproj | 7 +- src/libraries/pretest.proj | 8 + src/libraries/restore/runtime/runtime.depproj | 3 + src/mono/mono.proj | 21 +- .../WasmAppBuilder/PInvokeTableGenerator.cs | 146 ++ .../WasmAppBuilder/WasmAppBuilder.csproj | 16 + src/mono/wasm/Makefile | 100 ++ src/mono/wasm/runtime/binding_support.js | 1277 +++++++++++++++++ src/mono/wasm/runtime/corebindings.c | 179 +++ src/mono/wasm/runtime/dotnet_support.js | 96 ++ src/mono/wasm/runtime/driver.c | 759 ++++++++++ src/mono/wasm/runtime/library_mono.js | 1000 +++++++++++++ src/mono/wasm/runtime/linker-preserves.xml | 7 + src/mono/wasm/wasm.proj | 46 + 15 files changed, 3665 insertions(+), 2 deletions(-) create mode 100644 src/mono/msbuild/WasmAppBuilder/PInvokeTableGenerator.cs create mode 100644 src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.csproj create mode 100644 src/mono/wasm/Makefile create mode 100644 src/mono/wasm/runtime/binding_support.js create mode 100644 src/mono/wasm/runtime/corebindings.c create mode 100644 src/mono/wasm/runtime/dotnet_support.js create mode 100644 src/mono/wasm/runtime/driver.c create mode 100644 src/mono/wasm/runtime/library_mono.js create mode 100644 src/mono/wasm/runtime/linker-preserves.xml create mode 100644 src/mono/wasm/wasm.proj diff --git a/eng/liveBuilds.targets b/eng/liveBuilds.targets index 920392bae3260..6462ef23da441 100644 --- a/eng/liveBuilds.targets +++ b/eng/liveBuilds.targets @@ -137,6 +137,8 @@ Include="$(MonoArtifactsPath)\cross\*.*" /> + diff --git a/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj b/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj index 29f0b67ea8277..7f97f90c9b459 100644 --- a/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj +++ b/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj @@ -71,11 +71,16 @@ Include="@(MonoCrossFiles)"> runtimes/$(PackageRID)/native/cross - runtimes/$(PackageRID)/native/include/%(RecursiveDir) + + runtimes/$(PackageRID)/native/wasm/runtimes/%(RecursiveDir) + + runtimes/$(CoreCLRCrossTargetComponentDirName)_$(TargetArchitecture)/native diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj index d073141959ef5..08b8f5ae1caed 100644 --- a/src/libraries/pretest.proj +++ b/src/libraries/pretest.proj @@ -72,6 +72,14 @@ TargetRuntimeIdentifier="$(PackageRID)" /> + + + + + include/%(RecursiveDir) + + wasm/%(RecursiveDir) + diff --git a/src/mono/mono.proj b/src/mono/mono.proj index c6c35c2adcb22..0ac63489b21ed 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -944,9 +944,16 @@ Targets="Restore;Build" /> + + + + + - + <_MonoRuntimeFilePath Condition="'$(TargetsWindows)' == 'true' and '$(Platform)' == 'x64'">$(MonoObjDir)x64\Bin\$(Configuration)\mono-2.0-sgen.dll <_MonoRuntimeFilePath Condition="'$(TargetsWindows)' == 'true' and '$(Platform)' == 'x86'">$(MonoObjDir)Win32\Bin\$(Configuration)\mono-2.0-sgen.dll @@ -981,6 +988,18 @@ $(BinDir)cross\opt <_MonoIncludeArtifacts Include="$(MonoObjDir)out\include\**" /> + <_MonoRuntimeArtifacts Condition="'$(TargetsBrowser)' == 'true'" Include="$(MonoObjDir)out\lib\libmono-ee-interp.a"> + $(BinDir)libmono-ee-interp.a + + <_MonoRuntimeArtifacts Condition="'$(TargetsBrowser)' == 'true'" Include="$(MonoObjDir)out\lib\libmono-icall-table.a"> + $(BinDir)libmono-icall-table.a + + <_MonoRuntimeArtifacts Condition="'$(TargetsBrowser)' == 'true'" Include="$(MonoObjDir)out\lib\libmono-ilgen.a"> + $(BinDir)libmono-ilgen.a + + <_MonoRuntimeArtifacts Condition="'$(TargetsBrowser)' == 'true'" Include="$(MonoObjDir)out\lib\libmono-profiler-aot.a"> + $(BinDir)libmono-profiler-aot.a + item.ItemSpec).ToArray (), Assemblies!.Select (item => item.ItemSpec).ToArray ()); + return true; + } + + void GenPInvokeTable (string[] pinvokeModules, string[] assemblies) { + var modules = new Dictionary (); + foreach (var module in pinvokeModules) + modules [module] = module; + + var pinvokes = new List (); + + var resolver = new PathAssemblyResolver (assemblies); + var mlc = new MetadataLoadContext (resolver, "System.Private.CoreLib"); + foreach (var aname in assemblies) { + var a = mlc.LoadFromAssemblyPath (aname); + foreach (var type in a.GetTypes ()) + CollectPInvokes (pinvokes, type); + } + + Log.LogMessage (MessageImportance.Normal, $"Generating pinvoke table to '{OutputPath}'."); + + using (var w = File.CreateText (OutputPath!)) { + EmitPInvokeTable (w, modules, pinvokes); + } + } + + void CollectPInvokes (List pinvokes, Type type) { + foreach (var method in type.GetMethods (BindingFlags.DeclaredOnly|BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static|BindingFlags.Instance)) { + if ((method.Attributes & MethodAttributes.PinvokeImpl) == 0) + continue; + var dllimport = method.CustomAttributes.First (attr => attr.AttributeType.Name == "DllImportAttribute"); + var module = (string)dllimport.ConstructorArguments [0].Value!; + var entrypoint = (string)dllimport.NamedArguments.First (arg => arg.MemberName == "EntryPoint").TypedValue.Value!; + pinvokes.Add (new PInvoke (entrypoint, module, method)); + } + } + + void EmitPInvokeTable (StreamWriter w, Dictionary modules, List pinvokes) { + w.WriteLine ("// GENERATED FILE, DO NOT MODIFY"); + w.WriteLine ("typedef struct {"); + w.WriteLine ("const char *name;"); + w.WriteLine ("void *func;"); + w.WriteLine ("} PinvokeImport;"); + w.WriteLine (); + + foreach (var pinvoke in pinvokes) { + if (modules.ContainsKey (pinvoke.Module)) + w.WriteLine (GenPInvokeDecl (pinvoke)); + } + + foreach (var module in modules.Keys) { + string symbol = module.Replace (".", "_") + "_imports"; + w.WriteLine ("static PinvokeImport " + symbol + " [] = {"); + foreach (var pinvoke in pinvokes) { + if (pinvoke.Module == module) + w.WriteLine ("{\"" + pinvoke.EntryPoint + "\", " + pinvoke.EntryPoint + "},"); + } + w.WriteLine ("{NULL, NULL}"); + w.WriteLine ("};"); + } + w.Write ("static void *pinvoke_tables[] = { "); + foreach (var module in modules.Keys) { + string symbol = module.Replace (".", "_") + "_imports"; + w.Write (symbol + ","); + } + w.WriteLine ("};"); + w.Write ("static char *pinvoke_names[] = { "); + foreach (var module in modules.Keys) { + w.Write ("\"" + module + "\"" + ","); + } + w.WriteLine ("};"); + } + + string MapType (Type t) { + string name = t.Name; + if (name == "Void") + return "void"; + else if (name == "Double") + return "double"; + else if (name == "Single") + return "float"; + else if (name == "Int64") + return "int64_t"; + else if (name == "UInt64") + return "uint64_t"; + else + return "int"; + } + + string GenPInvokeDecl (PInvoke pinvoke) { + var sb = new StringBuilder (); + var method = pinvoke.Method; + sb.Append (MapType (method.ReturnType)); + sb.Append ($" {pinvoke.EntryPoint} ("); + int pindex = 0; + var pars = method.GetParameters (); + foreach (var p in pars) { + if (pindex > 0) + sb.Append (","); + sb.Append (MapType (pars [pindex].ParameterType)); + pindex ++; + } + sb.Append (");"); + return sb.ToString (); + } +} + +class PInvoke +{ + public PInvoke (string entry_point, string module, MethodInfo method) { + EntryPoint = entry_point; + Module = module; + Method = method; + } + + public string EntryPoint; + public string Module; + public MethodInfo Method; +} diff --git a/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.csproj b/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.csproj new file mode 100644 index 0000000000000..271afb933b491 --- /dev/null +++ b/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.csproj @@ -0,0 +1,16 @@ + + + Library + false + + + + + + + + + + + + diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile new file mode 100644 index 0000000000000..78e6a049d843e --- /dev/null +++ b/src/mono/wasm/Makefile @@ -0,0 +1,100 @@ +TOP=$(realpath $(CURDIR)/../../..) +-include Make.config + +# +# These variables are set by wasm.targets +# +EMSDK_PATH?=emsdk +CONFIG?=Release +BINDIR?=$(TOP)/artifacts/bin +OBJDIR?=$(TOP)/artifacts/obj +PINVOKE_TABLE?=$(TOP)/artifacts/obj/mono/Browser.wasm.$(CONFIG)/wasm/pinvoke-table.h +MONO_BIN_DIR?=$(BINDIR)/mono/Browser.wasm.$(CONFIG) +SYS_NATIVE_DIR?=$(BINDIR)/native/net5.0-Browser-$(CONFIG)-wasm/ + +all: build-native + +# +# EMSCRIPTEN SETUP +# +# If EMSDK_PATH is not set by the caller, download and setup a local emsdk install. +# + +EMSCRIPTEN_VERSION=1.39.11 +EMSDK_LOCAL_PATH=emsdk +EMCC=source $(CURDIR)/emsdk_env.sh && emcc + +.stamp-wasm-install-and-select-$(EMSCRIPTEN_VERSION): + rm -rf $(EMSDK_LOCAL_PATH) + git clone https://github.com/emscripten-core/emsdk.git $(EMSDK_LOCAL_PATH) + cd $(EMSDK_LOCAL_PATH) && git checkout $(EMSCRIPTEN_VERSION) + cd $(EMSDK_LOCAL_PATH) && ./emsdk install $(EMSCRIPTEN_VERSION) + cd $(EMSDK_LOCAL_PATH) && ./emsdk activate --embedded $(EMSCRIPTEN_VERSION) + touch $@ + +ifeq ($(EMSDK_PATH),emsdk) +provision-wasm: .stamp-wasm-install-and-select-$(EMSCRIPTEN_VERSION) +else +provision-wasm: +endif + +# emsdk_env.sh calls emsdk construct_env which is a bit slow so make a copy +emsdk_env.sh: | provision-wasm + cd $(EMSDK_PATH) && ./emsdk construct_env $(CURDIR)/emsdk_env.sh + +MONO_OBJ_DIR=$(OBJDIR)/mono/Browser.wasm.$(CONFIG) +MONO_LIBS = $(MONO_BIN_DIR)/{libmono-ee-interp.a,libmono.a,libmono-ilgen.a,libmono-icall-table.a} ${SYS_NATIVE_DIR}/libSystem.Native.a +MONO_INCLUDE_DIR=$(MONO_BIN_DIR)/include/mono-2.0 +BUILDS_BIN_DIR=$(MONO_BIN_DIR)/wasm/runtimes +BUILDS_OBJ_DIR=$(MONO_OBJ_DIR)/wasm/runtimes + +EMCC_FLAGS=--profiling-funcs -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN=1 -s ALIASING_FUNCTION_POINTERS=0 -s NO_EXIT_RUNTIME=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'FS_createPath', 'FS_createDataFile', 'cwrap', 'setValue', 'getValue', 'UTF8ToString', 'addFunction']" -s "EXPORTED_FUNCTIONS=['_putchar']" --source-map-base http://example.com -s WASM_OBJECT_FILES=0 -s FORCE_FILESYSTEM=1 -s USE_ZLIB=1 +EMCC_DEBUG_FLAGS =-g -Os -s ASSERTIONS=1 -DENABLE_NETCORE=1 +EMCC_RELEASE_FLAGS=-Oz --llvm-opts 2 --llvm-lto 1 -DENABLE_NETCORE=1 + +# +# Interpreter builds +# + +# $(1) - name +# $(2) - runtime dir +# $(3) - EMCC_FLAGS +# $(4) - libs +define InterpBuildTemplate + +$(BUILDS_BIN_DIR)/$(1)/: + mkdir -p $$@ + +$(BUILDS_OBJ_DIR)/$(1)/: + mkdir -p $$@ + +$(BUILDS_BIN_DIR)/$(1)/dotnet.js: $(BUILDS_OBJ_DIR)/$(1)/driver.o $(BUILDS_OBJ_DIR)/$(1)/corebindings.o runtime/library_mono.js runtime/binding_support.js runtime/dotnet_support.js $(5) | $(BUILDS_BIN_DIR)/$(1)/ emsdk_env.sh + $(EMCC) $(EMCC_FLAGS) $(3) --js-library runtime/library_mono.js --js-library runtime/binding_support.js --js-library runtime/dotnet_support.js $(BUILDS_OBJ_DIR)/$(1)/driver.o $(BUILDS_OBJ_DIR)/$(1)/corebindings.o $(4) -o $(BUILDS_BIN_DIR)/$(1)/dotnet.js + +$(BUILDS_OBJ_DIR)/$(1)/pinvoke-table.h: $(PINVOKE_TABLE) | $(BUILDS_OBJ_DIR)/$(1)/ + if cmp -s $(PINVOKE_TABLE) $$@ ; then : ; else cp $(PINVOKE_TABLE) $$@ ; fi + +$(BUILDS_OBJ_DIR)/$(1)/driver.o: runtime/driver.c runtime/corebindings.c $(BUILDS_OBJ_DIR)/$(1)/pinvoke-table.h $(5) | $(BUILDS_OBJ_DIR)/$(1)/ emsdk_env.sh + $(EMCC) $(EMCC_FLAGS) $(3) -Oz -DCORE_BINDINGS -I$(BUILDS_OBJ_DIR)/$(1) -I$(MONO_INCLUDE_DIR) runtime/driver.c -c -o $$@ + +$(BUILDS_OBJ_DIR)/$(1)/corebindings.o: runtime/corebindings.c | $(BUILDS_OBJ_DIR)/$(1)/ emsdk_env.sh + $(EMCC) $(3) -Oz -I$(MONO_INCLUDE_DIR) runtime/corebindings.c -c -o $$@ + +build-native: $(BUILDS_BIN_DIR)/$(1)/dotnet.js + +build-interp-$(1): $(BUILDS_BIN_DIR)/$(1)/dotnet.js + +endef + +$(eval $(call InterpBuildTemplate,debug,,$(EMCC_DEBUG_FLAGS),$(MONO_LIBS))) +$(eval $(call InterpBuildTemplate,release,,$(EMCC_RELEASE_FLAGS),$(MONO_LIBS))) + +build: + EMSDK_PATH=$(PWD)/wasm/emsdk ../../../.dotnet/dotnet build /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=Release + +clean-emsdk: + $(RM) -rf $(EMSDK_LOCAL_PATH) + +clean: + $(RM) -rf $(BUILDS_BIN_DIR) $(BUILDS_OBJ_DIR) + $(RM) emsdk_env.sh diff --git a/src/mono/wasm/runtime/binding_support.js b/src/mono/wasm/runtime/binding_support.js new file mode 100644 index 0000000000000..46b9383373e83 --- /dev/null +++ b/src/mono/wasm/runtime/binding_support.js @@ -0,0 +1,1277 @@ +// 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. + +var BindingSupportLib = { + $BINDING__postset: 'BINDING.export_functions (Module);', + $BINDING: { + BINDING_ASM: "[WebAssembly.Bindings]WebAssembly.Runtime", + mono_wasm_object_registry: [], + mono_wasm_ref_counter: 0, + mono_wasm_free_list: [], + mono_wasm_marshal_enum_as_int: false, + mono_bindings_init: function (binding_asm) { + this.BINDING_ASM = binding_asm; + }, + + export_functions: function (module) { + module ["mono_bindings_init"] = BINDING.mono_bindings_init.bind(BINDING); + module ["mono_method_invoke"] = BINDING.call_method.bind(BINDING); + module ["mono_method_get_call_signature"] = BINDING.mono_method_get_call_signature.bind(BINDING); + module ["mono_method_resolve"] = BINDING.resolve_method_fqn.bind(BINDING); + module ["mono_bind_static_method"] = BINDING.bind_static_method.bind(BINDING); + module ["mono_call_static_method"] = BINDING.call_static_method.bind(BINDING); + module ["mono_bind_assembly_entry_point"] = BINDING.bind_assembly_entry_point.bind(BINDING); + module ["mono_call_assembly_entry_point"] = BINDING.call_assembly_entry_point.bind(BINDING); + }, + + bindings_lazy_init: function () { + if (this.init) + return; + + this.assembly_load = Module.cwrap ('mono_wasm_assembly_load', 'number', ['string']); + this.find_class = Module.cwrap ('mono_wasm_assembly_find_class', 'number', ['number', 'string', 'string']); + this.find_method = Module.cwrap ('mono_wasm_assembly_find_method', 'number', ['number', 'string', 'number']); + this.invoke_method = Module.cwrap ('mono_wasm_invoke_method', 'number', ['number', 'number', 'number', 'number']); + this.mono_string_get_utf8 = Module.cwrap ('mono_wasm_string_get_utf8', 'number', ['number']); + this.js_string_to_mono_string = Module.cwrap ('mono_wasm_string_from_js', 'number', ['string']); + this.mono_get_obj_type = Module.cwrap ('mono_wasm_get_obj_type', 'number', ['number']); + this.mono_unbox_int = Module.cwrap ('mono_unbox_int', 'number', ['number']); + this.mono_unbox_float = Module.cwrap ('mono_wasm_unbox_float', 'number', ['number']); + this.mono_array_length = Module.cwrap ('mono_wasm_array_length', 'number', ['number']); + this.mono_array_get = Module.cwrap ('mono_wasm_array_get', 'number', ['number', 'number']); + this.mono_obj_array_new = Module.cwrap ('mono_wasm_obj_array_new', 'number', ['number']); + this.mono_obj_array_set = Module.cwrap ('mono_wasm_obj_array_set', 'void', ['number', 'number', 'number']); + this.mono_unbox_enum = Module.cwrap ('mono_wasm_unbox_enum', 'number', ['number']); + this.assembly_get_entry_point = Module.cwrap ('mono_wasm_assembly_get_entry_point', 'number', ['number']); + + // receives a byteoffset into allocated Heap with a size. + this.mono_typed_array_new = Module.cwrap ('mono_wasm_typed_array_new', 'number', ['number','number','number','number']); + + var binding_fqn_asm = this.BINDING_ASM.substring(this.BINDING_ASM.indexOf ("[") + 1, this.BINDING_ASM.indexOf ("]")).trim(); + var binding_fqn_class = this.BINDING_ASM.substring (this.BINDING_ASM.indexOf ("]") + 1).trim(); + + this.binding_module = this.assembly_load (binding_fqn_asm); + if (!this.binding_module) + throw "Can't find bindings module assembly: " + binding_fqn_asm; + + if (binding_fqn_class !== null && typeof binding_fqn_class !== "undefined") + { + var namespace = "WebAssembly"; + var classname = binding_fqn_class.length > 0 ? binding_fqn_class : "Runtime"; + if (binding_fqn_class.indexOf(".") != -1) { + var idx = binding_fqn_class.lastIndexOf("."); + namespace = binding_fqn_class.substring (0, idx); + classname = binding_fqn_class.substring (idx + 1); + } + } + + var wasm_runtime_class = this.find_class (this.binding_module, namespace, classname) + if (!wasm_runtime_class) + throw "Can't find " + binding_fqn_class + " class"; + + var get_method = function(method_name) { + var res = BINDING.find_method (wasm_runtime_class, method_name, -1) + if (!res) + throw "Can't find method " + namespace + "." + classname + ":" + method_name; + return res; + } + this.bind_js_obj = get_method ("BindJSObject"); + this.bind_core_clr_obj = get_method ("BindCoreCLRObject"); + this.bind_existing_obj = get_method ("BindExistingObject"); + this.unbind_js_obj = get_method ("UnBindJSObject"); + this.unbind_js_obj_and_free = get_method ("UnBindJSObjectAndFree"); + this.unbind_raw_obj_and_free = get_method ("UnBindRawJSObjectAndFree"); + this.get_js_id = get_method ("GetJSObjectId"); + this.get_raw_mono_obj = get_method ("GetMonoObject"); + + this.box_js_int = get_method ("BoxInt"); + this.box_js_double = get_method ("BoxDouble"); + this.box_js_bool = get_method ("BoxBool"); + this.is_simple_array = get_method ("IsSimpleArray"); + this.get_core_type = get_method ("GetCoreType"); + this.setup_js_cont = get_method ("SetupJSContinuation"); + + this.create_tcs = get_method ("CreateTaskSource"); + this.set_tcs_result = get_method ("SetTaskSourceResult"); + this.set_tcs_failure = get_method ("SetTaskSourceFailure"); + this.tcs_get_task_and_bind = get_method ("GetTaskAndBind"); + this.get_call_sig = get_method ("GetCallSignature"); + + this.object_to_string = get_method ("ObjectToString"); + this.get_date_value = get_method ("GetDateValue"); + this.create_date_time = get_method ("CreateDateTime"); + this.create_uri = get_method ("CreateUri"); + + this.object_to_enum = get_method ("ObjectToEnum"); + this.init = true; + }, + + get_js_obj: function (js_handle) { + if (js_handle > 0) + return this.mono_wasm_require_handle(js_handle); + return null; + }, + + conv_string: function (mono_obj) { + return MONO.string_decoder.copy (mono_obj); + }, + + is_nested_array: function (ele) { + return this.call_method (this.is_simple_array, null, "mi", [ ele ]); + }, + + mono_array_to_js_array: function (mono_array) { + if (mono_array == 0) + return null; + + var res = []; + var len = this.mono_array_length (mono_array); + for (var i = 0; i < len; ++i) + { + var ele = this.mono_array_get (mono_array, i); + if (this.is_nested_array(ele)) + res.push(this.mono_array_to_js_array(ele)); + else + res.push (this.unbox_mono_obj (ele)); + } + + return res; + }, + + js_array_to_mono_array: function (js_array) { + var mono_array = this.mono_obj_array_new (js_array.length); + for (var i = 0; i < js_array.length; ++i) { + this.mono_obj_array_set (mono_array, i, this.js_to_mono_obj (js_array [i])); + } + return mono_array; + }, + + unbox_mono_obj: function (mono_obj) { + if (mono_obj == 0) + return undefined; + var type = this.mono_get_obj_type (mono_obj); + //See MARSHAL_TYPE_ defines in driver.c + switch (type) { + case 1: // int + return this.mono_unbox_int (mono_obj); + case 2: // float + return this.mono_unbox_float (mono_obj); + case 3: //string + return this.conv_string (mono_obj); + case 4: //vts + throw new Error ("no idea on how to unbox value types"); + case 5: { // delegate + var obj = this.extract_js_obj (mono_obj); + return function () { + return BINDING.invoke_delegate (obj, arguments); + }; + } + case 6: {// Task + + if (typeof Promise === "undefined" || typeof Promise.resolve === "undefined") + throw new Error ("Promises are not supported thus C# Tasks can not work in this context."); + + var obj = this.extract_js_obj (mono_obj); + var cont_obj = null; + var promise = new Promise (function (resolve, reject) { + cont_obj = { + resolve: resolve, + reject: reject + }; + }); + + this.call_method (this.setup_js_cont, null, "mo", [ mono_obj, cont_obj ]); + obj.__mono_js_cont__ = cont_obj.__mono_gchandle__; + cont_obj.__mono_js_task__ = obj.__mono_gchandle__; + return promise; + } + + case 7: // ref type + return this.extract_js_obj (mono_obj); + + case 8: // bool + return this.mono_unbox_int (mono_obj) != 0; + + case 9: // enum + + if(this.mono_wasm_marshal_enum_as_int) + { + return this.mono_unbox_enum (mono_obj); + } + else + { + enumValue = this.call_method(this.object_to_string, null, "m", [ mono_obj ]); + } + + return enumValue; + + + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + { + throw new Error ("Marshalling of primitive arrays are not supported. Use the corresponding TypedArray instead."); + } + case 20: // clr .NET DateTime + var dateValue = this.call_method(this.get_date_value, null, "md", [ mono_obj ]); + return new Date(dateValue); + case 21: // clr .NET DateTimeOffset + var dateoffsetValue = this.call_method(this.object_to_string, null, "m", [ mono_obj ]); + return dateoffsetValue; + case 22: // clr .NET Uri + var uriValue = this.call_method(this.object_to_string, null, "m", [ mono_obj ]); + return uriValue; + default: + throw new Error ("no idea on how to unbox object kind " + type); + } + }, + + create_task_completion_source: function () { + return this.call_method (this.create_tcs, null, "i", [ -1 ]); + }, + + set_task_result: function (tcs, result) { + tcs.is_mono_tcs_result_set = true; + this.call_method (this.set_tcs_result, null, "oo", [ tcs, result ]); + if (tcs.is_mono_tcs_task_bound) + this.free_task_completion_source(tcs); + }, + + set_task_failure: function (tcs, reason) { + tcs.is_mono_tcs_result_set = true; + this.call_method (this.set_tcs_failure, null, "os", [ tcs, reason.toString () ]); + if (tcs.is_mono_tcs_task_bound) + this.free_task_completion_source(tcs); + }, + + // https://github.com/Planeshifter/emscripten-examples/blob/master/01_PassingArrays/sum_post.js + js_typedarray_to_heap: function(typedArray){ + var numBytes = typedArray.length * typedArray.BYTES_PER_ELEMENT; + var ptr = Module._malloc(numBytes); + var heapBytes = new Uint8Array(Module.HEAPU8.buffer, ptr, numBytes); + heapBytes.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, numBytes)); + return heapBytes; + }, + js_to_mono_obj: function (js_obj) { + this.bindings_lazy_init (); + + // determines if the javascript object is a Promise or Promise like which can happen + // when using an external Promise library. The javascript object should be marshalled + // as managed Task objects. + // + // Example is when Bluebird is included in a web page using a script tag, it overwrites the + // global Promise object by default with its own version of Promise. + function isThenable() { + // When using an external Promise library the Promise.resolve may not be sufficient + // to identify the object as a Promise. + return Promise.resolve(js_obj) === js_obj || + ((typeof js_obj === "object" || typeof js_obj === "function") && typeof js_obj.then === "function") + } + + switch (true) { + case js_obj === null: + case typeof js_obj === "undefined": + return 0; + case typeof js_obj === "number": + if (parseInt(js_obj) == js_obj) + return this.call_method (this.box_js_int, null, "im", [ js_obj ]); + return this.call_method (this.box_js_double, null, "dm", [ js_obj ]); + case typeof js_obj === "string": + return this.js_string_to_mono_string (js_obj); + case typeof js_obj === "boolean": + return this.call_method (this.box_js_bool, null, "im", [ js_obj ]); + case isThenable() === true: + var the_task = this.try_extract_mono_obj (js_obj); + if (the_task) + return the_task; + var tcs = this.create_task_completion_source (); + js_obj.then (function (result) { + BINDING.set_task_result (tcs, result); + }, function (reason) { + BINDING.set_task_failure (tcs, reason); + }) + return this.get_task_and_bind (tcs, js_obj); + case js_obj.constructor.name === "Date": + // We may need to take into account the TimeZone Offset + return this.call_method(this.create_date_time, null, "dm", [ js_obj.getTime() ]); + default: + return this.extract_mono_obj (js_obj); + } + }, + js_to_mono_uri: function (js_obj) { + this.bindings_lazy_init (); + + switch (true) { + case js_obj === null: + case typeof js_obj === "undefined": + return 0; + case typeof js_obj === "string": + return this.call_method(this.create_uri, null, "sm", [ js_obj ]) + default: + return this.extract_mono_obj (js_obj); + } + }, + js_typed_array_to_array : function (js_obj) { + + // JavaScript typed arrays are array-like objects and provide a mechanism for accessing + // raw binary data. (...) To achieve maximum flexibility and efficiency, JavaScript typed arrays + // split the implementation into buffers and views. A buffer (implemented by the ArrayBuffer object) + // is an object representing a chunk of data; it has no format to speak of, and offers no + // mechanism for accessing its contents. In order to access the memory contained in a buffer, + // you need to use a view. A view provides a context — that is, a data type, starting offset, + // and number of elements — that turns the data into an actual typed array. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays + if (!!(js_obj.buffer instanceof ArrayBuffer && js_obj.BYTES_PER_ELEMENT)) + { + var arrayType = 0; + if (js_obj instanceof Int8Array) + arrayType = 11; + if (js_obj instanceof Uint8Array) + arrayType = 12; + if (js_obj instanceof Uint8ClampedArray) + arrayType = 12; + if (js_obj instanceof Int16Array) + arrayType = 13; + if (js_obj instanceof Uint16Array) + arrayType = 14; + if (js_obj instanceof Int32Array) + arrayType = 15; + if (js_obj instanceof Uint32Array) + arrayType = 16; + if (js_obj instanceof Float32Array) + arrayType = 17; + if (js_obj instanceof Float64Array) + arrayType = 18; + + var heapBytes = this.js_typedarray_to_heap(js_obj); + var bufferArray = this.mono_typed_array_new(heapBytes.byteOffset, js_obj.length, js_obj.BYTES_PER_ELEMENT, arrayType); + Module._free(heapBytes.byteOffset); + return bufferArray; + } + else { + throw new Error("Object '" + js_obj + "' is not a typed array"); + } + + + }, + // Copy the existing typed array to the heap pointed to by the pinned array address + // typed array memory -> copy to heap -> address of managed pinned array + typedarray_copy_to : function (typed_array, pinned_array, begin, end, bytes_per_element) { + + // JavaScript typed arrays are array-like objects and provide a mechanism for accessing + // raw binary data. (...) To achieve maximum flexibility and efficiency, JavaScript typed arrays + // split the implementation into buffers and views. A buffer (implemented by the ArrayBuffer object) + // is an object representing a chunk of data; it has no format to speak of, and offers no + // mechanism for accessing its contents. In order to access the memory contained in a buffer, + // you need to use a view. A view provides a context — that is, a data type, starting offset, + // and number of elements — that turns the data into an actual typed array. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays + if (!!(typed_array.buffer instanceof ArrayBuffer && typed_array.BYTES_PER_ELEMENT)) + { + // Some sanity checks of what is being asked of us + // lets play it safe and throw an error here instead of assuming to much. + // Better safe than sorry later + if (bytes_per_element !== typed_array.BYTES_PER_ELEMENT) + throw new Error("Inconsistent element sizes: TypedArray.BYTES_PER_ELEMENT '" + typed_array.BYTES_PER_ELEMENT + "' sizeof managed element: '" + bytes_per_element + "'"); + + // how much space we have to work with + var num_of_bytes = (end - begin) * bytes_per_element; + // how much typed buffer space are we talking about + var view_bytes = typed_array.length * typed_array.BYTES_PER_ELEMENT; + // only use what is needed. + if (num_of_bytes > view_bytes) + num_of_bytes = view_bytes; + + // offset index into the view + var offset = begin * bytes_per_element; + + // Create a view over the heap pointed to by the pinned array address + var heapBytes = new Uint8Array(Module.HEAPU8.buffer, pinned_array + offset, num_of_bytes); + // Copy the bytes of the typed array to the heap. + heapBytes.set(new Uint8Array(typed_array.buffer, typed_array.byteOffset, num_of_bytes)); + + return num_of_bytes; + } + else { + throw new Error("Object '" + typed_array + "' is not a typed array"); + } + + }, + // Copy the pinned array address from pinned_array allocated on the heap to the typed array. + // adress of managed pinned array -> copy from heap -> typed array memory + typedarray_copy_from : function (typed_array, pinned_array, begin, end, bytes_per_element) { + + // JavaScript typed arrays are array-like objects and provide a mechanism for accessing + // raw binary data. (...) To achieve maximum flexibility and efficiency, JavaScript typed arrays + // split the implementation into buffers and views. A buffer (implemented by the ArrayBuffer object) + // is an object representing a chunk of data; it has no format to speak of, and offers no + // mechanism for accessing its contents. In order to access the memory contained in a buffer, + // you need to use a view. A view provides a context — that is, a data type, starting offset, + // and number of elements — that turns the data into an actual typed array. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays + if (!!(typed_array.buffer instanceof ArrayBuffer && typed_array.BYTES_PER_ELEMENT)) + { + // Some sanity checks of what is being asked of us + // lets play it safe and throw an error here instead of assuming to much. + // Better safe than sorry later + if (bytes_per_element !== typed_array.BYTES_PER_ELEMENT) + throw new Error("Inconsistent element sizes: TypedArray.BYTES_PER_ELEMENT '" + typed_array.BYTES_PER_ELEMENT + "' sizeof managed element: '" + bytes_per_element + "'"); + + // how much space we have to work with + var num_of_bytes = (end - begin) * bytes_per_element; + // how much typed buffer space are we talking about + var view_bytes = typed_array.length * typed_array.BYTES_PER_ELEMENT; + // only use what is needed. + if (num_of_bytes > view_bytes) + num_of_bytes = view_bytes; + + // Create a new view for mapping + var typedarrayBytes = new Uint8Array(typed_array.buffer, 0, num_of_bytes); + // offset index into the view + var offset = begin * bytes_per_element; + // Set view bytes to value from HEAPU8 + typedarrayBytes.set(Module.HEAPU8.subarray(pinned_array + offset, pinned_array + offset + num_of_bytes)); + return num_of_bytes; + } + else { + throw new Error("Object '" + typed_array + "' is not a typed array"); + } + + }, + // Creates a new typed array from pinned array address from pinned_array allocated on the heap to the typed array. + // adress of managed pinned array -> copy from heap -> typed array memory + typed_array_from : function (pinned_array, begin, end, bytes_per_element, type) { + + // typed array + var newTypedArray = 0; + + switch (type) + { + case 5: + newTypedArray = new Int8Array(end - begin); + break; + case 6: + newTypedArray = new Uint8Array(end - begin); + break; + case 7: + newTypedArray = new Int16Array(end - begin); + break; + case 8: + newTypedArray = new Uint16Array(end - begin); + break; + case 9: + newTypedArray = new Int32Array(end - begin); + break; + case 10: + newTypedArray = new Uint32Array(end - begin); + break; + case 13: + newTypedArray = new Float32Array(end - begin); + break; + case 14: + newTypedArray = new Float64Array(end - begin); + break; + case 15: // This is a special case because the typed array is also byte[] + newTypedArray = new Uint8ClampedArray(end - begin); + break; + } + + this.typedarray_copy_from(newTypedArray, pinned_array, begin, end, bytes_per_element); + return newTypedArray; + }, + js_to_mono_enum: function (method, parmIdx, js_obj) { + this.bindings_lazy_init (); + + if (js_obj === null || typeof js_obj === "undefined") + return 0; + + var monoObj = this.js_to_mono_obj(js_obj); + // Check enum contract + var monoEnum = this.call_method(this.object_to_enum, null, "iimm", [ method, parmIdx, monoObj ]) + // return the unboxed enum value. + return this.mono_unbox_enum(monoEnum); + }, + wasm_binding_obj_new: function (js_obj_id, type) + { + return this.call_method (this.bind_js_obj, null, "io", [js_obj_id, type]); + }, + wasm_bind_existing: function (mono_obj, js_id) + { + return this.call_method (this.bind_existing_obj, null, "mi", [mono_obj, js_id]); + }, + + wasm_bind_core_clr_obj: function (js_id, gc_handle) + { + return this.call_method (this.bind_core_clr_obj, null, "ii", [js_id, gc_handle]); + }, + + wasm_unbind_js_obj: function (js_obj_id) + { + this.call_method (this.unbind_js_obj, null, "i", [js_obj_id]); + }, + + wasm_unbind_js_obj_and_free: function (js_obj_id) + { + this.call_method (this.unbind_js_obj_and_free, null, "i", [js_obj_id]); + }, + + wasm_get_js_id: function (mono_obj) + { + return this.call_method (this.get_js_id, null, "m", [mono_obj]); + }, + + wasm_get_raw_obj: function (gchandle) + { + return this.call_method (this.get_raw_mono_obj, null, "im", [gchandle]); + }, + + try_extract_mono_obj:function (js_obj) { + if (js_obj === null || typeof js_obj === "undefined" || typeof js_obj.__mono_gchandle__ === "undefined") + return 0; + return this.wasm_get_raw_obj (js_obj.__mono_gchandle__); + }, + + mono_method_get_call_signature: function(method) { + this.bindings_lazy_init (); + + return this.call_method (this.get_call_sig, null, "i", [ method ]); + }, + + get_task_and_bind: function (tcs, js_obj) { + var gc_handle = this.mono_wasm_free_list.length ? this.mono_wasm_free_list.pop() : this.mono_wasm_ref_counter++; + var task_gchandle = this.call_method (this.tcs_get_task_and_bind, null, "oi", [ tcs, gc_handle + 1 ]); + js_obj.__mono_gchandle__ = task_gchandle; + this.mono_wasm_object_registry[gc_handle] = js_obj; + this.free_task_completion_source(tcs); + tcs.is_mono_tcs_task_bound = true; + js_obj.__mono_bound_tcs__ = tcs.__mono_gchandle__; + tcs.__mono_bound_task__ = js_obj.__mono_gchandle__; + return this.wasm_get_raw_obj (js_obj.__mono_gchandle__); + }, + + free_task_completion_source: function (tcs) { + if (tcs.is_mono_tcs_result_set) + { + this.call_method (this.unbind_raw_obj_and_free, null, "ii", [ tcs.__mono_gchandle__ ]); + } + if (tcs.__mono_bound_task__) + { + this.call_method (this.unbind_raw_obj_and_free, null, "ii", [ tcs.__mono_bound_task__ ]); + } + }, + + extract_mono_obj: function (js_obj) { + + if (js_obj === null || typeof js_obj === "undefined") + return 0; + + if (!js_obj.is_mono_bridged_obj) { + var gc_handle = this.mono_wasm_register_obj(js_obj); + return this.wasm_get_raw_obj (gc_handle); + } + + + return this.wasm_get_raw_obj (js_obj.__mono_gchandle__); + }, + + extract_js_obj: function (mono_obj) { + if (mono_obj == 0) + return null; + + var js_id = this.wasm_get_js_id (mono_obj); + if (js_id > 0) + return this.mono_wasm_require_handle(js_id); + + var gcHandle = this.mono_wasm_free_list.length ? this.mono_wasm_free_list.pop() : this.mono_wasm_ref_counter++; + var js_obj = { + __mono_gchandle__: this.wasm_bind_existing(mono_obj, gcHandle + 1), + is_mono_bridged_obj: true + }; + + this.mono_wasm_object_registry[gcHandle] = js_obj; + return js_obj; + }, + + /* + args_marshal is a string with one character per parameter that tells how to marshal it, here are the valid values: + + i: int32 + j: int32 - Enum with underlying type of int32 + l: int64 + k: int64 - Enum with underlying type of int64 + f: float + d: double + s: string + o: js object will be converted to a C# object (this will box numbers/bool/promises) + m: raw mono object. Don't use it unless you know what you're doing + + additionally you can append 'm' to args_marshal beyond `args.length` if you don't want the return value marshaled + */ + call_method: function (method, this_arg, args_marshal, args) { + this.bindings_lazy_init (); + + // Allocate memory for error + var has_args = args !== null && typeof args !== "undefined" && args.length > 0; + var has_args_marshal = args_marshal !== null && typeof args_marshal !== "undefined" && args_marshal.length > 0; + + if (has_args_marshal && (!has_args || args.length > args_marshal.length)) + throw Error("Parameter count mismatch."); + + var args_start = null; + var buffer = null; + var exception_out = null; + + // check if the method signature needs argument mashalling + if (has_args_marshal && has_args) { + var i; + + var converters = this.converters; + if (!converters) { + converters = new Map (); + converters.set ('m', { steps: [{ }], size: 0}); + converters.set ('s', { steps: [{ convert: this.js_string_to_mono_string.bind (this)}], size: 0}); + converters.set ('o', { steps: [{ convert: this.js_to_mono_obj.bind (this)}], size: 0}); + converters.set ('u', { steps: [{ convert: this.js_to_mono_uri.bind (this)}], size: 0}); + converters.set ('k', { steps: [{ convert: this.js_to_mono_enum.bind (this), indirect: 'i64'}], size: 8}); + converters.set ('j', { steps: [{ convert: this.js_to_mono_enum.bind (this), indirect: 'i32'}], size: 8}); + converters.set ('i', { steps: [{ indirect: 'i32'}], size: 8}); + converters.set ('l', { steps: [{ indirect: 'i64'}], size: 8}); + converters.set ('f', { steps: [{ indirect: 'float'}], size: 8}); + converters.set ('d', { steps: [{ indirect: 'double'}], size: 8}); + this.converters = converters; + } + + var converter = converters.get (args_marshal); + if (!converter) { + var steps = []; + var size = 0; + + for (i = 0; i < args_marshal.length; ++i) { + var conv = this.converters.get (args_marshal[i]); + if (!conv) + throw Error ("Unknown parameter type " + type); + + steps.push (conv.steps[0]); + size += conv.size; + } + converter = { steps: steps, size: size }; + converters.set (args_marshal, converter); + } + + // assume at least 8 byte alignment from malloc + buffer = Module._malloc (converter.size + (args.length * 4) + 4); + var indirect_start = buffer; // buffer + buffer % 8 + exception_out = indirect_start + converter.size; + args_start = exception_out + 4; + + var slot = args_start; + var indirect_value = indirect_start; + for (i = 0; i < args.length; ++i) { + var handler = converter.steps[i]; + var obj = handler.convert ? handler.convert (args[i], method, i) : args[i]; + + if (handler.indirect) { + Module.setValue (indirect_value, obj, handler.indirect); + obj = indirect_value; + indirect_value += 8; + } + + Module.setValue (slot, obj, "*"); + slot += 4; + } + } else { + // only marshal the exception + exception_out = buffer = Module._malloc (4); + } + + Module.setValue (exception_out, 0, "*"); + + var res = this.invoke_method (method, this_arg, args_start, exception_out); + var eh_res = Module.getValue (exception_out, "*"); + + Module._free (buffer); + + if (eh_res != 0) { + var msg = this.conv_string (res); + throw new Error (msg); //the convention is that invoke_method ToString () any outgoing exception + } + + if (has_args_marshal && has_args) { + if (args_marshal.length >= args.length && args_marshal [args.length] === "m") + return res; + } + + return this.unbox_mono_obj (res); + }, + + invoke_delegate: function (delegate_obj, js_args) { + this.bindings_lazy_init (); + + if (!this.delegate_dynamic_invoke) { + if (!this.corlib) + this.corlib = this.assembly_load ("mscorlib"); + if (!this.delegate_class) + this.delegate_class = this.find_class (this.corlib, "System", "Delegate"); + if (!this.delegate_class) + { + throw new Error("System.Delegate class can not be resolved."); + } + this.delegate_dynamic_invoke = this.find_method (this.delegate_class, "DynamicInvoke", -1); + } + var mono_args = this.js_array_to_mono_array (js_args); + if (!this.delegate_dynamic_invoke) + throw new Error("System.Delegate.DynamicInvoke method can not be resolved."); + // Note: the single 'm' passed here is causing problems with AOT. Changed to "mo" again. + // This may need more analysis if causes problems again. + return this.call_method (this.delegate_dynamic_invoke, this.extract_mono_obj (delegate_obj), "mo", [ mono_args ]); + }, + + resolve_method_fqn: function (fqn) { + var assembly = fqn.substring(fqn.indexOf ("[") + 1, fqn.indexOf ("]")).trim(); + fqn = fqn.substring (fqn.indexOf ("]") + 1).trim(); + + var methodname = fqn.substring(fqn.indexOf (":") + 1); + fqn = fqn.substring (0, fqn.indexOf (":")).trim (); + + var namespace = ""; + var classname = fqn; + if (fqn.indexOf(".") != -1) { + var idx = fqn.lastIndexOf("."); + namespace = fqn.substring (0, idx); + classname = fqn.substring (idx + 1); + } + + var asm = this.assembly_load (assembly); + if (!asm) + throw new Error ("Could not find assembly: " + assembly); + + var klass = this.find_class(asm, namespace, classname); + if (!klass) + throw new Error ("Could not find class: " + namespace + ":" +classname); + + var method = this.find_method (klass, methodname, -1); + if (!method) + throw new Error ("Could not find method: " + methodname); + return method; + }, + + call_static_method: function (fqn, args, signature) { + this.bindings_lazy_init (); + + var method = this.resolve_method_fqn (fqn); + + if (typeof signature === "undefined") + signature = Module.mono_method_get_call_signature (method); + + return this.call_method (method, null, signature, args); + }, + + bind_static_method: function (fqn, signature) { + this.bindings_lazy_init (); + + var method = this.resolve_method_fqn (fqn); + + if (typeof signature === "undefined") + signature = Module.mono_method_get_call_signature (method); + + return function() { + return BINDING.call_method (method, null, signature, arguments); + }; + }, + bind_assembly_entry_point: function (assembly) { + this.bindings_lazy_init (); + + var asm = this.assembly_load (assembly); + if (!asm) + throw new Error ("Could not find assembly: " + assembly); + + var method = this.assembly_get_entry_point(asm); + if (!method) + throw new Error ("Could not find entry point for assembly: " + assembly); + + if (typeof signature === "undefined") + signature = Module.mono_method_get_call_signature (method); + + return function() { + return BINDING.call_method (method, null, signature, arguments); + }; + }, + call_assembly_entry_point: function (assembly, args, signature) { + this.bindings_lazy_init (); + + var asm = this.assembly_load (assembly); + if (!asm) + throw new Error ("Could not find assembly: " + assembly); + + var method = this.assembly_get_entry_point(asm); + if (!method) + throw new Error ("Could not find entry point for assembly: " + assembly); + + if (typeof signature === "undefined") + signature = Module.mono_method_get_call_signature (method); + + return this.call_method (method, null, signature, args); + }, + wasm_get_core_type: function (obj) + { + return this.call_method (this.get_core_type, null, "so", [ "WebAssembly.Core."+obj.constructor.name ]); + }, + get_wasm_type: function(obj) { + var coreType = obj[Symbol.for("wasm type")]; + if (typeof coreType === "undefined") { + coreType = this.wasm_get_core_type(obj); + if (typeof coreType !== "undefined") { + obj.constructor.prototype[Symbol.for("wasm type")] = coreType; + } + } + return coreType; + }, + // Object wrapping helper functions to handle reference handles that will + // be used in managed code. + mono_wasm_register_obj: function(obj) { + + var gc_handle = undefined; + if (obj !== null && typeof obj !== "undefined") + { + gc_handle = obj.__mono_gchandle__; + + if (typeof gc_handle === "undefined") { + var handle = this.mono_wasm_free_list.length ? + this.mono_wasm_free_list.pop() : this.mono_wasm_ref_counter++; + obj.__mono_jshandle__ = handle; + // Obtain the JS -> C# type mapping. + var wasm_type = this.get_wasm_type(obj); + gc_handle = obj.__mono_gchandle__ = this.wasm_binding_obj_new(handle + 1, wasm_type); + this.mono_wasm_object_registry[handle] = obj; + + } + } + return gc_handle; + }, + mono_wasm_require_handle: function(handle) { + if (handle > 0) + return this.mono_wasm_object_registry[handle - 1]; + return null; + }, + mono_wasm_unregister_obj: function(js_id) { + var obj = this.mono_wasm_object_registry[js_id - 1]; + if (typeof obj !== "undefined" && obj !== null) { + // if this is the global object then do not + // unregister it. + if (typeof ___mono_wasm_global___ !== "undefined" && ___mono_wasm_global___ === obj) + return obj; + + var gc_handle = obj.__mono_gchandle__; + if (typeof gc_handle !== "undefined") { + this.wasm_unbind_js_obj_and_free(js_id); + + obj.__mono_gchandle__ = undefined; + obj.__mono_jshandle__ = undefined; + + this.mono_wasm_object_registry[js_id - 1] = undefined; + this.mono_wasm_free_list.push(js_id - 1); + } + } + return obj; + }, + mono_wasm_free_handle: function(handle) { + this.mono_wasm_unregister_obj(handle); + }, + mono_wasm_free_raw_object: function(js_id) { + var obj = this.mono_wasm_object_registry[js_id - 1]; + if (typeof obj !== "undefined" && obj !== null) { + // if this is the global object then do not + // unregister it. + if (typeof ___mono_wasm_global___ !== "undefined" && ___mono_wasm_global___ === obj) + return obj; + + var gc_handle = obj.__mono_gchandle__; + if (typeof gc_handle !== "undefined") { + + obj.__mono_gchandle__ = undefined; + obj.__mono_jshandle__ = undefined; + + this.mono_wasm_object_registry[js_id - 1] = undefined; + this.mono_wasm_free_list.push(js_id - 1); + } + } + return obj; + }, + mono_wasm_get_global: function() { + function testGlobal(obj) { + obj['___mono_wasm_global___'] = obj; + var success = typeof ___mono_wasm_global___ === 'object' && obj['___mono_wasm_global___'] === obj; + if (!success) { + delete obj['___mono_wasm_global___']; + } + return success; + } + if (typeof ___mono_wasm_global___ === 'object') { + return ___mono_wasm_global___; + } + if (typeof global === 'object' && testGlobal(global)) { + ___mono_wasm_global___ = global; + } else if (typeof window === 'object' && testGlobal(window)) { + ___mono_wasm_global___ = window; + } else if (testGlobal((function(){return Function;})()('return this')())) { + + ___mono_wasm_global___ = (function(){return Function;})()('return this')(); + + } + if (typeof ___mono_wasm_global___ === 'object') { + return ___mono_wasm_global___; + } + throw Error('Unable to get mono wasm global object.'); + }, + + }, + + mono_wasm_invoke_js_with_args: function(js_handle, method_name, args, is_exception) { + BINDING.bindings_lazy_init (); + + var obj = BINDING.get_js_obj (js_handle); + if (!obj) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid JS object handle '" + js_handle + "'"); + } + + var js_name = BINDING.conv_string (method_name); + if (!js_name) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid method name object '" + method_name + "'"); + } + + var js_args = BINDING.mono_array_to_js_array(args); + + var res; + try { + var m = obj [js_name]; + if (typeof m === "undefined") + throw new Error("Method: '" + js_name + "' not found for: '" + Object.prototype.toString.call(obj) + "'"); + var res = m.apply (obj, js_args); + return BINDING.js_to_mono_obj (res); + } catch (e) { + var res = e.toString (); + setValue (is_exception, 1, "i32"); + if (res === null || res === undefined) + res = "unknown exception"; + return BINDING.js_string_to_mono_string (res); + } + }, + mono_wasm_get_object_property: function(js_handle, property_name, is_exception) { + BINDING.bindings_lazy_init (); + + var obj = BINDING.mono_wasm_require_handle (js_handle); + if (!obj) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid JS object handle '" + js_handle + "'"); + } + + var js_name = BINDING.conv_string (property_name); + if (!js_name) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid property name object '" + js_name + "'"); + } + + var res; + try { + var m = obj [js_name]; + if (m === Object(m) && obj.__is_mono_proxied__) + m.__is_mono_proxied__ = true; + + return BINDING.js_to_mono_obj (m); + } catch (e) { + var res = e.toString (); + setValue (is_exception, 1, "i32"); + if (res === null || typeof res === "undefined") + res = "unknown exception"; + return BINDING.js_string_to_mono_string (res); + } + }, + mono_wasm_set_object_property: function (js_handle, property_name, value, createIfNotExist, hasOwnProperty, is_exception) { + + BINDING.bindings_lazy_init (); + + var requireObject = BINDING.mono_wasm_require_handle (js_handle); + if (!requireObject) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid JS object handle '" + js_handle + "'"); + } + + var property = BINDING.conv_string (property_name); + if (!property) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid property name object '" + property_name + "'"); + } + + var result = false; + + var js_value = BINDING.unbox_mono_obj(value); + + if (createIfNotExist) { + requireObject[property] = js_value; + result = true; + } + else { + result = false; + if (!createIfNotExist) + { + if (!requireObject.hasOwnProperty(property)) + return false; + } + if (hasOwnProperty === true) { + if (requireObject.hasOwnProperty(property)) { + requireObject[property] = js_value; + result = true; + } + } + else { + requireObject[property] = js_value; + result = true; + } + + } + return BINDING.call_method (BINDING.box_js_bool, null, "im", [ result ]); + }, + mono_wasm_get_by_index: function(js_handle, property_index, is_exception) { + BINDING.bindings_lazy_init (); + + var obj = BINDING.mono_wasm_require_handle (js_handle); + if (!obj) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid JS object handle '" + js_handle + "'"); + } + + try { + var m = obj [property_index]; + return BINDING.js_to_mono_obj (m); + } catch (e) { + var res = e.toString (); + setValue (is_exception, 1, "i32"); + if (res === null || typeof res === "undefined") + res = "unknown exception"; + return BINDING.js_string_to_mono_string (res); + } + }, + mono_wasm_set_by_index: function(js_handle, property_index, value, is_exception) { + BINDING.bindings_lazy_init (); + + var obj = BINDING.mono_wasm_require_handle (js_handle); + if (!obj) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid JS object handle '" + js_handle + "'"); + } + + var js_value = BINDING.unbox_mono_obj(value); + + try { + obj [property_index] = js_value; + return true; + } catch (e) { + var res = e.toString (); + setValue (is_exception, 1, "i32"); + if (res === null || typeof res === "undefined") + res = "unknown exception"; + return BINDING.js_string_to_mono_string (res); + } + }, + mono_wasm_get_global_object: function(global_name, is_exception) { + BINDING.bindings_lazy_init (); + + var js_name = BINDING.conv_string (global_name); + + var globalObj = undefined; + + if (!js_name) { + globalObj = BINDING.mono_wasm_get_global(); + } + else { + globalObj = BINDING.mono_wasm_get_global()[js_name]; + } + + if (globalObj === null || typeof globalObj === undefined) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Global object '" + js_name + "' not found."); + } + + return BINDING.js_to_mono_obj (globalObj); + }, + mono_wasm_release_handle: function(js_handle, is_exception) { + BINDING.bindings_lazy_init (); + + BINDING.mono_wasm_free_handle(js_handle); + }, + mono_wasm_release_object: function(js_handle, is_exception) { + BINDING.bindings_lazy_init (); + + BINDING.mono_wasm_free_raw_object(js_handle); + }, + mono_wasm_bind_core_object: function(js_handle, gc_handle, is_exception) { + BINDING.bindings_lazy_init (); + + var requireObject = BINDING.mono_wasm_require_handle (js_handle); + if (!requireObject) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid JS object handle '" + js_handle + "'"); + } + + BINDING.wasm_bind_core_clr_obj(js_handle, gc_handle ); + requireObject.__mono_gchandle__ = gc_handle; + return gc_handle; + }, + mono_wasm_bind_host_object: function(js_handle, gc_handle, is_exception) { + BINDING.bindings_lazy_init (); + + var requireObject = BINDING.mono_wasm_require_handle (js_handle); + if (!requireObject) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid JS object handle '" + js_handle + "'"); + } + + BINDING.wasm_bind_core_clr_obj(js_handle, gc_handle ); + requireObject.__mono_gchandle__ = gc_handle; + return gc_handle; + }, + mono_wasm_new: function (core_name, args, is_exception) { + BINDING.bindings_lazy_init (); + + var js_name = BINDING.conv_string (core_name); + + if (!js_name) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Core object '" + js_name + "' not found."); + } + + var coreObj = BINDING.mono_wasm_get_global()[js_name]; + + if (coreObj === null || typeof coreObj === "undefined") { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("JavaScript host object '" + js_name + "' not found."); + } + + var js_args = BINDING.mono_array_to_js_array(args); + + try { + + // This is all experimental !!!!!! + var allocator = function(constructor, js_args) { + // Not sure if we should be checking for anything here + var argsList = new Array(); + argsList[0] = constructor; + if (js_args) + argsList = argsList.concat(js_args); + var obj = new (constructor.bind.apply(constructor, argsList )); + return obj; + }; + + var res = allocator(coreObj, js_args); + var gc_handle = BINDING.mono_wasm_free_list.length ? BINDING.mono_wasm_free_list.pop() : BINDING.mono_wasm_ref_counter++; + BINDING.mono_wasm_object_registry[gc_handle] = res; + return BINDING.js_to_mono_obj (gc_handle + 1); + } catch (e) { + var res = e.toString (); + setValue (is_exception, 1, "i32"); + if (res === null || res === undefined) + res = "Error allocating object."; + return BINDING.js_string_to_mono_string (res); + } + + }, + mono_wasm_new_object: function(object_handle_or_function, args, is_exception) { + BINDING.bindings_lazy_init (); + + if (!object_handle_or_function) { + return BINDING.js_to_mono_obj ({}); + } + else { + + var requireObject; + if (typeof object_handle_or_function === 'function') + requireObject = object_handle_or_function; + else + requireObject = BINDING.mono_wasm_require_handle (object_handle_or_function); + + if (!requireObject) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid JS object handle '" + object_handle_or_function + "'"); + } + + var js_args = BINDING.mono_array_to_js_array(args); + + try { + + // This is all experimental !!!!!! + var allocator = function(constructor, js_args) { + // Not sure if we should be checking for anything here + var argsList = new Array(); + argsList[0] = constructor; + if (js_args) + argsList = argsList.concat(js_args); + var obj = new (constructor.bind.apply(constructor, argsList )); + return obj; + }; + + var res = allocator(requireObject, js_args); + return BINDING.extract_mono_obj (res); + } catch (e) { + var res = e.toString (); + setValue (is_exception, 1, "i32"); + if (res === null || res === undefined) + res = "Error allocating object."; + return BINDING.js_string_to_mono_string (res); + } + } + + }, + mono_wasm_typed_array_to_array: function(js_handle, is_exception) { + BINDING.bindings_lazy_init (); + + var requireObject = BINDING.mono_wasm_require_handle (js_handle); + if (!requireObject) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid JS object handle '" + js_handle + "'"); + } + + return BINDING.js_typed_array_to_array(requireObject); + }, + mono_wasm_typed_array_copy_to: function(js_handle, pinned_array, begin, end, bytes_per_element, is_exception) { + BINDING.bindings_lazy_init (); + + var requireObject = BINDING.mono_wasm_require_handle (js_handle); + if (!requireObject) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid JS object handle '" + js_handle + "'"); + } + + var res = BINDING.typedarray_copy_to(requireObject, pinned_array, begin, end, bytes_per_element); + return BINDING.js_to_mono_obj (res) + }, + mono_wasm_typed_array_from: function(pinned_array, begin, end, bytes_per_element, type, is_exception) { + BINDING.bindings_lazy_init (); + var res = BINDING.typed_array_from(pinned_array, begin, end, bytes_per_element, type); + return BINDING.js_to_mono_obj (res) + }, + mono_wasm_typed_array_copy_from: function(js_handle, pinned_array, begin, end, bytes_per_element, is_exception) { + BINDING.bindings_lazy_init (); + + var requireObject = BINDING.mono_wasm_require_handle (js_handle); + if (!requireObject) { + setValue (is_exception, 1, "i32"); + return BINDING.js_string_to_mono_string ("Invalid JS object handle '" + js_handle + "'"); + } + + var res = BINDING.typedarray_copy_from(requireObject, pinned_array, begin, end, bytes_per_element); + return BINDING.js_to_mono_obj (res) + }, + + +}; + +autoAddDeps(BindingSupportLib, '$BINDING') +mergeInto(LibraryManager.library, BindingSupportLib) diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c new file mode 100644 index 0000000000000..f4700369585f9 --- /dev/null +++ b/src/mono/wasm/runtime/corebindings.c @@ -0,0 +1,179 @@ +// 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. +#include +#include +#include +#include +#include +#include + +#include + +//JS funcs +extern MonoObject* mono_wasm_invoke_js_with_args (int js_handle, MonoString *method, MonoArray *args, int *is_exception); +extern MonoObject* mono_wasm_get_object_property (int js_handle, MonoString *propertyName, int *is_exception); +extern MonoObject* mono_wasm_get_by_index (int js_handle, int property_index, int *is_exception); +extern MonoObject* mono_wasm_set_object_property (int js_handle, MonoString *propertyName, MonoObject *value, int createIfNotExist, int hasOwnProperty, int *is_exception); +extern MonoObject* mono_wasm_set_by_index (int js_handle, int property_index, MonoObject *value, int *is_exception); +extern MonoObject* mono_wasm_get_global_object (MonoString *global_name, int *is_exception); +extern void* mono_wasm_release_handle (int js_handle, int *is_exception); +extern void* mono_wasm_release_object (int js_handle, int *is_exception); +extern MonoObject* mono_wasm_new_object (int js_handle, MonoArray *args, int *is_exception); +extern MonoObject* mono_wasm_new (MonoString *core_name, MonoArray *args, int *is_exception); +extern int mono_wasm_bind_core_object (int js_handle, int gc_handle, int *is_exception); +extern int mono_wasm_bind_host_object (int js_handle, int gc_handle, int *is_exception); +extern MonoObject* mono_wasm_typed_array_to_array (int js_handle, int *is_exception); +extern MonoObject* mono_wasm_typed_array_copy_to (int js_handle, int ptr, int begin, int end, int bytes_per_element, int *is_exception); +extern MonoObject* mono_wasm_typed_array_from (int ptr, int begin, int end, int bytes_per_element, int type, int *is_exception); +extern MonoObject* mono_wasm_typed_array_copy_from (int js_handle, int ptr, int begin, int end, int bytes_per_element, int *is_exception); + +// Compiles a JavaScript function from the function data passed. +// Note: code snippet is not a function definition. Instead it must create and return a function instance. +EM_JS(MonoObject*, compile_function, (int snippet_ptr, int len, int *is_exception), { + try { + var data = MONO.string_decoder.decode (snippet_ptr, snippet_ptr + len); + var wrapper = '(function () { ' + data + ' })'; + var funcFactory = eval(wrapper); + var func = funcFactory(); + if (typeof func !== 'function') { + throw new Error('Code must return an instance of a JavaScript function. ' + + 'Please use `return` statement to return a function.'); + } + setValue (is_exception, 0, "i32"); + return BINDING.js_to_mono_obj (func); + } + catch (e) + { + res = e.toString (); + setValue (is_exception, 1, "i32"); + if (res === null || res === undefined) + res = "unknown exception"; + return BINDING.js_to_mono_obj (res); + } +}); + +static MonoObject* +mono_wasm_compile_function (MonoString *str, int *is_exception) +{ + if (str == NULL) + return NULL; + //char *native_val = mono_string_to_utf8 (str); + mono_unichar2 *native_val = mono_string_chars (str); + int native_len = mono_string_length (str) * 2; + + MonoObject* native_res = compile_function((int)native_val, native_len, is_exception); + mono_free (native_val); + if (native_res == NULL) + return NULL; + return native_res; +} + +void core_initialize_internals () +{ + mono_add_internal_call ("WebAssembly.Runtime::InvokeJSWithArgs", mono_wasm_invoke_js_with_args); + mono_add_internal_call ("WebAssembly.Runtime::GetObjectProperty", mono_wasm_get_object_property); + mono_add_internal_call ("WebAssembly.Runtime::GetByIndex", mono_wasm_get_by_index); + mono_add_internal_call ("WebAssembly.Runtime::SetObjectProperty", mono_wasm_set_object_property); + mono_add_internal_call ("WebAssembly.Runtime::SetByIndex", mono_wasm_set_by_index); + mono_add_internal_call ("WebAssembly.Runtime::GetGlobalObject", mono_wasm_get_global_object); + mono_add_internal_call ("WebAssembly.Runtime::ReleaseHandle", mono_wasm_release_handle); + mono_add_internal_call ("WebAssembly.Runtime::ReleaseObject", mono_wasm_release_object); + mono_add_internal_call ("WebAssembly.Runtime::NewObjectJS", mono_wasm_new_object); + mono_add_internal_call ("WebAssembly.Runtime::BindCoreObject", mono_wasm_bind_core_object); + mono_add_internal_call ("WebAssembly.Runtime::BindHostObject", mono_wasm_bind_host_object); + mono_add_internal_call ("WebAssembly.Runtime::New", mono_wasm_new); + mono_add_internal_call ("WebAssembly.Runtime::TypedArrayToArray", mono_wasm_typed_array_to_array); + mono_add_internal_call ("WebAssembly.Runtime::TypedArrayCopyTo", mono_wasm_typed_array_copy_to); + mono_add_internal_call ("WebAssembly.Runtime::TypedArrayFrom", mono_wasm_typed_array_from); + mono_add_internal_call ("WebAssembly.Runtime::TypedArrayCopyFrom", mono_wasm_typed_array_copy_from); + mono_add_internal_call ("WebAssembly.Runtime::CompileFunction", mono_wasm_compile_function); + +} + +// Int8Array | int8_t | byte or SByte (signed byte) +// Uint8Array | uint8_t | byte or Byte (unsigned byte) +// Uint8ClampedArray| uint8_t | byte or Byte (unsigned byte) +// Int16Array | int16_t | short (signed short) +// Uint16Array | uint16_t | ushort (unsigned short) +// Int32Array | int32_t | int (signed integer) +// Uint32Array | uint32_t | uint (unsigned integer) +// Float32Array | float | float +// Float64Array | double | double +// typed array marshalling +#define MARSHAL_ARRAY_BYTE 11 +#define MARSHAL_ARRAY_UBYTE 12 +#define MARSHAL_ARRAY_SHORT 13 +#define MARSHAL_ARRAY_USHORT 14 +#define MARSHAL_ARRAY_INT 15 +#define MARSHAL_ARRAY_UINT 16 +#define MARSHAL_ARRAY_FLOAT 17 +#define MARSHAL_ARRAY_DOUBLE 18 + +EMSCRIPTEN_KEEPALIVE MonoArray* +mono_wasm_typed_array_new (char *arr, int length, int size, int type) +{ + MonoClass *typeClass = mono_get_byte_class(); // default is Byte + switch (type) { + case MARSHAL_ARRAY_BYTE: + typeClass = mono_get_sbyte_class(); + break; + case MARSHAL_ARRAY_SHORT: + typeClass = mono_get_int16_class(); + break; + case MARSHAL_ARRAY_USHORT: + typeClass = mono_get_uint16_class(); + break; + case MARSHAL_ARRAY_INT: + typeClass = mono_get_int32_class(); + break; + case MARSHAL_ARRAY_UINT: + typeClass = mono_get_uint32_class(); + break; + case MARSHAL_ARRAY_FLOAT: + typeClass = mono_get_single_class(); + break; + case MARSHAL_ARRAY_DOUBLE: + typeClass = mono_get_double_class(); + break; + } + + MonoArray *buffer; + + buffer = mono_array_new (mono_get_root_domain(), typeClass, length); + memcpy(mono_array_addr_with_size(buffer, sizeof(char), 0), arr, length * size); + + return buffer; +} + +EMSCRIPTEN_KEEPALIVE int +mono_wasm_unbox_enum (MonoObject *obj) +{ + if (!obj) + return 0; + + MonoType *type = mono_class_get_type (mono_object_get_class(obj)); + + void *ptr = mono_object_unbox (obj); + switch (mono_type_get_type(mono_type_get_underlying_type (type))) { + case MONO_TYPE_I1: + case MONO_TYPE_U1: + return *(unsigned char*)ptr; + case MONO_TYPE_I2: + return *(short*)ptr; + case MONO_TYPE_U2: + return *(unsigned short*)ptr; + case MONO_TYPE_I4: + return *(int*)ptr; + case MONO_TYPE_U4: + return *(unsigned int*)ptr; + // WASM doesn't support returning longs to JS + // case MONO_TYPE_I8: + // case MONO_TYPE_U8: + default: + printf ("Invalid type %d to mono_unbox_enum\n", mono_type_get_type(mono_type_get_underlying_type (type))); + return 0; + } +} + + diff --git a/src/mono/wasm/runtime/dotnet_support.js b/src/mono/wasm/runtime/dotnet_support.js new file mode 100644 index 0000000000000..e2db502123e4a --- /dev/null +++ b/src/mono/wasm/runtime/dotnet_support.js @@ -0,0 +1,96 @@ +// 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. + +var DotNetSupportLib = { + $DOTNET: { + _dotnet_get_global: function() { + function testGlobal(obj) { + obj['___dotnet_global___'] = obj; + var success = typeof ___dotnet_global___ === 'object' && obj['___dotnet_global___'] === obj; + if (!success) { + delete obj['___dotnet_global___']; + } + return success; + } + if (typeof ___dotnet_global___ === 'object') { + return ___dotnet_global___; + } + if (typeof global === 'object' && testGlobal(global)) { + ___dotnet_global___ = global; + } else if (typeof window === 'object' && testGlobal(window)) { + ___dotnet_global___ = window; + } + if (typeof ___dotnet_global___ === 'object') { + return ___dotnet_global___; + } + throw Error('unable to get DotNet global object.'); + }, + conv_string: function (mono_obj) { + return MONO.string_decoder.copy (mono_obj); + } + }, + mono_wasm_invoke_js_marshalled: function(exceptionMessage, asyncHandleLongPtr, functionName, argsJson) { + + var mono_string = DOTNET._dotnet_get_global()._mono_string_cached + || (DOTNET._dotnet_get_global()._mono_string_cached = Module.cwrap('mono_wasm_string_from_js', 'number', ['string'])); + + try { + // Passing a .NET long into JS via Emscripten is tricky. The method here is to pass + // as pointer to the long, then combine two reads from the HEAPU32 array. + // Even though JS numbers can't represent the full range of a .NET long, it's OK + // because we'll never exceed Number.MAX_SAFE_INTEGER (2^53 - 1) in this case. + //var u32Index = $1 >> 2; + var u32Index = asyncHandleLongPtr >> 2; + var asyncHandleJsNumber = Module.HEAPU32[u32Index + 1]*4294967296 + Module.HEAPU32[u32Index]; + + // var funcNameJsString = UTF8ToString (functionName); + // var argsJsonJsString = argsJson && UTF8ToString (argsJson); + var funcNameJsString = DOTNET.conv_string(functionName); + var argsJsonJsString = argsJson && DOTNET.conv_string (argsJson); + + var dotNetExports = DOTNET._dotnet_get_global().DotNet; + if (!dotNetExports) { + throw new Error('The Microsoft.JSInterop.js library is not loaded.'); + } + + if (asyncHandleJsNumber) { + dotNetExports.jsCallDispatcher.beginInvokeJSFromDotNet(asyncHandleJsNumber, funcNameJsString, argsJsonJsString); + return 0; + } else { + var resultJson = dotNetExports.jsCallDispatcher.invokeJSFromDotNet(funcNameJsString, argsJsonJsString); + return resultJson === null ? 0 : mono_string(resultJson); + } + } catch (ex) { + var exceptionJsString = ex.message + '\n' + ex.stack; + var exceptionSystemString = mono_string(exceptionJsString); + setValue (exceptionMessage, exceptionSystemString, 'i32'); // *exceptionMessage = exceptionSystemString; + return 0; + } + }, + mono_wasm_invoke_js_unmarshalled: function(exceptionMessage, funcName, arg0, arg1, arg2) { + try { + // Get the function you're trying to invoke + var funcNameJsString = DOTNET.conv_string(funcName); + var dotNetExports = DOTNET._dotnet_get_global().DotNet; + if (!dotNetExports) { + throw new Error('The Microsoft.JSInterop.js library is not loaded.'); + } + var funcInstance = dotNetExports.jsCallDispatcher.findJSFunction(funcNameJsString); + + return funcInstance.call(null, arg0, arg1, arg2); + } catch (ex) { + var exceptionJsString = ex.message + '\n' + ex.stack; + var mono_string = Module.cwrap('mono_wasm_string_from_js', 'number', ['string']); // TODO: Cache + var exceptionSystemString = mono_string(exceptionJsString); + setValue (exceptionMessage, exceptionSystemString, 'i32'); // *exceptionMessage = exceptionSystemString; + return 0; + } + } + + +}; + +autoAddDeps(DotNetSupportLib, '$DOTNET') +mergeInto(LibraryManager.library, DotNetSupportLib) + diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c new file mode 100644 index 0000000000000..c55ecba5a4c87 --- /dev/null +++ b/src/mono/wasm/runtime/driver.c @@ -0,0 +1,759 @@ +// 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. +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pinvoke-table.h" + +#ifdef CORE_BINDINGS +void core_initialize_internals (); +#endif + +// Blazor specific custom routines - see dotnet_support.js for backing code +extern void* mono_wasm_invoke_js_marshalled (MonoString **exceptionMessage, void *asyncHandleLongPtr, MonoString *funcName, MonoString *argsJson); +extern void* mono_wasm_invoke_js_unmarshalled (MonoString **exceptionMessage, MonoString *funcName, void* arg0, void* arg1, void* arg2); + +void mono_wasm_enable_debugging (int); + +void mono_ee_interp_init (const char *opts); +void mono_marshal_ilgen_init (void); +void mono_method_builder_ilgen_init (void); +void mono_sgen_mono_ilgen_init (void); +void mono_icall_table_init (void); +void mono_aot_register_module (void **aot_info); +char *monoeg_g_getenv(const char *variable); +int monoeg_g_setenv(const char *variable, const char *value, int overwrite); +void mono_free (void*); +int32_t mini_parse_debug_option (const char *option); + +static MonoClass* datetime_class; +static MonoClass* datetimeoffset_class; +static MonoClass* uri_class; + +int mono_wasm_enable_gc; + +/* Not part of public headers */ +#define MONO_ICALL_TABLE_CALLBACKS_VERSION 2 + +typedef struct { + int version; + void* (*lookup) (MonoMethod *method, char *classname, char *methodname, char *sigstart, int32_t *uses_handles); + const char* (*lookup_icall_symbol) (void* func); +} MonoIcallTableCallbacks; + +void +mono_install_icall_table_callbacks (const MonoIcallTableCallbacks *cb); + +int mono_regression_test_step (int verbose_level, char *image, char *method_name); +void mono_trace_init (void); + +#define g_new(type, size) ((type *) malloc (sizeof (type) * (size))) +#define g_new0(type, size) ((type *) calloc (sizeof (type), (size))) + +static MonoDomain *root_domain; + +static MonoString* +mono_wasm_invoke_js (MonoString *str, int *is_exception) +{ + if (str == NULL) + return NULL; + + mono_unichar2 *native_val = mono_string_chars (str); + int native_len = mono_string_length (str) * 2; + + mono_unichar2 *native_res = (mono_unichar2*)EM_ASM_INT ({ + var str = MONO.string_decoder.decode ($0, $0 + $1); + try { + var res = eval (str); + if (res === null || res == undefined) + return 0; + res = res.toString (); + setValue ($2, 0, "i32"); + } catch (e) { + res = e.toString (); + setValue ($2, 1, "i32"); + if (res === null || res === undefined) + res = "unknown exception"; + } + var buff = Module._malloc((res.length + 1) * 2); + stringToUTF16 (res, buff, (res.length + 1) * 2); + return buff; + }, (int)native_val, native_len, is_exception); + + if (native_res == NULL) + return NULL; + + MonoString *res = mono_string_from_utf16 (native_res); + free (native_res); + return res; +} + +static void +wasm_logger (const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data) +{ + if (fatal) { + EM_ASM( + var err = new Error(); + console.log ("Stacktrace: \n"); + console.log (err.stack); + ); + + fprintf (stderr, "%s\n", message); + fflush (stderr); + + abort (); + } else { + fprintf (stdout, "L: %s\n", message); + } +} + +#ifdef DRIVER_GEN +#include "driver-gen.c" +#endif + +typedef struct WasmAssembly_ WasmAssembly; + +struct WasmAssembly_ { + MonoBundledAssembly assembly; + WasmAssembly *next; +}; + +static WasmAssembly *assemblies; +static int assembly_count; + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_add_assembly (const char *name, const unsigned char *data, unsigned int size) +{ + int len = strlen (name); + if (!strcasecmp (".pdb", &name [len - 4])) { + char *new_name = strdup (name); + //FIXME handle debugging assemblies with .exe extension + strcpy (&new_name [len - 3], "dll"); + mono_register_symfile_for_assembly (new_name, data, size); + return; + } + WasmAssembly *entry = g_new0 (WasmAssembly, 1); + entry->assembly.name = strdup (name); + entry->assembly.data = data; + entry->assembly.size = size; + entry->next = assemblies; + assemblies = entry; + ++assembly_count; +} + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_setenv (const char *name, const char *value) +{ + monoeg_g_setenv (strdup (name), strdup (value), 1); +} + +#ifdef ENABLE_NETCORE +static void *sysglobal_native_handle; +#endif + +static void* +wasm_dl_load (const char *name, int flags, char **err, void *user_data) +{ + for (int i = 0; i < sizeof (pinvoke_tables) / sizeof (void*); ++i) { + if (!strcmp (name, pinvoke_names [i])) + return pinvoke_tables [i]; + } + +#ifdef ENABLE_NETCORE + if (!strcmp (name, "System.Globalization.Native")) + return sysglobal_native_handle; +#endif + +#if WASM_SUPPORTS_DLOPEN + return dlopen(name, flags); +#endif + + return NULL; +} + +static mono_bool +wasm_dl_is_pinvoke_tables (void* handle) +{ + for (int i = 0; i < sizeof (pinvoke_tables) / sizeof (void*); ++i) { + if (pinvoke_tables [i] == handle) { + return 1; + } + } + return 0; +} + +static void* +wasm_dl_symbol (void *handle, const char *name, char **err, void *user_data) +{ +#ifdef ENABLE_NETCORE + if (handle == sysglobal_native_handle) + assert (0); +#endif + +#if WASM_SUPPORTS_DLOPEN + if (!wasm_dl_is_pinvoke_tables (handle)) { + return dlsym (handle, name); + } +#endif + + PinvokeImport *table = (PinvokeImport*)handle; + for (int i = 0; table [i].name; ++i) { + if (!strcmp (table [i].name, name)) + return table [i].func; + } + return NULL; +} + +#ifdef ENABLE_NETCORE +/* Missing System.Native symbols */ +int SystemNative_CloseNetworkChangeListenerSocket (int a) { return 0; } +int SystemNative_CreateNetworkChangeListenerSocket (int a) { return 0; } +void SystemNative_ReadEvents (int a,int b) {} +int SystemNative_SchedGetAffinity (int a,int b) { return 0; } +int SystemNative_SchedSetAffinity (int a,int b) { return 0; } +#endif + +#if !defined(ENABLE_AOT) || defined(EE_MODE_LLVMONLY_INTERP) +#define NEED_INTERP 1 +#ifndef LINK_ICALLS +// FIXME: llvm+interp mode needs this to call icalls +#define NEED_NORMAL_ICALL_TABLES 1 +#endif +#endif + +#ifdef LINK_ICALLS + +#include "icall-table.h" + +static int +compare_int (const void *k1, const void *k2) +{ + return *(int*)k1 - *(int*)k2; +} + +static void* +icall_table_lookup (MonoMethod *method, char *classname, char *methodname, char *sigstart, int32_t *uses_handles) +{ + uint32_t token = mono_method_get_token (method); + assert (token); + assert ((token & MONO_TOKEN_METHOD_DEF) == MONO_TOKEN_METHOD_DEF); + uint32_t token_idx = token - MONO_TOKEN_METHOD_DEF; + + int *indexes = NULL; + int indexes_size = 0; + uint8_t *handles = NULL; + void **funcs = NULL; + + *uses_handles = 0; + + const char *image_name = mono_image_get_name (mono_class_get_image (mono_method_get_class (method))); + +#ifdef ICALL_TABLE_mscorlib + if (!strcmp (image_name, "mscorlib") || !strcmp (image_name, "System.Private.CoreLib")) { + indexes = mscorlib_icall_indexes; + indexes_size = sizeof (mscorlib_icall_indexes) / 4; + handles = mscorlib_icall_handles; + funcs = mscorlib_icall_funcs; + assert (sizeof (mscorlib_icall_indexes [0]) == 4); + } +#ifdef ICALL_TABLE_System + if (!strcmp (image_name, "System")) { + indexes = System_icall_indexes; + indexes_size = sizeof (System_icall_indexes) / 4; + handles = System_icall_handles; + funcs = System_icall_funcs; + } +#endif + assert (indexes); + + void *p = bsearch (&token_idx, indexes, indexes_size, 4, compare_int); + if (!p) { + return NULL; + printf ("wasm: Unable to lookup icall: %s\n", mono_method_get_name (method)); + exit (1); + } + + uint32_t idx = (int*)p - indexes; + *uses_handles = handles [idx]; + + //printf ("ICALL: %s %x %d %d\n", methodname, token, idx, (int)(funcs [idx])); + + return funcs [idx]; +#endif +} + +static const char* +icall_table_lookup_symbol (void *func) +{ + assert (0); + return NULL; +} + +#endif + +void mono_initialize_internals () +{ + mono_add_internal_call ("WebAssembly.Runtime::InvokeJS", mono_wasm_invoke_js); + // TODO: what happens when two types in different assemblies have the same FQN? + + // Blazor specific custom routines - see dotnet_support.js for backing code + mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJSMarshalled", mono_wasm_invoke_js_marshalled); + mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJSUnmarshalled", mono_wasm_invoke_js_unmarshalled); + +#ifdef CORE_BINDINGS + core_initialize_internals(); +#endif + +} + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_load_runtime (const char *managed_path, int enable_debugging) +{ + const char *interp_opts = ""; + + monoeg_g_setenv ("MONO_LOG_LEVEL", "debug", 0); + monoeg_g_setenv ("MONO_LOG_MASK", "gc", 0); +#ifdef ENABLE_NETCORE + monoeg_g_setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1", 0); +#endif + + mini_parse_debug_option ("top-runtime-invoke-unhandled"); + + mono_dl_fallback_register (wasm_dl_load, wasm_dl_symbol, NULL, NULL); + +#ifdef ENABLE_AOT + // Defined in driver-gen.c + register_aot_modules (); +#ifdef EE_MODE_LLVMONLY_INTERP + mono_jit_set_aot_mode (MONO_AOT_MODE_LLVMONLY_INTERP); +#else + mono_jit_set_aot_mode (MONO_AOT_MODE_LLVMONLY); +#endif +#else + mono_jit_set_aot_mode (MONO_AOT_MODE_INTERP_LLVMONLY); + if (enable_debugging) { + // Disable optimizations which interfere with debugging + interp_opts = "-all"; + mono_wasm_enable_debugging (enable_debugging); + } +#endif + +#ifdef LINK_ICALLS + /* Link in our own linked icall table */ + static const MonoIcallTableCallbacks mono_icall_table_callbacks = + { + MONO_ICALL_TABLE_CALLBACKS_VERSION, + icall_table_lookup, + icall_table_lookup_symbol + }; + mono_install_icall_table_callbacks (&mono_icall_table_callbacks); +#endif + +#ifdef NEED_NORMAL_ICALL_TABLES + mono_icall_table_init (); +#endif +#ifdef NEED_INTERP + mono_ee_interp_init (interp_opts); + mono_marshal_ilgen_init (); + mono_method_builder_ilgen_init (); + mono_sgen_mono_ilgen_init (); +#endif + + if (assembly_count) { + MonoBundledAssembly **bundle_array = g_new0 (MonoBundledAssembly*, assembly_count + 1); + WasmAssembly *cur = assemblies; + int i = 0; + while (cur) { + bundle_array [i] = &cur->assembly; + cur = cur->next; + ++i; + } + mono_register_bundled_assemblies ((const MonoBundledAssembly **)bundle_array); + } + + mono_trace_init (); + mono_trace_set_log_handler (wasm_logger, NULL); + root_domain = mono_jit_init_version ("mono", "v4.0.30319"); + + mono_initialize_internals(); + + mono_thread_set_main (mono_thread_current ()); +} + +EMSCRIPTEN_KEEPALIVE MonoAssembly* +mono_wasm_assembly_load (const char *name) +{ + MonoImageOpenStatus status; + MonoAssemblyName* aname = mono_assembly_name_new (name); + if (!name) + return NULL; + + MonoAssembly *res = mono_assembly_load (aname, NULL, &status); + mono_assembly_name_free (aname); + + return res; +} + +EMSCRIPTEN_KEEPALIVE MonoClass* +mono_wasm_assembly_find_class (MonoAssembly *assembly, const char *namespace, const char *name) +{ + return mono_class_from_name (mono_assembly_get_image (assembly), namespace, name); +} + +EMSCRIPTEN_KEEPALIVE MonoMethod* +mono_wasm_assembly_find_method (MonoClass *klass, const char *name, int arguments) +{ + return mono_class_get_method_from_name (klass, name, arguments); +} + +EMSCRIPTEN_KEEPALIVE MonoObject* +mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[], MonoObject **out_exc) +{ + MonoObject *exc = NULL; + MonoObject *res; + + if (out_exc) + *out_exc = NULL; + res = mono_runtime_invoke (method, this_arg, params, &exc); + if (exc) { + if (out_exc) + *out_exc = exc; + + MonoObject *exc2 = NULL; + res = (MonoObject*)mono_object_to_string (exc, &exc2); + if (exc2) + res = (MonoObject*) mono_string_new (root_domain, "Exception Double Fault"); + return res; + } + + MonoMethodSignature *sig = mono_method_signature (method); + MonoType *type = mono_signature_get_return_type (sig); + // If the method return type is void return null + // This gets around a memory access crash when the result return a value when + // a void method is invoked. + if (mono_type_get_type (type) == MONO_TYPE_VOID) + return NULL; + + return res; +} + +EMSCRIPTEN_KEEPALIVE MonoMethod* +mono_wasm_assembly_get_entry_point (MonoAssembly *assembly) +{ + MonoImage *image; + MonoMethod *method; + + image = mono_assembly_get_image (assembly); + uint32_t entry = mono_image_get_entry_point (image); + if (!entry) + return NULL; + + return mono_get_method (image, entry, NULL); +} + +EMSCRIPTEN_KEEPALIVE char * +mono_wasm_string_get_utf8 (MonoString *str) +{ + return mono_string_to_utf8 (str); //XXX JS is responsible for freeing this +} + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_string_convert (MonoString *str) +{ + if (str == NULL) + return; + + mono_unichar2 *native_val = mono_string_chars (str); + int native_len = mono_string_length (str) * 2; + + EM_ASM ({ + MONO.string_decoder.decode($0, $0 + $1, true); + }, (int)native_val, native_len); +} + +EMSCRIPTEN_KEEPALIVE MonoString * +mono_wasm_string_from_js (const char *str) +{ + if (str) + return mono_string_new (root_domain, str); + else + return NULL; +} + +static int +class_is_task (MonoClass *klass) +{ + if (!strcmp ("System.Threading.Tasks", mono_class_get_namespace (klass)) && + (!strcmp ("Task", mono_class_get_name (klass)) || !strcmp ("Task`1", mono_class_get_name (klass)))) + return 1; + + return 0; +} + +MonoClass* mono_get_uri_class(MonoException** exc) +{ + MonoAssembly* assembly = mono_wasm_assembly_load ("System"); + if (!assembly) + return NULL; + MonoClass* klass = mono_wasm_assembly_find_class(assembly, "System", "Uri"); + return klass; +} + +#define MARSHAL_TYPE_INT 1 +#define MARSHAL_TYPE_FP 2 +#define MARSHAL_TYPE_STRING 3 +#define MARSHAL_TYPE_VT 4 +#define MARSHAL_TYPE_DELEGATE 5 +#define MARSHAL_TYPE_TASK 6 +#define MARSHAL_TYPE_OBJECT 7 +#define MARSHAL_TYPE_BOOL 8 +#define MARSHAL_TYPE_ENUM 9 +#define MARSHAL_TYPE_DATE 20 +#define MARSHAL_TYPE_DATEOFFSET 21 +#define MARSHAL_TYPE_URI 22 + +// typed array marshalling +#define MARSHAL_ARRAY_BYTE 11 +#define MARSHAL_ARRAY_UBYTE 12 +#define MARSHAL_ARRAY_SHORT 13 +#define MARSHAL_ARRAY_USHORT 14 +#define MARSHAL_ARRAY_INT 15 +#define MARSHAL_ARRAY_UINT 16 +#define MARSHAL_ARRAY_FLOAT 17 +#define MARSHAL_ARRAY_DOUBLE 18 + +EMSCRIPTEN_KEEPALIVE int +mono_wasm_get_obj_type (MonoObject *obj) +{ + if (!obj) + return 0; + + if (!datetime_class) + datetime_class = mono_class_from_name (mono_get_corlib(), "System", "DateTime"); + if (!datetimeoffset_class) + datetimeoffset_class = mono_class_from_name (mono_get_corlib(), "System", "DateTimeOffset"); + if (!uri_class) { + MonoException** exc = NULL; + uri_class = mono_get_uri_class(exc); + } + + MonoClass *klass = mono_object_get_class (obj); + MonoType *type = mono_class_get_type (klass); + + switch (mono_type_get_type (type)) { + // case MONO_TYPE_CHAR: prob should be done not as a number? + case MONO_TYPE_BOOLEAN: + return MARSHAL_TYPE_BOOL; + case MONO_TYPE_I1: + case MONO_TYPE_U1: + case MONO_TYPE_I2: + case MONO_TYPE_U2: + case MONO_TYPE_I4: + case MONO_TYPE_U4: + case MONO_TYPE_I8: + case MONO_TYPE_U8: + case MONO_TYPE_I: // IntPtr + return MARSHAL_TYPE_INT; + case MONO_TYPE_R4: + case MONO_TYPE_R8: + return MARSHAL_TYPE_FP; + case MONO_TYPE_STRING: + return MARSHAL_TYPE_STRING; + case MONO_TYPE_SZARRAY: { // simple zero based one-dim-array + MonoClass *eklass = mono_class_get_element_class(klass); + MonoType *etype = mono_class_get_type (eklass); + + switch (mono_type_get_type (etype)) { + case MONO_TYPE_U1: + return MARSHAL_ARRAY_UBYTE; + case MONO_TYPE_I1: + return MARSHAL_ARRAY_BYTE; + case MONO_TYPE_U2: + return MARSHAL_ARRAY_USHORT; + case MONO_TYPE_I2: + return MARSHAL_ARRAY_SHORT; + case MONO_TYPE_U4: + return MARSHAL_ARRAY_UINT; + case MONO_TYPE_I4: + return MARSHAL_ARRAY_INT; + case MONO_TYPE_R4: + return MARSHAL_ARRAY_FLOAT; + case MONO_TYPE_R8: + return MARSHAL_ARRAY_DOUBLE; + default: + return MARSHAL_TYPE_OBJECT; + } + } + default: + if (klass == datetime_class) + return MARSHAL_TYPE_DATE; + if (klass == datetimeoffset_class) + return MARSHAL_TYPE_DATEOFFSET; + if (uri_class && mono_class_is_assignable_from(uri_class, klass)) + return MARSHAL_TYPE_URI; + if (mono_class_is_enum (klass)) + return MARSHAL_TYPE_ENUM; + if (!mono_type_is_reference (type)) //vt + return MARSHAL_TYPE_VT; + if (mono_class_is_delegate (klass)) + return MARSHAL_TYPE_DELEGATE; + if (class_is_task(klass)) + return MARSHAL_TYPE_TASK; + + return MARSHAL_TYPE_OBJECT; + } +} + +EMSCRIPTEN_KEEPALIVE int +mono_unbox_int (MonoObject *obj) +{ + if (!obj) + return 0; + MonoType *type = mono_class_get_type (mono_object_get_class(obj)); + + void *ptr = mono_object_unbox (obj); + switch (mono_type_get_type (type)) { + case MONO_TYPE_I1: + case MONO_TYPE_BOOLEAN: + return *(signed char*)ptr; + case MONO_TYPE_U1: + return *(unsigned char*)ptr; + case MONO_TYPE_I2: + return *(short*)ptr; + case MONO_TYPE_U2: + return *(unsigned short*)ptr; + case MONO_TYPE_I4: + case MONO_TYPE_I: + return *(int*)ptr; + case MONO_TYPE_U4: + return *(unsigned int*)ptr; + // WASM doesn't support returning longs to JS + // case MONO_TYPE_I8: + // case MONO_TYPE_U8: + default: + printf ("Invalid type %d to mono_unbox_int\n", mono_type_get_type (type)); + return 0; + } +} + +EMSCRIPTEN_KEEPALIVE double +mono_wasm_unbox_float (MonoObject *obj) +{ + if (!obj) + return 0; + MonoType *type = mono_class_get_type (mono_object_get_class(obj)); + + void *ptr = mono_object_unbox (obj); + switch (mono_type_get_type (type)) { + case MONO_TYPE_R4: + return *(float*)ptr; + case MONO_TYPE_R8: + return *(double*)ptr; + default: + printf ("Invalid type %d to mono_wasm_unbox_float\n", mono_type_get_type (type)); + return 0; + } +} + +EMSCRIPTEN_KEEPALIVE int +mono_wasm_array_length (MonoArray *array) +{ + return mono_array_length (array); +} + +EMSCRIPTEN_KEEPALIVE MonoObject* +mono_wasm_array_get (MonoArray *array, int idx) +{ + return mono_array_get (array, MonoObject*, idx); +} + +EMSCRIPTEN_KEEPALIVE MonoArray* +mono_wasm_obj_array_new (int size) +{ + return mono_array_new (root_domain, mono_get_object_class (), size); +} + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_obj_array_set (MonoArray *array, int idx, MonoObject *obj) +{ + mono_array_setref (array, idx, obj); +} + +EMSCRIPTEN_KEEPALIVE MonoArray* +mono_wasm_string_array_new (int size) +{ + return mono_array_new (root_domain, mono_get_string_class (), size); +} + +EMSCRIPTEN_KEEPALIVE int +mono_wasm_exec_regression (int verbose_level, char *image) +{ + return mono_regression_test_step (verbose_level, image, NULL) ? 0 : 1; +} + +EMSCRIPTEN_KEEPALIVE int +mono_wasm_exit (int exit_code) +{ + exit (exit_code); +} + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_set_main_args (int argc, char* argv[]) +{ + mono_runtime_set_main_args (argc, argv); +} + +EMSCRIPTEN_KEEPALIVE int +mono_wasm_strdup (const char *s) +{ + return (int)strdup (s); +} + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_parse_runtime_options (int argc, char* argv[]) +{ + mono_jit_parse_options (argc, argv); +} + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_enable_on_demand_gc (void) +{ + mono_wasm_enable_gc = 1; +} + +// Returns the local timezone default is UTC. +EM_JS(size_t, mono_wasm_timezone_get_local_name, (), +{ + var res = "UTC"; + try { + res = Intl.DateTimeFormat().resolvedOptions().timeZone; + } catch(e) {} + + var buff = Module._malloc((res.length + 1) * 2); + stringToUTF16 (res, buff, (res.length + 1) * 2); + return buff; +}) + +void +mono_timezone_get_local_name (MonoString **result) +{ + // WASM returns back an int pointer to a string UTF16 buffer. + // We then cast to `mono_unichar2*`. Returning `mono_unichar2*` from the JavaScript call will + // result in cast warnings from the compiler. + mono_unichar2 *tzd_local_name = (mono_unichar2*)mono_wasm_timezone_get_local_name (); + *result = mono_string_from_utf16 (tzd_local_name); + free (tzd_local_name); +} diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js new file mode 100644 index 0000000000000..61e6234949d50 --- /dev/null +++ b/src/mono/wasm/runtime/library_mono.js @@ -0,0 +1,1000 @@ +// 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. + +var MonoSupportLib = { + $MONO__postset: 'MONO.export_functions (Module);', + $MONO: { + pump_count: 0, + timeout_queue: [], + _vt_stack: [], + mono_wasm_runtime_is_ready : false, + mono_wasm_ignore_pdb_load_errors: true, + pump_message: function () { + if (!this.mono_background_exec) + this.mono_background_exec = Module.cwrap ("mono_background_exec", null); + while (MONO.timeout_queue.length > 0) { + --MONO.pump_count; + MONO.timeout_queue.shift()(); + } + while (MONO.pump_count > 0) { + --MONO.pump_count; + this.mono_background_exec (); + } + }, + + export_functions: function (module) { + module ["pump_message"] = MONO.pump_message; + module ["mono_load_runtime_and_bcl"] = MONO.mono_load_runtime_and_bcl; + }, + + mono_text_decoder: undefined, + string_decoder: { + copy: function (mono_string) { + if (mono_string == 0) + return null; + + if (!this.mono_wasm_string_convert) + this.mono_wasm_string_convert = Module.cwrap ("mono_wasm_string_convert", null, ['number']); + + this.mono_wasm_string_convert (mono_string); + var result = this.result; + this.result = undefined; + return result; + }, + decode: function (start, end, save) { + if (!MONO.mono_text_decoder) { + MONO.mono_text_decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : undefined; + } + + var str = ""; + if (MONO.mono_text_decoder) { + // When threading is enabled, TextDecoder does not accept a view of a + // SharedArrayBuffer, we must make a copy of the array first. + var subArray = typeof SharedArrayBuffer !== 'undefined' && Module.HEAPU8.buffer instanceof SharedArrayBuffer + ? Module.HEAPU8.slice(start, end) + : Module.HEAPU8.subarray(start, end); + + str = MONO.mono_text_decoder.decode(subArray); + } else { + for (var i = 0; i < end - start; i+=2) { + var char = Module.getValue (start + i, 'i16'); + str += String.fromCharCode (char); + } + } + if (save) + this.result = str; + + return str; + }, + }, + + mono_wasm_get_call_stack: function() { + if (!this.mono_wasm_current_bp_id) + this.mono_wasm_current_bp_id = Module.cwrap ("mono_wasm_current_bp_id", 'number'); + if (!this.mono_wasm_enum_frames) + this.mono_wasm_enum_frames = Module.cwrap ("mono_wasm_enum_frames", null); + + var bp_id = this.mono_wasm_current_bp_id (); + this.active_frames = []; + this.mono_wasm_enum_frames (); + + var the_frames = this.active_frames; + this.active_frames = []; + return { + "breakpoint_id": bp_id, + "frames": the_frames, + }; + }, + + _fixup_name_value_objects: function (var_list) { + var out_list = []; + + var _fixup_value = function (value) { + if (value != null && value != undefined) { + var descr = value.description; + if (descr == null || descr == undefined) + value.description = '' + value.value; + } + return value; + }; + + var i = 0; + while (i < var_list.length) { + var o = var_list [i]; + var name = o.name; + if (name == null || name == undefined) { + i ++; + o.value = _fixup_value(o.value); + out_list.push (o); + continue; + } + + if (i + 1 < var_list.length) + o.value = _fixup_value(var_list[i + 1].value); + + out_list.push (o); + i += 2; + } + + return out_list; + }, + + _filter_automatic_properties: function (props) { + var names_found = {}; + var final_var_list = []; + + for (var i in props) { + var p = props [i]; + if (p.name in names_found) + continue; + + if (p.name.endsWith ("k__BackingField")) + p.name = p.name.replace ("k__BackingField", "") + .replace ('<', '') + .replace ('>', ''); + + names_found [p.name] = p.name; + final_var_list.push (p); + } + + return final_var_list; + }, + + mono_wasm_get_variables: function(scope, var_list) { + if (!this.mono_wasm_get_var_info) + this.mono_wasm_get_var_info = Module.cwrap ("mono_wasm_get_var_info", null, [ 'number', 'number', 'number']); + + this.var_info = []; + var numBytes = var_list.length * Int32Array.BYTES_PER_ELEMENT; + var ptr = Module._malloc(numBytes); + var heapBytes = new Int32Array(Module.HEAP32.buffer, ptr, numBytes); + for (let i=0; i') > 0) + res [i].name = name.substring (1, name.indexOf ('>')); + } + + if (this._async_method_objectId != 0) { + for (let i in res) { + if (res [i].value.isValueType != undefined && res [i].value.isValueType) + res [i].value.objectId = `dotnet:valuetype:${this._async_method_objectId}:${res [i].fieldOffset}`; + } + } + + this._post_process_details(res); + this.var_info = [] + + return res; + }, + + mono_wasm_get_object_properties: function(objId, expandValueTypes) { + if (!this.mono_wasm_get_object_properties_info) + this.mono_wasm_get_object_properties_info = Module.cwrap ("mono_wasm_get_object_properties", null, [ 'number', 'bool' ]); + + this.var_info = []; + this.mono_wasm_get_object_properties_info (objId, expandValueTypes); + + var res = MONO._filter_automatic_properties (MONO._fixup_name_value_objects (this.var_info)); + for (var i = 0; i < res.length; i++) { + if (res [i].value.isValueType != undefined && res [i].value.isValueType) + res [i].value.objectId = `dotnet:valuetype:${objId}:${res [i].fieldOffset}`; + } + + this.var_info = []; + + return res; + }, + + mono_wasm_get_array_values: function(objId) { + if (!this.mono_wasm_get_array_values_info) + this.mono_wasm_get_array_values_info = Module.cwrap ("mono_wasm_get_array_values", null, [ 'number' ]); + + this.var_info = []; + this.mono_wasm_get_array_values_info (objId); + + var res = MONO._fixup_name_value_objects (this.var_info); + for (var i = 0; i < res.length; i++) { + if (res [i].value.isValueType != undefined && res [i].value.isValueType) + res [i].value.objectId = `dotnet:array:${objId}:${i}`; + } + + this.var_info = []; + + return res; + }, + + mono_wasm_get_array_value_expanded: function(objId, idx) { + if (!this.mono_wasm_get_array_value_expanded_info) + this.mono_wasm_get_array_value_expanded_info = Module.cwrap ("mono_wasm_get_array_value_expanded", null, [ 'number', 'number' ]); + + this.var_info = []; + this.mono_wasm_get_array_value_expanded_info (objId, idx); + + var res = MONO._fixup_name_value_objects (this.var_info); + // length should be exactly one! + if (res [0].value.isValueType != undefined && res [0].value.isValueType) + res [0].value.objectId = `dotnet:array:${objId}:${idx}`; + + this.var_info = []; + + return res; + }, + + _post_process_details: function (details) { + if (details == undefined) + return {}; + + if (details.length > 0) + this._extract_and_cache_value_types(details); + + return details; + }, + + _next_value_type_id: function () { + return ++this._next_value_type_id_var; + }, + + _extract_and_cache_value_types: function (var_list) { + if (var_list == undefined || !Array.isArray (var_list) || var_list.length == 0) + return var_list; + + for (let i in var_list) { + var value = var_list [i].value; + if (value == undefined || value.type != "object") + continue; + + if (value.isValueType != true || value.expanded != true) // undefined would also give us false + continue; + + var objectId = value.objectId; + if (objectId == undefined) + objectId = `dotnet:valuetype:${this._next_value_type_id ()}`; + value.objectId = objectId; + + this._extract_and_cache_value_types (value.members); + + this._value_types_cache [objectId] = value.members; + delete value.members; + } + + return var_list; + }, + + _get_details_for_value_type: function (objectId, fetchDetailsFn) { + if (objectId in this._value_types_cache) + return this._value_types_cache[objectId]; + + this._post_process_details (fetchDetailsFn()); + if (objectId in this._value_types_cache) + return this._value_types_cache[objectId]; + + // return error + throw new Error (`Could not get details for ${objectId}`); + }, + + _is_object_id_array: function (objectId) { + // Keep this in sync with `_get_array_details` + return (objectId.startsWith ('dotnet:array:') && objectId.split (':').length == 3); + }, + + _get_array_details: function (objectId, objectIdParts) { + // Keep this in sync with `_is_object_id_array` + switch (objectIdParts.length) { + case 3: + return this._post_process_details (this.mono_wasm_get_array_values(objectIdParts[2])); + + case 4: + var arrayObjectId = objectIdParts[2]; + var arrayIdx = objectIdParts[3]; + return this._get_details_for_value_type( + objectId, () => this.mono_wasm_get_array_value_expanded(arrayObjectId, arrayIdx)); + + default: + throw new Error (`object id format not supported : ${objectId}`); + } + }, + + mono_wasm_get_details: function (objectId, args) { + var parts = objectId.split(":"); + if (parts[0] != "dotnet") + throw new Error ("Can't handle non-dotnet object ids. ObjectId: " + objectId); + + switch (parts[1]) { + case "object": + if (parts.length != 3) + throw new Error(`exception this time: Invalid object id format: ${objectId}`); + + return this._post_process_details(this.mono_wasm_get_object_properties(parts[2], false)); + + case "array": + return this._get_array_details(objectId, parts); + + case "valuetype": + if (parts.length != 3 && parts.length != 4) { + // dotnet:valuetype:vtid + // dotnet:valuetype:containerObjectId:vtId + throw new Error(`Invalid object id format: ${objectId}`); + } + + var containerObjectId = parts[2]; + return this._get_details_for_value_type(objectId, () => this.mono_wasm_get_object_properties(containerObjectId, true)); + + case "cfo_res": { + if (!(objectId in this._call_function_res_cache)) + throw new Error(`Could not find any object with id ${objectId}`); + + var real_obj = this._call_function_res_cache [objectId]; + if (args.accessorPropertiesOnly) { + // var val_accessors = JSON.stringify ([ + // { + // name: "__proto__", + // get: { type: "function", className: "Function", description: "function get __proto__ () {}", objectId: "dotnet:cfo_res:9999" }, + // set: { type: "function", className: "Function", description: "function set __proto__ () {}", objectId: "dotnet:cfo_res:8888" }, + // isOwn: false + // }], undefined, 4); + return { __value_as_json_string__: "[]" }; + } + + // behaving as if (args.ownProperties == true) + var descriptors = Object.getOwnPropertyDescriptors (real_obj); + var own_properties = []; + Object.keys (descriptors).forEach (k => { + var new_obj; + var prop_desc = descriptors [k]; + if (typeof prop_desc.value == "object") { + // convert `{value: { type='object', ... }}` + // to `{ name: 'foo', value: { type='object', ... }} + new_obj = Object.assign ({ name: k}, prop_desc); + } else { + // This is needed for values that were not added by us, + // thus are like { value: 5 } + // instead of { value: { type = 'number', value: 5 }} + // + // This can happen, for eg., when `length` gets added for arrays + // or `__proto__`. + new_obj = { + name: k, + // merge/add `type` and `description` to `d.value` + value: Object.assign ({ type: (typeof prop_desc.value), description: '' + prop_desc.value }, + prop_desc) + }; + } + + own_properties.push (new_obj); + }); + + return { __value_as_json_string__: JSON.stringify (own_properties) }; + } + + default: + throw new Error(`Unknown object id format: ${objectId}`); + } + }, + + _cache_call_function_res: function (obj) { + var id = `dotnet:cfo_res:${this._next_call_function_res_id++}`; + this._call_function_res_cache[id] = obj; + return id; + }, + + mono_wasm_release_object: function (objectId) { + if (objectId in this._cache_call_function_res) + delete this._cache_call_function_res[objectId]; + }, + + mono_wasm_call_function_on: function (request) { + var objId = request.objectId; + var proxy; + + if (objId in this._call_function_res_cache) { + proxy = this._call_function_res_cache [objId]; + } else if (!objId.startsWith ('dotnet:cfo_res:')) { + var details = this.mono_wasm_get_details(objId); + var target_is_array = this._is_object_id_array (objId); + proxy = target_is_array ? [] : {}; + + Object.keys(details).forEach(p => { + var prop = details[p]; + if (target_is_array) { + proxy.push(prop.value); + } else { + if (prop.name != undefined) + proxy [prop.name] = prop.value; + else // when can this happen?? + proxy[''+p] = prop.value; + } + }); + } + + var fn_args = request.arguments != undefined ? request.arguments.map(a => a.value) : []; + var fn_eval_str = `var fn = ${request.functionDeclaration}; fn.call (proxy, ...[${fn_args}]);`; + + var fn_res = eval (fn_eval_str); + if (request.returnByValue) + return fn_res; + + if (fn_res == undefined) + throw Error ('Function returned undefined result'); + + var fn_res_id = this._cache_call_function_res (fn_res); + if (Object.getPrototypeOf (fn_res) == Array.prototype) { + return { + type: "object", + subtype: "array", + className: "Array", + description: `Array(${fn_res.length})`, + objectId: fn_res_id + }; + } else { + return { type: "object", className: "Object", description: "Object", objectId: fn_res_id }; + } + }, + + mono_wasm_start_single_stepping: function (kind) { + console.log (">> mono_wasm_start_single_stepping " + kind); + if (!this.mono_wasm_setup_single_step) + this.mono_wasm_setup_single_step = Module.cwrap ("mono_wasm_setup_single_step", 'number', [ 'number']); + + this._next_value_type_id_var = 0; + this._value_types_cache = {}; + + return this.mono_wasm_setup_single_step (kind); + }, + + mono_wasm_runtime_ready: function () { + this.mono_wasm_runtime_is_ready = true; + // DO NOT REMOVE - magic debugger init function + console.debug ("mono_wasm_runtime_ready", "fe00e07a-5519-4dfe-b35a-f867dbaf2e28"); + + this._next_value_type_id_var = 0; + this._value_types_cache = {}; + + // FIXME: where should this go? + this._next_call_function_res_id = 0; + this._call_function_res_cache = {}; + }, + + mono_wasm_set_breakpoint: function (assembly, method_token, il_offset) { + if (!this.mono_wasm_set_bp) + this.mono_wasm_set_bp = Module.cwrap ('mono_wasm_set_breakpoint', 'number', ['string', 'number', 'number']); + + return this.mono_wasm_set_bp (assembly, method_token, il_offset) + }, + + mono_wasm_remove_breakpoint: function (breakpoint_id) { + if (!this.mono_wasm_del_bp) + this.mono_wasm_del_bp = Module.cwrap ('mono_wasm_remove_breakpoint', 'number', ['number']); + + return this.mono_wasm_del_bp (breakpoint_id); + }, + + // Set environment variable NAME to VALUE + // Should be called before mono_load_runtime_and_bcl () in most cases + mono_wasm_setenv: function (name, value) { + if (!this.wasm_setenv) + this.wasm_setenv = Module.cwrap ('mono_wasm_setenv', null, ['string', 'string']); + this.wasm_setenv (name, value); + }, + + mono_wasm_set_runtime_options: function (options) { + if (!this.wasm_parse_runtime_options) + this.wasm_parse_runtime_options = Module.cwrap ('mono_wasm_parse_runtime_options', null, ['number', 'number']); + var argv = Module._malloc (options.length * 4); + var wasm_strdup = Module.cwrap ('mono_wasm_strdup', 'number', ['string']); + aindex = 0; + for (var i = 0; i < options.length; ++i) { + Module.setValue (argv + (aindex * 4), wasm_strdup (options [i]), "i32"); + aindex += 1; + } + this.wasm_parse_runtime_options (options.length, argv); + }, + + // + // Initialize the AOT profiler with OPTIONS. + // Requires the AOT profiler to be linked into the app. + // options = { write_at: "", send_to: "" } + // should be in the format ::. + // write_at defaults to 'WebAssembly.Runtime::StopProfile'. + // send_to defaults to 'WebAssembly.Runtime::DumpAotProfileData'. + // DumpAotProfileData stores the data into Module.aot_profile_data. + // + mono_wasm_init_aot_profiler: function (options) { + if (options == null) + options = {} + if (!('write_at' in options)) + options.write_at = 'WebAssembly.Runtime::StopProfile'; + if (!('send_to' in options)) + options.send_to = 'WebAssembly.Runtime::DumpAotProfileData'; + var arg = "aot:write-at-method=" + options.write_at + ",send-to-method=" + options.send_to; + Module.ccall ('mono_wasm_load_profiler_aot', null, ['string'], [arg]); + }, + + // options = { write_at: "", send_to: "" } + // should be in the format ::. + // write_at defaults to 'WebAssembly.Runtime::StopProfile'. + // send_to defaults to 'WebAssembly.Runtime::DumpCoverageProfileData'. + // DumpCoverageProfileData stores the data into Module.coverage_profile_data. + mono_wasm_init_coverage_profiler: function (options) { + if (options == null) + options = {} + if (!('write_at' in options)) + options.write_at = 'WebAssembly.Runtime::StopProfile'; + if (!('send_to' in options)) + options.send_to = 'WebAssembly.Runtime::DumpCoverageProfileData'; + var arg = "coverage:write-at-method=" + options.write_at + ",send-to-method=" + options.send_to; + Module.ccall ('mono_wasm_load_profiler_coverage', null, ['string'], [arg]); + }, + + mono_load_runtime_and_bcl: function (vfs_prefix, deploy_prefix, enable_debugging, file_list, loaded_cb, fetch_file_cb) { + var pending = file_list.length; + var loaded_files = []; + var mono_wasm_add_assembly = Module.cwrap ('mono_wasm_add_assembly', null, ['string', 'number', 'number']); + + if (!fetch_file_cb) { + if (ENVIRONMENT_IS_NODE) { + var fs = require('fs'); + fetch_file_cb = function (asset) { + console.log("MONO_WASM: Loading... " + asset); + var binary = fs.readFileSync (asset); + var resolve_func2 = function(resolve, reject) { + resolve(new Uint8Array (binary)); + }; + + var resolve_func1 = function(resolve, reject) { + var response = { + ok: true, + url: asset, + arrayBuffer: function() { + return new Promise(resolve_func2); + } + }; + resolve(response); + }; + + return new Promise(resolve_func1); + }; + } else { + fetch_file_cb = function (asset) { + return fetch (asset, { credentials: 'same-origin' }); + } + } + } + + file_list.forEach (function(file_name) { + + var fetch_promise = fetch_file_cb (locateFile(deploy_prefix + "/" + file_name)); + + fetch_promise.then (function (response) { + if (!response.ok) { + // If it's a 404 on a .pdb, we don't want to block the app from starting up. + // We'll just skip that file and continue (though the 404 is logged in the console). + if (response.status === 404 && file_name.match(/\.pdb$/) && MONO.mono_wasm_ignore_pdb_load_errors) { + --pending; + throw "MONO-WASM: Skipping failed load for .pdb file: '" + file_name + "'"; + } + else { + throw "MONO_WASM: Failed to load file: '" + file_name + "'"; + } + } + else { + loaded_files.push (response.url); + return response ['arrayBuffer'] (); + } + }).then (function (blob) { + var asm = new Uint8Array (blob); + var memory = Module._malloc(asm.length); + var heapBytes = new Uint8Array(Module.HEAPU8.buffer, memory, asm.length); + heapBytes.set (asm); + mono_wasm_add_assembly (file_name, memory, asm.length); + + //console.log ("MONO_WASM: Loaded: " + file_name); + --pending; + if (pending == 0) { + MONO.loaded_files = loaded_files; + var load_runtime = Module.cwrap ('mono_wasm_load_runtime', null, ['string', 'number']); + + console.log ("MONO_WASM: Initializing mono runtime"); + if (ENVIRONMENT_IS_SHELL || ENVIRONMENT_IS_NODE) { + try { + load_runtime (vfs_prefix, enable_debugging); + } catch (ex) { + print ("MONO_WASM: load_runtime () failed: " + ex); + var err = new Error(); + print ("MONO_WASM: Stacktrace: \n"); + print (err.stack); + + var wasm_exit = Module.cwrap ('mono_wasm_exit', null, ['number']); + wasm_exit (1); + } + } else { + load_runtime (vfs_prefix, enable_debugging); + } + MONO.mono_wasm_runtime_ready (); + loaded_cb (); + } + }); + }); + }, + + mono_wasm_get_loaded_files: function() { + console.log(">>>mono_wasm_get_loaded_files"); + return this.loaded_files; + }, + + mono_wasm_clear_all_breakpoints: function() { + if (!this.mono_clear_bps) + this.mono_clear_bps = Module.cwrap ('mono_wasm_clear_all_breakpoints', null); + + this.mono_clear_bps (); + }, + + mono_wasm_add_null_var: function(className) + { + fixed_class_name = MONO._mono_csharp_fixup_class_name(Module.UTF8ToString (className)); + if (!fixed_class_name) { + // Eg, when a @className is passed from js itself, like + // mono_wasm_add_null_var ("string") + fixed_class_name = className; + } + MONO.var_info.push ({value: { + type: "object", + className: fixed_class_name, + description: fixed_class_name, + subtype: "null" + }}); + }, + + _mono_wasm_add_string_var: function(var_value) { + if (var_value == 0) { + MONO.mono_wasm_add_null_var ("string"); + return; + } + + MONO.var_info.push({ + value: { + type: "string", + value: var_value, + } + }); + }, + + _mono_wasm_add_getter_var: function(className) { + fixed_class_name = MONO._mono_csharp_fixup_class_name (className); + var value = `${fixed_class_name} { get; }`; + MONO.var_info.push({ + value: { + type: "symbol", + value: value, + description: value + } + }); + }, + + _mono_wasm_add_array_var: function(className, objectId, length) { + fixed_class_name = MONO._mono_csharp_fixup_class_name(className); + if (objectId == 0) { + MONO.mono_wasm_add_null_var (fixed_class_name); + return; + } + + MONO.var_info.push({ + value: { + type: "object", + subtype: "array", + className: fixed_class_name, + description: `${fixed_class_name}(${length})`, + objectId: "dotnet:array:"+ objectId, + } + }); + }, + + mono_wasm_add_typed_value: function (type, str_value, value) { + var type_str = type; + if (typeof type != 'string') + type_str = Module.UTF8ToString (type); + if (typeof str_value != 'string') + str_value = Module.UTF8ToString (str_value); + + switch (type_str) { + case "bool": + MONO.var_info.push ({ + value: { + type: "boolean", + value: value != 0 + } + }); + break; + + case "char": + MONO.var_info.push ({ + value: { + type: "symbol", + value: `${value} '${String.fromCharCode (value)}'` + } + }); + break; + + case "number": + MONO.var_info.push ({ + value: { + type: "number", + value: value + } + }); + break; + + case "string": + MONO._mono_wasm_add_string_var (str_value); + break; + + case "getter": + MONO._mono_wasm_add_getter_var (str_value); + break; + + case "array": + MONO._mono_wasm_add_array_var (str_value, value.objectId, value.length); + break; + + case "pointer": { + MONO.var_info.push ({ + value: { + type: "symbol", + value: str_value, + description: str_value + } + }); + } + break; + + default: { + var msg = `'${str_value}' ${value}`; + + MONO.var_info.push ({ + value: { + type: "symbol", + value: msg, + description: msg + } + }); + break; + } + } + }, + + _mono_csharp_fixup_class_name: function(className) + { + // Fix up generic names like Foo`2 to Foo + // and nested class names like Foo/Bar to Foo.Bar + return className.replace(/\//g, '.').replace(/`\d+/g, ''); + }, + }, + + mono_wasm_add_typed_value: function (type, str_value, value) { + MONO.mono_wasm_add_typed_value (type, str_value, value); + }, + + mono_wasm_add_properties_var: function(name, field_offset) { + MONO.var_info.push({ + name: Module.UTF8ToString (name), + fieldOffset: field_offset + }); + }, + + mono_wasm_set_is_async_method: function(objectId) { + MONO._async_method_objectId = objectId; + }, + + mono_wasm_begin_value_type_var: function(className, toString) { + fixed_class_name = MONO._mono_csharp_fixup_class_name(Module.UTF8ToString (className)); + var vt_obj = { + value: { + type: "object", + className: fixed_class_name, + description: (toString == 0 ? fixed_class_name : Module.UTF8ToString (toString)), + // objectId will be generated by MonoProxy + expanded: true, + isValueType: true, + members: [] + } + }; + if (MONO._vt_stack.length == 0) + MONO._old_var_info = MONO.var_info; + + MONO.var_info = vt_obj.value.members; + MONO._vt_stack.push (vt_obj); + }, + + mono_wasm_end_value_type_var: function() { + var top_vt_obj_popped = MONO._vt_stack.pop (); + top_vt_obj_popped.value.members = MONO._filter_automatic_properties ( + MONO._fixup_name_value_objects (top_vt_obj_popped.value.members)); + + if (MONO._vt_stack.length == 0) { + MONO.var_info = MONO._old_var_info; + MONO.var_info.push(top_vt_obj_popped); + } else { + var top_obj = MONO._vt_stack [MONO._vt_stack.length - 1]; + top_obj.value.members.push (top_vt_obj_popped); + MONO.var_info = top_obj.value.members; + } + }, + + mono_wasm_add_value_type_unexpanded_var: function (className, toString) { + fixed_class_name = MONO._mono_csharp_fixup_class_name(Module.UTF8ToString (className)); + MONO.var_info.push({ + value: { + type: "object", + className: fixed_class_name, + description: (toString == 0 ? fixed_class_name : Module.UTF8ToString (toString)), + // objectId added when enumerating object's properties + expanded: false, + isValueType: true + } + }); + }, + + mono_wasm_add_enum_var: function(className, members, value) { + // FIXME: flags + // + + // group0: Monday:0 + // group1: Monday + // group2: 0 + var re = new RegExp (`[,]?([^,:]+):(${value}(?=,)|${value}$)`, 'g') + var members_str = Module.UTF8ToString (members); + + var match = re.exec(members_str); + var member_name = match == null ? ('' + value) : match [1]; + + fixed_class_name = MONO._mono_csharp_fixup_class_name(Module.UTF8ToString (className)); + MONO.var_info.push({ + value: { + type: "object", + className: fixed_class_name, + description: member_name, + isEnum: true + } + }); + }, + + mono_wasm_add_array_item: function(position) { + MONO.var_info.push({ + name: `${position}` + }); + }, + + mono_wasm_add_obj_var: function(className, toString, objectId) { + if (objectId == 0) { + MONO.mono_wasm_add_null_var (className); + return; + } + + fixed_class_name = MONO._mono_csharp_fixup_class_name(Module.UTF8ToString (className)); + MONO.var_info.push({ + value: { + type: "object", + className: fixed_class_name, + description: (toString == 0 ? fixed_class_name : Module.UTF8ToString (toString)), + objectId: "dotnet:object:"+ objectId, + } + }); + }, + + /* + * @className, and @targetName are in the following format: + * + * :[]: + */ + mono_wasm_add_func_var: function (className, targetName, objectId) { + if (objectId == 0) { + MONO.mono_wasm_add_null_var ( + MONO._mono_csharp_fixup_class_name (Module.UTF8ToString (className))); + return; + } + + function args_to_sig (args_str) { + var parts = args_str.split (":"); + // TODO: min length = 3? + parts = parts.map (a => MONO._mono_csharp_fixup_class_name (a)); + + // method name at the end + var method_name = parts.pop (); + + // ret type at the beginning + var ret_sig = parts [0]; + var args_sig = parts.splice (1).join (', '); + return `${ret_sig} ${method_name} (${args_sig})`; + } + + var tgt_sig; + if (targetName != 0) + tgt_sig = args_to_sig (Module.UTF8ToString (targetName)); + + var type_name = MONO._mono_csharp_fixup_class_name (Module.UTF8ToString (className)); + + if (objectId == -1) { + // Target property + MONO.var_info.push ({ + value: { + type: "symbol", + value: tgt_sig, + description: tgt_sig, + } + }); + } else { + MONO.var_info.push ({ + value: { + type: "object", + className: type_name, + description: tgt_sig, + objectId: "dotnet:object:" + objectId, + } + }); + } + }, + + mono_wasm_add_frame: function(il, method, assembly_name, method_full_name) { + var parts = Module.UTF8ToString (method_full_name).split (":", 2); + MONO.active_frames.push( { + il_pos: il, + method_token: method, + assembly_name: Module.UTF8ToString (assembly_name), + // Extract just the method name from `{class_name}:{method_name}` + method_name: parts [parts.length - 1] + }); + }, + + schedule_background_exec: function () { + ++MONO.pump_count; + if (ENVIRONMENT_IS_WEB) { + window.setTimeout (MONO.pump_message, 0); + } else if (ENVIRONMENT_IS_WORKER) { + self.setTimeout (MONO.pump_message, 0); + } else if (ENVIRONMENT_IS_NODE) { + global.setTimeout (MONO.pump_message, 0); + } + }, + + mono_set_timeout: function (timeout, id) { + if (!this.mono_set_timeout_exec) + this.mono_set_timeout_exec = Module.cwrap ("mono_set_timeout_exec", null, [ 'number' ]); + if (ENVIRONMENT_IS_WEB) { + window.setTimeout (function () { + this.mono_set_timeout_exec (id); + }, timeout); + } else if (ENVIRONMENT_IS_WORKER) { + self.setTimeout (function () { + this.mono_set_timeout_exec (id); + }, timeout); + } else if (ENVIRONMENT_IS_NODE) { + global.setTimeout (function () { + global.mono_set_timeout_exec (id); + }, timeout); + } else { + ++MONO.pump_count; + MONO.timeout_queue.push(function() { + this.mono_set_timeout_exec (id); + }) + } + }, + + mono_wasm_fire_bp: function () { + console.log ("mono_wasm_fire_bp"); + debugger; + } +}; + +autoAddDeps(MonoSupportLib, '$MONO') +mergeInto(LibraryManager.library, MonoSupportLib) diff --git a/src/mono/wasm/runtime/linker-preserves.xml b/src/mono/wasm/runtime/linker-preserves.xml new file mode 100644 index 0000000000000..2e46279b8793a --- /dev/null +++ b/src/mono/wasm/runtime/linker-preserves.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj new file mode 100644 index 0000000000000..3ea7167a8c5c3 --- /dev/null +++ b/src/mono/wasm/wasm.proj @@ -0,0 +1,46 @@ + + + $(NetCoreAppCurrent) + + + + + + $(MonoObjDir)wasm/pinvoke-table.h + $(ArtifactsDir)bin\lib-runtime-packs\runtimes\browser-wasm\lib\$(NetCoreAppCurrent) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 210a82a2e7f024365309c532f4511ed4122a4743 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Tue, 12 May 2020 04:47:59 -0700 Subject: [PATCH 127/420] Build tests as self contained apps for mobile targets (#36262) This uses the SDK to publish tests as self contained apps before building the app bundle using the built runtime pack. I moved the `RunTests.sh` output path to `BundleDir` as whenever we start sending to helix, there is no need to .zip up the whole `OutDir` as we can just send the bundle + `RunTests.sh` script. --- eng/testing/AndroidRunnerTemplate.sh | 4 +- eng/testing/AppleRunnerTemplate.sh | 4 +- eng/testing/tests.mobile.targets | 114 ++++++++++++++++++++++++++ eng/testing/tests.props | 7 +- eng/testing/tests.targets | 117 +-------------------------- 5 files changed, 125 insertions(+), 121 deletions(-) create mode 100644 eng/testing/tests.mobile.targets diff --git a/eng/testing/AndroidRunnerTemplate.sh b/eng/testing/AndroidRunnerTemplate.sh index dfb90ecaa156b..1a683aa348986 100644 --- a/eng/testing/AndroidRunnerTemplate.sh +++ b/eng/testing/AndroidRunnerTemplate.sh @@ -4,7 +4,7 @@ EXECUTION_DIR=$(dirname $0) TEST_NAME=$1 TARGET_ARCH=$2 -APK=$EXECUTION_DIR/Bundle/bin/$TEST_NAME.apk +APK=$EXECUTION_DIR/bin/$TEST_NAME.apk # it doesn't support parallel execution yet, so, here is a hand-made semaphore: LOCKDIR=/tmp/androidtests.lock @@ -20,4 +20,4 @@ done dotnet xharness android test -i="net.dot.MonoRunner" \ --package-name="net.dot.$TEST_NAME" \ - --app=$APK -o=$EXECUTION_DIR/Bundle/TestResults -v + --app=$APK -o=$EXECUTION_DIR/TestResults -v diff --git a/eng/testing/AppleRunnerTemplate.sh b/eng/testing/AppleRunnerTemplate.sh index 11b5675fab77f..809580e5d73eb 100644 --- a/eng/testing/AppleRunnerTemplate.sh +++ b/eng/testing/AppleRunnerTemplate.sh @@ -25,7 +25,7 @@ fi # "Release" in SCHEME_SDK is what xcode produces (see "bool Optimized" property in AppleAppBuilderTask) -APP_BUNDLE=$EXECUTION_DIR/Bundle/$TEST_NAME/$SCHEME_SDK/$TEST_NAME.app +APP_BUNDLE=$EXECUTION_DIR/$TEST_NAME/$SCHEME_SDK/$TEST_NAME.app # it doesn't support parallel execution yet, so, here is a hand-made semaphore: LOCKDIR=/tmp/runonsim.lock @@ -39,7 +39,7 @@ while true; do fi done -XHARNESS_OUT="$EXECUTION_DIR/Bundle/xharness-output" +XHARNESS_OUT="$EXECUTION_DIR/xharness-output" dotnet xharness ios test --app="$APP_BUNDLE" \ --targets=$TARGET \ diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets new file mode 100644 index 0000000000000..aa0f1450faef7 --- /dev/null +++ b/eng/testing/tests.mobile.targets @@ -0,0 +1,114 @@ + + + + $([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle')) + $([MSBuild]::NormalizePath('$(BundleDir)', '$(RunScriptOutputName)')) + + + + + + + arm64-v8a + armeabi + x86_64 + $(TargetArchitecture) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eng/testing/tests.props b/eng/testing/tests.props index f736c75d4279f..09b51e3163a7d 100644 --- a/eng/testing/tests.props +++ b/eng/testing/tests.props @@ -20,12 +20,17 @@ <_withoutCategories Condition="!$(_withCategories.Contains('failing'))">$(_withoutCategories);failing - + $(NetCoreAppCurrent)-$(MonoConfiguration) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder', '$(MobileHelpersDirSuffix)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleTestRunner', '$(MobileHelpersDirSuffix)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', '$(MobileHelpersDirSuffix)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidTestRunner', '$(MobileHelpersDirSuffix)')) + + $(PackageRID) + true + false + - - - - $(OutDir)\Bundle - arm64-v8a - armeabi - x86_64 - $(TargetArchitecture) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(OutDir)\Bundle - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + From 8271d53e6210161b4898af880fe4bf87d3714eac Mon Sep 17 00:00:00 2001 From: Adeel Mujahid Date: Tue, 12 May 2020 16:45:02 +0300 Subject: [PATCH 128/420] Add configurations for SunOS CoreCLR managed build (#36266) --- eng/Configurations.props | 1 + eng/build.sh | 22 +++++++++--------- eng/native/build-commons.sh | 2 +- eng/native/configurecompiler.cmake | 14 +++++------ eng/run-test.sh | 23 +++++++++++-------- eng/targetframeworksuffix.props | 7 ++++++ src/coreclr/dir.common.props | 3 ++- src/coreclr/run-cppcheck.sh | 23 ++++++++++--------- src/coreclr/src/.nuget/Directory.Build.props | 22 +++++++++++++++++- .../targets/Microsoft.NET.Sdk.IL.targets | 12 ++++++---- .../src/dlls/mscoree/coreclr/CMakeLists.txt | 4 ++-- src/coreclr/src/inc/pedecoder.h | 2 ++ src/coreclr/src/jit/CMakeLists.txt | 2 +- .../pal_sxs/test1/CMakeLists.txt | 4 ++-- .../Target_X64/TargetRegisterMap.cs | 2 ++ .../Common/TypeSystem/Common/TargetDetails.cs | 1 + .../ObjectWriter/TargetExtensions.cs | 1 + .../ReadyToRunReader.cs | 1 + src/coreclr/tests/scripts/run-corefx-tests.sh | 14 +++++++---- .../scripts/run-gc-reliability-framework.sh | 3 +++ .../tests/setup-stress-dependencies.sh | 2 +- src/coreclr/tests/src/Directory.Build.props | 16 ++++++++++++- .../JIT/Directed/StructABI/StructABI.csproj | 2 +- 23 files changed, 123 insertions(+), 60 deletions(-) diff --git a/eng/Configurations.props b/eng/Configurations.props index 764887c3ae5a6..94646e7991b87 100644 --- a/eng/Configurations.props +++ b/eng/Configurations.props @@ -43,6 +43,7 @@ OSX FreeBSD NetBSD + SunOS Linux Windows_NT $(TargetOS) diff --git a/eng/build.sh b/eng/build.sh index 64496fd108050..36e68ef1c1dc4 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -18,7 +18,7 @@ usage() { echo "Common settings:" echo " --subset Build a subset, print available subsets with -subset help (short: -s)" - echo " --os Build operating system: Windows_NT, Linux, FreeBSD, OSX, tvOS, iOS, Android or Browser" + echo " --os Build operating system: Windows_NT, Linux, FreeBSD, OSX, tvOS, iOS, Android, Browser, NetBSD or SunOS" echo " --arch Build platform: x86, x64, arm, armel, arm64 or wasm" echo " --configuration Build configuration: Debug, Release or [CoreCLR]Checked (short: -c)" echo " --runtimeConfiguration Runtime build configuration: Debug, Release or [CoreCLR]Checked (short: -rc)" @@ -108,16 +108,16 @@ while [[ $# > 0 ]]; do exit 0 ;; -subset|-s) - if [ -z ${2+x} ]; then + if [ -z ${2+x} ]; then arguments="$arguments /p:Subset=help" shift 1 - else + else arguments="$arguments /p:Subset=$2" shift 2 fi ;; -arch) - if [ -z ${2+x} ]; then + if [ -z ${2+x} ]; then echo "No architecture supplied. See help (--help) for supported architectures." 1>&2 exit 1 fi @@ -125,7 +125,7 @@ while [[ $# > 0 ]]; do shift 2 ;; -configuration|-c) - if [ -z ${2+x} ]; then + if [ -z ${2+x} ]; then echo "No configuration supplied. See help (--help) for supported configurations." 1>&2 exit 1 fi @@ -134,7 +134,7 @@ while [[ $# > 0 ]]; do shift 2 ;; -framework|-f) - if [ -z ${2+x} ]; then + if [ -z ${2+x} ]; then echo "No framework supplied. See help (--help) for supported frameworks." 1>&2 exit 1 fi @@ -143,7 +143,7 @@ while [[ $# > 0 ]]; do shift 2 ;; -os) - if [ -z ${2+x} ]; then + if [ -z ${2+x} ]; then echo "No target operating system supplied. See help (--help) for supported target operating systems." 1>&2 exit 1 fi @@ -156,7 +156,7 @@ while [[ $# > 0 ]]; do shift 1 ;; -testscope) - if [ -z ${2+x} ]; then + if [ -z ${2+x} ]; then echo "No test scope supplied. See help (--help) for supported test scope values." 1>&2 exit 1 fi @@ -172,7 +172,7 @@ while [[ $# > 0 ]]; do shift 1 ;; -runtimeconfiguration|-rc) - if [ -z ${2+x} ]; then + if [ -z ${2+x} ]; then echo "No runtime configuration supplied. See help (--help) for supported runtime configurations." 1>&2 exit 1 fi @@ -181,7 +181,7 @@ while [[ $# > 0 ]]; do shift 2 ;; -librariesconfiguration|-lc) - if [ -z ${2+x} ]; then + if [ -z ${2+x} ]; then echo "No libraries configuration supplied. See help (--help) for supported libraries configurations." 1>&2 exit 1 fi @@ -198,7 +198,7 @@ while [[ $# > 0 ]]; do shift 1 ;; -cmakeargs) - if [ -z ${2+x} ]; then + if [ -z ${2+x} ]; then echo "No cmake args supplied." 1>&2 exit 1 fi diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh index 27381c68d0e35..309244b9671cc 100755 --- a/eng/native/build-commons.sh +++ b/eng/native/build-commons.sh @@ -409,7 +409,7 @@ done # Get the number of processors available to the scheduler # Other techniques such as `nproc` only get the number of # processors available to a single process. -platform=$(uname) +platform="$(uname)" if [[ "$platform" == "FreeBSD" ]]; then __NumProc=$(sysctl hw.ncpu | awk '{ print $2+1 }') elif [[ "$platform" == "NetBSD" || "$platform" == "SunOS" ]]; then diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index 735f77b028217..e0301cb6b3fc1 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -227,15 +227,13 @@ if (CLR_CMAKE_HOST_UNIX) if(CLR_CMAKE_HOST_OSX) message("Detected OSX x86_64") - endif(CLR_CMAKE_HOST_OSX) - - if(CLR_CMAKE_HOST_FREEBSD) + elseif(CLR_CMAKE_HOST_FREEBSD) message("Detected FreeBSD amd64") - endif(CLR_CMAKE_HOST_FREEBSD) - - if(CLR_CMAKE_HOST_NETBSD) + elseif(CLR_CMAKE_HOST_NETBSD) message("Detected NetBSD amd64") - endif(CLR_CMAKE_HOST_NETBSD) + elseif(CLR_CMAKE_HOST_SUNOS) + message("Detected SunOS amd64") + endif(CLR_CMAKE_HOST_SUNOS) endif(CLR_CMAKE_HOST_UNIX) if (CLR_CMAKE_HOST_WIN32) @@ -373,6 +371,8 @@ if(CLR_CMAKE_TARGET_UNIX) add_definitions(-DTARGET_LINUX) elseif(CLR_CMAKE_TARGET_NETBSD) add_definitions(-DTARGET_NETBSD) + elseif(CLR_CMAKE_TARGET_SUNOS) + add_definitions(-DTARGET_SUNOS) elseif(CLR_CMAKE_TARGET_ANDROID) add_definitions(-DTARGET_ANDROID) endif() diff --git a/eng/run-test.sh b/eng/run-test.sh index abd1d920b1615..5f14e6f6121be 100644 --- a/eng/run-test.sh +++ b/eng/run-test.sh @@ -15,12 +15,12 @@ wait_on_pids() usage() { - echo "Runs .NET CoreFX tests on FreeBSD, NetBSD or Linux" + echo "Runs .NET CoreFX tests on FreeBSD, Linux, NetBSD or SunOS" echo "usage: run-test [options]" echo echo "Input sources:" echo " --runtime Location of root of the binaries directory" - echo " containing the FreeBSD, NetBSD or Linux runtime" + echo " containing the FreeBSD, Linux, NetBSD or SunOS runtime" echo " default: /bin/testhost/netcoreapp---" echo " --corefx-tests Location of the root binaries location containing" echo " the tests to run" @@ -29,7 +29,7 @@ usage() echo "Flavor/OS/Architecture options:" echo " --configuration Configuration to run (Debug/Release)" echo " default: Debug" - echo " --os OS to run (FreeBSD, NetBSD or Linux)" + echo " --os OS to run (FreeBSD, Linux, NetBSD or SunOS)" echo " default: detect current OS" echo " --arch Architecture to run (x64, arm, armel, x86, arm64)" echo " default: detect current architecture" @@ -236,34 +236,34 @@ done # Compute paths to the binaries if they haven't already been computed -if [ "$Runtime" == "" ] +if [ -z "$Runtime" ] then Runtime="$ProjectRoot/artifacts/bin/testhost/netcoreapp-$OS-$Configuration-$__Arch" fi -if [ "$CoreFxTests" == "" ] +if [ -z "$CoreFxTests" ] then CoreFxTests="$ProjectRoot/artifacts/bin" fi # Check parameters up front for valid values: -if [ ! "$Configuration" == "Debug" ] && [ ! "$Configuration" == "Release" ] +if [ "$Configuration" != "Debug" ] && [ "$Configuration" != "Release" ] then echo "error: Configuration should be Debug or Release" exit 1 fi -if [ ! "$OS" == "FreeBSD" ] && [ ! "$OS" == "NetBSD" ] && [ ! "$OS" == "Linux" ] +if [ "$OS" != "FreeBSD" ] && [ "$OS" != "Linux" ] && [ "$OS" != "NetBSD" ] && [ "$OS" != "SunOS" ] then - echo "error: OS should be FreeBSD, NetBSD or Linux" + echo "error: OS should be FreeBSD, Linux, NetBSD or Linux" exit 1 fi export CORECLR_SERVER_GC="$serverGC" export PAL_OUTPUTDEBUGSTRING="1" -if [ "$LANG" == "" ] +if [ -z "$LANG" ] then export LANG="en_US.UTF-8" fi @@ -285,7 +285,10 @@ if [ $RunTestSequential -eq 1 ] then maxProcesses=1; else - if [ `uname` = "NetBSD" ] || [ `uname` = "FreeBSD" ]; then + platform="$(uname)" + if [ "$platform" = "FreeBSD" ]; then + maxProcesses=$(sysctl hw.ncpu | awk '{ print $2+1 }') + if [ "$platform" = "NetBSD" ] || [ "$platform" = "SunOS" ] ; then maxProcesses=$(($(getconf NPROCESSORS_ONLN)+1)) else maxProcesses=$(($(getconf _NPROCESSORS_ONLN)+1)) diff --git a/eng/targetframeworksuffix.props b/eng/targetframeworksuffix.props index 2f427328fd5fd..f89923d3ab86c 100644 --- a/eng/targetframeworksuffix.props +++ b/eng/targetframeworksuffix.props @@ -62,6 +62,13 @@ netbsd + + + true + true + sunos + + true diff --git a/src/coreclr/dir.common.props b/src/coreclr/dir.common.props index e4d212b2aee16..2ff54f14de24a 100644 --- a/src/coreclr/dir.common.props +++ b/src/coreclr/dir.common.props @@ -55,10 +55,11 @@ true true true + true true true - true + true $(__DistroRid) diff --git a/src/coreclr/run-cppcheck.sh b/src/coreclr/run-cppcheck.sh index c505fd184dedc..46e51e1e7471f 100755 --- a/src/coreclr/run-cppcheck.sh +++ b/src/coreclr/run-cppcheck.sh @@ -17,13 +17,13 @@ usage() check_dependencies() { # Check presence of cppcheck on the path - if [ "$RunCppCheck" == true ] + if [ "$RunCppCheck" = "true" ] then hash cppcheck 2>/dev/null || { echo >&2 "Please install cppcheck before running this script"; exit 1; } fi - + # Check presence of sloccount on the path - if [ "$RunSlocCount" == true ] + if [ "$RunSlocCount" = "true" ] then hash sloccount 2>/dev/null || { echo >&2 "Please install sloccount before running this script"; exit 1; } fi @@ -39,9 +39,10 @@ SloccountOutput="sloccount.sc" # Get the number of processors available to the scheduler # Other techniques such as `nproc` only get the number of # processors available to a single process. -if [ `uname` = "FreeBSD" ]; then -NumProc=`sysctl hw.ncpu | awk '{ print $2+1 }'` -elif [ `uname` = "NetBSD" ]; then +platform="$(uname)" +if [ "$platform" = "FreeBSD" ]; then +NumProc=$(sysctl hw.ncpu | awk '{ print $2+1 }') +elif [ "$platform" = "NetBSD" || "$platform" = "SunOS" ]; then NumProc=$(($(getconf NPROCESSORS_ONLN)+1)) else NumProc=$(($(getconf _NPROCESSORS_ONLN)+1)) @@ -80,19 +81,19 @@ do esac done -if [ "$FilesFromArgs" != "" ]; +if [ -n "$FilesFromArgs" ]; then Files=$FilesFromArgs fi -if [ "$CppCheckOutput" == "" ]; +if [ -z "$CppCheckOutput" ]; then echo "Expected: file for cppcheck output" usage exit 1 fi -if [ "$SloccountOutput" == "" ]; +if [ -z "$SloccountOutput" ]; then echo "Expected: file for sloccount output" usage @@ -101,14 +102,14 @@ fi check_dependencies -if [ "$RunCppCheck" == true ] +if [ "$RunCppCheck" = "true" ] then echo "Running cppcheck for files: $Files" cppcheck --enable=all -j $NumProc --xml --xml-version=2 --force $Files 2> $CppCheckOutput CppCheckOutputs="$CppCheckOutput (cppcheck)" fi -if [ "$RunSlocCount" == true ] +if [ "$RunSlocCount" = "true" ] then echo "Running sloccount for files: $Files" sloccount --wide --details $Files > $SloccountOutput diff --git a/src/coreclr/src/.nuget/Directory.Build.props b/src/coreclr/src/.nuget/Directory.Build.props index e321b384626e0..2fd932c03b84e 100644 --- a/src/coreclr/src/.nuget/Directory.Build.props +++ b/src/coreclr/src/.nuget/Directory.Build.props @@ -28,7 +28,7 @@ $(OSRid) - Windows_NT;OSX;Android;Linux;FreeBSD + Windows_NT;OSX;Android;Linux;FreeBSD;NetBSD;SunOS ;$(SupportedPackageOSGroups); + netbsd-$(TargetArchitecture) + + + + + sunos-$(TargetArchitecture) + + sunos-$(TargetArchitecture) + + android.21-$(TargetArchitecture) @@ -159,6 +173,12 @@ + + + + + + x86 diff --git a/src/coreclr/src/.nuget/Microsoft.NET.Sdk.IL/targets/Microsoft.NET.Sdk.IL.targets b/src/coreclr/src/.nuget/Microsoft.NET.Sdk.IL/targets/Microsoft.NET.Sdk.IL.targets index 299511fa2a8be..f2c0a3fb64973 100644 --- a/src/coreclr/src/.nuget/Microsoft.NET.Sdk.IL/targets/Microsoft.NET.Sdk.IL.targets +++ b/src/coreclr/src/.nuget/Microsoft.NET.Sdk.IL/targets/Microsoft.NET.Sdk.IL.targets @@ -7,7 +7,7 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and created a backup copy. Incorrect changes to this file will make it impossible to load or build your projects from the command-line or the IDE. -Copyright (c) .NET Foundation. All rights reserved. +Copyright (c) .NET Foundation. All rights reserved. *********************************************************************************************** --> @@ -24,13 +24,15 @@ Copyright (c) .NET Foundation. All rights reserved. <_OSPlatform Condition="$([MSBuild]::IsOSPlatform('linux'))">linux <_OSPlatform Condition="$([MSBuild]::IsOSPlatform('osx'))">osx <_OSPlatform Condition="$([MSBuild]::IsOSPlatform('freebsd'))">freebsd + <_OSPlatform Condition="$([MSBuild]::IsOSPlatform('netbsd'))">netbsd + <_OSPlatform Condition="$([MSBuild]::IsOSPlatform('sunos'))">sunos <_OSArchitecture>$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) $(_OSPlatform)-$(_OSArchitecture.ToLower()) 5.0.0 runtime.$(MicrosoftNetCoreIlasmPackageRuntimeId).microsoft.netcore.ilasm runtime.$(MicrosoftNetCoreIlasmPackageRuntimeId).microsoft.netcore.ildasm - + <_IlasmDir Condition="'$(ILAsmToolPath)' != ''">$([MSBuild]::NormalizeDirectory($(ILAsmToolPath))) @@ -68,8 +70,8 @@ Copyright (c) .NET Foundation. All rights reserved. - @@ -122,7 +124,7 @@ Copyright (c) .NET Foundation. All rights reserved. <_KeyFileArgument Condition="'$(KeyOriginatorFile)' != ''">-KEY="$(KeyOriginatorFile)" - <_IlasmSwitches>-QUIET -NOLOGO + <_IlasmSwitches>-QUIET -NOLOGO <_IlasmSwitches Condition="'$(FoldIdenticalMethods)' == 'True'">$(_IlasmSwitches) -FOLD <_IlasmSwitches Condition="'$(SizeOfStackReserve)' != ''">$(_IlasmSwitches) -STACK=$(SizeOfStackReserve) <_IlasmSwitches Condition="'$(DebugType)' == 'Full'">$(_IlasmSwitches) -DEBUG diff --git a/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt index 4358d79669b45..4260ea92d1916 100644 --- a/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt @@ -61,10 +61,10 @@ else(CLR_CMAKE_HOST_WIN32) set(EXPORTS_LINKER_OPTION "${EXPORTS_LINKER_OPTION} -Wl,--no-warn-shared-textrel") endif(CLR_CMAKE_TARGET_ANDROID AND CLR_CMAKE_HOST_ARCH_ARM) - if(CLR_CMAKE_HOST_SUNOS) + if(CLR_CMAKE_TARGET_SUNOS) # Add linker exports file option set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) - endif(CLR_CMAKE_HOST_SUNOS) + endif(CLR_CMAKE_TARGET_SUNOS) endif (CLR_CMAKE_HOST_WIN32) diff --git a/src/coreclr/src/inc/pedecoder.h b/src/coreclr/src/inc/pedecoder.h index ad0e77e532c15..c4f4e92b6b613 100644 --- a/src/coreclr/src/inc/pedecoder.h +++ b/src/coreclr/src/inc/pedecoder.h @@ -95,6 +95,8 @@ inline CHECK CheckOverflow(RVA value1, COUNT_T value2) #define IMAGE_FILE_MACHINE_NATIVE_OS_OVERRIDE 0x7B79 #elif defined(__NetBSD__) #define IMAGE_FILE_MACHINE_NATIVE_OS_OVERRIDE 0x1993 +#elif defined(__sun) +#define IMAGE_FILE_MACHINE_NATIVE_OS_OVERRIDE 0x1992 #else #define IMAGE_FILE_MACHINE_NATIVE_OS_OVERRIDE 0 #endif diff --git a/src/coreclr/src/jit/CMakeLists.txt b/src/coreclr/src/jit/CMakeLists.txt index 8ba2c47973fde..0fd69af598209 100644 --- a/src/coreclr/src/jit/CMakeLists.txt +++ b/src/coreclr/src/jit/CMakeLists.txt @@ -325,7 +325,7 @@ else() set(JIT_EXPORTS_LINKER_OPTION -Wl,--version-script=${JIT_EXPORTS_FILE}) elseif(CLR_CMAKE_TARGET_OSX) set(JIT_EXPORTS_LINKER_OPTION -Wl,-exported_symbols_list,${JIT_EXPORTS_FILE}) - elseif(CLR_CMAKE_HOST_SUNOS) + elseif(CLR_CMAKE_TARGET_SUNOS) # Add linker exports file option set(JIT_EXPORTS_LINKER_OPTION -Wl,-M,${JIT_EXPORTS_FILE}) endif() diff --git a/src/coreclr/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/CMakeLists.txt b/src/coreclr/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/CMakeLists.txt index 37ff7de67a1fc..2d2d037ca29c6 100644 --- a/src/coreclr/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/CMakeLists.txt +++ b/src/coreclr/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/CMakeLists.txt @@ -26,10 +26,10 @@ if(CLR_CMAKE_TARGET_OSX) set(EXPORTS_LINKER_OPTION1 -Wl,-exported_symbols_list,${EXPORTS_FILE1}) endif(CLR_CMAKE_TARGET_OSX) -if(CLR_CMAKE_HOST_SUNOS) +if(CLR_CMAKE_TARGET_SUNOS) # Add linker exports file option set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) -endif(CLR_CMAKE_HOST_SUNOS) +endif(CLR_CMAKE_TARGET_SUNOS) set(DLL1SOURCES dlltest1.cpp) add_library(paltest_pal_sxs_test1_dll1 SHARED ${DLL1SOURCES}) diff --git a/src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/Target_X64/TargetRegisterMap.cs b/src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/Target_X64/TargetRegisterMap.cs index 808f8ed03c583..7d76bf5259b78 100644 --- a/src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/Target_X64/TargetRegisterMap.cs +++ b/src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/Target_X64/TargetRegisterMap.cs @@ -34,6 +34,8 @@ public TargetRegisterMap(TargetOS os) case TargetOS.Linux: case TargetOS.OSX: case TargetOS.FreeBSD: + case TargetOS.SunOS: + case TargetOS.NetBSD: Arg0 = Register.RDI; Arg1 = Register.RSI; Arg2 = Register.RDX; diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/TargetDetails.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/TargetDetails.cs index 162df18395aab..9337d7670904a 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/TargetDetails.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/TargetDetails.cs @@ -31,6 +31,7 @@ public enum TargetOS OSX, FreeBSD, NetBSD, + SunOS, WebAssembly, } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ObjectWriter/TargetExtensions.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ObjectWriter/TargetExtensions.cs index d4ba4683609c2..0b943d6233991 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ObjectWriter/TargetExtensions.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ObjectWriter/TargetExtensions.cs @@ -20,6 +20,7 @@ public enum MachineOSOverride : ushort Apple = 0x4644, FreeBSD = 0xADC4, NetBSD = 0x1993, + SunOS = 0x1992, } /// diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index c252c306d46a0..729a492215755 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -31,6 +31,7 @@ public enum OperatingSystem FreeBSD = 0xADC4, Linux = 0x7B79, NetBSD = 0x1993, + SunOS = 0x1992, Windows = 0, Unknown = -1 } diff --git a/src/coreclr/tests/scripts/run-corefx-tests.sh b/src/coreclr/tests/scripts/run-corefx-tests.sh index 03d186f04c9d5..39a87d03834d2 100755 --- a/src/coreclr/tests/scripts/run-corefx-tests.sh +++ b/src/coreclr/tests/scripts/run-corefx-tests.sh @@ -16,7 +16,7 @@ usage() echo "Flavor/OS/Architecture options:" echo " --configuration Configuration to run (Debug/Release)" echo " default: Debug" - echo " --os OS to run (FreeBSD, Linux, NetBSD or OSX)" + echo " --os OS to run (FreeBSD, Linux, NetBSD, OSX, SunOS)" echo " default: detect current OS" echo " --arch Architecture to run (x64, arm, armel, x86, arm64)" echo " default: detect current architecture" @@ -37,7 +37,7 @@ usage() echo "Runtime Code Coverage options:" echo " --coreclr-coverage Optional argument to get coreclr code coverage reports" echo " --coreclr-objs Location of root of the object directory" - echo " containing the FreeBSD, Linux, NetBSD or OSX coreclr build" + echo " containing the FreeBSD, Linux, NetBSD, OSX or SunOS coreclr build" echo " default: /bin/obj/.x64. Location of root of the directory" echo " containing the coreclr source files" @@ -81,6 +81,10 @@ case $OSName in OS=NetBSD ;; + SunOS) + OS=SunOS + ;; + *) echo "Unsupported OS $OSName detected, configuring as if for Linux" OS=Linux @@ -342,7 +346,7 @@ run_test() coreclr_code_coverage() { - if [ ! "$OS" == "FreeBSD" ] && [ ! "$OS" == "Linux" ] && [ ! "$OS" == "NetBSD" ] && [ ! "$OS" == "OSX" ] ; then + if [ "$OS" != "FreeBSD" ] && [ "$OS" != "Linux" ] && [ "$OS" != "NetBSD" ] && [ "$OS" != "OSX" ] && [ "$OS" != "SunOS" ] ; then echo "error: Code Coverage not supported on $OS" exit 1 fi @@ -501,9 +505,9 @@ then exit 1 fi -if [ ! "$OS" == "FreeBSD" ] && [ ! "$OS" == "Linux" ] && [ ! "$OS" == "NetBSD" ] && [ ! "$OS" == "OSX" ] +if [ "$OS" != "FreeBSD" ] && [ "$OS" != "Linux" ] && [ "$OS" != "NetBSD" ] && [ "$OS" != "OSX" ] && [ "$OS" != "SunOS" ] then - echo "error: OS should be FreeBSD, Linux, NetBSD or OSX" + echo "error: OS should be FreeBSD, Linux, NetBSD, OSX or SunOS" exit 1 fi diff --git a/src/coreclr/tests/scripts/run-gc-reliability-framework.sh b/src/coreclr/tests/scripts/run-gc-reliability-framework.sh index 8f8886a1bc84d..c136c1561ec9c 100755 --- a/src/coreclr/tests/scripts/run-gc-reliability-framework.sh +++ b/src/coreclr/tests/scripts/run-gc-reliability-framework.sh @@ -18,6 +18,9 @@ case $OSName in OS=NetBSD ;; + SunOS) + OS=SunOS + ;; *) echo "Unsupported OS $OSName detected, configuring as if for Linux" OS=Linux diff --git a/src/coreclr/tests/setup-stress-dependencies.sh b/src/coreclr/tests/setup-stress-dependencies.sh index 400a78003f6d5..a81c8fff7b2a7 100755 --- a/src/coreclr/tests/setup-stress-dependencies.sh +++ b/src/coreclr/tests/setup-stress-dependencies.sh @@ -82,7 +82,7 @@ if [ -z "$libInstallDir" ]; then exit_with_error 1 fi -if [ "$__BuildArch" == "arm64" ] || [ "$__BuildArch" == "arm" ]; then +if [ "$__BuildArch" = "arm64" ] || [ "$__BuildArch" = "arm" ]; then echo "No runtime dependencies for arm32/arm64" exit $EXIT_CODE_SUCCESS fi diff --git a/src/coreclr/tests/src/Directory.Build.props b/src/coreclr/tests/src/Directory.Build.props index fd07aff01d369..c4ed9921bd310 100644 --- a/src/coreclr/tests/src/Directory.Build.props +++ b/src/coreclr/tests/src/Directory.Build.props @@ -91,6 +91,20 @@ ubuntu.14.04-$(TargetArchitecture) + + + true + true + ubuntu.14.04-$(TargetArchitecture) + + + + + true + true + ubuntu.14.04-$(TargetArchitecture) + + @@ -109,7 +123,7 @@ - true + true C# IL diff --git a/src/coreclr/tests/src/JIT/Directed/StructABI/StructABI.csproj b/src/coreclr/tests/src/JIT/Directed/StructABI/StructABI.csproj index d43bf082a225b..440413d3e2853 100644 --- a/src/coreclr/tests/src/JIT/Directed/StructABI/StructABI.csproj +++ b/src/coreclr/tests/src/JIT/Directed/StructABI/StructABI.csproj @@ -16,7 +16,7 @@ - + From b57a099c1773eeb52d3c663211e275131b4b7938 Mon Sep 17 00:00:00 2001 From: Tom Deseyn Date: Tue, 12 May 2020 16:08:50 +0200 Subject: [PATCH 129/420] Ensure Process.ProcessName doesn't change when setting Thread.Name on Linux (#34064) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/dotnet/runtime/issues/33673 This issue is a side-effect of adding support for setting thread names on Linux in https://github.com/dotnet/coreclr/pull/27182. Co-authored-by: Dan Moseley Co-authored-by: Aleksey Kliger (λgeek) --- src/coreclr/src/pal/src/thread/thread.cpp | 7 +++++++ .../System.Threading.Thread/tests/ThreadTests.cs | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/coreclr/src/pal/src/thread/thread.cpp b/src/coreclr/src/pal/src/thread/thread.cpp index a6a14c20f9ba8..36a523e28d120 100644 --- a/src/coreclr/src/pal/src/thread/thread.cpp +++ b/src/coreclr/src/pal/src/thread/thread.cpp @@ -1641,6 +1641,13 @@ CorUnix::InternalSetThreadDescription( pTargetThread->Lock(pThread); + // Ignore requests to set the main thread name because + // it causes the value returned by Process.ProcessName to change. + if ((pid_t)pTargetThread->GetThreadId() == getpid()) + { + goto InternalSetThreadDescriptionExit; + } + /* translate the wide char lpThreadDescription string to multibyte string */ nameSize = WideCharToMultiByte(CP_ACP, 0, lpThreadDescription, -1, NULL, 0, NULL, NULL); diff --git a/src/libraries/System.Threading.Thread/tests/ThreadTests.cs b/src/libraries/System.Threading.Thread/tests/ThreadTests.cs index 846602b863b3b..797629521a807 100644 --- a/src/libraries/System.Threading.Thread/tests/ThreadTests.cs +++ b/src/libraries/System.Threading.Thread/tests/ThreadTests.cs @@ -651,6 +651,21 @@ public static void NameTest() }); } + [Fact] + [ActiveIssue ("https://github.com/dotnet/runtime/issues/35908", TestRuntimes.Mono)] + public static void ThreadNameDoesNotAffectProcessName() + { + // On Linux, changing the main thread name affects ProcessName. + // To avoid that, .NET ignores requests to change the main thread name. + RemoteExecutor.Invoke(() => + { + const string ThreadName = "my-thread"; + Thread.CurrentThread.Name = ThreadName; + Assert.Equal(ThreadName, Thread.CurrentThread.Name); + Assert.NotEqual(ThreadName, Process.GetCurrentProcess().ProcessName); + }).Dispose(); + } + [Fact] public static void PriorityTest() { From dba28fe6fd8813899104f5e7766a393e79015469 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 12 May 2020 12:48:50 -0400 Subject: [PATCH 130/420] [master] Update dependencies from 4 repositories (#36279) * Update dependencies from https://github.com/dotnet/arcade build 20200508.8 - Microsoft.DotNet.XUnitExtensions: 5.0.0-beta.20256.5 -> 5.0.0-beta.20258.8 - Microsoft.DotNet.VersionTools.Tasks: 5.0.0-beta.20256.5 -> 5.0.0-beta.20258.8 - Microsoft.DotNet.ApiCompat: 5.0.0-beta.20256.5 -> 5.0.0-beta.20258.8 - Microsoft.DotNet.Arcade.Sdk: 5.0.0-beta.20256.5 -> 5.0.0-beta.20258.8 - Microsoft.DotNet.Build.Tasks.Feed: 5.0.0-beta.20256.5 -> 5.0.0-beta.20258.8 - Microsoft.DotNet.Build.Tasks.Packaging: 5.0.0-beta.20256.5 -> 5.0.0-beta.20258.8 - Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk: 5.0.0-beta.20256.5 -> 5.0.0-beta.20258.8 - Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk: 5.0.0-beta.20256.5 -> 5.0.0-beta.20258.8 - Microsoft.DotNet.CodeAnalysis: 5.0.0-beta.20256.5 -> 5.0.0-beta.20258.8 - Microsoft.DotNet.XUnitConsoleRunner: 2.5.1-beta.20256.5 -> 2.5.1-beta.20258.8 - Microsoft.DotNet.Helix.Sdk: 5.0.0-beta.20256.5 -> 5.0.0-beta.20258.8 - Microsoft.DotNet.RemoteExecutor: 5.0.0-beta.20256.5 -> 5.0.0-beta.20258.8 - Microsoft.DotNet.GenFacades: 5.0.0-beta.20256.5 -> 5.0.0-beta.20258.8 * Update dependencies from https://github.com/mono/linker build 20200511.2 - Microsoft.NET.ILLink.Tasks: 5.0.0-preview.3.20257.4 -> 5.0.0-preview.3.20261.2 * Update dependencies from https://github.com/dotnet/llvm-project build 20200511.3 - runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: 6.0.1-alpha.1.20261.1 -> 6.0.1-alpha.1.20261.3 - runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: 6.0.1-alpha.1.20261.1 -> 6.0.1-alpha.1.20261.3 - runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: 6.0.1-alpha.1.20261.1 -> 6.0.1-alpha.1.20261.3 - runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: 6.0.1-alpha.1.20261.1 -> 6.0.1-alpha.1.20261.3 - runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: 6.0.1-alpha.1.20261.1 -> 6.0.1-alpha.1.20261.3 - runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: 6.0.1-alpha.1.20261.1 -> 6.0.1-alpha.1.20261.3 * Update dependencies from https://github.com/dotnet/xharness build 20200511.4 - Microsoft.DotNet.XHarness.Tests.Runners: 1.0.0-prerelease.20257.4 -> 1.0.0-prerelease.20261.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 84 +++++++++---------- eng/Versions.props | 34 ++++---- eng/common/build.ps1 | 6 +- eng/common/build.sh | 9 +- eng/common/post-build/symbols-validation.ps1 | 18 +++- .../templates/post-build/post-build.yml | 30 ++++++- eng/common/tools.ps1 | 16 ++-- eng/common/tools.sh | 16 +++- global.json | 8 +- 9 files changed, 140 insertions(+), 81 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2680982faa6c2..b6e8267ae4427 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -6,61 +6,61 @@ - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 https://github.com/dotnet/arcade 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 - + https://github.com/dotnet/arcade - 8547938aefa24475a04877285553f0b2663ae249 + 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization @@ -118,29 +118,29 @@ https://github.com/dotnet/runtime-assets 71b9284907ebc69e5f80b491a51084c75e0ef7d3 - + https://github.com/dotnet/llvm-project - 89f53d2cb6cd37267794895ff2ab47a30c094e63 + 921922eeae800011ab13ddb5402644b86d832df0 - + https://github.com/dotnet/llvm-project - 89f53d2cb6cd37267794895ff2ab47a30c094e63 + 921922eeae800011ab13ddb5402644b86d832df0 - + https://github.com/dotnet/llvm-project - 89f53d2cb6cd37267794895ff2ab47a30c094e63 + 921922eeae800011ab13ddb5402644b86d832df0 - + https://github.com/dotnet/llvm-project - 89f53d2cb6cd37267794895ff2ab47a30c094e63 + 921922eeae800011ab13ddb5402644b86d832df0 - + https://github.com/dotnet/llvm-project - 89f53d2cb6cd37267794895ff2ab47a30c094e63 + 921922eeae800011ab13ddb5402644b86d832df0 - + https://github.com/dotnet/llvm-project - 89f53d2cb6cd37267794895ff2ab47a30c094e63 + 921922eeae800011ab13ddb5402644b86d832df0 https://github.com/dotnet/runtime @@ -170,13 +170,13 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - 6e17588c5e0c1804312d81e98dceeab5eb7f6f1f + ffec224a2a69f0cde4c43d9c90090dcb294ca6c6 - + https://github.com/dotnet/xharness - a8346dcc301875ef9cede0500f3736a73dbbc3cf + 5365f3db98459bc56b1faa2d73657269ab5b8956 diff --git a/eng/Versions.props b/eng/Versions.props index dca797f403a22..457e9a4a90704 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -57,16 +57,16 @@ - 5.0.0-beta.20256.5 - 5.0.0-beta.20256.5 - 5.0.0-beta.20256.5 + 5.0.0-beta.20258.8 + 5.0.0-beta.20258.8 + 5.0.0-beta.20258.8 5.0.0-beta.20258.8 - 5.0.0-beta.20256.5 - 5.0.0-beta.20256.5 - 2.5.1-beta.20256.5 - 5.0.0-beta.20256.5 - 5.0.0-beta.20256.5 - 5.0.0-beta.20256.5 + 5.0.0-beta.20258.8 + 5.0.0-beta.20258.8 + 2.5.1-beta.20258.8 + 5.0.0-beta.20258.8 + 5.0.0-beta.20258.8 + 5.0.0-beta.20258.8 5.0.0-preview.4.20202.18 5.0.0-preview.4.20202.18 @@ -113,7 +113,7 @@ 4.8.0 16.7.0-preview-20200429-01 - 1.0.0-prerelease.20257.4 + 1.0.0-prerelease.20261.4 2.4.1 1.2.1 2.0.5 @@ -122,14 +122,14 @@ 3.1.0-preview-20200129.1 - 5.0.0-preview.3.20257.4 + 5.0.0-preview.3.20261.2 - 6.0.1-alpha.1.20261.1 - 6.0.1-alpha.1.20261.1 - 6.0.1-alpha.1.20261.1 - 6.0.1-alpha.1.20261.1 - 6.0.1-alpha.1.20261.1 - 6.0.1-alpha.1.20261.1 + 6.0.1-alpha.1.20261.3 + 6.0.1-alpha.1.20261.3 + 6.0.1-alpha.1.20261.3 + 6.0.1-alpha.1.20261.3 + 6.0.1-alpha.1.20261.3 + 6.0.1-alpha.1.20261.3 diff --git a/eng/common/build.ps1 b/eng/common/build.ps1 index 813d440d2a834..67ee6d28d3faa 100644 --- a/eng/common/build.ps1 +++ b/eng/common/build.ps1 @@ -20,6 +20,7 @@ Param( [switch] $publish, [switch] $clean, [switch][Alias('bl')]$binaryLog, + [switch][Alias('nobl')]$excludeCIBinarylog, [switch] $ci, [switch] $prepareMachine, [switch] $help, @@ -58,6 +59,7 @@ function Print-Usage() { Write-Host "Advanced settings:" Write-Host " -projects Semi-colon delimited list of sln/proj's to build. Globbing is supported (*.sln)" Write-Host " -ci Set when running on CI server" + Write-Host " -excludeCIBinarylog Don't output binary log (short: -nobl)" Write-Host " -prepareMachine Prepare machine for CI run, clean up processes after build" Write-Host " -warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" Write-Host " -msbuildEngine Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)." @@ -134,7 +136,9 @@ try { } if ($ci) { - $binaryLog = $true + if (-not $excludeCIBinarylog) { + $binaryLog = $true + } $nodeReuse = $false } diff --git a/eng/common/build.sh b/eng/common/build.sh index 36f9aa0462ee1..6d7c5a1f69c20 100755 --- a/eng/common/build.sh +++ b/eng/common/build.sh @@ -32,6 +32,7 @@ usage() echo "Advanced settings:" echo " --projects Project or solution file(s) to build" echo " --ci Set when running on CI server" + echo " --excludeCIBinarylog Don't output binary log (short: -nobl)" echo " --prepareMachine Prepare machine for CI run, clean up processes after build" echo " --nodeReuse Sets nodereuse msbuild parameter ('true' or 'false')" echo " --warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" @@ -68,6 +69,7 @@ clean=false warn_as_error=true node_reuse=true binary_log=false +exclude_ci_binary_log=false pipelines_log=false projects='' @@ -98,6 +100,9 @@ while [[ $# > 0 ]]; do -binarylog|-bl) binary_log=true ;; + -excludeCIBinarylog|-nobl) + exclude_ci_binary_log=true + ;; -pipelineslog|-pl) pipelines_log=true ;; @@ -156,8 +161,10 @@ done if [[ "$ci" == true ]]; then pipelines_log=true - binary_log=true node_reuse=false + if [[ "$exclude_ci_binary_log" == false ]]; then + binary_log=true + fi fi . "$scriptroot/tools.sh" diff --git a/eng/common/post-build/symbols-validation.ps1 b/eng/common/post-build/symbols-validation.ps1 index 22eeb2656a2bf..8e9527113ca08 100644 --- a/eng/common/post-build/symbols-validation.ps1 +++ b/eng/common/post-build/symbols-validation.ps1 @@ -2,7 +2,8 @@ param( [Parameter(Mandatory=$true)][string] $InputPath, # Full path to directory where NuGet packages to be checked are stored [Parameter(Mandatory=$true)][string] $ExtractPath, # Full path to directory where the packages will be extracted during validation [Parameter(Mandatory=$true)][string] $DotnetSymbolVersion, # Version of dotnet symbol to use - [Parameter(Mandatory=$false)][switch] $ContinueOnError # If we should keep checking symbols after an error + [Parameter(Mandatory=$false)][switch] $ContinueOnError, # If we should keep checking symbols after an error + [Parameter(Mandatory=$false)][switch] $Clean # Clean extracted symbols directory after checking symbols ) function FirstMatchingSymbolDescriptionOrDefault { @@ -81,7 +82,14 @@ function CountMissingSymbols { $ExtractPath = Join-Path -Path $ExtractPath -ChildPath $PackageGuid $SymbolsPath = Join-Path -Path $ExtractPath -ChildPath 'Symbols' - [System.IO.Compression.ZipFile]::ExtractToDirectory($PackagePath, $ExtractPath) + try { + [System.IO.Compression.ZipFile]::ExtractToDirectory($PackagePath, $ExtractPath) + } + catch { + Write-Host "Something went wrong extracting $PackagePath" + Write-Host $_ + return -1 + } Get-ChildItem -Recurse $ExtractPath | Where-Object {$RelevantExtensions -contains $_.Extension} | @@ -116,6 +124,10 @@ function CountMissingSymbols { } } + if ($Clean) { + Remove-Item $ExtractPath -Recurse -Force + } + Pop-Location return $MissingSymbols @@ -151,7 +163,7 @@ function CheckSymbolsAvailable { if ($Status -ne 0) { Write-PipelineTelemetryError -Category 'CheckSymbols' -Message "Missing symbols for $Status modules in the package $FileName" - + if ($ContinueOnError) { $TotalFailures++ } diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index 47be0bedd71d4..b51bc5375ecf0 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -40,6 +40,8 @@ parameters: Net5Preview3ChannelId: 739 Net5Preview4ChannelId: 856 Net5Preview5ChannelId: 857 + NetCoreSDK313xxChannelId: 759 + NetCoreSDK313xxInternalChannelId: 760 NetCoreSDK314xxChannelId: 921 NetCoreSDK314xxInternalChannelId: 922 @@ -66,7 +68,7 @@ stages: inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/check-channel-consistency.ps1 arguments: -PromoteToChannels "$(TargetChannels)" - -AvailableChannelIds ${{parameters.NetEngLatestChannelId}},${{parameters.NetEngValidationChannelId}},${{parameters.NetDev5ChannelId}},${{parameters.GeneralTestingChannelId}},${{parameters.NETCoreToolingDevChannelId}},${{parameters.NETCoreToolingReleaseChannelId}},${{parameters.NETInternalToolingChannelId}},${{parameters.NETCoreExperimentalChannelId}},${{parameters.NetEngServicesIntChannelId}},${{parameters.NetEngServicesProdChannelId}},${{parameters.Net5Preview3ChannelId}},${{parameters.Net5Preview4ChannelId}},${{parameters.Net5Preview5ChannelId}},${{parameters.NetCoreSDK314xxChannelId}},${{parameters.NetCoreSDK314xxInternalChannelId}} + -AvailableChannelIds ${{parameters.NetEngLatestChannelId}},${{parameters.NetEngValidationChannelId}},${{parameters.NetDev5ChannelId}},${{parameters.GeneralTestingChannelId}},${{parameters.NETCoreToolingDevChannelId}},${{parameters.NETCoreToolingReleaseChannelId}},${{parameters.NETInternalToolingChannelId}},${{parameters.NETCoreExperimentalChannelId}},${{parameters.NetEngServicesIntChannelId}},${{parameters.NetEngServicesProdChannelId}},${{parameters.Net5Preview3ChannelId}},${{parameters.Net5Preview4ChannelId}},${{parameters.Net5Preview5ChannelId}},${{parameters.NetCoreSDK313xxChannelId}},${{parameters.NetCoreSDK313xxInternalChannelId}},${{parameters.NetCoreSDK314xxChannelId}},${{parameters.NetCoreSDK314xxInternalChannelId}} - job: displayName: NuGet Validation @@ -408,3 +410,29 @@ stages: transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json' shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json' symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-symbols/nuget/v3/index.json' + +- template: \eng\common\templates\post-build\channels\generic-public-channel.yml + parameters: + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'NETCore_SDK_313xx_Publishing' + channelName: '.NET Core SDK 3.1.3xx' + channelId: ${{ parameters.NetCoreSDK313xxChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json' + +- template: \eng\common\templates\post-build\channels\generic-internal-channel.yml + parameters: + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} + publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} + symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} + stageName: 'NETCore_SDK_313xx_Internal_Publishing' + channelName: '.NET Core SDK 3.1.3xx Internal' + channelId: ${{ parameters.NetCoreSDK313xxInternalChannelId }} + transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-symbols/nuget/v3/index.json' diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index f31377a6be54c..d8dfc5e00498c 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -7,9 +7,11 @@ # Build configuration. Common values include 'Debug' and 'Release', but the repository may use other names. [string]$configuration = if (Test-Path variable:configuration) { $configuration } else { 'Debug' } +# Set to true to opt out of outputting binary log while running in CI +[bool]$excludeCIBinarylog = if (Test-Path variable:excludeCIBinarylog) { $excludeCIBinarylog } else { $false } + # Set to true to output binary log from msbuild. Note that emitting binary log slows down the build. -# Binary log must be enabled on CI. -[bool]$binaryLog = if (Test-Path variable:binaryLog) { $binaryLog } else { $ci } +[bool]$binaryLog = if (Test-Path variable:binaryLog) { $binaryLog } else { $ci -and !$excludeCIBinarylog } # Set to true to use the pipelines logger which will enable Azure logging output. # https://github.com/Microsoft/azure-pipelines-tasks/blob/master/docs/authoring/commands.md @@ -55,10 +57,8 @@ set-strictmode -version 2.0 $ErrorActionPreference = 'Stop' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -function Create-Directory([string[]] $path) { - if (!(Test-Path $path)) { - New-Item -path $path -force -itemType 'Directory' | Out-Null - } +function Create-Directory ([string[]] $path) { + New-Item -Path $path -Force -ItemType 'Directory' | Out-Null } function Unzip([string]$zipfile, [string]$outpath) { @@ -605,8 +605,8 @@ function MSBuild() { # function MSBuild-Core() { if ($ci) { - if (!$binaryLog) { - Write-PipelineTelemetryError -Category 'Build' -Message 'Binary log must be enabled in CI build.' + if (!$binaryLog -and !$excludeCIBinarylog) { + Write-PipelineTelemetryError -Category 'Build' -Message 'Binary log must be enabled in CI build, or explicitly opted-out from with the -excludeCIBinarylog switch.' ExitWithExitCode 1 } diff --git a/eng/common/tools.sh b/eng/common/tools.sh index a9dff4408c234..e94fce22ec37b 100755 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -18,9 +18,17 @@ fi # Build configuration. Common values include 'Debug' and 'Release', but the repository may use other names. configuration=${configuration:-'Debug'} +# Set to true to opt out of outputting binary log while running in CI +exclude_ci_binary_log=${exclude_ci_binary_log:-false} + +if [[ "$ci" == true && "$exclude_ci_binary_log" == false ]]; then + binary_log_default=true +else + binary_log_default=false +fi + # Set to true to output binary log from msbuild. Note that emitting binary log slows down the build. -# Binary log must be enabled on CI. -binary_log=${binary_log:-$ci} +binary_log=${binary_log:-$binary_log_default} # Turns on machine preparation/clean up code that changes the machine state (e.g. kills build processes). prepare_machine=${prepare_machine:-false} @@ -404,8 +412,8 @@ function MSBuild { function MSBuild-Core { if [[ "$ci" == true ]]; then - if [[ "$binary_log" != true ]]; then - Write-PipelineTelemetryError -category 'Build' "Binary log must be enabled in CI build." + if [[ "$binary_log" != true && "$exclude_ci_binary_log" != true ]]; then + Write-PipelineTelemetryError -category 'Build' "Binary log must be enabled in CI build, or explicitly opted-out from with the -noBinaryLog switch." ExitWithExitCode 1 fi diff --git a/global.json b/global.json index b2f8615d5d8a8..e4fb17844fd35 100644 --- a/global.json +++ b/global.json @@ -12,10 +12,10 @@ "python3": "3.7.1" }, "msbuild-sdks": { - "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20256.5", - "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20256.5", - "Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.20256.5", - "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20256.5", + "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20258.8", + "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20258.8", + "Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.20258.8", + "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20258.8", "FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0", "Microsoft.NET.Sdk.IL": "5.0.0-preview.4.20202.18", "Microsoft.Build.NoTargets": "1.0.53", From df8e2d751ef852bb5c440ae4dfb5d7cde000a4d4 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Tue, 12 May 2020 09:49:05 -0700 Subject: [PATCH 131/420] Update testing.md (#36286) --- docs/workflow/testing/libraries/testing.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/workflow/testing/libraries/testing.md b/docs/workflow/testing/libraries/testing.md index 986d0e9606e4c..9ab30e12be41a 100644 --- a/docs/workflow/testing/libraries/testing.md +++ b/docs/workflow/testing/libraries/testing.md @@ -12,18 +12,18 @@ build.cmd/sh -subset libs.tests - The following builds and runs all tests in release configuration: ``` -build.cmd/sh -subset libs -test -c Release +build.cmd/sh -subset libs.tests -test -c Release ``` - The following example shows how to pass extra msbuild properties to ignore tests ignored in CI: ``` -build.cmd/sh -subset libs -test /p:WithoutCategories=IgnoreForCI +build.cmd/sh -subset libs.tests -test /p:WithoutCategories=IgnoreForCI ``` Unless you specifiy `-testnobuild`, test assemblies are implicitly built when invoking the `Test` action. - The following shows how to only test the libraries without building them ``` -build.cmd/sh -subset libs -test -testnobuild +build.cmd/sh -subset libs.tests -test -testnobuild ``` ## Running tests on the command line @@ -38,7 +38,7 @@ dotnet build /t:Test It is possible to pass parameters to the underlying xunit runner via the `XUnitOptions` parameter, e.g.: ```cmd -dotnet build /t:Test "/p:XUnitOptions=-class Test.ClassUnderTests" +dotnet build /t:Test /p:XUnitOptions="-class Test.ClassUnderTests" ``` There may be multiple projects in some directories so you may need to specify the path to a specific test project to get it to build and run the tests. From 583fa67ff9551784456b876d2ea30bc9697077b7 Mon Sep 17 00:00:00 2001 From: Youssef Victor <31348972+Youssef1313@users.noreply.github.com> Date: Tue, 12 May 2020 18:50:06 +0200 Subject: [PATCH 132/420] Use CopyTo(arr) instead of creating List first (#36228) * Use LINQ ToArray * Update RoType.cs * Update RoType.cs * Update src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs Co-authored-by: Stephen Toub * Fix whitespace causing analyzer warnings Co-authored-by: Stephen Toub --- .../src/System/Reflection/TypeLoading/Types/RoType.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs index ea73a31460503..b88f8a42fc3e8 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs @@ -192,9 +192,14 @@ private RoType[] ComputeInterfaceClosure() } } - // todo: use IEnumerable extension: return ifcs.ToArray() - List list = new List(ifcs); - return list.ToArray(); + if (ifcs.Count == 0) + { + return Array.Empty(); + } + + var arr = new RoType[ifcs.Count]; + ifcs.CopyTo(arr); + return arr; } private volatile RoType[]? _lazyInterfaces; From f8410edc074b9189b5f1c997c779a09f906fb6f4 Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Tue, 12 May 2020 13:16:16 -0400 Subject: [PATCH 133/420] [mono] Don't throw inheritance error on interfaces in IsDefined (#35516) Issue is very similar to the one fixed in https://github.com/dotnet/runtime/commit/3df21ae60ec7de12abc77f4cc329903abe9ea542. When adding the error messages, we were too strict on when to throw. This should hopefully avoid all that by being significantly more lax. Test moved to be in a location better suited to both examples. Fixes https://github.com/dotnet/runtime/issues/35514 --- .../System.Runtime/tests/System/Attributes.cs | 26 +++++++++++++++++++ .../tests/System/Type/TypeTests.Get.cs | 20 -------------- .../src/System/Attribute.Mono.cs | 3 ++- .../src/System/Reflection/CustomAttribute.cs | 2 +- 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/libraries/System.Runtime/tests/System/Attributes.cs b/src/libraries/System.Runtime/tests/System/Attributes.cs index d56a39850df29..92926dab8c377 100644 --- a/src/libraries/System.Runtime/tests/System/Attributes.cs +++ b/src/libraries/System.Runtime/tests/System/Attributes.cs @@ -81,6 +81,12 @@ public void IsDefined_PropertyInfo_Override() Assert.False(Attribute.IsDefined(pi, typeof(ComVisibleAttribute), false)); Assert.False(Attribute.IsDefined(pi, typeof(ComVisibleAttribute), true)); } + + [Fact] + public void IsDefined_Interface() + { + Assert.True(typeof(ExampleWithAttribute).IsDefined(typeof(INameable), false)); + } } public static class AttributeGetCustomAttributes @@ -206,6 +212,12 @@ public static void MultipleAttributesTest() Assert.Equal("System.Tests.MyCustomAttribute System.Tests.MyCustomAttribute", string.Join(" ", typeof(MultipleAttributes).GetCustomAttributes(inherit: false))); Assert.Equal("System.Tests.MyCustomAttribute System.Tests.MyCustomAttribute", string.Join(" ", typeof(MultipleAttributes).GetCustomAttributes(inherit: true))); } + + [Fact] + public static void GetCustomAttributes_Interface() + { + Assert.True(typeof(ExampleWithAttribute).GetCustomAttributes(typeof(INameable), inherit: false)[0] is NameableAttribute); + } } public static class GetCustomAttribute @@ -798,4 +810,18 @@ public override string PropBase3 class MultipleAttributes { } + + public interface INameable + { + string Name { get; } + } + + [AttributeUsage (AttributeTargets.All, AllowMultiple = true)] + public class NameableAttribute : Attribute, INameable + { + string INameable.Name => "Nameable"; + } + + [Nameable] + public class ExampleWithAttribute { } } diff --git a/src/libraries/System.Runtime/tests/System/Type/TypeTests.Get.cs b/src/libraries/System.Runtime/tests/System/Type/TypeTests.Get.cs index 124687962d0f0..5f19479bc6211 100644 --- a/src/libraries/System.Runtime/tests/System/Type/TypeTests.Get.cs +++ b/src/libraries/System.Runtime/tests/System/Type/TypeTests.Get.cs @@ -91,12 +91,6 @@ public void GetInterface_MixedCaseAmbiguity_ThrowsAmbiguousMatchException() { Assert.Throws(() => typeof(ClassWithMixedCaseInterfaces).GetInterface("mixedinterface", ignoreCase: true)); } - - [Fact] - public void GetCustomAttributes_Interface() - { - Assert.True(typeof(ExampleWithAttribute).GetCustomAttributes(typeof(INameable), inherit: false)[0] is NameableAttribute); - } } public class ClassWithNoInterfaces { } @@ -122,20 +116,6 @@ public interface Interface1 { } public interface Interface2 { } public interface Interface3 { } } - - public interface INameable - { - string Name { get; } - } - - [AttributeUsage (AttributeTargets.All, AllowMultiple=true)] - public class NameableAttribute : Attribute, INameable - { - string INameable.Name => "Nameable"; - } - - [Nameable] - public class ExampleWithAttribute { } } public interface Interface1 { } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Attribute.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Attribute.Mono.cs index fc6c82a6dcc5f..c362e7792c1f6 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Attribute.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Attribute.Mono.cs @@ -12,7 +12,8 @@ public partial class Attribute { if (attributeType == null) throw new ArgumentNullException(nameof(attributeType)); - if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute) && attributeType != typeof(CustomAttribute)) + if (!attributeType.IsSubclassOf(typeof(Attribute)) && !attributeType.IsInterface + && attributeType != typeof(Attribute) && attributeType != typeof(CustomAttribute)) throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass + " " + attributeType.FullName); object[] attrs = CustomAttribute.GetCustomAttributes(element, attributeType, inherit); diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs index e21888056a3fa..76c1e4e8b529c 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs @@ -551,7 +551,7 @@ internal static bool IsDefined(ICustomAttributeProvider obj, Type attributeType, { if (attributeType == null) throw new ArgumentNullException(nameof(attributeType)); - if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute)) + if (!attributeType.IsSubclassOf(typeof(Attribute)) && !attributeType.IsInterface && attributeType != typeof(Attribute)) throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass + " " + attributeType.FullName); AttributeUsageAttribute? usage = null; From 14094d2a6363d9aa40d39ffa63b52279be3e4ce6 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Lopez <1175054+carlossanlop@users.noreply.github.com> Date: Tue, 12 May 2020 10:43:28 -0700 Subject: [PATCH 134/420] Apply CA1835 - Prefer memory overloads for Stream.ReadAsync/WriteAsync (#35941) * Apply CA1835 Roslyn fixes on .NET Libraries - Prefer the Stream.ReadAsync and Stream.WriteAsync memory overloads. - Unit test fix suggested by buyaa-n to adjust the usage of these overloads. * Additional missing unit test overload for ReadOnlyMemory --- .../src/System/Net/BufferedReadStream.cs | 2 +- .../tests/misc/LoadSaveAsyncTests.cs | 6 ++++++ .../System/Xml/Core/XmlEncodedRawTextWriterAsync.cs | 6 +++--- .../Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude | 8 ++++---- .../src/System/Xml/Core/XmlTextReaderImplAsync.cs | 6 +++--- .../src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs | 2 +- .../System.Private.Xml/tests/XmlWriter/DisposeTests.cs | 10 ++++++++++ .../src/System/IO/StreamOperationsImplementation.cs | 4 ++-- .../System/Text/Json/Document/JsonDocument.Parse.cs | 8 ++++++++ .../src/System/Media/SoundPlayer.cs | 4 ++-- 10 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/libraries/System.Net.Mail/src/System/Net/BufferedReadStream.cs b/src/libraries/System.Net.Mail/src/System/Net/BufferedReadStream.cs index 95f851e240dc6..c9f5c51e5c346 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/BufferedReadStream.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/BufferedReadStream.cs @@ -97,7 +97,7 @@ public override Task ReadAsync(byte[] buffer, int offset, int count, Cancel private async Task ReadMoreAsync(int bytesAlreadyRead, byte[] buffer, int offset, int count, CancellationToken cancellationToken) { - int returnValue = await base.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); + int returnValue = await base.ReadAsync(buffer.AsMemory(offset, count), cancellationToken).ConfigureAwait(false); return bytesAlreadyRead + returnValue; } diff --git a/src/libraries/System.Private.Xml.Linq/tests/misc/LoadSaveAsyncTests.cs b/src/libraries/System.Private.Xml.Linq/tests/misc/LoadSaveAsyncTests.cs index 2e9db3bc282ca..774c7bc4540ec 100644 --- a/src/libraries/System.Private.Xml.Linq/tests/misc/LoadSaveAsyncTests.cs +++ b/src/libraries/System.Private.Xml.Linq/tests/misc/LoadSaveAsyncTests.cs @@ -415,6 +415,12 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati Assert.True(_isAsync, "Stream is not in asynchronous mode when asynchronous Write is called"); return Task.CompletedTask; } + + public override ValueTask WriteAsync(ReadOnlyMemory source, CancellationToken cancellationToken = default) + { + Assert.True(_isAsync, "Stream is not in asynchronous mode when asynchronous Write is called"); + return default; + } } public class CheckSyncAsyncStream : Stream diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.cs index 13a694c1f98aa..dadeda60d0756 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.cs @@ -645,7 +645,7 @@ protected virtual async Task FlushBufferAsync() if (bufPos - 1 > 0) { // Write text to TextWriter - await writer.WriteAsync(bufChars, 1, bufPos - 1).ConfigureAwait(false); + await writer.WriteAsync(bufChars.AsMemory(1, bufPos - 1)).ConfigureAwait(false); } } } @@ -688,13 +688,13 @@ private async Task EncodeCharsAsync(int startOffset, int endOffset, bool writeAl bufBytesUsed += bEnc; if (bufBytesUsed >= (bufBytes.Length - 16)) { - await stream.WriteAsync(bufBytes, 0, bufBytesUsed).ConfigureAwait(false); + await stream.WriteAsync(bufBytes.AsMemory(0, bufBytesUsed)).ConfigureAwait(false); bufBytesUsed = 0; } } if (writeAllToStream && bufBytesUsed > 0) { - await stream.WriteAsync(bufBytes, 0, bufBytesUsed).ConfigureAwait(false); + await stream.WriteAsync(bufBytes.AsMemory(0, bufBytesUsed)).ConfigureAwait(false); bufBytesUsed = 0; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude index 52032722d5d9a..a87f83b553c79 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude @@ -624,7 +624,7 @@ namespace System.Xml if (bufPos - 1 > 0) { Debug.Assert(stream != null); - await stream.WriteAsync(bufBytes, 1, bufPos - 1).ConfigureAwait(false); + await stream.WriteAsync(bufBytes.AsMemory(1, bufPos - 1)).ConfigureAwait(false); } <# } else { #> Debug.Assert(stream != null || writer != null); @@ -656,7 +656,7 @@ namespace System.Xml if (bufPos - 1 > 0) { // Write text to TextWriter - await writer.WriteAsync(<#= BufferName #>, 1, bufPos - 1).ConfigureAwait(false); + await writer.WriteAsync(<#= BufferName #>.AsMemory(1, bufPos - 1)).ConfigureAwait(false); } } <# } #> @@ -711,13 +711,13 @@ namespace System.Xml bufBytesUsed += bEnc; if (bufBytesUsed >= (bufBytes.Length - 16)) { - await stream.WriteAsync(bufBytes, 0, bufBytesUsed).ConfigureAwait(false); + await stream.WriteAsync(bufBytes.AsMemory(0, bufBytesUsed)).ConfigureAwait(false); bufBytesUsed = 0; } } if (writeAllToStream && bufBytesUsed > 0) { - await stream.WriteAsync(bufBytes, 0, bufBytesUsed).ConfigureAwait(false); + await stream.WriteAsync(bufBytes.AsMemory(0, bufBytesUsed)).ConfigureAwait(false); bufBytesUsed = 0; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImplAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImplAsync.cs index a6e8135b92176..50a457599f8f0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImplAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImplAsync.cs @@ -975,7 +975,7 @@ private async Task InitStreamInputAsync(Uri baseUri, string baseUriStr, Stream s _ps.bytePos = 0; while (_ps.bytesUsed < 4 && _ps.bytes.Length - _ps.bytesUsed > 0) { - int read = await stream.ReadAsync(_ps.bytes, _ps.bytesUsed, _ps.bytes.Length - _ps.bytesUsed).ConfigureAwait(false); + int read = await stream.ReadAsync(_ps.bytes.AsMemory(_ps.bytesUsed)).ConfigureAwait(false); if (read == 0) { _ps.isStreamEof = true; @@ -1192,7 +1192,7 @@ private async Task ReadDataAsync() // read new bytes if (_ps.bytePos == _ps.bytesUsed && _ps.bytes.Length - _ps.bytesUsed > 0) { - int read = await _ps.stream.ReadAsync(_ps.bytes, _ps.bytesUsed, _ps.bytes.Length - _ps.bytesUsed).ConfigureAwait(false); + int read = await _ps.stream.ReadAsync(_ps.bytes.AsMemory(_ps.bytesUsed)).ConfigureAwait(false); if (read == 0) { _ps.isStreamEof = true; @@ -1214,7 +1214,7 @@ private async Task ReadDataAsync() else if (_ps.textReader != null) { // read chars - charsRead = await _ps.textReader.ReadAsync(_ps.chars, _ps.charsUsed, _ps.chars.Length - _ps.charsUsed - 1).ConfigureAwait(false); + charsRead = await _ps.textReader.ReadAsync(_ps.chars.AsMemory(_ps.charsUsed, _ps.chars.Length - _ps.charsUsed - 1)).ConfigureAwait(false); _ps.charsUsed += charsRead; } else diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs index d4916eb83445a..950ebe60acd85 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs @@ -552,7 +552,7 @@ protected virtual async Task FlushBufferAsync() if (bufPos - 1 > 0) { Debug.Assert(stream != null); - await stream.WriteAsync(bufBytes, 1, bufPos - 1).ConfigureAwait(false); + await stream.WriteAsync(bufBytes.AsMemory(1, bufPos - 1)).ConfigureAwait(false); } } } diff --git a/src/libraries/System.Private.Xml/tests/XmlWriter/DisposeTests.cs b/src/libraries/System.Private.Xml/tests/XmlWriter/DisposeTests.cs index 7701003b2c186..1c1c2ef314263 100644 --- a/src/libraries/System.Private.Xml/tests/XmlWriter/DisposeTests.cs +++ b/src/libraries/System.Private.Xml/tests/XmlWriter/DisposeTests.cs @@ -255,6 +255,11 @@ public override Task WriteAsync(char[] buffer, int offset, int count) { return Task.CompletedTask; } + + public override Task WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } } internal class AsyncOnlyStream : MemoryStream @@ -278,6 +283,11 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati { return Task.CompletedTask; } + + public override ValueTask WriteAsync(ReadOnlyMemory source, CancellationToken cancellationToken = default) + { + return default; + } } } } diff --git a/src/libraries/System.Runtime.WindowsRuntime/src/System/IO/StreamOperationsImplementation.cs b/src/libraries/System.Runtime.WindowsRuntime/src/System/IO/StreamOperationsImplementation.cs index 9414d9f042cc2..5fd829c8ed949 100644 --- a/src/libraries/System.Runtime.WindowsRuntime/src/System/IO/StreamOperationsImplementation.cs +++ b/src/libraries/System.Runtime.WindowsRuntime/src/System/IO/StreamOperationsImplementation.cs @@ -111,7 +111,7 @@ internal static class StreamOperationsImplementation try { // Read asynchronously: - bytesRead = await stream.ReadAsync(data!, offset + bytesCompleted, bytesRequested - bytesCompleted, cancelToken) + bytesRead = await stream.ReadAsync(data!.AsMemory(offset + bytesCompleted, bytesRequested - bytesCompleted), cancelToken) .ConfigureAwait(continueOnCapturedContext: false); // We will continue here on a different thread when read async completed: @@ -181,7 +181,7 @@ internal static class StreamOperationsImplementation int bytesToWrite = (int)buffer.Length; - await stream.WriteAsync(data, offset, bytesToWrite, cancelToken).ConfigureAwait(continueOnCapturedContext: false); + await stream.WriteAsync(data.AsMemory(offset, bytesToWrite), cancelToken).ConfigureAwait(continueOnCapturedContext: false); if (progressListener != null) progressListener.Report((uint)bytesToWrite); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.Parse.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.Parse.cs index 0ffe89e51e823..49770ef3f5f67 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.Parse.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.Parse.cs @@ -675,9 +675,13 @@ private static async Debug.Assert(rented.Length >= JsonConstants.Utf8Bom.Length); lastRead = await stream.ReadAsync( +#if BUILDING_INBOX_LIBRARY + rented.AsMemory(written, utf8BomLength - written), +#else rented, written, utf8BomLength - written, +#endif cancellationToken).ConfigureAwait(false); written += lastRead; @@ -702,9 +706,13 @@ private static async } lastRead = await stream.ReadAsync( +#if BUILDING_INBOX_LIBRARY + rented.AsMemory(written), +#else rented, written, rented.Length - written, +#endif cancellationToken).ConfigureAwait(false); written += lastRead; diff --git a/src/libraries/System.Windows.Extensions/src/System/Media/SoundPlayer.cs b/src/libraries/System.Windows.Extensions/src/System/Media/SoundPlayer.cs index 69d474b8803a1..ae9cd72ae2e24 100644 --- a/src/libraries/System.Windows.Extensions/src/System/Media/SoundPlayer.cs +++ b/src/libraries/System.Windows.Extensions/src/System/Media/SoundPlayer.cs @@ -489,7 +489,7 @@ private async Task CopyStreamAsync(CancellationToken cancellationToken) _streamData = new byte[BlockSize]; - int readBytes = await _stream.ReadAsync(_streamData, _currentPos, BlockSize, cancellationToken).ConfigureAwait(false); + int readBytes = await _stream.ReadAsync(_streamData.AsMemory(_currentPos, BlockSize), cancellationToken).ConfigureAwait(false); int totalBytes = readBytes; while (readBytes > 0) @@ -501,7 +501,7 @@ private async Task CopyStreamAsync(CancellationToken cancellationToken) Array.Copy(_streamData, newData, _streamData.Length); _streamData = newData; } - readBytes = await _stream.ReadAsync(_streamData, _currentPos, BlockSize, cancellationToken).ConfigureAwait(false); + readBytes = await _stream.ReadAsync(_streamData.AsMemory(_currentPos, BlockSize), cancellationToken).ConfigureAwait(false); totalBytes += readBytes; } From 67bf042d4838b9ea9fcec00b94ba015ca4fb5b56 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Tue, 12 May 2020 19:52:35 +0200 Subject: [PATCH 135/420] Minor MethodTable building optimization (#36283) When learning on how virtual method overriding is implemented in the runtime, I've bumped into two places where we were calling MapToImplSlotNumber twice in a row without any reason. Since this method isn't trivial, it seems worth fixing. --- src/coreclr/src/vm/methodtable.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/vm/methodtable.cpp b/src/coreclr/src/vm/methodtable.cpp index 60925514bb715..2332f44e98371 100644 --- a/src/coreclr/src/vm/methodtable.cpp +++ b/src/coreclr/src/vm/methodtable.cpp @@ -8617,7 +8617,7 @@ MethodDesc *MethodTable::MethodDataInterfaceImpl::GetImplMethodDesc(UINT32 slotN if (implSlotNumber == INVALID_SLOT_NUMBER) { return NULL; } - return m_pImpl->GetImplMethodDesc(MapToImplSlotNumber(slotNumber)); + return m_pImpl->GetImplMethodDesc(implSlotNumber); } //========================================================================================== @@ -8628,7 +8628,7 @@ void MethodTable::MethodDataInterfaceImpl::InvalidateCachedVirtualSlot(UINT32 sl if (implSlotNumber == INVALID_SLOT_NUMBER) { return; } - return m_pImpl->InvalidateCachedVirtualSlot(MapToImplSlotNumber(slotNumber)); + return m_pImpl->InvalidateCachedVirtualSlot(implSlotNumber); } //========================================================================================== From 8ab694028f2cb37a1a92073fa348e48644fdf10b Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 12 May 2020 13:04:48 -0500 Subject: [PATCH 136/420] Fix build break by bumping DependencyModel package version (#36285) --- src/libraries/pkg/baseline/packageIndex.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libraries/pkg/baseline/packageIndex.json b/src/libraries/pkg/baseline/packageIndex.json index 5a90065e0e664..bf8e67b252645 100644 --- a/src/libraries/pkg/baseline/packageIndex.json +++ b/src/libraries/pkg/baseline/packageIndex.json @@ -543,12 +543,13 @@ "3.1.0", "3.1.1", "3.1.2", - "3.1.3" + "3.1.3", + "3.1.4" ], "BaselineVersion": "5.0.0", "InboxOn": {}, "AssemblyVersionInPackageVersion": { - "3.1.3.0": "5.0.0", + "3.1.4.0": "5.0.0", "5.0.0.0": "5.0.0" } }, From 14835fbb7fdb2065983866ac186ed8408ee9b388 Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Tue, 12 May 2020 12:54:18 -0700 Subject: [PATCH 137/420] Ignore the private key handle cert property for persisted keys When a CERT_CONTEXT value has both property 2 (prov info) and property 78 (ncrypt key handle), prefer to load based on the property 2 state. This avoids a scenario where calling Get[Algorithm]PrivateKey sets the 'CLR IsEphemeral' property on a persisted key, preventing future loads of that key. An alternative approach of preferring the loaded key over the cold-load was not selected to avoid value contamination of ephemeral properties set on the CngKey object directly after the caller calls Get[Algorithm]PrivateKey. --- .../Pal.Windows/CertificatePal.PrivateKey.cs | 3 +- .../tests/ExportTests.cs | 126 ++++++++++++++++++ 2 files changed, 128 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.PrivateKey.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.PrivateKey.cs index 5ba5eb0a55c26..2baabf516b325 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.PrivateKey.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.PrivateKey.cs @@ -215,8 +215,9 @@ public ICertificatePal CopyWithPrivateKey(RSA rsa) IntPtr privateKeyPtr; - // If the certificate has a key handle instead of a key prov info, return the + // If the certificate has a key handle without a key prov info, return the // ephemeral key + if (!certificateContext.HasPersistedPrivateKey) { int cbData = IntPtr.Size; diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/ExportTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/ExportTests.cs index c473d80895fa8..30a1b19bb6893 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/ExportTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/ExportTests.cs @@ -157,5 +157,131 @@ public static void ExportAsPfxWithPrivateKey() } } } + + [Fact] + [PlatformSpecific(TestPlatforms.Windows)] + [OuterLoop("Modifies user-persisted state")] + public static void ExportDoesNotCorruptPrivateKeyMethods() + { + string keyName = $"clrtest.{Guid.NewGuid():D}"; + X509Store cuMy = new X509Store(StoreName.My, StoreLocation.CurrentUser); + cuMy.Open(OpenFlags.ReadWrite); + X509Certificate2 createdCert = null; + X509Certificate2 foundCert = null; + X509Certificate2 foundCert2 = null; + + try + { + string commonName = nameof(ExportDoesNotCorruptPrivateKeyMethods); + string subject = $"CN={commonName},OU=.NET"; + + using (ImportedCollection toClean = new ImportedCollection(cuMy.Certificates)) + { + X509Certificate2Collection coll = toClean.Collection; + + using (ImportedCollection matches = + new ImportedCollection(coll.Find(X509FindType.FindBySubjectName, commonName, false))) + { + foreach (X509Certificate2 cert in matches.Collection) + { + cuMy.Remove(cert); + } + } + } + + foreach (X509Certificate2 cert in cuMy.Certificates) + { + if (subject.Equals(cert.Subject)) + { + cuMy.Remove(cert); + } + + cert.Dispose(); + } + + CngKeyCreationParameters options = new CngKeyCreationParameters + { + ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport, + }; + + using (CngKey key = CngKey.Create(CngAlgorithm.Rsa, keyName, options)) + using (RSACng rsaCng = new RSACng(key)) + { + CertificateRequest certReq = new CertificateRequest( + subject, + rsaCng, + HashAlgorithmName.SHA256, + RSASignaturePadding.Pkcs1); + + DateTimeOffset now = DateTimeOffset.UtcNow.AddMinutes(-5); + createdCert = certReq.CreateSelfSigned(now, now.AddDays(1)); + } + + cuMy.Add(createdCert); + + using (ImportedCollection toClean = new ImportedCollection(cuMy.Certificates)) + { + X509Certificate2Collection matches = toClean.Collection.Find( + X509FindType.FindBySubjectName, + commonName, + validOnly: false); + + Assert.Equal(1, matches.Count); + foundCert = matches[0]; + } + + Assert.False(HasEphemeralKey(foundCert)); + foundCert.Export(X509ContentType.Pfx, ""); + Assert.False(HasEphemeralKey(foundCert)); + + using (ImportedCollection toClean = new ImportedCollection(cuMy.Certificates)) + { + X509Certificate2Collection matches = toClean.Collection.Find( + X509FindType.FindBySubjectName, + commonName, + validOnly: false); + + Assert.Equal(1, matches.Count); + foundCert2 = matches[0]; + } + + Assert.False(HasEphemeralKey(foundCert2)); + } + finally + { + if (createdCert != null) + { + cuMy.Remove(createdCert); + createdCert.Dispose(); + } + + cuMy.Dispose(); + + foundCert?.Dispose(); + foundCert2?.Dispose(); + + try + { + CngKey key = CngKey.Open(keyName); + key.Delete(); + key.Dispose(); + } + catch (Exception) + { + } + } + + bool HasEphemeralKey(X509Certificate2 c) + { + using (RSA key = c.GetRSAPrivateKey()) + { + // This code is not defensive against the type changing, because it + // is in the source tree with the code that produces the value. + // Don't blind-cast like this in library or application code. + RSACng rsaCng = (RSACng)key; + return rsaCng.Key.IsEphemeral; + } + } + } } } From 7fb42d900a4e8949f1f55caf0aec258d8b723e5d Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 12 May 2020 15:09:17 -0500 Subject: [PATCH 138/420] Remove PlatformAbstractions from runtime tests. (#36243) * Remove PlatformAbstractions from runtime tests. Contributes to #3470 --- .../System/PlatformDetection.Unix.cs | 97 +++++++------------ .../TestUtilities/System/PlatformDetection.cs | 4 +- .../tests/TestUtilities/TestUtilities.csproj | 1 - .../tests/ReferenceAssemblyResolverTests.cs | 2 - .../DateTimeFormatInfoData.cs | 4 +- 5 files changed, 39 insertions(+), 69 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs index 4ecee83ba6693..38fb7d598ce0a 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs @@ -2,8 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.IO; using System.Runtime.InteropServices; -using System.Xml.Linq; namespace System { @@ -34,14 +34,10 @@ public static partial class PlatformDetection // OSX family public static bool IsOSX => RuntimeInformation.IsOSPlatform(OSPlatform.OSX); public static bool IsNotOSX => !IsOSX; - public static Version OSXVersion => IsOSX ? - ToVersion(Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment.OperatingSystemVersion) : - throw new PlatformNotSupportedException(); - private static Lazy m_osxProductVersion = new Lazy(GetOSXProductVersion); - public static bool IsMacOsHighSierraOrHigher => IsOSX && (m_osxProductVersion.Value.Major > 10 || (m_osxProductVersion.Value.Major == 10 && m_osxProductVersion.Value.Minor >= 13)); + public static bool IsMacOsHighSierraOrHigher => IsOSX && Environment.OSVersion.Version >= new Version(10, 13); public static bool IsNotMacOsHighSierraOrHigher => !IsMacOsHighSierraOrHigher; - public static bool IsMacOsMojaveOrHigher => IsOSX && (m_osxProductVersion.Value.Major > 10 || (m_osxProductVersion.Value.Major == 10 && m_osxProductVersion.Value.Minor >= 14)); - public static bool IsMacOsCatalinaOrHigher => IsOSX && (m_osxProductVersion.Value.Major > 10 || (m_osxProductVersion.Value.Major == 10 && m_osxProductVersion.Value.Minor >= 15)); + public static bool IsMacOsMojaveOrHigher => IsOSX && Environment.OSVersion.Version >= new Version(10, 14); + public static bool IsMacOsCatalinaOrHigher => IsOSX && Environment.OSVersion.Version >= new Version(10, 15); // RedHat family covers RedHat and CentOS public static bool IsRedHatFamily => IsRedHatFamilyAndVersion(); @@ -106,56 +102,6 @@ public static string LibcVersion } } - private static Version GetOSXProductVersion() - { - if (IsOSX) - { - try - { - // - // - // ProductBuildVersion - // 17A330h - // ProductCopyright - // 1983-2017 Apple Inc. - // ProductName - // Mac OS X - // ProductUserVisibleVersion - // 10.13 - // ProductVersion - // 10.13 - // - // - - XElement dict = XDocument.Load("/System/Library/CoreServices/SystemVersion.plist").Root.Element("dict"); - if (dict != null) - { - foreach (XElement key in dict.Elements("key")) - { - if ("ProductVersion".Equals(key.Value)) - { - XElement stringElement = key.NextNode as XElement; - if (stringElement != null && stringElement.Name.LocalName.Equals("string")) - { - string versionString = stringElement.Value; - if (versionString != null) - { - return Version.Parse(versionString); - } - } - } - } - } - } - catch - { - } - } - - // In case of exception, couldn't get the version or non osx - return new Version(0, 0, 0); - } - private static Version s_opensslVersion; private static Version GetOpenSslVersion() { @@ -204,11 +150,38 @@ private static Version ToVersion(string versionString) } } - private static DistroInfo GetDistroInfo() => new DistroInfo() + private static DistroInfo GetDistroInfo() { - Id = Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment.OperatingSystem, - VersionId = ToVersion(Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment.OperatingSystemVersion) - }; + DistroInfo result = new DistroInfo(); + + if (IsFreeBSD) + { + result.Id = "FreeBSD"; + // example: + // FreeBSD 11.0-RELEASE-p1 FreeBSD 11.0-RELEASE-p1 #0 r306420: Thu Sep 29 01:43:23 UTC 2016 root@releng2.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC + // What we want is major release as minor releases should be compatible. + result.VersionId = ToVersion(RuntimeInformation.OSDescription.Split()[1].Split('.')[0]); + } + else if (File.Exists("/etc/os-release")) + { + foreach (string line in File.ReadAllLines("/etc/os-release")) + { + if (line.StartsWith("ID=", StringComparison.Ordinal)) + { + result.Id = line.Substring(3).Trim('"', '\''); + } + else if (line.StartsWith("VERSION_ID=", StringComparison.Ordinal)) + { + result.VersionId = ToVersion(line.Substring(11).Trim('"', '\'')); + } + } + } + + result.Id ??= "Linux"; + result.VersionId ??= ToVersion(string.Empty); + + return result; + } private static bool IsRedHatFamilyAndVersion(int major = -1, int minor = -1, int build = -1, int revision = -1) { diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index 37fd12003365c..df828e0f7eeff 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -113,7 +113,7 @@ public static bool IsNonZeroLowerBoundArraySupported ((!IsOSX && !IsWindows) && (OpenSslVersion.Major >= 1 && (OpenSslVersion.Minor >= 1 || OpenSslVersion.Build >= 2))); - public static bool SupportsClientAlpn => SupportsAlpn || (IsOSX && PlatformDetection.OSXVersion > new Version(10, 12)); + public static bool SupportsClientAlpn => SupportsAlpn || (IsOSX && Environment.OSVersion.Version > new Version(10, 12)); // OpenSSL 1.1.1 and above. public static bool SupportsTls13 => GetTls13Support(); @@ -142,7 +142,7 @@ public static string GetDistroVersionString() } else if (IsOSX) { - return "OSX Version=" + m_osxProductVersion.Value.ToString(); + return "OSX Version=" + Environment.OSVersion.Version.ToString(); } else { diff --git a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj index a589043f2a565..b9207224c8709 100644 --- a/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj +++ b/src/libraries/Common/tests/TestUtilities/TestUtilities.csproj @@ -63,6 +63,5 @@ - diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/tests/ReferenceAssemblyResolverTests.cs b/src/libraries/Microsoft.Extensions.DependencyModel/tests/ReferenceAssemblyResolverTests.cs index 99f8fa4ed6c29..a165d17eacccd 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/tests/ReferenceAssemblyResolverTests.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/tests/ReferenceAssemblyResolverTests.cs @@ -6,8 +6,6 @@ using System.Collections.Generic; using System.IO; using FluentAssertions; -using Microsoft.DotNet.PlatformAbstractions; -using Microsoft.Extensions.DependencyModel; using Microsoft.Extensions.DependencyModel.Resolution; using Xunit; using F = Microsoft.Extensions.DependencyModel.Tests.TestLibraryFactory; diff --git a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoData.cs b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoData.cs index ed232bbf21593..3d370acb84319 100644 --- a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoData.cs +++ b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoData.cs @@ -29,7 +29,7 @@ public static string JaJPAbbreviatedEraName() public static string[] FrFRDayNames() { - if (PlatformDetection.IsOSX && PlatformDetection.OSXVersion < new Version(10, 12)) + if (PlatformDetection.IsOSX && Environment.OSVersion.Version < new Version(10, 12)) { return new string[] { "Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi" }; } @@ -38,7 +38,7 @@ public static string[] FrFRDayNames() public static string[] FrFRAbbreviatedDayNames() { - if (PlatformDetection.IsOSX && PlatformDetection.OSXVersion < new Version(10, 12)) + if (PlatformDetection.IsOSX && Environment.OSVersion.Version < new Version(10, 12)) { return new string[] { "Dim.", "Lun.", "Mar.", "Mer.", "Jeu.", "Ven.", "Sam." }; } From c67b1086173517bd2b64a557041048a9a6faefa6 Mon Sep 17 00:00:00 2001 From: Koundinya Veluri Date: Tue, 12 May 2020 13:14:37 -0700 Subject: [PATCH 139/420] Address feedback, disable a test on Mono, slightly simplify same test (avoid two guids in name) --- src/coreclr/src/pal/src/synchobj/mutex.cpp | 9 ++------- src/libraries/System.Threading/tests/MutexTests.cs | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/coreclr/src/pal/src/synchobj/mutex.cpp b/src/coreclr/src/pal/src/synchobj/mutex.cpp index 6c90ab475e721..d36752a204057 100644 --- a/src/coreclr/src/pal/src/synchobj/mutex.cpp +++ b/src/coreclr/src/pal/src/synchobj/mutex.cpp @@ -1632,19 +1632,14 @@ void NamedMutexProcessData::Abandon() _ASSERTE(IsLockOwnedByCurrentThread()); _ASSERTE(m_lockCount != 0); - bool hasRefFromLockOwnerThread = m_hasRefFromLockOwnerThread; - if (hasRefFromLockOwnerThread) - { - m_hasRefFromLockOwnerThread = false; - } - sharedData->SetIsAbandoned(true); m_lockCount = 0; SetLockOwnerThread(nullptr); ActuallyReleaseLock(); - if (hasRefFromLockOwnerThread) + if (m_hasRefFromLockOwnerThread) { + m_hasRefFromLockOwnerThread = false; m_processDataHeader->DecRefCount(); } } diff --git a/src/libraries/System.Threading/tests/MutexTests.cs b/src/libraries/System.Threading/tests/MutexTests.cs index e5143a4484446..1557a24f8a0da 100644 --- a/src/libraries/System.Threading/tests/MutexTests.cs +++ b/src/libraries/System.Threading/tests/MutexTests.cs @@ -394,14 +394,14 @@ public static IEnumerable AbandonExisting_MemberData() public static IEnumerable CrossProcess_NamedMutex_ProtectedFileAccessAtomic_MemberData() { - var nameGuidStr = Guid.NewGuid().ToString("N"); foreach (var namePrefix in GetNamePrefixes()) { - yield return new object[] { namePrefix + nameGuidStr }; + yield return new object[] { namePrefix }; } } [Theory] + [ActiveIssue("https://github.com/dotnet/runtime/issues/36307", TestRuntimes.Mono)] [MemberData(nameof(CrossProcess_NamedMutex_ProtectedFileAccessAtomic_MemberData))] public void CrossProcess_NamedMutex_ProtectedFileAccessAtomic(string prefix) { From 932a7363409c52fdc30728f2041e31e37c7044b8 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Tue, 12 May 2020 13:43:24 -0700 Subject: [PATCH 140/420] Use Publish target for self contained test apps (#36290) --- eng/testing/tests.mobile.targets | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index aa0f1450faef7..b78d6451612c8 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -23,17 +23,17 @@ - + + DestinationFolder="$(PublishDir)" SkipUnchangedFiles="true"/> + DestinationFolder="$(PublishDir)" SkipUnchangedFiles="true"/> - + + SourceDir="$(PublishDir)"> @@ -62,9 +62,9 @@ - + - + + AppDir="$(PublishDir)"> @@ -99,8 +99,6 @@ @@ -109,6 +107,6 @@ + AfterTargets="Build" + DependsOnTargets="UpdateRuntimePack;Publish;BundleTestAppleApp;BundleTestAndroidApp" /> From 9656d04077cf4f95544722e5be73988516d816a5 Mon Sep 17 00:00:00 2001 From: Aaron Hudon Date: Tue, 12 May 2020 14:29:36 -0700 Subject: [PATCH 141/420] Comment typos (#36296) --- .../src/HostingHostBuilderExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs b/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs index 277995d71b183..ddfb1feeb450a 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs @@ -167,7 +167,7 @@ public static IHostBuilder UseConsoleLifetime(this IHostBuilder hostBuilder, Act /// /// The to configure. /// A that can be used to cancel the console. - /// A that only completes when the token is triggeredor shutdown is triggered. + /// A that only completes when the token is triggered or shutdown is triggered. public static Task RunConsoleAsync(this IHostBuilder hostBuilder, CancellationToken cancellationToken = default) { return hostBuilder.UseConsoleLifetime().Build().RunAsync(cancellationToken); @@ -179,7 +179,7 @@ public static Task RunConsoleAsync(this IHostBuilder hostBuilder, CancellationTo /// The to configure. /// The delegate for configuring the . /// A that can be used to cancel the console. - /// A that only completes when the token is triggeredor shutdown is triggered. + /// A that only completes when the token is triggered or shutdown is triggered. public static Task RunConsoleAsync(this IHostBuilder hostBuilder, Action configureOptions, CancellationToken cancellationToken = default) { return hostBuilder.UseConsoleLifetime(configureOptions).Build().RunAsync(cancellationToken); From 5cfda7737f69864e9ab639e083428f239d672dfb Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Tue, 12 May 2020 10:25:43 -0700 Subject: [PATCH 142/420] make Poll enums shared --- .../src/Interop/Unix/Interop.Poll.Structs.cs | 28 +++++++++++++ .../Unix/System.Native/Interop.Poll.cs | 19 --------- .../System.Console/src/System.Console.csproj | 2 + .../src/System/ConsolePal.Unix.cs | 2 +- .../src/System.IO.FileSystem.Watcher.csproj | 2 + .../src/System/IO/FileSystemWatcher.Linux.cs | 6 +-- .../src/System.IO.Pipes.csproj | 2 - .../src/Interop/Unix/Interop.Serial.cs | 19 --------- .../src/System.IO.Ports.csproj | 2 + .../src/System/IO/Ports/SerialStream.Unix.cs | 20 ++++----- .../src/System.Net.Http.csproj | 2 + .../src/System.Net.Sockets.csproj | 2 + .../src/System/Net/Sockets/SocketPal.Unix.cs | 42 +++++++++---------- 13 files changed, 73 insertions(+), 75 deletions(-) create mode 100644 src/libraries/Common/src/Interop/Unix/Interop.Poll.Structs.cs diff --git a/src/libraries/Common/src/Interop/Unix/Interop.Poll.Structs.cs b/src/libraries/Common/src/Interop/Unix/Interop.Poll.Structs.cs new file mode 100644 index 0000000000000..34ca249bcdc95 --- /dev/null +++ b/src/libraries/Common/src/Interop/Unix/Interop.Poll.Structs.cs @@ -0,0 +1,28 @@ +// 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. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + [Flags] + internal enum PollEvents : short + { + POLLNONE = 0x0000, // No events occurred. + POLLIN = 0x0001, // non-urgent readable data available + POLLPRI = 0x0002, // urgent readable data available + POLLOUT = 0x0004, // data can be written without blocked + POLLERR = 0x0008, // an error occurred + POLLHUP = 0x0010, // the file descriptor hung up + POLLNVAL = 0x0020, // the requested events were invalid + } + + internal struct PollEvent + { + internal int FileDescriptor; // The file descriptor to poll + internal PollEvents Events; // The events to poll for + internal PollEvents TriggeredEvents; // The events that occurred which triggered the poll + } +} diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Poll.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Poll.cs index 549617257de44..895ce720e31a3 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Poll.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Poll.cs @@ -10,25 +10,6 @@ internal static partial class Interop { internal static partial class Sys { - [Flags] - internal enum PollEvents : short - { - POLLNONE = 0x0000, // No events occurred. - POLLIN = 0x0001, // non-urgent readable data available - POLLPRI = 0x0002, // urgent readable data available - POLLOUT = 0x0004, // data can be written without blocked - POLLERR = 0x0008, // an error occurred - POLLHUP = 0x0010, // the file descriptor hung up - POLLNVAL = 0x0020, // the requested events were invalid - } - - internal struct PollEvent - { - internal int FileDescriptor; // The file descriptor to poll - internal PollEvents Events; // The events to poll for - internal PollEvents TriggeredEvents; // The events that occurred which triggered the poll - } - /// /// Polls a set of file descriptors for signals and returns what signals have been set /// diff --git a/src/libraries/System.Console/src/System.Console.csproj b/src/libraries/System.Console/src/System.Console.csproj index 43368249004c8..23b21f1ee3168 100644 --- a/src/libraries/System.Console/src/System.Console.csproj +++ b/src/libraries/System.Console/src/System.Console.csproj @@ -194,6 +194,8 @@ Link="Common\Interop\Unix\Interop.OpenFlags.cs" /> + + diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs index def4ae5681fe6..5b04282c713d6 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs @@ -680,11 +680,11 @@ private void ProcessEvents() // that's actually what's needed (otherwise it'd be fine to block indefinitely waiting // for the next event to arrive). const int MillisecondsTimeout = 2; - Interop.Sys.PollEvents events; - Interop.Sys.Poll(_inotifyHandle, Interop.Sys.PollEvents.POLLIN, MillisecondsTimeout, out events); + Interop.PollEvents events; + Interop.Sys.Poll(_inotifyHandle, Interop.PollEvents.POLLIN, MillisecondsTimeout, out events); // If we error or don't have any signaled handles, send the deleted event - if (events == Interop.Sys.PollEvents.POLLNONE) + if (events == Interop.PollEvents.POLLNONE) { // There isn't any more data in the queue so this is a deleted event watcher.NotifyFileSystemEventArgs(WatcherChangeTypes.Deleted, expandedName); diff --git a/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj b/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj index ee5dd288580e6..9c2991aedecb4 100644 --- a/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj +++ b/src/libraries/System.IO.Pipes/src/System.IO.Pipes.csproj @@ -151,8 +151,6 @@ Link="Common\Interop\Unix\Interop.Permissions.cs" /> - + diff --git a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs index 887c869321339..dd8ea97d7b96c 100644 --- a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs +++ b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs @@ -464,7 +464,7 @@ public override IAsyncResult BeginRead(byte[] array, int offset, int numBytes, A // Will wait `timeout` miliseconds or until reading or writing is possible // If no operation is requested it will throw // Returns event which has happened - private Interop.Serial.PollEvents PollEvents(int timeout, bool pollReadEvents, bool pollWriteEvents, out Interop.ErrorInfo? error) + private Interop.PollEvents PollEvents(int timeout, bool pollReadEvents, bool pollWriteEvents, out Interop.ErrorInfo? error) { if (!pollReadEvents && !pollWriteEvents) { @@ -472,19 +472,19 @@ private Interop.Serial.PollEvents PollEvents(int timeout, bool pollReadEvents, b throw new Exception(); } - Interop.Serial.PollEvents eventsToPoll = Interop.Serial.PollEvents.POLLERR; + Interop.PollEvents eventsToPoll = Interop.PollEvents.POLLERR; if (pollReadEvents) { - eventsToPoll |= Interop.Serial.PollEvents.POLLIN; + eventsToPoll |= Interop.PollEvents.POLLIN; } if (pollWriteEvents) { - eventsToPoll |= Interop.Serial.PollEvents.POLLOUT; + eventsToPoll |= Interop.PollEvents.POLLOUT; } - Interop.Serial.PollEvents events = Interop.Serial.PollEvents.POLLNONE; + Interop.PollEvents events = Interop.PollEvents.POLLNONE; Interop.Error ret = Interop.Serial.Poll( _handle, eventsToPoll, @@ -843,7 +843,7 @@ private unsafe void IOLoop() } else { - Interop.Serial.PollEvents events = PollEvents(1, + Interop.PollEvents events = PollEvents(1, pollReadEvents: hasPendingReads, pollWriteEvents: hasPendingWrites, out Interop.ErrorInfo? error); @@ -854,21 +854,21 @@ private unsafe void IOLoop() break; } - if (events.HasFlag(Interop.Serial.PollEvents.POLLNVAL) || - events.HasFlag(Interop.Serial.PollEvents.POLLERR)) + if (events.HasFlag(Interop.PollEvents.POLLNVAL) || + events.HasFlag(Interop.PollEvents.POLLERR)) { // bad descriptor or some other error we can't handle FinishPendingIORequests(); break; } - if (events.HasFlag(Interop.Serial.PollEvents.POLLIN)) + if (events.HasFlag(Interop.PollEvents.POLLIN)) { int bytesRead = DoIORequest(_readQueue, _processReadDelegate); _totalBytesRead += bytesRead; } - if (events.HasFlag(Interop.Serial.PollEvents.POLLOUT)) + if (events.HasFlag(Interop.PollEvents.POLLOUT)) { DoIORequest(_writeQueue, _processWriteDelegate); } diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index 18b529238e6c8..ee9e25ba90a99 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -541,6 +541,8 @@ Link="Common\Interop\Unix\System.Native\Interop.Pipe.cs" /> + + Date: Tue, 12 May 2020 18:48:53 -0400 Subject: [PATCH 143/420] Fix nullable annotations on DangerousAcceptAnyServerCertificateValidator (#36305) It should match ServerCertificateCustomValidationCallback. --- src/libraries/System.Net.Http/ref/System.Net.Http.cs | 2 +- .../System.Net.Http/src/System/Net/Http/HttpClientHandler.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Http/ref/System.Net.Http.cs b/src/libraries/System.Net.Http/ref/System.Net.Http.cs index 3026fa779ab0d..91d4676d3ab99 100644 --- a/src/libraries/System.Net.Http/ref/System.Net.Http.cs +++ b/src/libraries/System.Net.Http/ref/System.Net.Http.cs @@ -99,7 +99,7 @@ public partial class HttpClientHandler : System.Net.Http.HttpMessageHandler public System.Security.Cryptography.X509Certificates.X509CertificateCollection ClientCertificates { get { throw null; } } public System.Net.CookieContainer CookieContainer { get { throw null; } set { } } public System.Net.ICredentials? Credentials { get { throw null; } set { } } - public static System.Func DangerousAcceptAnyServerCertificateValidator { get { throw null; } } + public static System.Func DangerousAcceptAnyServerCertificateValidator { get { throw null; } } public System.Net.ICredentials? DefaultProxyCredentials { get { throw null; } set { } } public int MaxAutomaticRedirections { get { throw null; } set { } } public int MaxConnectionsPerServer { get { throw null; } set { } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs index 1851c5aa3da6a..304b810d54874 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs @@ -222,7 +222,7 @@ public SslProtocols SslProtocols _socketsHttpHandler.SendAsync(request, cancellationToken); } - public static Func DangerousAcceptAnyServerCertificateValidator { get; } = delegate { return true; }; + public static Func DangerousAcceptAnyServerCertificateValidator { get; } = delegate { return true; }; private void ThrowForModifiedManagedSslOptionsIfStarted() { From bc3bec788cd8d1f9d882b359ca8368248bf051a4 Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Tue, 12 May 2020 16:10:36 -0700 Subject: [PATCH 144/420] Add QCALL_CONTRACT_NO_GC_TRANSITION (#36294) New QCall macro for APIs that use SuppressGCTransitionAttribute. --- src/coreclr/src/vm/interoplibinterface.cpp | 6 ++---- src/coreclr/src/vm/qcall.h | 6 ++++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/coreclr/src/vm/interoplibinterface.cpp b/src/coreclr/src/vm/interoplibinterface.cpp index 3eaf5ba37f410..94e7402f09533 100644 --- a/src/coreclr/src/vm/interoplibinterface.cpp +++ b/src/coreclr/src/vm/interoplibinterface.cpp @@ -1385,8 +1385,7 @@ void ComWrappersNative::MarkWrapperAsComActivated(_In_ IUnknown* wrapperMaybe) void QCALLTYPE GlobalComWrappersForMarshalling::SetGlobalInstanceRegisteredForMarshalling() { - // QCALL contracts are not used here because the managed declaration - // uses the SuppressGCTransition attribute + QCALL_CONTRACT_NO_GC_TRANSITION; _ASSERTE(!g_IsGlobalComWrappersRegisteredForMarshalling); g_IsGlobalComWrappersRegisteredForMarshalling = true; @@ -1455,8 +1454,7 @@ bool GlobalComWrappersForMarshalling::TryGetOrCreateObjectForComInstance( void QCALLTYPE GlobalComWrappersForTrackerSupport::SetGlobalInstanceRegisteredForTrackerSupport() { - // QCALL contracts are not used here because the managed declaration - // uses the SuppressGCTransition attribute + QCALL_CONTRACT_NO_GC_TRANSITION; _ASSERTE(!g_IsGlobalComWrappersRegisteredForTrackerSupport); g_IsGlobalComWrappersRegisteredForTrackerSupport = true; diff --git a/src/coreclr/src/vm/qcall.h b/src/coreclr/src/vm/qcall.h index 380a041ca9215..32ce22f1bec8a 100644 --- a/src/coreclr/src/vm/qcall.h +++ b/src/coreclr/src/vm/qcall.h @@ -137,7 +137,13 @@ GC_TRIGGERS; \ MODE_PREEMPTIVE; \ +#define QCALL_CHECK_NO_GC_TRANSITION \ + THROWS; \ + GC_TRIGGERS; \ + MODE_COOPERATIVE; \ + #define QCALL_CONTRACT CONTRACTL { QCALL_CHECK; } CONTRACTL_END; +#define QCALL_CONTRACT_NO_GC_TRANSITION CONTRACTL { QCALL_CHECK_NO_GC_TRANSITION; } CONTRACTL_END; // // Scope class for QCall helper methods and types From 4aa943df8cd385f38320e4d31a79eba7e943794b Mon Sep 17 00:00:00 2001 From: Nikiforov Alexey Date: Wed, 13 May 2020 03:13:16 +0300 Subject: [PATCH 145/420] Add ctor to JsonSerializerOptions that takes serializer defaults (#36073) * add ctor to JsonSerializerOptions that takes serializer defaults * add out of range handling; enhance xml documentation * test serializer option construction via serializer defaults * adjust PredefinedSerializerOptions tests --- .../System.Text.Json/ref/System.Text.Json.cs | 6 ++++ .../src/System.Text.Json.csproj | 3 +- .../Serialization/JsonSerializerDefaults.cs | 27 +++++++++++++++++ .../Serialization/JsonSerializerOptions.cs | 19 +++++++++++- .../tests/Serialization/OptionsTests.cs | 29 +++++++++++++++++-- 5 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerDefaults.cs diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index c4c74cf1a43a2..21b3c645040f4 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -209,6 +209,7 @@ public sealed partial class JsonSerializerOptions { public JsonSerializerOptions() { } public JsonSerializerOptions(System.Text.Json.JsonSerializerOptions options) { } + public JsonSerializerOptions(System.Text.Json.JsonSerializerDefaults defaults) { } public bool AllowTrailingCommas { get { throw null; } set { } } public System.Collections.Generic.IList Converters { get { throw null; } } public int DefaultBufferSize { get { throw null; } set { } } @@ -224,6 +225,11 @@ public sealed partial class JsonSerializerOptions public bool WriteIndented { get { throw null; } set { } } public System.Text.Json.Serialization.JsonConverter GetConverter(System.Type typeToConvert) { throw null; } } + public enum JsonSerializerDefaults + { + General = 0, + Web = 1, + } public enum JsonTokenType : byte { None = (byte)0, diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index 5a704054c3e33..7fcf718583ae6 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -15,7 +15,7 @@ $(DefineConstants);BUILDING_INBOX_LIBRARY - $(NoWarn);nullable + $(NoWarn);nullable + diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerDefaults.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerDefaults.cs new file mode 100644 index 0000000000000..7df69c390daa7 --- /dev/null +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerDefaults.cs @@ -0,0 +1,27 @@ +// 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. + +namespace System.Text.Json +{ + /// + /// Signifies what default options are used by . + /// + public enum JsonSerializerDefaults + { + /// + /// Specifies that general-purpose values should be used. These are the same settings applied if a isn't specified. + /// + /// + /// This option implies that property names are treated as case-sensitive and that "PascalCase" name formatting should be employed. + /// + General = 0, + /// + /// Specifies that values should be used more appropriate to web-based scenarios. + /// + /// + /// This option implies that property names are treated as case-insensitive and that "camelCase" name formatting should be employed. + /// + Web = 1 + } +} diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs index 53d1a676d107c..dead794f239f8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs @@ -82,7 +82,24 @@ public JsonSerializerOptions(JsonSerializerOptions options) // _classes is not copied as sharing the JsonClassInfo and JsonPropertyInfo caches can result in // unnecessary references to type metadata, potentially hindering garbage collection on the source options. - // _haveTypesBeenCreated is not copied; it's okay to make changes to this options instance as (de)serialization has not occured. + // _haveTypesBeenCreated is not copied; it's okay to make changes to this options instance as (de)serialization has not occurred. + } + + /// + /// Constructs a new instance with a predefined set of options determined by the specified . + /// + /// The to reason about. + public JsonSerializerOptions(JsonSerializerDefaults defaults) : this() + { + if (defaults == JsonSerializerDefaults.Web) + { + _propertyNameCaseInsensitive = true; + _jsonPropertyNamingPolicy = JsonNamingPolicy.CamelCase; + } + else if (defaults != JsonSerializerDefaults.General) + { + throw new ArgumentOutOfRangeException(nameof(defaults)); + } } /// diff --git a/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs b/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs index aedd10bf6b876..5892a338e47f1 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs @@ -340,7 +340,7 @@ private static void GenericObjectOrJsonElementConverterTestHelper(string conv JsonConverter converter = (JsonConverter)options.GetConverter(typeof(T)); Assert.Equal(converterName, converter.GetType().Name); - + ReadOnlySpan data = Encoding.UTF8.GetBytes(stringValue); Utf8JsonReader reader = new Utf8JsonReader(data); reader.Read(); @@ -406,7 +406,6 @@ public static void Options_GetConverter_GivesCorrectDefaultConverterAndReadWrite GenericConverterTestHelper("GuidConverter", testGuid, $"\"{testGuid.ToString()}\"", options); GenericConverterTestHelper>("KeyValuePairConverter`2", new KeyValuePair("key", "value"), @"{""Key"":""key"",""Value"":""value""}", options); GenericConverterTestHelper("UriConverter", new Uri("http://test.com"), "\"http://test.com\"", options); - } [Fact] @@ -539,6 +538,32 @@ public static void CopyConstructorTest_NullInput() Assert.Contains("options", ex.ToString()); } + [Fact] + public static void DefaultSerializerOptions_General() + { + var options = new JsonSerializerOptions(); + var newOptions = new JsonSerializerOptions(JsonSerializerDefaults.General); + VerifyOptionsEqual(options, newOptions); + } + + [Fact] + public static void PredefinedSerializerOptions_Web() + { + var options = new JsonSerializerOptions(JsonSerializerDefaults.Web); + JsonNamingPolicy policy = options.PropertyNamingPolicy; + Assert.True(options.PropertyNameCaseInsensitive); + Assert.Same(JsonNamingPolicy.CamelCase, policy); + } + + [Theory] + [InlineData(-1)] + [InlineData(2)] + public static void PredefinedSerializerOptions_UnhandledDefaults(int enumValue) + { + var outOfRangeSerializerDefaults = (JsonSerializerDefaults)enumValue; + Assert.Throws(() => new JsonSerializerOptions(outOfRangeSerializerDefaults)); + } + private static JsonSerializerOptions CreateOptionsInstance() { var options = new JsonSerializerOptions From 9740aa5fd5ad01c7dc1be86c7bcf0561dd5e1415 Mon Sep 17 00:00:00 2001 From: David Shulman Date: Tue, 12 May 2020 17:36:08 -0700 Subject: [PATCH 146/420] Fix HttpClient SSL3.0 test on newer Windows OS (#36308) When I upgraded my dev machine to Windows 10 Version 2004 Preview, I noticed that the HttpClient GetAsync_SupportedSSLVersion_Succeeds test was failing when using SSL 3.0. This new version of Windows changes the default setting of SSL 3.0. So, by default, SSL 3.0 is no longer enabled. The problem was that this specific test wasn't using our PlatformDetection.SupportsSsl30 logic. Fixed the test so that it will properly detect whether SSL 3.0 is enabled on the machine. --- .../System/Net/Http/HttpClientHandlerTest.SslProtocols.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs index 06133d3398bc3..9c9ad3fc8b16a 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs @@ -151,9 +151,7 @@ public async Task GetAsync_AllowedSSLVersion_Succeeds(SslProtocols acceptedProto public static IEnumerable SupportedSSLVersionServers() { #pragma warning disable 0618 // SSL2/3 are deprecated - if (PlatformDetection.IsWindows || - PlatformDetection.IsOSX || - (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && PlatformDetection.OpenSslVersion < new Version(1, 0, 2) && !PlatformDetection.IsDebian)) + if (PlatformDetection.SupportsSsl3) { yield return new object[] { SslProtocols.Ssl3, Configuration.Http.SSLv3RemoteServer }; } From f2cdf3b6ebd516a93efbe2115e317aabdfd7e492 Mon Sep 17 00:00:00 2001 From: Elinor Fung <47805090+elinor-fung@users.noreply.github.com> Date: Tue, 12 May 2020 18:04:14 -0700 Subject: [PATCH 147/420] Set ExactSpelling=true on P/Invokes in System.Private.CoreLib that already specify the unicode W suffix (#36257) * Set ExactSpelling=true on P/Invokes in System.Private.CoreLib that already specify the unicode W suffix * PR feedback: refactor NDirectMethodDesc::FindEntryPoint --- src/coreclr/src/vm/method.cpp | 65 ++++++++++--------- src/coreclr/src/vm/method.hpp | 1 + .../Advapi32/Interop.RegCreateKeyEx.cs | 2 +- .../Advapi32/Interop.RegDeleteKeyEx.cs | 2 +- .../Advapi32/Interop.RegDeleteValue.cs | 2 +- .../Windows/Advapi32/Interop.RegEnumKeyEx.cs | 2 +- .../Windows/Advapi32/Interop.RegEnumValue.cs | 2 +- .../Windows/Advapi32/Interop.RegOpenKeyEx.cs | 4 +- .../Advapi32/Interop.RegQueryValueEx.cs | 8 +-- .../Windows/Advapi32/Interop.RegSetValueEx.cs | 10 +-- .../Kernel32/Interop.EventWaitHandle.cs | 4 +- .../Interop.ExpandEnvironmentStrings.cs | 2 +- .../Kernel32/Interop.FindFirstFileEx.cs | 2 +- .../Windows/Kernel32/Interop.FormatMessage.cs | 2 +- .../Interop.FreeEnvironmentStrings.cs | 2 +- .../Kernel32/Interop.GetComputerName.cs | 2 +- .../Kernel32/Interop.GetCurrentDirectory.cs | 2 +- .../Kernel32/Interop.GetEnvironmentStrings.cs | 2 +- .../Interop.GetEnvironmentVariable.cs | 2 +- .../Kernel32/Interop.GetFileAttributesEx.cs | 2 +- .../Kernel32/Interop.GetSystemDirectoryW.cs | 2 +- .../Kernel32/Interop.GetTempFileNameW.cs | 2 +- .../Windows/Kernel32/Interop.GetTempPathW.cs | 2 +- .../Kernel32/Interop.LoadLibraryEx_IntPtr.cs | 2 +- .../Interop/Windows/Kernel32/Interop.Mutex.cs | 4 +- .../Windows/Kernel32/Interop.Semaphore.cs | 4 +- .../Kernel32/Interop.SetCurrentDirectory.cs | 2 +- .../Interop.SetEnvironmentVariable.cs | 2 +- .../Windows/Secur32/Interop.GetUserNameExW.cs | 2 +- .../Windows/User32/Interop.LoadString.cs | 2 +- 30 files changed, 75 insertions(+), 69 deletions(-) diff --git a/src/coreclr/src/vm/method.cpp b/src/coreclr/src/vm/method.cpp index 314b777052cd8..690051b905bf8 100644 --- a/src/coreclr/src/vm/method.cpp +++ b/src/coreclr/src/vm/method.cpp @@ -5307,6 +5307,23 @@ FARPROC NDirectMethodDesc::FindEntryPointWithMangling(NATIVE_LIBRARY_HANDLE hMod return pFunc; } + +FARPROC NDirectMethodDesc::FindEntryPointWithSuffix(NATIVE_LIBRARY_HANDLE hMod, PTR_CUTF8 entryPointName, char suffix) const +{ + // Allocate space for a copy of the entry point name. + DWORD entryPointWithSuffixLen = (DWORD)(strlen(entryPointName) + 1); // +1 for charset decorations + int dstbufsize = (int)(sizeof(char) * (entryPointWithSuffixLen + 1)); // +1 for the null terminator + LPSTR entryPointWithSuffix = ((LPSTR)_alloca(dstbufsize)); + + // Copy the name so we can mangle it. + strcpy_s(entryPointWithSuffix, dstbufsize, entryPointName); + entryPointWithSuffix[entryPointWithSuffixLen] = '\0'; // Null terminator + entryPointWithSuffix[entryPointWithSuffixLen - 1] = suffix; // Charset suffix + + // Look for entry point with the suffix based on charset + return FindEntryPointWithMangling(hMod, entryPointWithSuffix); +} + #endif //******************************************************************************* @@ -5332,39 +5349,27 @@ LPVOID NDirectMethodDesc::FindEntryPoint(NATIVE_LIBRARY_HANDLE hMod) const return reinterpret_cast(GetProcAddress(hMod, (LPCSTR)(size_t)((UINT16)ordinal))); } - // Just look for the user-provided name without charset suffixes. - // If it is unicode fcn, we are going - // to need to check for the 'W' API because it takes precedence over the - // unmangled one (on NT some APIs have unmangled ANSI exports). - FARPROC pFunc = FindEntryPointWithMangling(hMod, funcName); - if ((pFunc != NULL && IsNativeAnsi()) || IsNativeNoMangled()) + FARPROC pFunc = NULL; + if (IsNativeNoMangled()) { - return reinterpret_cast(pFunc); + // Look for the user-provided entry point name only + pFunc = FindEntryPointWithMangling(hMod, funcName); } - - DWORD probedEntrypointNameLength = (DWORD)(strlen(funcName) + 1); // +1 for charset decorations - - // Allocate space for a copy of the entry point name. - int dstbufsize = (int)(sizeof(char) * (probedEntrypointNameLength + 1)); // +1 for the null terminator - - LPSTR szProbedEntrypointName = ((LPSTR)_alloca(dstbufsize)); - - // Copy the name so we can mangle it. - strcpy_s(szProbedEntrypointName, dstbufsize, funcName); - szProbedEntrypointName[probedEntrypointNameLength] = '\0'; // Add an extra '\0'. - - if(!IsNativeNoMangled()) + else if (IsNativeAnsi()) { - szProbedEntrypointName[probedEntrypointNameLength - 1] = IsNativeAnsi() ? 'A' : 'W'; - - FARPROC pProbedFunc = FindEntryPointWithMangling(hMod, szProbedEntrypointName); - - if(pProbedFunc != NULL) - { - pFunc = pProbedFunc; - } - - probedEntrypointNameLength++; + // For ANSI, look for the user-provided entry point name first. + // If that does not exist, try the charset suffix. + pFunc = FindEntryPointWithMangling(hMod, funcName); + if (pFunc == NULL) + pFunc = FindEntryPointWithSuffix(hMod, funcName, 'A'); + } + else + { + // For Unicode, look for the entry point name with the charset suffix first. + // The 'W' API takes precedence over the undecorated one. + pFunc = FindEntryPointWithSuffix(hMod, funcName, 'W'); + if (pFunc == NULL) + pFunc = FindEntryPointWithMangling(hMod, funcName); } return reinterpret_cast(pFunc); diff --git a/src/coreclr/src/vm/method.hpp b/src/coreclr/src/vm/method.hpp index 8870e7a5f5a23..ba5f6ae096778 100644 --- a/src/coreclr/src/vm/method.hpp +++ b/src/coreclr/src/vm/method.hpp @@ -3150,6 +3150,7 @@ class NDirectMethodDesc : public MethodDesc #ifdef TARGET_WINDOWS private: FARPROC FindEntryPointWithMangling(NATIVE_LIBRARY_HANDLE mod, PTR_CUTF8 entryPointName) const; + FARPROC FindEntryPointWithSuffix(NATIVE_LIBRARY_HANDLE mod, PTR_CUTF8 entryPointName, char suffix) const; #endif public: diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegCreateKeyEx.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegCreateKeyEx.cs index bb9da06c11d48..3caac3041f920 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegCreateKeyEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegCreateKeyEx.cs @@ -16,7 +16,7 @@ internal static partial class Advapi32 { // Note: RegCreateKeyEx won't set the last error on failure - it returns // an error code if it fails. - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegCreateKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegCreateKeyExW", ExactSpelling = true)] internal static extern int RegCreateKeyEx( SafeRegistryHandle hKey, string lpSubKey, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteKeyEx.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteKeyEx.cs index 487caf8b6d79d..2fff3b1ed5164 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteKeyEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteKeyEx.cs @@ -13,7 +13,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegDeleteKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegDeleteKeyExW", ExactSpelling = true)] internal static extern int RegDeleteKeyEx(SafeRegistryHandle hKey, string lpSubKey, int samDesired, int Reserved); } } diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteValue.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteValue.cs index 43cf683c2bddf..7bb376930fa75 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteValue.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegDeleteValue.cs @@ -14,7 +14,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegDeleteValueW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegDeleteValueW", ExactSpelling = true)] internal static extern int RegDeleteValue(SafeRegistryHandle hKey, string? lpValueName); } } diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumKeyEx.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumKeyEx.cs index 11165cc91a966..d618b50cd1cd8 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumKeyEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumKeyEx.cs @@ -14,7 +14,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumKeyExW", ExactSpelling = true)] internal static extern unsafe int RegEnumKeyEx( SafeRegistryHandle hKey, int dwIndex, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumValue.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumValue.cs index e2ab45dea1933..02a7ad9692844 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumValue.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegEnumValue.cs @@ -15,7 +15,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumValueW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumValueW", ExactSpelling = true)] internal static extern unsafe int RegEnumValue( SafeRegistryHandle hKey, int dwIndex, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegOpenKeyEx.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegOpenKeyEx.cs index 5f5b6b6e372ed..0bc2cdce3c836 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegOpenKeyEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegOpenKeyEx.cs @@ -15,7 +15,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW", ExactSpelling = true)] internal static extern int RegOpenKeyEx( SafeRegistryHandle hKey, string? lpSubKey, @@ -24,7 +24,7 @@ internal static partial class Advapi32 out SafeRegistryHandle hkResult); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW", ExactSpelling = true)] internal static extern int RegOpenKeyEx( IntPtr hKey, string? lpSubKey, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegQueryValueEx.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegQueryValueEx.cs index 72b8aa8f7bcf1..bde703ad18632 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegQueryValueEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegQueryValueEx.cs @@ -14,7 +14,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW", ExactSpelling = true)] internal static extern int RegQueryValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -23,7 +23,7 @@ internal static partial class Advapi32 [Out] byte[]? lpData, ref int lpcbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW", ExactSpelling = true)] internal static extern int RegQueryValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -32,7 +32,7 @@ internal static partial class Advapi32 ref int lpData, ref int lpcbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW", ExactSpelling = true)] internal static extern int RegQueryValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -41,7 +41,7 @@ internal static partial class Advapi32 ref long lpData, ref int lpcbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW", ExactSpelling = true)] internal static extern int RegQueryValueEx( SafeRegistryHandle hKey, string? lpValueName, diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegSetValueEx.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegSetValueEx.cs index 847d28fa1c577..72cee21e1a17b 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegSetValueEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.RegSetValueEx.cs @@ -14,7 +14,7 @@ internal static partial class Interop { internal static partial class Advapi32 { - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW", ExactSpelling = true)] internal static extern int RegSetValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -23,7 +23,7 @@ internal static partial class Advapi32 byte[]? lpData, int cbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW", ExactSpelling = true)] internal static extern int RegSetValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -32,7 +32,7 @@ internal static partial class Advapi32 char[]? lpData, int cbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW", ExactSpelling = true)] internal static extern int RegSetValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -41,7 +41,7 @@ internal static partial class Advapi32 ref int lpData, int cbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW", ExactSpelling = true)] internal static extern int RegSetValueEx( SafeRegistryHandle hKey, string? lpValueName, @@ -50,7 +50,7 @@ internal static partial class Advapi32 ref long lpData, int cbData); - [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW", ExactSpelling = true)] internal static extern int RegSetValueEx( SafeRegistryHandle hKey, string? lpValueName, diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs index c3adfadb53d54..e4b0904b76ba1 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs @@ -20,10 +20,10 @@ internal static partial class Kernel32 [DllImport(Libraries.Kernel32, SetLastError = true)] internal static extern bool ResetEvent(SafeWaitHandle handle); - [DllImport(Libraries.Kernel32, EntryPoint = "CreateEventExW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "CreateEventExW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern SafeWaitHandle CreateEventEx(IntPtr lpSecurityAttributes, string? name, uint flags, uint desiredAccess); - [DllImport(Libraries.Kernel32, EntryPoint = "OpenEventW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "OpenEventW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern SafeWaitHandle OpenEvent(uint desiredAccess, bool inheritHandle, string name); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.ExpandEnvironmentStrings.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.ExpandEnvironmentStrings.cs index fbd5da84b8e0a..94a3714644e12 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.ExpandEnvironmentStrings.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.ExpandEnvironmentStrings.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "ExpandEnvironmentStringsW", CharSet = CharSet.Unicode, SetLastError = true)] + [DllImport(Libraries.Kernel32, EntryPoint = "ExpandEnvironmentStringsW", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] internal static extern uint ExpandEnvironmentStrings(string lpSrc, ref char lpDst, uint nSize); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs index 6ab52b4d0e9e2..a7cd35262d50d 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs @@ -15,7 +15,7 @@ internal static partial class Kernel32 /// /// WARNING: This method does not implicitly handle long paths. Use FindFirstFile. /// - [DllImport(Libraries.Kernel32, EntryPoint = "FindFirstFileExW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "FindFirstFileExW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] private static extern SafeFindHandle FindFirstFileExPrivate(string lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, ref WIN32_FIND_DATA lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, IntPtr lpSearchFilter, int dwAdditionalFlags); internal static SafeFindHandle FindFirstFile(string fileName, ref WIN32_FIND_DATA data) diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FormatMessage.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FormatMessage.cs index 2eda58f250426..14ba39b044b9f 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FormatMessage.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FormatMessage.cs @@ -16,7 +16,7 @@ internal static partial class Kernel32 private const int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; private const int ERROR_INSUFFICIENT_BUFFER = 0x7A; - [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "FormatMessageW", SetLastError = true, BestFitMapping = true)] + [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "FormatMessageW", SetLastError = true, BestFitMapping = true, ExactSpelling = true)] private static extern unsafe int FormatMessage( int dwFlags, IntPtr lpSource, diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FreeEnvironmentStrings.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FreeEnvironmentStrings.cs index c222db8ef91b5..f325c281df8cf 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FreeEnvironmentStrings.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.FreeEnvironmentStrings.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "FreeEnvironmentStringsW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, EntryPoint = "FreeEnvironmentStringsW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)] internal static extern unsafe bool FreeEnvironmentStrings(char* lpszEnvironmentBlock); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetComputerName.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetComputerName.cs index 011430da5c7e8..92cfb955a4cba 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetComputerName.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetComputerName.cs @@ -10,7 +10,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "GetComputerNameW")] + [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "GetComputerNameW", ExactSpelling = true)] private static extern unsafe int GetComputerName(ref char lpBuffer, ref uint nSize); // maximum length of the NETBIOS name (not including NULL) diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetCurrentDirectory.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetCurrentDirectory.cs index 4e30a8be4328a..bf283df9c4046 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetCurrentDirectory.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetCurrentDirectory.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "GetCurrentDirectoryW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, EntryPoint = "GetCurrentDirectoryW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)] internal static extern uint GetCurrentDirectory(uint nBufferLength, ref char lpBuffer); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentStrings.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentStrings.cs index 5594fe7a4cb8e..cdbd01ca50208 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentStrings.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentStrings.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "GetEnvironmentStringsW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, EntryPoint = "GetEnvironmentStringsW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)] internal static extern unsafe char* GetEnvironmentStrings(); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentVariable.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentVariable.cs index 43463e52304cb..0c14b3dd40398 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentVariable.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetEnvironmentVariable.cs @@ -17,7 +17,7 @@ internal static unsafe int GetEnvironmentVariable(string lpName, Span buff } } - [DllImport(Libraries.Kernel32, EntryPoint = "GetEnvironmentVariableW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "GetEnvironmentVariableW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] private static extern unsafe int GetEnvironmentVariable(string lpName, char* lpBuffer, int nSize); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs index aed8919cd03e9..84cd7326b39fe 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs @@ -13,7 +13,7 @@ internal static partial class Kernel32 /// /// WARNING: This method does not implicitly handle long paths. Use GetFileAttributesEx. /// - [DllImport(Libraries.Kernel32, EntryPoint = "GetFileAttributesExW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "GetFileAttributesExW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] private static extern bool GetFileAttributesExPrivate(string? name, GET_FILEEX_INFO_LEVELS fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation); internal static bool GetFileAttributesEx(string? name, GET_FILEEX_INFO_LEVELS fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation) diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetSystemDirectoryW.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetSystemDirectoryW.cs index 197f6f5eadcdb..b247a509c40d8 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetSystemDirectoryW.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetSystemDirectoryW.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true)] + [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] internal static extern uint GetSystemDirectoryW(ref char lpBuffer, uint uSize); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs index d7f9b828c0c03..5c3140b82ea66 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false, ExactSpelling = true)] internal static extern uint GetTempFileNameW(ref char lpPathName, string lpPrefixString, uint uUnique, ref char lpTempFileName); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempPathW.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempPathW.cs index 8d2b0b199edd0..654a3b57011cd 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempPathW.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.GetTempPathW.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)] internal static extern uint GetTempPathW(int bufferLen, ref char buffer); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.LoadLibraryEx_IntPtr.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.LoadLibraryEx_IntPtr.cs index a77cf49179382..3e3d1d34a81a7 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.LoadLibraryEx_IntPtr.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.LoadLibraryEx_IntPtr.cs @@ -12,7 +12,7 @@ internal static partial class Kernel32 internal const int LOAD_LIBRARY_AS_DATAFILE = 0x00000002; internal const int LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800; - [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "LoadLibraryExW", SetLastError = true)] + [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "LoadLibraryExW", SetLastError = true, ExactSpelling = true)] internal static extern IntPtr LoadLibraryEx(string libFilename, IntPtr reserved, int flags); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Mutex.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Mutex.cs index 6adaf98737040..ad1d649fe9da8 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Mutex.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Mutex.cs @@ -13,10 +13,10 @@ internal static partial class Kernel32 { internal const uint CREATE_MUTEX_INITIAL_OWNER = 0x1; - [DllImport(Libraries.Kernel32, EntryPoint = "OpenMutexW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "OpenMutexW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern SafeWaitHandle OpenMutex(uint desiredAccess, bool inheritHandle, string name); - [DllImport(Libraries.Kernel32, EntryPoint = "CreateMutexExW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "CreateMutexExW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern SafeWaitHandle CreateMutexEx(IntPtr lpMutexAttributes, string? name, uint flags, uint desiredAccess); [DllImport(Libraries.Kernel32, SetLastError = true)] diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Semaphore.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Semaphore.cs index 4f6d8de8768a3..c83db1f934c00 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Semaphore.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Semaphore.cs @@ -11,10 +11,10 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "OpenSemaphoreW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "OpenSemaphoreW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern SafeWaitHandle OpenSemaphore(uint desiredAccess, bool inheritHandle, string name); - [DllImport(Libraries.Kernel32, EntryPoint = "CreateSemaphoreExW", SetLastError = true, CharSet = CharSet.Unicode)] + [DllImport(Libraries.Kernel32, EntryPoint = "CreateSemaphoreExW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern SafeWaitHandle CreateSemaphoreEx(IntPtr lpSecurityAttributes, int initialCount, int maximumCount, string? name, uint flags, uint desiredAccess); [DllImport(Libraries.Kernel32, SetLastError = true)] diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetCurrentDirectory.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetCurrentDirectory.cs index d268d4daa6f77..17360399a7c0d 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetCurrentDirectory.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetCurrentDirectory.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "SetCurrentDirectoryW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, EntryPoint = "SetCurrentDirectoryW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)] internal static extern bool SetCurrentDirectory(string path); } } diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetEnvironmentVariable.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetEnvironmentVariable.cs index 243bd6562e034..ab3a6d34cd42b 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetEnvironmentVariable.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.SetEnvironmentVariable.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Kernel32 { - [DllImport(Libraries.Kernel32, EntryPoint = "SetEnvironmentVariableW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)] + [DllImport(Libraries.Kernel32, EntryPoint = "SetEnvironmentVariableW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)] internal static extern bool SetEnvironmentVariable(string lpName, string? lpValue); } } diff --git a/src/libraries/Common/src/Interop/Windows/Secur32/Interop.GetUserNameExW.cs b/src/libraries/Common/src/Interop/Windows/Secur32/Interop.GetUserNameExW.cs index e88864cd9e747..7001cd6df09ea 100644 --- a/src/libraries/Common/src/Interop/Windows/Secur32/Interop.GetUserNameExW.cs +++ b/src/libraries/Common/src/Interop/Windows/Secur32/Interop.GetUserNameExW.cs @@ -8,7 +8,7 @@ internal static partial class Interop { internal static partial class Secur32 { - [DllImport(Libraries.Secur32, CharSet = CharSet.Unicode, SetLastError = true)] + [DllImport(Libraries.Secur32, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] internal static extern BOOLEAN GetUserNameExW(int NameFormat, ref char lpNameBuffer, ref uint lpnSize); internal const int NameSamCompatible = 2; diff --git a/src/libraries/Common/src/Interop/Windows/User32/Interop.LoadString.cs b/src/libraries/Common/src/Interop/Windows/User32/Interop.LoadString.cs index 6ff50442eb428..8824f7c3dfa02 100644 --- a/src/libraries/Common/src/Interop/Windows/User32/Interop.LoadString.cs +++ b/src/libraries/Common/src/Interop/Windows/User32/Interop.LoadString.cs @@ -9,7 +9,7 @@ internal static partial class Interop { internal static partial class User32 { - [DllImport(Libraries.User32, SetLastError = true, EntryPoint = "LoadStringW", CharSet = CharSet.Unicode)] + [DllImport(Libraries.User32, SetLastError = true, EntryPoint = "LoadStringW", CharSet = CharSet.Unicode, ExactSpelling = true)] internal static extern unsafe int LoadString(IntPtr hInstance, uint uID, char* lpBuffer, int cchBufferMax); } } From b1baf3fae49ac3cf7029c73a8461f2001d2c86e8 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 12 May 2020 20:07:59 -0500 Subject: [PATCH 148/420] Fix Microsoft.Extensions.DependencyModel AssemblyVersionInPackageVersion (#36301) --- src/libraries/pkg/baseline/packageIndex.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/pkg/baseline/packageIndex.json b/src/libraries/pkg/baseline/packageIndex.json index bf8e67b252645..d3fffa85b3feb 100644 --- a/src/libraries/pkg/baseline/packageIndex.json +++ b/src/libraries/pkg/baseline/packageIndex.json @@ -549,7 +549,8 @@ "BaselineVersion": "5.0.0", "InboxOn": {}, "AssemblyVersionInPackageVersion": { - "3.1.4.0": "5.0.0", + "3.1.3.0": "3.1.3", + "3.1.4.0": "3.1.4", "5.0.0.0": "5.0.0" } }, From 7c66b6fb6fb00dd86d969ec622a9bb2830016375 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Sanchez Date: Tue, 12 May 2020 18:58:51 -0700 Subject: [PATCH 149/420] Prevent build scripts from letting random values through (#35642) * Arch, OS, and Config no longer let random values through when building the repo. Also, removed the casing restrictions on the bash version. * Fixed the bash build script! Also, casing restrictions are gone! * Added safeguards for bogus values on -rc and -lc on the sh build script. * Fixed the merge conflict on build.sh * Used awk instead of declare for increased compatibility on build.sh * Restored execute permissions to build.sh --- eng/build.ps1 | 6 ++-- eng/build.sh | 96 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 10 deletions(-) diff --git a/eng/build.ps1 b/eng/build.ps1 index e811cf6db27d7..42677b1c7e6dd 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -2,15 +2,15 @@ Param( [switch][Alias('h')]$help, [switch][Alias('t')]$test, - [string[]][Alias('c')]$configuration = @("Debug"), + [ValidateSet("Debug","Release","Checked")][string[]][Alias('c')]$configuration = @("Debug"), [string][Alias('f')]$framework, [string]$vs, - [string]$os, + [ValidateSet("Windows_NT","Unix")][string]$os, [switch]$allconfigurations, [switch]$coverage, [string]$testscope, [switch]$testnobuild, - [string[]][Alias('a')]$arch = @([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant()), + [ValidateSet("x86","x64","arm","arm64")][string[]][Alias('a')]$arch = @([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant()), [Parameter(Position=0)][string][Alias('s')]$subset, [ValidateSet("Debug","Release","Checked")][string][Alias('rc')]$runtimeConfiguration, [ValidateSet("Debug","Release")][string][Alias('lc')]$librariesConfiguration, diff --git a/eng/build.sh b/eng/build.sh index 36e68ef1c1dc4..02c5d278e259d 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -107,6 +107,7 @@ while [[ $# > 0 ]]; do usage exit 0 ;; + -subset|-s) if [ -z ${2+x} ]; then arguments="$arguments /p:Subset=help" @@ -116,23 +117,46 @@ while [[ $# > 0 ]]; do shift 2 fi ;; + -arch) if [ -z ${2+x} ]; then echo "No architecture supplied. See help (--help) for supported architectures." 1>&2 exit 1 fi - arch=$2 + passedArch="$(echo "$2" | awk '{print tolower($0)}')" + case "$passedArch" in + x64|x86|arm|armel|arm64|wasm) + arch=$passedArch + ;; + *) + echo "Unsupported target architecture '$2'." + echo "The allowed values are x86, x64, arm, armel, arm64, and wasm." + exit 1 + ;; + esac shift 2 ;; + -configuration|-c) - if [ -z ${2+x} ]; then + if [ -z ${2+x} ]; then echo "No configuration supplied. See help (--help) for supported configurations." 1>&2 exit 1 fi - val="$(tr '[:lower:]' '[:upper:]' <<< ${2:0:1})${2:1}" + passedConfig="$(echo "$2" | awk '{print tolower($0)}')" + case "$passedConfig" in + debug|release|checked) + val="$(tr '[:lower:]' '[:upper:]' <<< ${passedConfig:0:1})${passedConfig:1}" + ;; + *) + echo "Unsupported target configuration '$2'." + echo "The allowed values are Debug, Release, and Checked." + exit 1 + ;; + esac arguments="$arguments -configuration $val" shift 2 ;; + -framework|-f) if [ -z ${2+x} ]; then echo "No framework supplied. See help (--help) for supported frameworks." 1>&2 @@ -142,19 +166,47 @@ while [[ $# > 0 ]]; do arguments="$arguments /p:BuildTargetFramework=$val" shift 2 ;; + -os) if [ -z ${2+x} ]; then echo "No target operating system supplied. See help (--help) for supported target operating systems." 1>&2 exit 1 fi - os=$2 - arguments="$arguments /p:TargetOS=$2" + passedOS="$(echo "$2" | awk '{print tolower($0)}')" + case "$passedOS" in + windows_nt) + os="Windows_NT" ;; + linux) + os="Linux" ;; + freebsd) + os="FreeBSD" ;; + osx) + os="OSX" ;; + tvos) + os="tvOS" ;; + ios) + os="iOS" ;; + android) + os="Android" ;; + browser) + os="Browser" ;; + sunos) + os="SunOS" ;; + *) + echo "Unsupported target OS '$2'." + echo "The allowed values are Windows_NT, Linux, FreeBSD, OSX, tvOS, iOS, Android, Browser, and SunOS." + exit 1 + ;; + esac + arguments="$arguments /p:TargetOS=$os" shift 2 ;; + -allconfigurations) arguments="$arguments /p:BuildAllConfigurations=true" shift 1 ;; + -testscope) if [ -z ${2+x} ]; then echo "No test scope supplied. See help (--help) for supported test scope values." 1>&2 @@ -163,40 +215,68 @@ while [[ $# > 0 ]]; do arguments="$arguments /p:TestScope=$2" shift 2 ;; + -testnobuild) arguments="$arguments /p:TestNoBuild=true" shift 1 ;; + -coverage) arguments="$arguments /p:Coverage=true" shift 1 ;; + -runtimeconfiguration|-rc) if [ -z ${2+x} ]; then echo "No runtime configuration supplied. See help (--help) for supported runtime configurations." 1>&2 exit 1 fi - val="$(tr '[:lower:]' '[:upper:]' <<< ${2:0:1})${2:1}" + passedRuntimeConf="$(echo "$2" | awk '{print tolower($0)}')" + case "$passedRuntimeConf" in + debug|release|checked) + val="$(tr '[:lower:]' '[:upper:]' <<< ${passedRuntimeConf:0:1})${passedRuntimeConf:1}" + ;; + *) + echo "Unsupported runtime configuration '$2'." + echo "The allowed values are Debug, Release, and Checked." + exit 1 + ;; + esac arguments="$arguments /p:RuntimeConfiguration=$val" shift 2 ;; + -librariesconfiguration|-lc) if [ -z ${2+x} ]; then echo "No libraries configuration supplied. See help (--help) for supported libraries configurations." 1>&2 exit 1 fi - arguments="$arguments /p:LibrariesConfiguration=$2" + passedLibConf="$(echo "$2" | awk '{print tolower($0)}')" + case "$passedLibConf" in + debug|release) + val="$(tr '[:lower:]' '[:upper:]' <<< ${passedLibConf:0:1})${passedLibConf:1}" + ;; + *) + echo "Unsupported libraries configuration '$2'." + echo "The allowed values are Debug and Release." + exit 1 + ;; + esac + arguments="$arguments /p:LibrariesConfiguration=$val" shift 2 ;; + -cross) crossBuild=1 arguments="$arguments /p:CrossBuild=True" shift 1 ;; + -clang*) arguments="$arguments /p:Compiler=$opt" shift 1 ;; + -cmakeargs) if [ -z ${2+x} ]; then echo "No cmake args supplied." 1>&2 @@ -205,10 +285,12 @@ while [[ $# > 0 ]]; do cmakeargs="${cmakeargs} ${opt} $2" shift 2 ;; + -gcc*) arguments="$arguments /p:Compiler=$opt" shift 1 ;; + *) extraargs="$extraargs $1" shift 1 From 095abc7380c239a819a64719c6c5bbab09029b47 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 12 May 2020 21:39:49 -0500 Subject: [PATCH 150/420] Remove unsed variable in MsQuicApi (#36302) --- .../Quic/Implementations/MsQuic/Internal/MsQuicApi.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs index 0b9893333d715..dd42af8ff6142 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs @@ -142,8 +142,6 @@ static MsQuicApi() // - Otherwise, dial this in to reflect actual minimum requirements and add some sort of platform // error code mapping when creating exceptions. - OperatingSystem ver = Environment.OSVersion; - // TODO: try to initialize TLS 1.3 in SslStream. try From 34eaf4f8e87f8c8be4bb2428b1d7d6af0cffd40c Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Tue, 12 May 2020 19:55:48 -0700 Subject: [PATCH 151/420] Flow exit code from RunTests.sh in iOS (#36315) --- eng/testing/AppleRunnerTemplate.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/eng/testing/AppleRunnerTemplate.sh b/eng/testing/AppleRunnerTemplate.sh index 809580e5d73eb..c146f7e0364b1 100644 --- a/eng/testing/AppleRunnerTemplate.sh +++ b/eng/testing/AppleRunnerTemplate.sh @@ -45,4 +45,8 @@ dotnet xharness ios test --app="$APP_BUNDLE" \ --targets=$TARGET \ --output-directory=$XHARNESS_OUT +_exitCode=$? + echo "Xharness artifacts: $XHARNESS_OUT" + +exit $_exitCode From 8a72700b6784e582170ff01076b9e1190295dcd0 Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Tue, 12 May 2020 20:16:00 -0700 Subject: [PATCH 152/420] Add POH size counter (#36150) * Add POH size counter * Add 'Pinned Object Heap' to DisplayName --- .../src/System/Diagnostics/Tracing/RuntimeEventSource.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs index 336e981bd622a..4086fa0491ccd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs @@ -35,6 +35,7 @@ internal sealed class RuntimeEventSource : EventSource private PollingCounter? _gen1SizeCounter; private PollingCounter? _gen2SizeCounter; private PollingCounter? _lohSizeCounter; + private PollingCounter? _pohSizeCounter; private PollingCounter? _assemblyCounter; #endif @@ -76,6 +77,7 @@ protected override void OnEventCommand(EventCommandEventArgs command) _gen1SizeCounter ??= new PollingCounter("gen-1-size", this, () => GC.GetGenerationSize(1)) { DisplayName = "Gen 1 Size", DisplayUnits = "B" }; _gen2SizeCounter ??= new PollingCounter("gen-2-size", this, () => GC.GetGenerationSize(2)) { DisplayName = "Gen 2 Size", DisplayUnits = "B" }; _lohSizeCounter ??= new PollingCounter("loh-size", this, () => GC.GetGenerationSize(3)) { DisplayName = "LOH Size", DisplayUnits = "B" }; + _pohSizeCounter ??= new PollingCounter("poh-size", this, () => GC.GetGenerationSize(4)) { DisplayName = "POH (Pinned Object Heap) Size", DisplayUnits = "B" }; _assemblyCounter ??= new PollingCounter("assembly-count", this, () => System.Reflection.Assembly.GetAssemblyCount()) { DisplayName = "Number of Assemblies Loaded" }; #endif } From c3d7041480a8f64f693de9c5e7c0aa13843d74bb Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Tue, 12 May 2020 23:35:53 -0400 Subject: [PATCH 153/420] Remove several unnecessary arrays used with Split (#36304) Now that we have a Split overload that takes a single char, the previous optimization to cache an array and reuse that array with the array-based overload isn't needed. --- src/libraries/Common/src/System/Net/Mail/MailBnfHelper.cs | 4 +--- .../src/System/ComponentModel/Design/DesignerOptionService.cs | 3 +-- .../src/System/ComponentModel/EnumConverter.cs | 4 +--- src/libraries/System.Data.Common/src/System/Data/XDRSchema.cs | 3 +-- .../src/System/Diagnostics/FileVersionInfo.Unix.cs | 4 +--- .../src/System/Drawing/Printing/PrintingServices.Unix.cs | 4 ++-- .../src/System/Security/Cryptography/CryptoConfig.cs | 4 +--- 7 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/libraries/Common/src/System/Net/Mail/MailBnfHelper.cs b/src/libraries/Common/src/System/Net/Mail/MailBnfHelper.cs index 5f72eaf1bafa1..494eaea415eb2 100644 --- a/src/libraries/Common/src/System/Net/Mail/MailBnfHelper.cs +++ b/src/libraries/Common/src/System/Net/Mail/MailBnfHelper.cs @@ -45,8 +45,6 @@ internal static class MailBnfHelper internal const char Comma = ','; internal const char Dot = '.'; - private static readonly char[] s_colonSeparator = new char[] { ':' }; - // NOTE: See RFC 2822 for more detail. By default, every value in the array is false and only // those values which are allowed in that particular set are then set to true. The numbers // annotating each definition below are the range of ASCII values which are allowed in that definition. @@ -317,7 +315,7 @@ internal static string ReadToken(string data, ref int offset, StringBuilder? bui localBuilder.Append(' '); } - string[] offsetFields = offset.Split(s_colonSeparator); + string[] offsetFields = offset.Split(':'); localBuilder.Append(offsetFields[0]); localBuilder.Append(offsetFields[1]); return (builder != null ? null : localBuilder.ToString()); diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerOptionService.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerOptionService.cs index f80f2c00babdd..ae870960bbf87 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerOptionService.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerOptionService.cs @@ -14,7 +14,6 @@ namespace System.ComponentModel.Design public abstract class DesignerOptionService : IDesignerOptionService { private DesignerOptionCollection _options; - private static readonly char[] s_slash = { '\\' }; /// /// Returns the options collection for this service. There is @@ -70,7 +69,7 @@ private PropertyDescriptor GetOptionProperty(string pageName, string valueName) throw new ArgumentNullException(nameof(valueName)); } - string[] optionNames = pageName.Split(s_slash); + string[] optionNames = pageName.Split('\\'); DesignerOptionCollection options = Options; foreach (string optionName in optionNames) diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/EnumConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/EnumConverter.cs index b7db262f29830..2ae15a3c54741 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/EnumConverter.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/EnumConverter.cs @@ -16,8 +16,6 @@ namespace System.ComponentModel /// public class EnumConverter : TypeConverter { - private static readonly char[] s_separators = { ',' }; - /// /// Initializes a new instance of the class for the given /// type. @@ -83,7 +81,7 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c { bool isUnderlyingTypeUInt64 = Enum.GetUnderlyingType(EnumType) == typeof(ulong); long convertedValue = 0; - string[] values = strValue.Split(s_separators); + string[] values = strValue.Split(','); foreach (string v in values) { convertedValue |= GetEnumValue(isUnderlyingTypeUInt64, (Enum)Enum.Parse(EnumType, v, true), culture); diff --git a/src/libraries/System.Data.Common/src/System/Data/XDRSchema.cs b/src/libraries/System.Data.Common/src/System/Data/XDRSchema.cs index b2d21c2315b7c..ef5ed183c08fe 100644 --- a/src/libraries/System.Data.Common/src/System/Data/XDRSchema.cs +++ b/src/libraries/System.Data.Common/src/System/Data/XDRSchema.cs @@ -16,7 +16,6 @@ internal sealed class XDRSchema : XMLSchema internal string _schemaUri; internal XmlElement _schemaRoot; internal DataSet _ds; - private static readonly char[] s_colonArray = new char[] { ':' }; internal XDRSchema(DataSet ds, bool fInline) { @@ -294,7 +293,7 @@ private static NameType FindNameType(string name) private Type ParseDataType(string dt, string dtValues) { string strType = dt; - string[] parts = dt.Split(s_colonArray); // ":" + string[] parts = dt.Split(':'); if (parts.Length > 2) { diff --git a/src/libraries/System.Diagnostics.FileVersionInfo/src/System/Diagnostics/FileVersionInfo.Unix.cs b/src/libraries/System.Diagnostics.FileVersionInfo/src/System/Diagnostics/FileVersionInfo.Unix.cs index 661b0092b2537..842ba39e86b79 100644 --- a/src/libraries/System.Diagnostics.FileVersionInfo/src/System/Diagnostics/FileVersionInfo.Unix.cs +++ b/src/libraries/System.Diagnostics.FileVersionInfo/src/System/Diagnostics/FileVersionInfo.Unix.cs @@ -11,8 +11,6 @@ namespace System.Diagnostics { public sealed partial class FileVersionInfo { - private static readonly char[] s_versionSeparators = new char[] { '.' }; - private FileVersionInfo(string fileName) { _fileName = fileName; @@ -204,7 +202,7 @@ private static void ParseVersion(string? versionString, out int major, out int m if (versionString != null) { - string[] parts = versionString.Split(s_versionSeparators); + string[] parts = versionString.Split('.'); if (parts.Length <= 4 && parts.Length > 0) { major = ParseUInt16UntilNonDigit(parts[0], out bool endedEarly); diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintingServices.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintingServices.Unix.cs index c9da109eb951d..baf19efb84f6c 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintingServices.Unix.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Printing/PrintingServices.Unix.cs @@ -422,9 +422,9 @@ internal static void LoadPrinterResolutions(string printer, PrinterSettings sett int x_resolution, y_resolution; try { - if (resolution.Contains("x")) // string.Contains(char) is .NetCore2.1+ specific + if (resolution.Contains('x')) { - string[] resolutions = resolution.Split(new[] { 'x' }); + string[] resolutions = resolution.Split('x'); x_resolution = Convert.ToInt32(resolutions[0]); y_resolution = Convert.ToInt32(resolutions[1]); } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/CryptoConfig.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/CryptoConfig.cs index 3d9583c02f76f..3614db5655489 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/CryptoConfig.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/CryptoConfig.cs @@ -38,8 +38,6 @@ public class CryptoConfig private static readonly ConcurrentDictionary appNameHT = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); private static readonly ConcurrentDictionary appOidHT = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - private static readonly char[] SepArray = { '.' }; // valid ASN.1 separators - // .NET Core does not support AllowOnlyFipsAlgorithms public static bool AllowOnlyFipsAlgorithms => false; @@ -503,7 +501,7 @@ public static byte[] EncodeOID(string str) if (str == null) throw new ArgumentNullException(nameof(str)); - string[] oidString = str.Split(SepArray); + string[] oidString = str.Split('.'); // valid ASN.1 separator uint[] oidNums = new uint[oidString.Length]; for (int i = 0; i < oidString.Length; i++) { From cb3c4b1da18967601bbc7b97b8d90caa8ce1d2df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Wed, 13 May 2020 12:50:39 +0200 Subject: [PATCH 154/420] Add MonoAOTCompiler msbuild task (#35961) --- eng/testing/tests.mobile.targets | 56 ++-- eng/testing/tests.props | 1 + src/mono/Directory.Build.props | 1 + src/mono/mono.proj | 180 +++++------- .../AotCompilerTask/MonoAOTCompiler.cs | 256 ++++++++++++++++++ .../AotCompilerTask/MonoAOTCompiler.csproj | 17 ++ .../AotCompilerTask/MonoAOTCompiler.props | 17 ++ src/mono/msbuild/AotCompilerTask/Utils.cs | 88 ++++++ .../msbuild/AppleAppBuilder/AotCompiler.cs | 152 ----------- .../AppleAppBuilder/AppleAppBuilder.cs | 124 +++++---- .../AppleAppBuilder/AppleAppBuilder.csproj | 1 - .../Templates/CMakeLists.txt.template | 3 + src/mono/msbuild/AppleAppBuilder/Xcode.cs | 12 +- .../System.Private.CoreLib.xml | 3 + .../netcore/sample/Android/Program.csproj | 6 +- src/mono/netcore/sample/iOS/Makefile | 2 +- src/mono/netcore/sample/iOS/Program.csproj | 78 ++++-- 17 files changed, 646 insertions(+), 351 deletions(-) create mode 100644 src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.cs create mode 100644 src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.csproj create mode 100644 src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.props create mode 100644 src/mono/msbuild/AotCompilerTask/Utils.cs delete mode 100644 src/mono/msbuild/AppleAppBuilder/AotCompiler.cs diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index b78d6451612c8..90a18f86ca84e 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -3,17 +3,19 @@ $([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle')) $([MSBuild]::NormalizePath('$(BundleDir)', '$(RunScriptOutputName)')) + true + - arm64-v8a - armeabi - x86_64 - $(TargetArchitecture) + arm64-v8a + armeabi + x86_64 + x86 @@ -22,7 +24,6 @@ - @@ -35,10 +36,11 @@ - + @@ -53,6 +55,11 @@ + + + + @@ -60,25 +67,44 @@ + - - - + @@ -87,8 +113,6 @@ - diff --git a/eng/testing/tests.props b/eng/testing/tests.props index 09b51e3163a7d..382ffe67684d9 100644 --- a/eng/testing/tests.props +++ b/eng/testing/tests.props @@ -26,6 +26,7 @@ $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleTestRunner', '$(MobileHelpersDirSuffix)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', '$(MobileHelpersDirSuffix)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidTestRunner', '$(MobileHelpersDirSuffix)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'MonoAOTCompiler', '$(MobileHelpersDirSuffix)')) $(PackageRID) true diff --git a/src/mono/Directory.Build.props b/src/mono/Directory.Build.props index 425f7a1cf725a..aa7e500eb75a6 100644 --- a/src/mono/Directory.Build.props +++ b/src/mono/Directory.Build.props @@ -108,5 +108,6 @@ $([MSBuild]::NormalizeDirectory('$(MonoProjectRoot)', 'msbuild', 'AppleTestRunner')) $([MSBuild]::NormalizeDirectory('$(MonoProjectRoot)', 'msbuild', 'AndroidAppBuilder')) $([MSBuild]::NormalizeDirectory('$(MonoProjectRoot)', 'msbuild', 'AndroidTestRunner')) + $([MSBuild]::NormalizeDirectory('$(MonoProjectRoot)', 'msbuild', 'AotCompilerTask')) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 0ac63489b21ed..834b513f5ec38 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -29,13 +29,14 @@ $(ArtifactsDir)bin\testhost\$(NetCoreAppCurrent)-$(TargetOS)-$(LibrariesTestConfig)-$(Platform)\ $(LibrariesTesthostRoot)shared\Microsoft.NETCore.App\$(ProductVersion)\ /Applications/Xcode.app/Contents/Developer - true - true + true + true true + $(MonoObjDir)cross\config.h - + @@ -163,56 +164,7 @@ <_MonoLDFLAGS Include="-lobjc" /> <_MonoLDFLAGS Include="-lc++" /> - - <_MonoAotCrossConfigureParams Include="--host=x86_64-apple-darwin10" /> - <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'arm64'" Include="--target=aarch64-darwin" /> - <_MonoAotCrossConfigureParams Include="--with-cross-offsets=$(MonoObjDir)cross/offsets-$(Platform)-darwin.h" /> - <_MonoAotCrossConfigureParams Include="--with-core=only" /> - <_MonoAotCrossConfigureParams Include="--enable-maintainer-mode" /> - <_MonoAotCrossConfigureParams Include="--enable-compile-warnings" /> - <_MonoAotCrossConfigureParams Include="--prefix=$(MonoObjDir)cross/out" /> - <_MonoAotCrossConfigureParams Include="--disable-boehm" /> - <_MonoAotCrossConfigureParams Include="--disable-btls" /> - <_MonoAotCrossConfigureParams Include="--disable-iconv" /> - <_MonoAotCrossConfigureParams Include="--disable-libraries" /> - <_MonoAotCrossConfigureParams Include="--disable-mcs-build" /> - <_MonoAotCrossConfigureParams Include="--disable-nls" /> - <_MonoAotCrossConfigureParams Include="--enable-dtrace=no" /> - <_MonoAotCrossConfigureParams Include="--enable-icall-symbol-map" /> - <_MonoAotCrossConfigureParams Include="--enable-minimal=com,remoting" /> - <_MonoAotCrossConfigureParams Include="--enable-monotouch" /> - <_MonoAotCrossConfigureParams Include="--disable-crash-reporting" /> - <_MonoAotCrossConfigureParams Include="--with-llvm=$(MonoLLVMDir)" /> - - <_MonoAotCrossAC_VARS Include="ac_cv_func_shm_open_working_with_mmap=no" /> - - <_MonoAotCrossCFLAGS Include="-O2" /> - <_MonoAotCrossCFLAGS Include="-g" /> - <_MonoAotCrossCFLAGS Include="-isysroot $(XcodeDir)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$(macOSVersion).sdk" /> - <_MonoAotCrossCFLAGS Include="-mmacosx-version-min=$(macOSVersionMin)" /> - <_MonoAotCrossCFLAGS Include="-Qunused-arguments" /> - <_MonoAotCrossCFLAGS Include="-m64" /> - - <_MonoAotCrossCXXFLAGS Include="-O2" /> - <_MonoAotCrossCXXFLAGS Include="-g" /> - <_MonoAotCrossCXXFLAGS Include="-isysroot $(XcodeDir)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$(macOSVersion).sdk" /> - <_MonoAotCrossCXXFLAGS Include="-mmacosx-version-min=$(macOSVersionMin)" /> - <_MonoAotCrossCXXFLAGS Include="-Qunused-arguments" /> - <_MonoAotCrossCXXFLAGS Include="-stdlib=libc++" /> - <_MonoAotCrossCXXFLAGS Include="-m64" /> - - <_MonoAotCrossCPPFLAGS Include="-O2" /> - <_MonoAotCrossCPPFLAGS Include="-g" /> - <_MonoAotCrossCPPFLAGS Include="-DMONOTOUCH=1" /> - <_MonoAotCrossCPPFLAGS Include="-m64" /> - - <_MonoAotCrossCXXPPFLAGS Include="-O2" /> - <_MonoAotCrossCXXPPFLAGS Include="-g" /> - <_MonoAotCrossCXXPPFLAGS Include="-m64" /> - - <_MonoAotCrossLDFLAGS Include="-stdlib=libc++" /> - <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' == 'arm64'" Include="--abi=aarch64-apple-darwin10" /> <_MonoAotCrossOffsetsToolParams Include="--netcore" /> <_MonoAotCrossOffsetsToolParams Include="--targetdir="$(MonoObjDir)"" /> @@ -356,57 +308,7 @@ <_MonoLDFLAGS Include="-lobjc" /> <_MonoLDFLAGS Include="-lc++" /> - - <_MonoAotCrossConfigureParams Include="--host=x86_64-apple-darwin10" /> - <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'arm64'" Include="--target=aarch64-darwin" /> - <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'arm'" Include="--target=arm-darwin" /> - <_MonoAotCrossConfigureParams Include="--with-cross-offsets=$(MonoObjDir)cross/offsets-$(Platform)-darwin.h" /> - <_MonoAotCrossConfigureParams Include="--with-core=only" /> - <_MonoAotCrossConfigureParams Include="--enable-maintainer-mode" /> - <_MonoAotCrossConfigureParams Include="--enable-compile-warnings" /> - <_MonoAotCrossConfigureParams Include="--prefix=$(MonoObjDir)cross/out" /> - <_MonoAotCrossConfigureParams Include="--disable-boehm" /> - <_MonoAotCrossConfigureParams Include="--disable-btls" /> - <_MonoAotCrossConfigureParams Include="--disable-iconv" /> - <_MonoAotCrossConfigureParams Include="--disable-libraries" /> - <_MonoAotCrossConfigureParams Include="--disable-mcs-build" /> - <_MonoAotCrossConfigureParams Include="--disable-nls" /> - <_MonoAotCrossConfigureParams Include="--enable-dtrace=no" /> - <_MonoAotCrossConfigureParams Include="--enable-icall-symbol-map" /> - <_MonoAotCrossConfigureParams Include="--enable-minimal=com,remoting" /> - <_MonoAotCrossConfigureParams Include="--enable-monotouch" /> - <_MonoAotCrossConfigureParams Include="--disable-crash-reporting" /> - <_MonoAotCrossConfigureParams Include="--with-llvm=$(MonoLLVMDir)" /> - - <_MonoAotCrossAC_VARS Include="ac_cv_func_shm_open_working_with_mmap=no" /> - - <_MonoAotCrossCFLAGS Include="-O2" /> - <_MonoAotCrossCFLAGS Include="-g" /> - <_MonoAotCrossCFLAGS Include="-isysroot $(XcodeDir)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$(macOSVersion).sdk" /> - <_MonoAotCrossCFLAGS Include="-mmacosx-version-min=$(macOSVersionMin)" /> - <_MonoAotCrossCFLAGS Include="-Qunused-arguments" /> - <_MonoAotCrossCFLAGS Include="-m64" /> - - <_MonoAotCrossCXXFLAGS Include="-O2" /> - <_MonoAotCrossCXXFLAGS Include="-g" /> - <_MonoAotCrossCXXFLAGS Include="-isysroot $(XcodeDir)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$(macOSVersion).sdk" /> - <_MonoAotCrossCXXFLAGS Include="-mmacosx-version-min=$(macOSVersionMin)" /> - <_MonoAotCrossCXXFLAGS Include="-Qunused-arguments" /> - <_MonoAotCrossCXXFLAGS Include="-stdlib=libc++" /> - <_MonoAotCrossCXXFLAGS Include="-m64" /> - - <_MonoAotCrossCPPFLAGS Include="-O2" /> - <_MonoAotCrossCPPFLAGS Include="-g" /> - <_MonoAotCrossCPPFLAGS Include="-DMONOTOUCH=1" /> - <_MonoAotCrossCPPFLAGS Include="-m64" /> - - <_MonoAotCrossCXXPPFLAGS Include="-O2" /> - <_MonoAotCrossCXXPPFLAGS Include="-g" /> - <_MonoAotCrossCXXPPFLAGS Include="-m64" /> - - <_MonoAotCrossLDFLAGS Include="-stdlib=libc++" /> - <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' == 'arm64'" Include="--abi=aarch64-apple-darwin10" /> <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' == 'arm'" Include="--abi=arm-apple-darwin10" /> <_MonoAotCrossOffsetsToolParams Include="--netcore" /> @@ -467,6 +369,61 @@ <_MonoCPPFLAGS Include="-DHOST_IOS" /> + + + + + <_MonoAotCrossConfigureParams Include="--host=x86_64-apple-darwin10" /> + <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'arm64'" Include="--target=aarch64-darwin" /> + <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'arm'" Include="--target=arm-darwin" /> + <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'x86'" Include="--target=i386-apple-darwin" /> + <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'arm'" Include="--with-cross-offsets=$(MonoObjDir)cross/offsets-$(Platform)-darwin.h" /> + <_MonoAotCrossConfigureParams Include="--with-core=only" /> + <_MonoAotCrossConfigureParams Include="--enable-maintainer-mode" /> + <_MonoAotCrossConfigureParams Include="--enable-compile-warnings" /> + <_MonoAotCrossConfigureParams Include="--prefix=$(MonoObjDir)cross/out" /> + <_MonoAotCrossConfigureParams Include="--disable-boehm" /> + <_MonoAotCrossConfigureParams Include="--disable-btls" /> + <_MonoAotCrossConfigureParams Include="--disable-iconv" /> + <_MonoAotCrossConfigureParams Include="--disable-libraries" /> + <_MonoAotCrossConfigureParams Include="--disable-mcs-build" /> + <_MonoAotCrossConfigureParams Include="--disable-nls" /> + <_MonoAotCrossConfigureParams Include="--enable-dtrace=no" /> + <_MonoAotCrossConfigureParams Include="--enable-icall-symbol-map" /> + <_MonoAotCrossConfigureParams Include="--enable-minimal=com,remoting" /> + <_MonoAotCrossConfigureParams Include="--enable-monotouch" /> + <_MonoAotCrossConfigureParams Include="--disable-crash-reporting" /> + <_MonoAotCrossConfigureParams Include="--with-llvm=$(MonoLLVMDir)" /> + + <_MonoAotCrossAC_VARS Include="ac_cv_func_shm_open_working_with_mmap=no" /> + + <_MonoAotCrossCFLAGS Include="-O2" /> + <_MonoAotCrossCFLAGS Include="-g" /> + <_MonoAotCrossCFLAGS Include="-isysroot $(XcodeDir)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$(macOSVersion).sdk" /> + <_MonoAotCrossCFLAGS Include="-mmacosx-version-min=$(macOSVersionMin)" /> + <_MonoAotCrossCFLAGS Include="-Qunused-arguments" /> + <_MonoAotCrossCFLAGS Include="-m64" /> + + <_MonoAotCrossCXXFLAGS Include="-O2" /> + <_MonoAotCrossCXXFLAGS Include="-g" /> + <_MonoAotCrossCXXFLAGS Include="-isysroot $(XcodeDir)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$(macOSVersion).sdk" /> + <_MonoAotCrossCXXFLAGS Include="-mmacosx-version-min=$(macOSVersionMin)" /> + <_MonoAotCrossCXXFLAGS Include="-Qunused-arguments" /> + <_MonoAotCrossCXXFLAGS Include="-stdlib=libc++" /> + <_MonoAotCrossCXXFLAGS Include="-m64" /> + + <_MonoAotCrossCPPFLAGS Include="-O2" /> + <_MonoAotCrossCPPFLAGS Include="-g" /> + <_MonoAotCrossCPPFLAGS Include="-DMONOTOUCH=1" /> + <_MonoAotCrossCPPFLAGS Include="-m64" /> + + <_MonoAotCrossCXXPPFLAGS Include="-O2" /> + <_MonoAotCrossCXXPPFLAGS Include="-g" /> + <_MonoAotCrossCXXPPFLAGS Include="-m64" /> + + <_MonoAotCrossLDFLAGS Include="-stdlib=libc++" /> + + <_MonoConfigureParams Condition="'$(Platform)' == 'arm64'" Include="--host=aarch64-linux-android" /> @@ -727,7 +684,7 @@ <_MonoAotCrossCCLDFLAGSOption Condition="@(_MonoAotCrossCCLDFLAGS->Count()) > 0">CCLDFLAGS="@(_MonoAotCrossCCLDFLAGS, ' ')" <_MonoAotCrossConfigureCommand>$(MonoProjectRoot)configure @(_MonoAotCrossConfigureParams, ' ') @(_MonoAotCrossAC_VARS, ' ') $(_MonoAotCrossCFLAGSOption) $(_MonoAotCrossCXXFLAGSOption) $(_MonoAotCrossCPPFLAGSOption) $(_MonoAotCrossCXXCPPFLAGSOption) $(_MonoAotCrossLDFLAGSOption) $(_MonoAotCrossCCLDFLAGSOption) $(_MonoCCOption) $(_MonoCXXOption) $(_MonoAROption) $(_MonoASOption) $(_MonoCPPOption) $(_MonoCXXCPPOption) $(_MonoDLLTOOLOption) $(_MonoLDOption) $(_MonoOBJDUMPOption) $(_MonoRANLIBOption) $(_MonoCMAKEOption) $(_MonoSTRIPOption) - <_MonoAotCrossOffsetsCommand>python3 $(MonoProjectRoot)mono/tools/offsets-tool/offsets-tool.py @(_MonoAotCrossOffsetsToolParams, ' ') + <_MonoAotCrossOffsetsCommand Condition="@(_MonoAotCrossOffsetsToolParams->Count()) > 0">python3 $(MonoProjectRoot)mono/tools/offsets-tool/offsets-tool.py @(_MonoAotCrossOffsetsToolParams, ' ') @@ -926,7 +883,7 @@ - + @@ -935,7 +892,7 @@ Targets="Restore;Build" /> - + @@ -945,15 +902,21 @@ - + + + + + - + <_MonoRuntimeFilePath Condition="'$(TargetsWindows)' == 'true' and '$(Platform)' == 'x64'">$(MonoObjDir)x64\Bin\$(Configuration)\mono-2.0-sgen.dll <_MonoRuntimeFilePath Condition="'$(TargetsWindows)' == 'true' and '$(Platform)' == 'x86'">$(MonoObjDir)Win32\Bin\$(Configuration)\mono-2.0-sgen.dll @@ -966,7 +929,10 @@ <_MonoRuntimeStaticFilePath Condition="'$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true' or '$(TargetsAndroid)' == 'true'">$(MonoObjDir)out\lib\libmonosgen-2.0.a <_MonoAotCrossFilePath Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'arm64'">$(MonoObjDir)cross\out\bin\aarch64-darwin-mono-sgen <_MonoAotCrossFilePath Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'arm'">$(MonoObjDir)cross\out\bin\arm-darwin-mono-sgen + <_MonoAotCrossFilePath Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'x64'">$(MonoObjDir)cross\out\bin\mono-sgen + <_MonoAotCrossFilePath Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'x86'">$(MonoObjDir)cross\out\bin\mono-sgen <_MonoAotCrossFilePath Condition="'$(TargetstvOS)' == 'true' and '$(Platform)' == 'arm64'">$(MonoObjDir)cross\out\bin\aarch64-darwin-mono-sgen + <_MonoAotCrossFilePath Condition="'$(TargetstvOS)' == 'true' and '$(Platform)' == 'x64'">$(MonoObjDir)cross\out\bin\mono-sgen <_MonoAotCrossFilePath Condition="'$(TargetsBrowser)' == 'true'">$(MonoObjDir)cross\out\bin\wasm32-unknown-none-mono-sgen diff --git a/src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.cs b/src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.cs new file mode 100644 index 0000000000000..8f8643ae606d7 --- /dev/null +++ b/src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.cs @@ -0,0 +1,256 @@ +// 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. + +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +public class MonoAOTCompiler : Microsoft.Build.Utilities.Task +{ + /// + /// Path to AOT cross-compiler binary (mono-aot-cross) + /// + [Required] + public string CompilerBinaryPath { get; set; } = ""!; + + /// + /// Assemblies to be AOTd. They need to be in a self-contained directory. + /// + /// Metadata: + /// - AotArguments: semicolon-separated list of options that will be passed to --aot= + /// - ProcessArguments: semicolon-separated list of options that will be passed to the AOT compiler itself + /// + [Required] + public ITaskItem[] Assemblies { get; set; } = Array.Empty(); + + /// + /// Assemblies which were AOT compiled. + /// + /// Successful AOT compilation will set the following metadata on the items: + /// - AssemblerFile (when using OutputType=AsmOnly) + /// - ObjectFile (when using OutputType=Normal) + /// - AotDataFile + /// - LlvmObjectFile (if using LLVM) + /// - LlvmBitcodeFile (if using LLVM-only) + /// + [Output] + public ITaskItem[]? CompiledAssemblies { get; set; } + + /// + /// Disable parallel AOT compilation + /// + public bool DisableParallelAot { get; set; } + + /// + /// Use LLVM for AOT compilation. + /// The cross-compiler must be built with LLVM support + /// + public bool UseLLVM { get; set; } + + /// + /// Choose between 'Normal', 'Full', 'LLVMOnly'. + /// LLVMOnly means to use only LLVM for FullAOT, AOT result will be a LLVM Bitcode file (the cross-compiler must be built with LLVM support) + /// + public string Mode { get; set; } = nameof(MonoAotMode.Normal); + + /// + /// Choose between 'Normal', 'AsmOnly' + /// AsmOnly means the AOT compiler will produce .s assembly code instead of an .o object file. + /// + public string OutputType { get; set; } = nameof(MonoAotOutputType.Normal); + + /// + /// Path to the directory where LLVM binaries (opt and llc) are found. + /// It's required if UseLLVM is set + /// + public string? LLVMPath { get; set; } + + /// + /// Path to the directory where msym artifacts are stored. + /// + public string? MsymPath { get; set; } + + ConcurrentBag compiledAssemblies = new ConcurrentBag(); + MonoAotMode parsedAotMode; + MonoAotOutputType parsedOutputType; + + public override bool Execute() + { + Utils.Logger = Log; + + if (string.IsNullOrEmpty(CompilerBinaryPath)) + { + throw new ArgumentException($"'{nameof(CompilerBinaryPath)}' is required.", nameof(CompilerBinaryPath)); + } + + if (!File.Exists(CompilerBinaryPath)) + { + throw new ArgumentException($"'{CompilerBinaryPath}' doesn't exist.", nameof(CompilerBinaryPath)); + } + + if (Assemblies.Length == 0) + { + throw new ArgumentException($"'{nameof(Assemblies)}' is required.", nameof(Assemblies)); + } + + if (UseLLVM && string.IsNullOrEmpty(LLVMPath)) + { + // prevent using some random llc/opt from PATH (installed with clang) + throw new ArgumentException($"'{nameof(LLVMPath)}' is required when '{nameof(UseLLVM)}' is true.", nameof(LLVMPath)); + } + + switch (Mode) + { + case "Normal": parsedAotMode = MonoAotMode.Normal; break; + case "Full": parsedAotMode = MonoAotMode.Full; break; + case "LLVMOnly": parsedAotMode = MonoAotMode.LLVMOnly; break; + default: + throw new ArgumentException($"'{nameof(Mode)}' must be one of: '{nameof(MonoAotMode.Normal)}', '{nameof(MonoAotMode.Full)}', '{nameof(MonoAotMode.LLVMOnly)}'. Received: '{Mode}'.", nameof(Mode)); + } + + switch (OutputType) + { + case "Normal": parsedOutputType = MonoAotOutputType.Normal; break; + case "AsmOnly": parsedOutputType = MonoAotOutputType.AsmOnly; break; + default: + throw new ArgumentException($"'{nameof(OutputType)}' must be one of: '{nameof(MonoAotOutputType.Normal)}', '{nameof(MonoAotOutputType.AsmOnly)}'. Received: '{OutputType}'.", nameof(OutputType)); + } + + if (parsedAotMode == MonoAotMode.LLVMOnly && !UseLLVM) + { + throw new ArgumentException($"'{nameof(UseLLVM)}' must be true when '{nameof(Mode)}' is {nameof(MonoAotMode.LLVMOnly)}.", nameof(UseLLVM)); + } + + Parallel.ForEach(Assemblies, + new ParallelOptions { MaxDegreeOfParallelism = DisableParallelAot ? 1 : Environment.ProcessorCount }, + assemblyItem => PrecompileLibrary (assemblyItem)); + + CompiledAssemblies = compiledAssemblies.ToArray(); + + return true; + } + + private void PrecompileLibrary(ITaskItem assemblyItem) + { + string assembly = assemblyItem.ItemSpec; + string directory = Path.GetDirectoryName(assembly)!; + var aotAssembly = new TaskItem(assembly); + var aotArgs = new List(); + var processArgs = new List(); + + var a = assemblyItem.GetMetadata("AotArguments"); + if (a != null) + { + aotArgs.AddRange(a.Split(";", StringSplitOptions.RemoveEmptyEntries)); + } + + var p = assemblyItem.GetMetadata("ProcessArguments"); + if (p != null) + { + processArgs.AddRange(p.Split(";", StringSplitOptions.RemoveEmptyEntries)); + } + + Utils.LogInfo($"[AOT] {assembly}"); + + processArgs.Add("--debug"); + + // add LLVM options + if (UseLLVM) + { + processArgs.Add("--llvm"); + + aotArgs.Add($"nodebug"); // can't use debug symbols with LLVM + aotArgs.Add($"llvm-path={LLVMPath}"); + } + else + { + processArgs.Add("--nollvm"); + } + + // compute output mode and file names + if (parsedAotMode == MonoAotMode.LLVMOnly) + { + aotArgs.Add("llvmonly"); + + string llvmBitcodeFile = Path.ChangeExtension(assembly, ".dll.bc"); + aotArgs.Add($"outfile={llvmBitcodeFile}"); + aotAssembly.SetMetadata("LlvmBitcodeFile", llvmBitcodeFile); + } + else + { + if (parsedAotMode == MonoAotMode.Full) + { + aotArgs.Add("full"); + } + + if (parsedOutputType == MonoAotOutputType.AsmOnly) + { + aotArgs.Add("asmonly"); + + string assemblerFile = Path.ChangeExtension(assembly, ".dll.s"); + aotArgs.Add($"outfile={assemblerFile}"); + aotAssembly.SetMetadata("AssemblerFile", assemblerFile); + } + else + { + string objectFile = Path.ChangeExtension(assembly, ".dll.o"); + aotArgs.Add($"outfile={objectFile}"); + aotAssembly.SetMetadata("ObjectFile", objectFile); + } + + if (UseLLVM) + { + string llvmObjectFile = Path.ChangeExtension(assembly, ".dll-llvm.o"); + aotArgs.Add($"llvm-outfile={llvmObjectFile}"); + aotAssembly.SetMetadata("LlvmObjectFile", llvmObjectFile); + } + } + + // pass msym-dir if specified + if (MsymPath != null) + { + aotArgs.Add($"msym-dir={MsymPath}"); + } + + string aotDataFile = Path.ChangeExtension(assembly, ".aotdata"); + aotArgs.Add($"data-outfile={aotDataFile}"); + aotAssembly.SetMetadata("AotDataFile", aotDataFile); + + // we need to quote the entire --aot arguments here to make sure it is parsed + // on Windows as one argument. Otherwise it will be split up into multiple + // values, which wont work. + processArgs.Add($"\"--aot={String.Join(",", aotArgs)}\""); + + processArgs.Add(assembly); + + var envVariables = new Dictionary + { + {"MONO_PATH", directory}, + {"MONO_ENV_OPTIONS", String.Empty} // we do not want options to be provided out of band to the cross compilers + }; + + // run the AOT compiler + Utils.RunProcess(CompilerBinaryPath, String.Join(" ", processArgs), envVariables, directory); + + compiledAssemblies.Add(aotAssembly); + } +} + +public enum MonoAotMode +{ + Normal, + Full, + LLVMOnly, +} + +public enum MonoAotOutputType +{ + Normal, + AsmOnly, +} \ No newline at end of file diff --git a/src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.csproj b/src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.csproj new file mode 100644 index 0000000000000..f5766a3fdcfb7 --- /dev/null +++ b/src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.csproj @@ -0,0 +1,17 @@ + + + Library + true + false + + + + + + + + + + + + diff --git a/src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.props b/src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.props new file mode 100644 index 0000000000000..6824a7fc1c6f1 --- /dev/null +++ b/src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.props @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/src/mono/msbuild/AotCompilerTask/Utils.cs b/src/mono/msbuild/AotCompilerTask/Utils.cs new file mode 100644 index 0000000000000..ac649c9661843 --- /dev/null +++ b/src/mono/msbuild/AotCompilerTask/Utils.cs @@ -0,0 +1,88 @@ +// 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. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +internal class Utils +{ + public static string RunProcess( + string path, + string args = "", + IDictionary? envVars = null, + string? workingDir = null, + bool ignoreErrors = false) + { + LogInfo($"Running: {path} {args}"); + var outputBuilder = new StringBuilder(); + var errorBuilder = new StringBuilder(); + var processStartInfo = new ProcessStartInfo + { + FileName = path, + UseShellExecute = false, + CreateNoWindow = true, + RedirectStandardError = true, + RedirectStandardOutput = true, + Arguments = args, + }; + + if (workingDir != null) + { + processStartInfo.WorkingDirectory = workingDir; + } + + if (envVars != null) + { + foreach (KeyValuePair envVar in envVars) + { + processStartInfo.EnvironmentVariables[envVar.Key] = envVar.Value; + } + } + + Process process = Process.Start(processStartInfo)!; + process.ErrorDataReceived += (sender, e) => + { + LogError(e.Data); + outputBuilder.AppendLine(e.Data); + errorBuilder.AppendLine(e.Data); + }; + process.OutputDataReceived += (sender, e) => + { + LogInfo(e.Data); + outputBuilder.AppendLine(e.Data); + }; + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + process.WaitForExit(); + if (process.ExitCode != 0) + { + throw new Exception("Error: " + errorBuilder); + } + + return outputBuilder.ToString().Trim('\r','\n'); + } + + public static TaskLoggingHelper? Logger { get; set; } + + public static void LogInfo(string? msg) + { + if (msg != null) + { + Logger?.LogMessage(MessageImportance.High, msg); + } + } + + public static void LogError(string? msg) + { + if (msg != null) + { + Logger?.LogError(msg); + } + } +} diff --git a/src/mono/msbuild/AppleAppBuilder/AotCompiler.cs b/src/mono/msbuild/AppleAppBuilder/AotCompiler.cs deleted file mode 100644 index 5a5b8f9ae8b55..0000000000000 --- a/src/mono/msbuild/AppleAppBuilder/AotCompiler.cs +++ /dev/null @@ -1,152 +0,0 @@ -// 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. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading.Tasks; - -internal class AotCompiler -{ - /// - /// Precompile all assemblies in parallel - /// - public static void PrecompileLibraries( - string crossCompiler, - string arch, - bool parallel, - string binDir, - string[] libsToPrecompile, - IDictionary envVariables, - bool optimize, - bool useLlvm, - string? llvmPath) - { - Parallel.ForEach(libsToPrecompile, - new ParallelOptions { MaxDegreeOfParallelism = parallel ? Environment.ProcessorCount : 1 }, - lib => PrecompileLibrary(crossCompiler, arch, binDir, lib, envVariables, optimize, useLlvm, llvmPath)); - } - - private static void PrecompileLibrary( - string crossCompiler, - string arch, - string binDir, - string libToPrecompile, - IDictionary envVariables, - bool optimize, - bool useLlvm, - string? llvmPath) - { - Utils.LogInfo($"[AOT] {libToPrecompile}"); - - var crossArgs = new StringBuilder(); - crossArgs - .Append(" -O=gsharedvt") - .Append(" -O=-float32") - .Append(useLlvm ? " --llvm" : " --nollvm") - .Append(" --debug"); - - string libName = Path.GetFileNameWithoutExtension(libToPrecompile); - var aotArgs = new StringBuilder(); - aotArgs - .Append("mtriple=").Append(arch).Append("-ios,") - .Append("static,") - .Append("asmonly,") - .Append("direct-icalls,") - .Append("nodebug,") - .Append("dwarfdebug,") - .Append("outfile=").Append(Path.Combine(binDir, libName + ".dll.s,")) - .Append("msym-dir=").Append(Path.Combine(binDir, "Msym,")) - .Append("data-outfile=").Append(Path.Combine(binDir, libName + ".aotdata,")) - // TODO: enable direct-pinvokes (to get rid of -force_loads) - //.Append("direct-pinvoke,") - .Append("full,") - .Append("mattr=+crc,"); // enable System.Runtime.Intrinsics.Arm (Crc32 and ArmBase for now) - - if (useLlvm) - { - aotArgs - .Append("llvm-path=").Append(llvmPath).Append(',') - .Append("llvm-outfile=").Append(Path.Combine(binDir, libName + ".dll-llvm.o,")); - // it has -llvm.o suffix because we need both LLVM and non-LLVM bits for every assembly - // most of the stuff from non-llvm .o will be linked out. - } - - // TODO: enable Interpreter - - crossArgs - .Append(" --aot=").Append(aotArgs).Append(" ") - .Append(libToPrecompile); - - Utils.RunProcess(crossCompiler, crossArgs.ToString(), envVariables, binDir); - - var clangArgs = new StringBuilder(); - if (optimize) - { - clangArgs.Append(" -Os"); - } - clangArgs - .Append(" -isysroot ").Append(Xcode.Sysroot) - .Append(" -miphoneos-version-min=10.1") - .Append(" -arch ").Append(arch) - .Append(" -c ").Append(Path.Combine(binDir, libName)).Append(".dll.s") - .Append(" -o ").Append(Path.Combine(binDir, libName)).Append(".dll.o"); - - Utils.RunProcess("clang", clangArgs.ToString(), workingDir: binDir); - } - - public static void GenerateLinkAllFile(string[] objFiles, string outputFile) - { - // Generates 'modules.m' in order to register all managed libraries - // - // - // extern void *mono_aot_module_Lib1_info; - // extern void *mono_aot_module_Lib2_info; - // ... - // - // void mono_ios_register_modules (void) - // { - // mono_aot_register_module (mono_aot_module_Lib1_info); - // mono_aot_register_module (mono_aot_module_Lib2_info); - // ... - // } - - Utils.LogInfo("Generating 'modules.m'..."); - - var lsDecl = new StringBuilder(); - lsDecl - .AppendLine("#include ") - .AppendLine("#include ") - .AppendLine() - .AppendLine("#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR") - .AppendLine(); - - var lsUsage = new StringBuilder(); - lsUsage - .AppendLine("void mono_ios_register_modules (void)") - .AppendLine("{"); - foreach (string objFile in objFiles) - { - string symbol = "mono_aot_module_" + - Path.GetFileName(objFile) - .Replace(".dll.o", "") - .Replace(".", "_") - .Replace("-", "_") + "_info"; - - lsDecl.Append("extern void *").Append(symbol).Append(';').AppendLine(); - lsUsage.Append("\tmono_aot_register_module (").Append(symbol).Append(");").AppendLine(); - } - lsDecl - .AppendLine() - .Append(lsUsage) - .AppendLine("}") - .AppendLine() - .AppendLine("#endif") - .AppendLine(); - - File.WriteAllText(outputFile, lsDecl.ToString()); - Utils.LogInfo($"Saved to {outputFile}."); - } -} diff --git a/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.cs b/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.cs index bdf5362a88818..41bc3cb75eebe 100644 --- a/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.cs +++ b/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.cs @@ -6,18 +6,13 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Text; using System.Linq; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; public class AppleAppBuilderTask : Task { - /// - /// Path to arm64 AOT cross-compiler (mono-aot-cross) - /// It's not used for x64 (Simulator) - /// - public string? CrossCompiler { get; set; } - /// /// ProjectName is used as an app name, bundleId and xcode project name /// @@ -43,20 +38,20 @@ public class AppleAppBuilderTask : Task public string MainLibraryFileName { get; set; } = ""!; /// - /// Path to store build artifacts + /// List of paths to assemblies to be included in the app. For AOT builds the 'ObjectFile' metadata key needs to point to the object file. /// - public string? OutputDirectory { get; set; } + [Required] + public ITaskItem[] Assemblies { get; set; } = Array.Empty(); /// - /// Produce optimized binaries (e.g. use -O2 in AOT) - /// and use 'Release' config in xcode + /// Path to store build artifacts /// - public bool Optimized { get; set; } + public string? OutputDirectory { get; set; } /// - /// Disable parallel AOT compilation + /// Produce optimized binaries and use 'Release' config in xcode /// - public bool DisableParallelAot { get; set; } + public bool Optimized { get; set; } /// /// Target arch, can be "arm64" (device) or "x64" (simulator) at the moment @@ -96,18 +91,6 @@ public class AppleAppBuilderTask : Task /// public bool UseConsoleUITemplate { get; set; } - /// - /// Use LLVM for FullAOT - /// The cross-compiler must be built with LLVM support - /// - public bool UseLlvm { get; set; } - - /// - /// Path to LLVM binaries (opt and llc) - /// It's required if UseLlvm is set - /// - public string? LlvmPath { get; set; } - /// /// Path to *.app bundle /// @@ -124,10 +107,6 @@ public override bool Execute() { Utils.Logger = Log; bool isDevice = Arch.Equals("arm64", StringComparison.InvariantCultureIgnoreCase); - if (isDevice && string.IsNullOrEmpty(CrossCompiler)) - { - throw new ArgumentException("arm64 arch requires CrossCompiler"); - } if (!File.Exists(Path.Combine(AppDir, MainLibraryFileName))) { @@ -139,12 +118,6 @@ public override bool Execute() throw new ArgumentException($"ProjectName='{ProjectName}' should not contain spaces"); } - if (UseLlvm && string.IsNullOrEmpty(LlvmPath)) - { - // otherwise we might accidentally use some random llc/opt from PATH (installed with clang) - throw new ArgumentException($"LlvmPath shoun't be empty when UseLlvm is set"); - } - string[] excludes = new string[0]; if (ExcludeFromAppDir != null) { @@ -153,9 +126,6 @@ public override bool Execute() .Select(i => i.ItemSpec) .ToArray(); } - string[] libsToAot = Directory.GetFiles(AppDir, "*.dll") - .Where(f => !excludes.Contains(Path.GetFileName(f))) - .ToArray(); string binDir = Path.Combine(AppDir, $"bin-{ProjectName}-{Arch}"); if (!string.IsNullOrEmpty(OutputDirectory)) @@ -164,25 +134,30 @@ public override bool Execute() } Directory.CreateDirectory(binDir); - // run AOT compilation only for devices - if (isDevice) + var assemblerFiles = new List(); + foreach (ITaskItem file in Assemblies) { - if (string.IsNullOrEmpty(CrossCompiler)) - throw new InvalidOperationException("cross-compiler is not set"); + // use AOT files if available + var obj = file.GetMetadata("AssemblerFile"); + if (!String.IsNullOrEmpty(obj)) + { + assemblerFiles.Add(obj); + } + } - AotCompiler.PrecompileLibraries(CrossCompiler, Arch, !DisableParallelAot, binDir, libsToAot, - new Dictionary { {"MONO_PATH", AppDir} }, - Optimized, UseLlvm, LlvmPath); + if (isDevice && !assemblerFiles.Any()) + { + throw new InvalidOperationException("Need list of AOT files for device builds."); } // generate modules.m - AotCompiler.GenerateLinkAllFile( - Directory.GetFiles(binDir, "*.dll.o"), + GenerateLinkAllFile( + assemblerFiles, Path.Combine(binDir, "modules.m")); if (GenerateXcodeProject) { - XcodeProjectPath = Xcode.GenerateXCode(ProjectName, MainLibraryFileName, + XcodeProjectPath = Xcode.GenerateXCode(ProjectName, MainLibraryFileName, assemblerFiles, AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, NativeMainSource); if (BuildAppBundle) @@ -203,4 +178,57 @@ public override bool Execute() return true; } + + static void GenerateLinkAllFile(IEnumerable asmFiles, string outputFile) + { + // Generates 'modules.m' in order to register all managed libraries + // + // + // extern void *mono_aot_module_Lib1_info; + // extern void *mono_aot_module_Lib2_info; + // ... + // + // void mono_ios_register_modules (void) + // { + // mono_aot_register_module (mono_aot_module_Lib1_info); + // mono_aot_register_module (mono_aot_module_Lib2_info); + // ... + // } + + Utils.LogInfo("Generating 'modules.m'..."); + + var lsDecl = new StringBuilder(); + lsDecl + .AppendLine("#include ") + .AppendLine("#include ") + .AppendLine() + .AppendLine("#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR") + .AppendLine(); + + var lsUsage = new StringBuilder(); + lsUsage + .AppendLine("void mono_ios_register_modules (void)") + .AppendLine("{"); + foreach (string asmFile in asmFiles) + { + string symbol = "mono_aot_module_" + + Path.GetFileName(asmFile) + .Replace(".dll.s", "") + .Replace(".", "_") + .Replace("-", "_") + "_info"; + + lsDecl.Append("extern void *").Append(symbol).Append(';').AppendLine(); + lsUsage.Append("\tmono_aot_register_module (").Append(symbol).Append(");").AppendLine(); + } + lsDecl + .AppendLine() + .Append(lsUsage) + .AppendLine("}") + .AppendLine() + .AppendLine("#endif") + .AppendLine(); + + File.WriteAllText(outputFile, lsDecl.ToString()); + Utils.LogInfo($"Saved to {outputFile}."); + } } diff --git a/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj b/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj index 32022609a7d61..859da678a7d27 100644 --- a/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj +++ b/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj @@ -14,7 +14,6 @@ - diff --git a/src/mono/msbuild/AppleAppBuilder/Templates/CMakeLists.txt.template b/src/mono/msbuild/AppleAppBuilder/Templates/CMakeLists.txt.template index 78afc51ecd1d1..8ba0e854c063e 100644 --- a/src/mono/msbuild/AppleAppBuilder/Templates/CMakeLists.txt.template +++ b/src/mono/msbuild/AppleAppBuilder/Templates/CMakeLists.txt.template @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.14.5) project(%ProjectName%) +enable_language(OBJC ASM) set(APP_RESOURCES %AppResources% @@ -15,6 +16,8 @@ add_executable( ${APP_RESOURCES} ) +%AotSources% + include_directories("%MonoInclude%") set_target_properties(%ProjectName% PROPERTIES diff --git a/src/mono/msbuild/AppleAppBuilder/Xcode.cs b/src/mono/msbuild/AppleAppBuilder/Xcode.cs index 305e5d4576256..5c51e245135f2 100644 --- a/src/mono/msbuild/AppleAppBuilder/Xcode.cs +++ b/src/mono/msbuild/AppleAppBuilder/Xcode.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; @@ -14,6 +15,7 @@ internal class Xcode public static string GenerateXCode( string projectName, string entryPointLib, + IEnumerable asmFiles, string workspace, string binDir, string monoInclude, @@ -66,12 +68,18 @@ internal class Xcode toLink += $" \"-force_load {lib}\"{Environment.NewLine}"; } } - foreach (string lib in Directory.GetFiles(binDir, "*.dll.o")) + + string aotSources = ""; + foreach (string asm in asmFiles) { // these libraries are linked via modules.m - toLink += $" \"{lib}\"{Environment.NewLine}"; + var name = Path.GetFileNameWithoutExtension(asm); + aotSources += $"add_library({name} OBJECT {asm}){Environment.NewLine}"; + toLink += $" {name}{Environment.NewLine}"; } + cmakeLists = cmakeLists.Replace("%NativeLibrariesToLink%", toLink); + cmakeLists = cmakeLists.Replace("%AotSources%", aotSources); string plist = Utils.GetEmbeddedResource("Info.plist.template") .Replace("%BundleIdentifier%", projectName); diff --git a/src/mono/netcore/System.Private.CoreLib/src/LinkerDescriptor/System.Private.CoreLib.xml b/src/mono/netcore/System.Private.CoreLib/src/LinkerDescriptor/System.Private.CoreLib.xml index 57d8454b006e4..3489337befd19 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/LinkerDescriptor/System.Private.CoreLib.xml +++ b/src/mono/netcore/System.Private.CoreLib/src/LinkerDescriptor/System.Private.CoreLib.xml @@ -386,6 +386,9 @@ + + + diff --git a/src/mono/netcore/sample/Android/Program.csproj b/src/mono/netcore/sample/Android/Program.csproj index 7a7247fda82d5..00831a0d344eb 100644 --- a/src/mono/netcore/sample/Android/Program.csproj +++ b/src/mono/netcore/sample/Android/Program.csproj @@ -7,7 +7,7 @@ x64 $(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-Android-$(Configuration)-$(TargetArchitecture)\runtimes\android-$(TargetArchitecture) $(MSBuildThisFileDirectory)\bin\bundle - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', '$(NetCoreAppCurrent)-$(Configuration)')) @@ -15,8 +15,8 @@ Properties="Configuration=$(Configuration);Platform=$(HostArch)" Targets="Restore;Build" /> - + diff --git a/src/mono/netcore/sample/iOS/Makefile b/src/mono/netcore/sample/iOS/Makefile index 31a7e9340f5f6..40a59f0c07e8d 100644 --- a/src/mono/netcore/sample/iOS/Makefile +++ b/src/mono/netcore/sample/iOS/Makefile @@ -12,7 +12,7 @@ program: bundle: clean program $(DOTNET) msbuild /t:BuildAppBundle /p:Configuration=$(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH) \ - /p:UseLlvm=$(USE_LLVM) + /p:UseLLVM=$(USE_LLVM) deploy-sim: $(DOTNET) msbuild /t:IosDeployToSimulator /p:Configuration=$(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH) diff --git a/src/mono/netcore/sample/iOS/Program.csproj b/src/mono/netcore/sample/iOS/Program.csproj index 32e8b6ef336cd..473832246ae0b 100644 --- a/src/mono/netcore/sample/iOS/Program.csproj +++ b/src/mono/netcore/sample/iOS/Program.csproj @@ -4,11 +4,14 @@ bin Portable $(NetCoreAppCurrent) + iOS x64 $(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-iOS-$(Configuration)-$(TargetArchitecture)\runtimes\ios-$(TargetArchitecture) $(ArtifactsDir)bin\mono\iOS.$(TargetArchitecture).$(Configuration) $(MSBuildThisFileDirectory)\bin\bundle - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder', '$(NetCoreAppCurrent)-$(Configuration)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'MonoAOTCompiler', '$(NetCoreAppCurrent)-$(Configuration)')) + true @@ -16,39 +19,72 @@ Properties="Configuration=$(Configuration);Platform=$(HostArch)" Targets="Restore;Build" /> - + + + - - - arm64 - x64 - + + + + + + + + + + + + + + + + + + + + - - - - + + @(MonoAOTCompilerDefaultAotArguments, ';') + @(MonoAOTCompilerDefaultProcessArguments, ';') + + + + + + + - - - - - + + + + + + From 925fcef0b1abbf423369084fbdc8e82044cefbc8 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Wed, 13 May 2020 08:01:30 -0400 Subject: [PATCH 155/420] [runtime] Move delegate_bound_static_invoke_cache to MonoWrapperCaches. (#36309) Co-authored-by: vargaz --- src/mono/mono/metadata/image.c | 2 +- src/mono/mono/metadata/marshal.c | 10 +++++++--- src/mono/mono/metadata/metadata-internals.h | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/metadata/image.c b/src/mono/mono/metadata/image.c index 3d4d47c6c0177..0fda88735990c 100644 --- a/src/mono/mono/metadata/image.c +++ b/src/mono/mono/metadata/image.c @@ -2286,6 +2286,7 @@ mono_wrapper_caches_free (MonoWrapperCaches *cache) free_hash (cache->delegate_invoke_cache); free_hash (cache->delegate_begin_invoke_cache); free_hash (cache->delegate_end_invoke_cache); + free_hash (cache->delegate_bound_static_invoke_cache); free_hash (cache->runtime_invoke_signature_cache); free_hash (cache->delegate_abstract_invoke_cache); @@ -2430,7 +2431,6 @@ mono_image_close_except_pools (MonoImage *image) g_hash_table_destroy (image->name_cache); } - free_hash (image->delegate_bound_static_invoke_cache); free_hash (image->ldfld_wrapper_cache); free_hash (image->ldflda_wrapper_cache); free_hash (image->stfld_wrapper_cache); diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 95adfa6cbbaeb..e7264dfa888e5 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -2228,7 +2228,11 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt return res; cache_key = method->klass; } else if (static_method_with_first_arg_bound) { - cache = get_cache (&get_method_image (target_method)->delegate_bound_static_invoke_cache, + GHashTable **cache_ptr; + + cache_ptr = &mono_method_get_wrapper_cache (target_method)->delegate_bound_static_invoke_cache; + + cache = get_cache (cache_ptr, (GHashFunc)mono_signature_hash, (GCompareFunc)mono_metadata_signature_equal); /* @@ -6548,8 +6552,8 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method) if (image->wrapper_caches.delegate_abstract_invoke_cache) g_hash_table_foreach_remove (image->wrapper_caches.delegate_abstract_invoke_cache, signature_pointer_pair_matches_pointer, method); // FIXME: Need to clear the caches in other images as well - if (image->delegate_bound_static_invoke_cache) - g_hash_table_remove (image->delegate_bound_static_invoke_cache, mono_method_signature_internal (method)); + if (image->wrapper_caches.delegate_bound_static_invoke_cache) + g_hash_table_remove (image->wrapper_caches.delegate_bound_static_invoke_cache, mono_method_signature_internal (method)); if (marshal_mutex_initialized) mono_marshal_unlock (); diff --git a/src/mono/mono/metadata/metadata-internals.h b/src/mono/mono/metadata/metadata-internals.h index 30b7f4e78d3b6..561748a33842a 100644 --- a/src/mono/mono/metadata/metadata-internals.h +++ b/src/mono/mono/metadata/metadata-internals.h @@ -251,6 +251,7 @@ typedef struct { * indexed by SignaturePointerPair */ GHashTable *delegate_abstract_invoke_cache; + GHashTable *delegate_bound_static_invoke_cache; /* * indexed by MonoMethod pointers @@ -502,7 +503,6 @@ struct _MonoImage { /* * indexed by SignaturePointerPair */ - GHashTable *delegate_bound_static_invoke_cache; GHashTable *native_func_wrapper_cache; /* From 18de953cc008be6c21c8059a4cb53b8f47f92380 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Wed, 13 May 2020 08:23:28 -0400 Subject: [PATCH 156/420] Emit DWARF debug_abbrev offset for compile units as a label instead of 0 (#36320) When outputting DWARF code to start a compilation unit in .debug_info, the standard expect a 4-byte offset from the .debug_abbrev code. Mono has always output an offset of 0. However, this doesn't work in every cases. When we have linux+fullaot, we link two object files (one from Mono, one from LLVM). Both have their .debug_abbrev section. If we use 0 as an offset, it seems possible that the linker will keep thinking that our offset is 0, no matter the circumstances. Since the offset is always 0, it can be using the wrong abbreviation table (i.e. the one from the LLVM assembly instead of the one from the Mono assembly). The consequence of this is that the linked file is not valid DWARF (dwarfdump and objdump will complain about invalid offsets). At best, some tools will be able to work with a part of what we have, but any program requiring entirely valid DWARF will fail. To fix this, we generate a label for the start of our debug_abbrev section and we instead generate it by generating a long with that label. This matches existing behavior seen in the LLVM generated code, and makes dwarfdump and objdump react properly to the linked product. Fixes mono/mono#8806 Co-authored-by: mathieubourgeois --- src/mono/mono/mini/dwarfwriter.c | 9 +++++- src/mono/mono/mini/image-writer.c | 50 +++++++++++++++++++++++++++---- src/mono/mono/mini/image-writer.h | 2 ++ 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/mini/dwarfwriter.c b/src/mono/mono/mini/dwarfwriter.c index bf2ff736feb33..c93151ec613c4 100644 --- a/src/mono/mono/mini/dwarfwriter.c +++ b/src/mono/mono/mini/dwarfwriter.c @@ -181,6 +181,12 @@ emit_int32 (MonoDwarfWriter *w, int value) mono_img_writer_emit_int32 (w->w, value); } +static void +emit_symbol (MonoDwarfWriter *w, const char *symbol) +{ + mono_img_writer_emit_symbol (w->w, symbol); +} + static void emit_symbol_diff (MonoDwarfWriter *w, const char *end, const char* start, int offset) { @@ -799,6 +805,7 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, const char *cu_name, GSLis w->cie_program = base_unwind_program; emit_section_change (w, ".debug_abbrev", 0); + emit_label (w, ".Ldebug_abbrev_start"); emit_dwarf_abbrev (w, ABBREV_COMPILE_UNIT, DW_TAG_compile_unit, TRUE, compile_unit_attr, G_N_ELEMENTS (compile_unit_attr)); emit_dwarf_abbrev (w, ABBREV_SUBPROGRAM, DW_TAG_subprogram, TRUE, @@ -842,7 +849,7 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, const char *cu_name, GSLis emit_symbol_diff (w, ".Ldebug_info_end", ".Ldebug_info_begin", 0); /* length */ emit_label (w, ".Ldebug_info_begin"); emit_int16 (w, 0x2); /* DWARF version 2 */ - emit_int32 (w, 0); /* .debug_abbrev offset */ + emit_symbol (w, ".Ldebug_abbrev_start"); /* .debug_abbrev offset */ emit_byte (w, sizeof (target_mgreg_t)); /* address size */ /* Compilation unit */ diff --git a/src/mono/mono/mini/image-writer.c b/src/mono/mono/mini/image-writer.c index 7314c5ee8308a..b191269667aa4 100644 --- a/src/mono/mono/mini/image-writer.c +++ b/src/mono/mono/mini/image-writer.c @@ -410,11 +410,14 @@ create_reloc (MonoImageWriter *acfg, const char *end, const char* start, int off BinReloc *reloc; reloc = (BinReloc *)mono_mempool_alloc0 (acfg->mempool, sizeof (BinReloc)); reloc->val1 = mono_mempool_strdup (acfg->mempool, end); - if (strcmp (start, ".") == 0) { - reloc->val2_section = acfg->cur_section; - reloc->val2_offset = acfg->cur_section->cur_offset; - } else { - reloc->val2 = mono_mempool_strdup (acfg->mempool, start); + if (start) + { + if (strcmp (start, ".") == 0) { + reloc->val2_section = acfg->cur_section; + reloc->val2_offset = acfg->cur_section->cur_offset; + } else { + reloc->val2 = mono_mempool_strdup (acfg->mempool, start); + } } reloc->offset = offset; reloc->section = acfg->cur_section; @@ -424,6 +427,13 @@ create_reloc (MonoImageWriter *acfg, const char *end, const char* start, int off return reloc; } +static void +bin_writer_emit_symbol (MonoImageWriter *acfg, const char *symbol) +{ + create_reloc (acfg, symbol, NULL, 0); + acfg->cur_section->cur_offset += 4; +} + static void bin_writer_emit_symbol_diff (MonoImageWriter *acfg, const char *end, const char* start, int offset) { @@ -1924,6 +1934,23 @@ asm_writer_emit_int32 (MonoImageWriter *acfg, int value) fprintf (acfg->fp, "%d", value); } +static void +asm_writer_emit_symbol (MonoImageWriter *acfg, const char *symbol) +{ + if (acfg->mode != EMIT_LONG) { + acfg->mode = EMIT_LONG; + acfg->col_count = 0; + } + + symbol = get_label (symbol); + + if ((acfg->col_count++ % 8) == 0) + fprintf (acfg->fp, "\n\t%s ", AS_INT32_DIRECTIVE); + else + fprintf (acfg->fp, ","); + fprintf (acfg->fp, "%s", symbol); +} + static void asm_writer_emit_symbol_diff (MonoImageWriter *acfg, const char *end, const char* start, int offset) { @@ -2213,6 +2240,19 @@ mono_img_writer_emit_int32 (MonoImageWriter *acfg, int value) #endif } +void +mono_img_writer_emit_symbol (MonoImageWriter *acfg, const char *symbol) +{ +#ifdef USE_BIN_WRITER + if (acfg->use_bin_writer) + bin_writer_emit_symbol (acfg, symbol); + else + asm_writer_emit_symbol (acfg, symbol); +#else + asm_writer_emit_symbol (acfg, symbol); +#endif +} + void mono_img_writer_emit_symbol_diff (MonoImageWriter *acfg, const char *end, const char* start, int offset) { diff --git a/src/mono/mono/mini/image-writer.h b/src/mono/mono/mini/image-writer.h index 0c34246422e8b..309ec37c059a7 100644 --- a/src/mono/mono/mini/image-writer.h +++ b/src/mono/mono/mini/image-writer.h @@ -98,6 +98,8 @@ void mono_img_writer_emit_int16 (MonoImageWriter *w, int value); void mono_img_writer_emit_int32 (MonoImageWriter *w, int value); +void mono_img_writer_emit_symbol (MonoImageWriter *w, const char *symbol); + void mono_img_writer_emit_symbol_diff (MonoImageWriter *w, const char *end, const char* start, int offset); void mono_img_writer_emit_zero_bytes (MonoImageWriter *w, int num); From 5c667210d0f41b8e0ba94eeee2c29eb3d07bb0f0 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Wed, 13 May 2020 09:13:14 -0400 Subject: [PATCH 157/420] Remove some `= null!`s from corelib (#36175) * Remove some `= null!`s from corelib In some cases, this was achieved by: - Using [MemberNotNull] when it could be used to enable the compiler to appropriately follow the initialization - Making the field nullable and using `!`s at usage sites in cases where the `= null!` wasn't appropriate because the field could actually be null - Making the field nullable and adding null checks sparingly - Suppressing warnings in cases where fields weren't accessed in managed code - Removing stale cases where it wasn't necessary anymore anyway - Removing unnecessary empty internal/private ctors * Address PR feedback * Disable test on mono --- .../System/Reflection/Emit/AssemblyBuilder.cs | 4 +- .../Reflection/Emit/ConstructorBuilder.cs | 2 +- .../Reflection/Emit/CustomAttributeBuilder.cs | 114 ++++++++---------- .../Reflection/Emit/DynamicILGenerator.cs | 19 +-- .../System/Reflection/Emit/DynamicMethod.cs | 10 +- .../src/System/Reflection/Emit/ILGenerator.cs | 53 +++----- .../System/Reflection/Emit/MethodBuilder.cs | 2 +- .../System/Reflection/Emit/SignatureHelper.cs | 8 +- .../src/System/Reflection/Emit/TypeBuilder.cs | 41 ++++--- .../System/Reflection/MethodBase.CoreCLR.cs | 2 +- .../Reflection/RuntimeConstructorInfo.cs | 10 +- .../src/System/Reflection/RuntimeEventInfo.cs | 8 +- .../src/System/Reflection/RuntimeFieldInfo.cs | 8 +- .../System/Reflection/RuntimeParameterInfo.cs | 12 +- .../CrossLoaderAllocatorHashHelpers.cs | 4 +- .../Runtime/CompilerServices/GCHeapHash.cs | 2 +- .../src/System/RuntimeHandles.cs | 94 ++++++++------- .../src/System/RuntimeType.CoreCLR.cs | 19 +-- .../src/System/Collections/ArrayList.cs | 11 +- .../Diagnostics/Tracing/EventCounter.cs | 4 +- .../src/System/Globalization/CompareInfo.cs | 3 +- .../Globalization/DateTimeFormatInfo.cs | 4 +- .../src/System/Globalization/StringInfo.cs | 4 +- .../src/System/IO/UnmanagedMemoryAccessor.cs | 2 +- .../src/System/Resources/ResourceManager.cs | 10 +- .../src/System/RuntimeType.cs | 2 +- .../src/System/Security/SecurityElement.cs | 6 +- .../src/System/Text/Encoding.cs | 6 +- .../src/System/Text/UTF7Encoding.cs | 10 +- .../src/System/Threading/Timer.cs | 4 +- .../tests/DynamicMethodDefineParameter.cs | 9 ++ 31 files changed, 243 insertions(+), 244 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs index 3b190943be0d4..1407f8705246e 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Diagnostics.SymbolStore; using System.Globalization; using System.IO; @@ -125,7 +126,7 @@ public sealed class AssemblyBuilder : Assembly // This is only valid in the "external" AssemblyBuilder internal AssemblyBuilderData _assemblyData; private readonly InternalAssemblyBuilder _internalAssemblyBuilder; - private ModuleBuilder _manifestModuleBuilder = null!; + private ModuleBuilder _manifestModuleBuilder; // Set to true if the manifest module was returned by code:DefineDynamicModule to the user private bool _isManifestModuleUsedAsDefinedModule; @@ -208,6 +209,7 @@ internal ModuleBuilder GetModuleBuilder(InternalModuleBuilder module) } } + [MemberNotNull(nameof(_manifestModuleBuilder))] private void InitManifestModule() { InternalModuleBuilder modBuilder = (InternalModuleBuilder)GetInMemoryAssemblyModule(GetNativeHandle()); diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs index 80cb55b796c50..fb6b4c623eab9 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs @@ -19,7 +19,7 @@ public sealed class ConstructorBuilder : ConstructorInfo m_methodBuilder = new MethodBuilder(name, attributes, callingConvention, null, null, null, parameterTypes, requiredCustomModifiers, optionalCustomModifiers, mod, type); - type.m_listMethods.Add(m_methodBuilder); + type.m_listMethods!.Add(m_methodBuilder); m_methodBuilder.GetMethodSignature().InternalGetSignature(out _); diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs index 506c98b28e5e2..d1e89aaf0c3bf 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs @@ -14,91 +14,42 @@ ===========================================================*/ using System.Buffers.Binary; +using System.Diagnostics; using System.IO; using System.Text; -using System.Diagnostics; namespace System.Reflection.Emit { public class CustomAttributeBuilder { + internal ConstructorInfo m_con; + private object?[] m_constructorArgs; + private byte[] m_blob; + // public constructor to form the custom attribute with constructor and constructor // parameters. - public CustomAttributeBuilder(ConstructorInfo con, object?[] constructorArgs) + public CustomAttributeBuilder(ConstructorInfo con, object?[] constructorArgs) : + this(con, constructorArgs, Array.Empty(), Array.Empty(), Array.Empty(), Array.Empty()) { - InitCustomAttributeBuilder(con, constructorArgs, - Array.Empty(), Array.Empty(), - Array.Empty(), Array.Empty()); } // public constructor to form the custom attribute with constructor, constructor // parameters and named properties. - public CustomAttributeBuilder(ConstructorInfo con, object?[] constructorArgs, - PropertyInfo[] namedProperties, object?[] propertyValues) + public CustomAttributeBuilder(ConstructorInfo con, object?[] constructorArgs, PropertyInfo[] namedProperties, object?[] propertyValues) : + this(con, constructorArgs, namedProperties, propertyValues, Array.Empty(), Array.Empty()) { - InitCustomAttributeBuilder(con, constructorArgs, namedProperties, - propertyValues, Array.Empty(), Array.Empty()); } // public constructor to form the custom attribute with constructor and constructor // parameters. - public CustomAttributeBuilder(ConstructorInfo con, object?[] constructorArgs, - FieldInfo[] namedFields, object?[] fieldValues) + public CustomAttributeBuilder(ConstructorInfo con, object?[] constructorArgs, FieldInfo[] namedFields, object?[] fieldValues) : + this(con, constructorArgs, Array.Empty(), Array.Empty(), namedFields, fieldValues) { - InitCustomAttributeBuilder(con, constructorArgs, Array.Empty(), - Array.Empty(), namedFields, fieldValues); } // public constructor to form the custom attribute with constructor and constructor // parameters. - public CustomAttributeBuilder(ConstructorInfo con, object?[] constructorArgs, - PropertyInfo[] namedProperties, object?[] propertyValues, - FieldInfo[] namedFields, object?[] fieldValues) - { - InitCustomAttributeBuilder(con, constructorArgs, namedProperties, - propertyValues, namedFields, fieldValues); - } - - // Check that a type is suitable for use in a custom attribute. - private bool ValidateType(Type t) - { - if (t.IsPrimitive) - { - return t != typeof(IntPtr) && t != typeof(UIntPtr); - } - if (t == typeof(string) || t == typeof(Type)) - { - return true; - } - if (t.IsEnum) - { - switch (Type.GetTypeCode(Enum.GetUnderlyingType(t))) - { - case TypeCode.SByte: - case TypeCode.Byte: - case TypeCode.Int16: - case TypeCode.UInt16: - case TypeCode.Int32: - case TypeCode.UInt32: - case TypeCode.Int64: - case TypeCode.UInt64: - return true; - default: - return false; - } - } - if (t.IsArray) - { - if (t.GetArrayRank() != 1) - return false; - return ValidateType(t.GetElementType()!); - } - return t == typeof(object); - } - - internal void InitCustomAttributeBuilder(ConstructorInfo con, object?[] constructorArgs, - PropertyInfo[] namedProperties, object?[] propertyValues, - FieldInfo[] namedFields, object?[] fieldValues) + public CustomAttributeBuilder(ConstructorInfo con, object?[] constructorArgs, PropertyInfo[] namedProperties, object?[] propertyValues, FieldInfo[] namedFields, object?[] fieldValues) { if (con == null) throw new ArgumentNullException(nameof(con)); @@ -289,6 +240,43 @@ private bool ValidateType(Type t) m_blob = ((MemoryStream)writer.BaseStream).ToArray(); } + // Check that a type is suitable for use in a custom attribute. + private bool ValidateType(Type t) + { + if (t.IsPrimitive) + { + return t != typeof(IntPtr) && t != typeof(UIntPtr); + } + if (t == typeof(string) || t == typeof(Type)) + { + return true; + } + if (t.IsEnum) + { + switch (Type.GetTypeCode(Enum.GetUnderlyingType(t))) + { + case TypeCode.SByte: + case TypeCode.Byte: + case TypeCode.Int16: + case TypeCode.UInt16: + case TypeCode.Int32: + case TypeCode.UInt32: + case TypeCode.Int64: + case TypeCode.UInt64: + return true; + default: + return false; + } + } + if (t.IsArray) + { + if (t.GetArrayRank() != 1) + return false; + return ValidateType(t.GetElementType()!); + } + return t == typeof(object); + } + private static void VerifyTypeAndPassedObjectType(Type type, Type passedType, string paramName) { if (type != typeof(object) && Type.GetTypeCode(passedType) != Type.GetTypeCode(type)) @@ -549,9 +537,5 @@ internal void CreateCustomAttribute(ModuleBuilder mod, int tkOwner, int tkAttrib TypeBuilder.DefineCustomAttribute(mod, tkOwner, tkAttrib, m_blob, toDisk, typeof(System.Diagnostics.DebuggableAttribute) == m_con.DeclaringType); } - - internal ConstructorInfo m_con = null!; - internal object?[] m_constructorArgs = null!; - internal byte[] m_blob = null!; } } diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs index a1a85b47d0bf3..d8e330dd7f98b 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs @@ -345,7 +345,7 @@ public override void BeginExceptFilterBlock() if (CurrExcStackCount == 0) throw new NotSupportedException(SR.Argument_NotInExceptionBlock); - __ExceptionInfo current = CurrExcStack[CurrExcStackCount - 1]; + __ExceptionInfo current = CurrExcStack![CurrExcStackCount - 1]; Label endLabel = current.GetEndLabel(); Emit(OpCodes.Leave, endLabel); @@ -359,7 +359,7 @@ public override void BeginCatchBlock(Type exceptionType) if (CurrExcStackCount == 0) throw new NotSupportedException(SR.Argument_NotInExceptionBlock); - __ExceptionInfo current = CurrExcStack[CurrExcStackCount - 1]; + __ExceptionInfo current = CurrExcStack![CurrExcStackCount - 1]; RuntimeType? rtType = exceptionType as RuntimeType; @@ -558,7 +558,7 @@ private int GetTokenForSig(byte[] sig) internal class DynamicResolver : Resolver { #region Private Data Members - private __ExceptionInfo[] m_exceptions = null!; + private __ExceptionInfo[]? m_exceptions; private byte[]? m_exceptionHeader; private DynamicMethod m_method; private byte[] m_code; @@ -571,7 +571,7 @@ internal class DynamicResolver : Resolver internal DynamicResolver(DynamicILGenerator ilGenerator) { m_stackSize = ilGenerator.GetMaxStackSize(); - m_exceptions = ilGenerator.GetExceptions()!; + m_exceptions = ilGenerator.GetExceptions(); m_code = ilGenerator.BakeByteArray()!; m_localSignature = ilGenerator.m_localSignature.InternalGetSignatureArray(); m_scope = ilGenerator.m_scope; @@ -586,7 +586,6 @@ internal DynamicResolver(DynamicILInfo dynamicILInfo) m_code = dynamicILInfo.Code; m_localSignature = dynamicILInfo.LocalSignature; m_exceptionHeader = dynamicILInfo.Exceptions; - // m_exceptions = dynamicILInfo.Exceptions; m_scope = dynamicILInfo.DynamicScope; m_method = dynamicILInfo.DynamicMethod; @@ -740,6 +739,8 @@ internal override byte[] GetLocalsSignature() internal override unsafe void GetEHInfo(int excNumber, void* exc) { + Debug.Assert(m_exceptions != null); + CORINFO_EH_CLAUSE* exception = (CORINFO_EH_CLAUSE*)exc; for (int i = 0; i < m_exceptions.Length; i++) { @@ -819,11 +820,13 @@ internal override void ResolveToken(int token, out IntPtr typeHandle, out IntPtr { if (vaMeth.m_dynamicMethod == null) { - methodHandle = vaMeth.m_method.MethodHandle.Value; + methodHandle = vaMeth.m_method!.MethodHandle.Value; typeHandle = vaMeth.m_method.GetDeclaringTypeInternal().GetTypeHandleInternal().Value; } else + { methodHandle = vaMeth.m_dynamicMethod.GetMethodDescriptor().Value; + } return; } @@ -1098,8 +1101,8 @@ internal GenericFieldInfo(RuntimeFieldHandle fieldHandle, RuntimeTypeHandle cont internal sealed class VarArgMethod { - internal RuntimeMethodInfo m_method = null!; - internal DynamicMethod m_dynamicMethod = null!; + internal RuntimeMethodInfo? m_method; + internal DynamicMethod? m_dynamicMethod; internal SignatureHelper m_signature; internal VarArgMethod(DynamicMethod dm, SignatureHelper signature) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs index 35a708a1f867d..c8c5468801d72 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.CompilerServices; using System.Text; @@ -12,9 +13,9 @@ namespace System.Reflection.Emit { public sealed class DynamicMethod : MethodInfo { - private RuntimeType[] m_parameterTypes = null!; + private RuntimeType[] m_parameterTypes; internal IRuntimeMethodInfo? m_methodHandle; - private RuntimeType m_returnType = null!; + private RuntimeType m_returnType; private DynamicILGenerator? m_ilGenerator; private DynamicILInfo? m_DynamicILInfo; private bool m_fInitLocals; @@ -28,7 +29,7 @@ public sealed class DynamicMethod : MethodInfo // If we allowed use of RTDynamicMethod, the creator of the DynamicMethod would // not be able to bound access to the DynamicMethod. Hence, we need to ensure that // we do not allow direct use of RTDynamicMethod. - private RTDynamicMethod m_dynMethod = null!; + private RTDynamicMethod m_dynMethod; // needed to keep the object alive during jitting // assigned by the DynamicResolver ctor @@ -249,6 +250,9 @@ private static RuntimeModule GetDynamicMethodsModule() return s_anonymouslyHostedDynamicMethodsModule; } + [MemberNotNull(nameof(m_parameterTypes))] + [MemberNotNull(nameof(m_returnType))] + [MemberNotNull(nameof(m_dynMethod))] private void Init(string name, MethodAttributes attributes, CallingConventions callingConvention, diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs index c8f6febd432e5..354d470bb982a 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs @@ -40,20 +40,20 @@ internal static T[] EnlargeArray(T[] incoming, int requiredSize) private int m_length; private byte[] m_ILStream; - private int[] m_labelList; + private int[]? m_labelList; private int m_labelCount; - private __FixupData[] m_fixupData; + private __FixupData[]? m_fixupData; private int m_fixupCount; - private int[] m_RelocFixupList; + private int[]? m_RelocFixupList; private int m_RelocFixupCount; private int m_exceptionCount; private int m_currExcStackCount; - private __ExceptionInfo[] m_exceptions; // This is the list of all of the exceptions in this ILStream. - private __ExceptionInfo[] m_currExcStack; // This is the stack of exceptions which we're currently in. + private __ExceptionInfo[]? m_exceptions; // This is the list of all of the exceptions in this ILStream. + private __ExceptionInfo[]? m_currExcStack; // This is the stack of exceptions which we're currently in. internal ScopeTree m_ScopeTree; // this variable tracks all debugging scope information internal LineNumberInfo m_LineNumberInfo; // this variable tracks all line number information @@ -69,7 +69,7 @@ internal static T[] EnlargeArray(T[] incoming, int requiredSize) internal int CurrExcStackCount => m_currExcStackCount; - internal __ExceptionInfo[] CurrExcStack => m_currExcStack; + internal __ExceptionInfo[]? CurrExcStack => m_currExcStack; #endregion @@ -87,29 +87,12 @@ internal ILGenerator(MethodInfo methodBuilder, int size) m_ILStream = new byte[Math.Max(size, DefaultSize)]; - m_length = 0; - - m_labelCount = 0; - m_fixupCount = 0; - m_labelList = null!; - - m_fixupData = null!; - - m_exceptions = null!; - m_exceptionCount = 0; - m_currExcStack = null!; - m_currExcStackCount = 0; - - m_RelocFixupList = null!; - m_RelocFixupCount = 0; - // initialize the scope tree m_ScopeTree = new ScopeTree(); m_LineNumberInfo = new LineNumberInfo(); m_methodBuilder = methodBuilder; // initialize local signature - m_localCount = 0; MethodBuilder? mb = m_methodBuilder as MethodBuilder; m_localSignature = SignatureHelper.GetLocalVarSigHelper(mb?.GetTypeBuilder().Module); } @@ -215,7 +198,7 @@ private int GetMethodToken(MethodBase method, Type[]? optionalParameterTypes, bo // replacing them with their proper values. for (int i = 0; i < m_fixupCount; i++) { - __FixupData fixupData = m_fixupData[i]; + __FixupData fixupData = m_fixupData![i]; int updateAddr = GetLabelPos(fixupData.m_fixupLabel) - (fixupData.m_fixupPos + fixupData.m_fixupInstSize); // Handle single byte instructions @@ -253,7 +236,7 @@ private int GetMethodToken(MethodBase method, Type[]? optionalParameterTypes, bo } var temp = new __ExceptionInfo[m_exceptionCount]; - Array.Copy(m_exceptions, temp, m_exceptionCount); + Array.Copy(m_exceptions!, temp, m_exceptionCount); SortExceptions(temp); return temp; } @@ -288,7 +271,7 @@ private int GetLabelPos(Label lbl) int index = lbl.GetLabelValue(); - if (index < 0 || index >= m_labelCount) + if (index < 0 || index >= m_labelCount || m_labelList is null) throw new ArgumentException(SR.Argument_BadLabel); if (m_labelList[index] < 0) @@ -355,7 +338,7 @@ private static void SortExceptions(__ExceptionInfo[] exceptions) } int[] narrowTokens = new int[m_RelocFixupCount]; - Array.Copy(m_RelocFixupList, narrowTokens, m_RelocFixupCount); + Array.Copy(m_RelocFixupList!, narrowTokens, m_RelocFixupCount); return narrowTokens; } #endregion @@ -964,7 +947,7 @@ public virtual void EndExceptionBlock() } // Pop the current exception block - __ExceptionInfo current = m_currExcStack[m_currExcStackCount - 1]; + __ExceptionInfo current = m_currExcStack![m_currExcStackCount - 1]; m_currExcStack[--m_currExcStackCount] = null!; Label endLabel = current.GetEndLabel(); @@ -988,7 +971,7 @@ public virtual void EndExceptionBlock() // Check if we've already set this label. // The only reason why we might have set this is if we have a finally block. - Label label = m_labelList[endLabel.GetLabelValue()] != -1 + Label label = m_labelList![endLabel.GetLabelValue()] != -1 ? current.m_finallyEndLabel : endLabel; @@ -1004,7 +987,7 @@ public virtual void BeginExceptFilterBlock() if (m_currExcStackCount == 0) throw new NotSupportedException(SR.Argument_NotInExceptionBlock); - __ExceptionInfo current = m_currExcStack[m_currExcStackCount - 1]; + __ExceptionInfo current = m_currExcStack![m_currExcStackCount - 1]; Emit(OpCodes.Leave, current.GetEndLabel()); @@ -1019,7 +1002,7 @@ public virtual void BeginCatchBlock(Type exceptionType) { throw new NotSupportedException(SR.Argument_NotInExceptionBlock); } - __ExceptionInfo current = m_currExcStack[m_currExcStackCount - 1]; + __ExceptionInfo current = m_currExcStack![m_currExcStackCount - 1]; if (current.GetCurrentState() == __ExceptionInfo.State_Filter) { @@ -1050,7 +1033,7 @@ public virtual void BeginFaultBlock() { throw new NotSupportedException(SR.Argument_NotInExceptionBlock); } - __ExceptionInfo current = m_currExcStack[m_currExcStackCount - 1]; + __ExceptionInfo current = m_currExcStack![m_currExcStackCount - 1]; // emit the leave for the clause before this one. Emit(OpCodes.Leave, current.GetEndLabel()); @@ -1064,7 +1047,7 @@ public virtual void BeginFinallyBlock() { throw new NotSupportedException(SR.Argument_NotInExceptionBlock); } - __ExceptionInfo current = m_currExcStack[m_currExcStackCount - 1]; + __ExceptionInfo current = m_currExcStack![m_currExcStackCount - 1]; int state = current.GetCurrentState(); Label endLabel = current.GetEndLabel(); int catchEndAddr = 0; @@ -1114,8 +1097,8 @@ public virtual void MarkLabel(Label loc) int labelIndex = loc.GetLabelValue(); - // This should never happen. - if (labelIndex < 0 || labelIndex >= m_labelList.Length) + // This should only happen if a label from another generator is used with this one. + if (m_labelList is null || labelIndex < 0 || labelIndex >= m_labelList.Length) { throw new ArgumentException(SR.Argument_InvalidLabel); } diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs index c5ae82adaeed6..e3c189f910beb 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs @@ -620,7 +620,7 @@ public MethodToken GetToken() // We need to lock here to prevent a method from being "tokenized" twice. // We don't need to synchronize this with Type.DefineMethod because it only appends newly // constructed MethodBuilders to the end of m_listMethods - lock (m_containingType.m_listMethods) + lock (m_containingType.m_listMethods!) { if (m_tkMethod.Token != 0) { diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/SignatureHelper.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/SignatureHelper.cs index 0808335d3b8de..a9db943c8ae58 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/SignatureHelper.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/SignatureHelper.cs @@ -2,10 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Text; using System.Buffers.Binary; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +using System.Text; namespace System.Reflection.Emit { @@ -185,7 +186,7 @@ internal static SignatureHelper GetTypeSigToken(Module module, Type type) #endregion #region Private Data Members - private byte[] m_signature = null!; + private byte[] m_signature; private int m_currSig; // index into m_signature buffer for next available byte private int m_sizeLoc; // index into m_signature buffer to put m_argCount (will be NO_SIZE_IN_SIG if no arg count is needed) private ModuleBuilder? m_module; @@ -225,6 +226,7 @@ private SignatureHelper(Module mod, Type type) AddOneArgTypeHelper(type); } + [MemberNotNull(nameof(m_signature))] private void Init(Module? mod) { m_signature = new byte[32]; @@ -238,11 +240,13 @@ private void Init(Module? mod) throw new ArgumentException(SR.NotSupported_MustBeModuleBuilder); } + [MemberNotNull(nameof(m_signature))] private void Init(Module? mod, MdSigCallingConvention callingConvention) { Init(mod, callingConvention, 0); } + [MemberNotNull(nameof(m_signature))] private void Init(Module? mod, MdSigCallingConvention callingConvention, int cGenericParam) { Init(mod); diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs index a78fd852c9799..65d61ca28adee 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs @@ -396,15 +396,15 @@ internal static unsafe void SetConstantValue(ModuleBuilder module, int tk, Type #region Private Data Members private List? m_ca; private TypeToken m_tdType; - private readonly ModuleBuilder m_module = null!; + private readonly ModuleBuilder m_module; private readonly string? m_strName; private readonly string? m_strNameSpace; private string? m_strFullQualName; private Type? m_typeParent; - private List m_typeInterfaces = null!; + private List? m_typeInterfaces; private readonly TypeAttributes m_iAttr; private GenericParameterAttributes m_genParamAttributes; - internal List m_listMethods = null!; + internal List? m_listMethods; internal int m_lastTokenizedMethod; private int m_constructorCount; private readonly int m_iTypeSize; @@ -430,7 +430,7 @@ internal TypeBuilder(ModuleBuilder module) { m_tdType = new TypeToken((int)MetadataTokenType.TypeDef); m_isHiddenGlobalType = true; - m_module = (ModuleBuilder)module; + m_module = module; m_listMethods = new List(); // No token has been created so let's initialize it to -1 // The first time we call MethodBuilder.GetToken this will incremented. @@ -438,8 +438,13 @@ internal TypeBuilder(ModuleBuilder module) } // ctor for generic method parameter - internal TypeBuilder(string szName, int genParamPos, MethodBuilder declMeth) : this(szName, genParamPos) + internal TypeBuilder(string szName, int genParamPos, MethodBuilder declMeth) { + m_strName = szName; + m_genParamPos = genParamPos; + m_bIsGenParam = true; + m_typeInterfaces = new List(); + Debug.Assert(declMeth != null); m_declMeth = declMeth; m_DeclaringType = m_declMeth.GetTypeBuilder(); @@ -447,20 +452,16 @@ internal TypeBuilder(string szName, int genParamPos, MethodBuilder declMeth) : t } // ctor for generic type parameter - private TypeBuilder(string szName, int genParamPos, TypeBuilder declType) : this(szName, genParamPos) - { - Debug.Assert(declType != null); - m_DeclaringType = declType; - m_module = declType.GetModuleBuilder(); - } - - // only for delegating to by other ctors - private TypeBuilder(string szName, int genParamPos) + private TypeBuilder(string szName, int genParamPos, TypeBuilder declType) { m_strName = szName; m_genParamPos = genParamPos; m_bIsGenParam = true; m_typeInterfaces = new List(); + + Debug.Assert(declType != null); + m_DeclaringType = declType; + m_module = declType.GetModuleBuilder(); } internal TypeBuilder( @@ -1295,7 +1296,7 @@ public MethodBuilder DefineMethod(string name, MethodAttributes attributes, Call } } - m_listMethods.Add(method); + m_listMethods!.Add(method); return method; } @@ -1381,7 +1382,7 @@ public MethodBuilder DefineMethod(string name, MethodAttributes attributes, Call // and our equals check won't work. _ = method.GetMethodSignature().InternalGetSignature(out _); - if (m_listMethods.Contains(method)) + if (m_listMethods!.Contains(method)) { throw new ArgumentException(SR.Argument_MethodRedefined); } @@ -1954,7 +1955,7 @@ internal void CheckContext(params Type?[]? types) } } - int size = m_listMethods.Count; + int size = m_listMethods!.Count; for (int i = 0; i < size; i++) { @@ -2032,12 +2033,12 @@ internal void CheckContext(params Type?[]? types) m_hasBeenCreated = true; // Terminate the process. - RuntimeType cls = null!; + RuntimeType? cls = null; TermCreateClass(new QCallModule(ref module), m_tdType.Token, ObjectHandleOnStack.Create(ref cls)); if (!m_isHiddenGlobalType) { - m_bakedRuntimeType = cls; + m_bakedRuntimeType = cls!; // if this type is a nested type, we need to invalidate the cached nested runtime type on the nesting type if (m_DeclaringType != null && m_DeclaringType.m_bakedRuntimeType != null) @@ -2105,7 +2106,7 @@ public void AddInterfaceImplementation(Type interfaceType) ModuleBuilder module = m_module; AddInterfaceImpl(new QCallModule(ref module), m_tdType.Token, tkInterface.Token); - m_typeInterfaces.Add(interfaceType); + m_typeInterfaces!.Add(interfaceType); } public TypeToken TypeToken diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/MethodBase.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/MethodBase.CoreCLR.cs index 3c467b743290d..7ab2a594ab52f 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/MethodBase.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/MethodBase.CoreCLR.cs @@ -69,7 +69,7 @@ internal virtual Type[] GetParameterTypes() // copy the arguments in a different array so we detach from any user changes object[] copyOfParameters = new object[parameters.Length]; - ParameterInfo[] p = null!; + ParameterInfo[]? p = null; for (int i = 0; i < parameters.Length; i++) { object arg = parameters[i]; diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs index 77367461e462d..133f825dbcc06 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs @@ -18,11 +18,11 @@ internal sealed class RuntimeConstructorInfo : ConstructorInfo, IRuntimeMethodIn private RuntimeTypeCache m_reflectedTypeCache; private string? m_toString; private ParameterInfo[]? m_parameters; // Created lazily when GetParameters() is called. -#pragma warning disable CA1823, 414 - private object _empty1 = null!; // These empties are used to ensure that RuntimeConstructorInfo and RuntimeMethodInfo are have a layout which is sufficiently similar - private object _empty2 = null!; - private object _empty3 = null!; -#pragma warning restore CA1823, 414 +#pragma warning disable CA1823, 414, 169 + private object? _empty1; // These empties are used to ensure that RuntimeConstructorInfo and RuntimeMethodInfo are have a layout which is sufficiently similar + private object? _empty2; + private object? _empty3; +#pragma warning restore CA1823, 414, 169 private IntPtr m_handle; private MethodAttributes m_methodAttributes; private BindingFlags m_bindingFlags; diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeEventInfo.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeEventInfo.cs index 0b24a02472d5a..2a14dc6b9a188 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeEventInfo.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeEventInfo.cs @@ -15,20 +15,16 @@ internal sealed unsafe class RuntimeEventInfo : EventInfo private EventAttributes m_flags; private string? m_name; private void* m_utf8name; - private RuntimeTypeCache m_reflectedTypeCache = null!; + private RuntimeTypeCache m_reflectedTypeCache; private RuntimeMethodInfo? m_addMethod; private RuntimeMethodInfo? m_removeMethod; private RuntimeMethodInfo? m_raiseMethod; private MethodInfo[]? m_otherMethod; - private RuntimeType m_declaringType = null!; + private RuntimeType m_declaringType; private BindingFlags m_bindingFlags; #endregion #region Constructor - internal RuntimeEventInfo() - { - // Used for dummy head node during population - } internal RuntimeEventInfo(int tkEvent, RuntimeType declaredType, RuntimeTypeCache reflectedTypeCache, out bool isPrivate) { Debug.Assert(declaredType != null); diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeFieldInfo.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeFieldInfo.cs index 5eb9a5fd3cc20..fc64e1d9713a6 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeFieldInfo.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeFieldInfo.cs @@ -11,15 +11,11 @@ internal abstract class RuntimeFieldInfo : FieldInfo { #region Private Data Members private BindingFlags m_bindingFlags; - protected RuntimeTypeCache m_reflectedTypeCache = null!; - protected RuntimeType m_declaringType = null!; + protected RuntimeTypeCache m_reflectedTypeCache; + protected RuntimeType m_declaringType; #endregion #region Constructor - protected RuntimeFieldInfo() - { - // Used for dummy head node during population - } protected RuntimeFieldInfo(RuntimeTypeCache reflectedTypeCache, RuntimeType declaringType, BindingFlags bindingFlags) { m_bindingFlags = bindingFlags; diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeParameterInfo.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeParameterInfo.cs index c7ad03319ddf3..f8a0ff0b329ce 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeParameterInfo.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeParameterInfo.cs @@ -113,7 +113,7 @@ internal static ParameterInfo GetReturnParameter(IRuntimeMethodInfo method, Memb #region Private Data Members private int m_tkParamDef; private MetadataImport m_scope; - private Signature m_signature = null!; + private Signature? m_signature; private volatile bool m_nameIsCached = false; private readonly bool m_noMetadata = false; private bool m_noDefaultValue = false; @@ -217,6 +217,8 @@ public override Type ParameterType // only instance of ParameterInfo has ClassImpl, all its subclasses don't if (ClassImpl == null) { + Debug.Assert(m_signature != null); + RuntimeType parameterType; if (PositionImpl == -1) parameterType = m_signature.ReturnType; @@ -481,12 +483,16 @@ private static DateTime GetRawDateTimeConstant(CustomAttributeData attr) public override Type[] GetRequiredCustomModifiers() { - return m_signature.GetCustomModifiers(PositionImpl + 1, true); + return m_signature is null ? + Type.EmptyTypes : + m_signature.GetCustomModifiers(PositionImpl + 1, true); } public override Type[] GetOptionalCustomModifiers() { - return m_signature.GetCustomModifiers(PositionImpl + 1, false); + return m_signature is null ? + Type.EmptyTypes : + m_signature.GetCustomModifiers(PositionImpl + 1, false); } #endregion diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/CrossLoaderAllocatorHashHelpers.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/CrossLoaderAllocatorHashHelpers.cs index 9f45efa3df1c5..89d0773075d8a 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/CrossLoaderAllocatorHashHelpers.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/CrossLoaderAllocatorHashHelpers.cs @@ -30,7 +30,7 @@ internal class LAHashDependentHashTracker [StructLayout(LayoutKind.Sequential)] internal class LAHashKeyToTrackers { - private object _trackerOrTrackerSet = null!; - private object _laLocalKeyValueStore = null!; + private object? _trackerOrTrackerSet; + private object? _laLocalKeyValueStore; } } diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/GCHeapHash.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/GCHeapHash.cs index 763ab98ceb3ca..396967048ff0b 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/GCHeapHash.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/GCHeapHash.cs @@ -13,7 +13,7 @@ namespace System.Runtime.CompilerServices [StructLayout(LayoutKind.Sequential)] internal class GCHeapHash { - private Array _data = null!; + private Array? _data; private int _count; private int _deletedCount; } diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs index 5661ce8130ec5..c95afb2036300 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -446,10 +446,10 @@ internal static RuntimeType GetTypeByNameUsingCARules(string name, RuntimeModule if (string.IsNullOrEmpty(name)) throw new ArgumentException(null, nameof(name)); - RuntimeType type = null!; + RuntimeType? type = null; GetTypeByNameUsingCARules(name, new QCallModule(ref scope), ObjectHandleOnStack.Create(ref type)); - return type; + return type!; } [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] @@ -457,18 +457,18 @@ internal static RuntimeType GetTypeByNameUsingCARules(string name, RuntimeModule internal RuntimeType[] GetInstantiationInternal() { - RuntimeType[] types = null!; + RuntimeType[]? types = null; RuntimeTypeHandle nativeHandle = GetNativeHandle(); GetInstantiation(new QCallTypeHandle(ref nativeHandle), ObjectHandleOnStack.Create(ref types), Interop.BOOL.TRUE); - return types; + return types!; } internal Type[] GetInstantiationPublic() { - Type[] types = null!; + Type[]? types = null; RuntimeTypeHandle nativeHandle = GetNativeHandle(); GetInstantiation(new QCallTypeHandle(ref nativeHandle), ObjectHandleOnStack.Create(ref types), Interop.BOOL.FALSE); - return types; + return types!; } [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] @@ -481,11 +481,11 @@ internal RuntimeType Instantiate(Type[]? inst) fixed (IntPtr* pInst = instHandles) { - RuntimeType type = null!; + RuntimeType? type = null; RuntimeTypeHandle nativeHandle = GetNativeHandle(); Instantiate(new QCallTypeHandle(ref nativeHandle), pInst, instCount, ObjectHandleOnStack.Create(ref type)); GC.KeepAlive(inst); - return type; + return type!; } } @@ -494,10 +494,10 @@ internal RuntimeType Instantiate(Type[]? inst) internal RuntimeType MakeArray(int rank) { - RuntimeType type = null!; + RuntimeType? type = null; RuntimeTypeHandle nativeHandle = GetNativeHandle(); MakeArray(new QCallTypeHandle(ref nativeHandle), rank, ObjectHandleOnStack.Create(ref type)); - return type; + return type!; } [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] @@ -505,10 +505,10 @@ internal RuntimeType MakeArray(int rank) internal RuntimeType MakeSZArray() { - RuntimeType type = null!; + RuntimeType? type = null; RuntimeTypeHandle nativeHandle = GetNativeHandle(); MakeSZArray(new QCallTypeHandle(ref nativeHandle), ObjectHandleOnStack.Create(ref type)); - return type; + return type!; } [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] @@ -516,10 +516,10 @@ internal RuntimeType MakeSZArray() internal RuntimeType MakeByRef() { - RuntimeType type = null!; + RuntimeType? type = null; RuntimeTypeHandle nativeHandle = GetNativeHandle(); MakeByRef(new QCallTypeHandle(ref nativeHandle), ObjectHandleOnStack.Create(ref type)); - return type; + return type!; } [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] @@ -527,10 +527,10 @@ internal RuntimeType MakeByRef() internal RuntimeType MakePointer() { - RuntimeType type = null!; + RuntimeType? type = null; RuntimeTypeHandle nativeHandle = GetNativeHandle(); MakePointer(new QCallTypeHandle(ref nativeHandle), ObjectHandleOnStack.Create(ref type)); - return type; + return type!; } [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] @@ -665,15 +665,15 @@ public RuntimeMethodInfoStub(IntPtr methodHandleValue, object keepalive) private readonly object m_keepalive; // These unused variables are used to ensure that this class has the same layout as RuntimeMethodInfo -#pragma warning disable CA1823, 414 - private object m_a = null!; - private object m_b = null!; - private object m_c = null!; - private object m_d = null!; - private object m_e = null!; - private object m_f = null!; - private object m_g = null!; -#pragma warning restore CA1823, 414 +#pragma warning disable CA1823, 414, 169 + private object? m_a; + private object? m_b; + private object? m_c; + private object? m_d; + private object? m_e; + private object? m_f; + private object? m_g; +#pragma warning restore CA1823, 414, 169 public RuntimeMethodHandleInternal m_value; @@ -861,25 +861,25 @@ internal static MdUtf8String GetUtf8Name(RuntimeMethodHandleInternal method) internal static RuntimeType[] GetMethodInstantiationInternal(IRuntimeMethodInfo method) { - RuntimeType[] types = null!; + RuntimeType[]? types = null; GetMethodInstantiation(EnsureNonNullMethodInfo(method).Value, ObjectHandleOnStack.Create(ref types), Interop.BOOL.TRUE); GC.KeepAlive(method); - return types; + return types!; } internal static RuntimeType[] GetMethodInstantiationInternal(RuntimeMethodHandleInternal method) { - RuntimeType[] types = null!; + RuntimeType[]? types = null; GetMethodInstantiation(method, ObjectHandleOnStack.Create(ref types), Interop.BOOL.TRUE); - return types; + return types!; } internal static Type[] GetMethodInstantiationPublic(IRuntimeMethodInfo method) { - RuntimeType[] types = null!; + RuntimeType[]? types = null; GetMethodInstantiation(EnsureNonNullMethodInfo(method).Value, ObjectHandleOnStack.Create(ref types), Interop.BOOL.FALSE); GC.KeepAlive(method); - return types; + return types!; } [MethodImpl(MethodImplOptions.InternalCall)] @@ -1000,14 +1000,14 @@ RuntimeFieldHandleInternal Value internal class RuntimeFieldInfoStub : IRuntimeFieldInfo { // These unused variables are used to ensure that this class has the same layout as RuntimeFieldInfo -#pragma warning disable 414 - private object m_keepalive = null!; - private object m_c = null!; - private object m_d = null!; +#pragma warning disable 414, 169 + private object? m_keepalive; + private object? m_c; + private object? m_d; private int m_b; - private object m_e = null!; + private object? m_e; private RuntimeFieldHandleInternal m_fieldHandle; -#pragma warning restore 414 +#pragma warning restore 414, 169 RuntimeFieldHandleInternal IRuntimeFieldInfo.Value => m_fieldHandle; } @@ -1209,11 +1209,11 @@ internal static RuntimeType ResolveTypeHandleInternal(RuntimeModule module, int fixed (IntPtr* typeInstArgs = typeInstantiationContextHandles, methodInstArgs = methodInstantiationContextHandles) { - RuntimeType type = null!; + RuntimeType? type = null; ResolveType(new QCallModule(ref module), typeToken, typeInstArgs, typeInstCount, methodInstArgs, methodInstCount, ObjectHandleOnStack.Create(ref type)); GC.KeepAlive(typeInstantiationContext); GC.KeepAlive(methodInstantiationContext); - return type; + return type!; } } @@ -1288,11 +1288,11 @@ internal static IRuntimeFieldInfo ResolveFieldHandleInternal(RuntimeModule modul fixed (IntPtr* typeInstArgs = typeInstantiationContextHandles, methodInstArgs = methodInstantiationContextHandles) { - IRuntimeFieldInfo field = null!; + IRuntimeFieldInfo? field = null; ResolveField(new QCallModule(ref module), fieldToken, typeInstArgs, typeInstCount, methodInstArgs, methodInstCount, ObjectHandleOnStack.Create(ref field)); GC.KeepAlive(typeInstantiationContext); GC.KeepAlive(methodInstantiationContext); - return field; + return field!; } } @@ -1318,9 +1318,9 @@ internal static bool ContainsPropertyMatchingHash(RuntimeModule module, int prop internal static RuntimeType GetModuleType(RuntimeModule module) { - RuntimeType type = null!; + RuntimeType? type = null; GetModuleType(new QCallModule(ref module), ObjectHandleOnStack.Create(ref type)); - return type; + return type!; } [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] @@ -1375,6 +1375,8 @@ internal enum MdSigCallingConvention : byte #endregion #region FCalls + [MemberNotNull(nameof(m_arguments))] + [MemberNotNull(nameof(m_returnTypeORfieldType))] [MethodImpl(MethodImplOptions.InternalCall)] private extern void GetSignature( void* pCorSig, int cCorSig, @@ -1386,9 +1388,9 @@ internal enum MdSigCallingConvention : byte // // Keep the layout in sync with SignatureNative in the VM // - internal RuntimeType[] m_arguments = null!; - internal RuntimeType m_declaringType = null!; // seems not used - internal RuntimeType m_returnTypeORfieldType = null!; + internal RuntimeType[] m_arguments; + internal RuntimeType? m_declaringType; + internal RuntimeType m_returnTypeORfieldType; internal object? m_keepalive; internal void* m_sig; internal int m_managedCallingConventionAndArgIteratorFlags; // lowest byte is CallingConvention, upper 3 bytes are ArgIterator flags diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index 93cfd86bc167b..bfbdbea7de41d 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -244,14 +244,17 @@ internal MethodBase AddMethod(RuntimeType declaringType, RuntimeMethodHandleInte switch (cacheType) { case CacheType.Method: - list = (T[])(object)new RuntimeMethodInfo[1] { - new RuntimeMethodInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags, null) - }; + list = (T[])(object)new RuntimeMethodInfo[1] + { + new RuntimeMethodInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags, null) + }; break; + case CacheType.Constructor: - list = (T[])(object)new RuntimeConstructorInfo[1] { - new RuntimeConstructorInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags) - }; + list = (T[])(object)new RuntimeConstructorInfo[1] + { + new RuntimeConstructorInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags) + }; break; } @@ -4062,7 +4065,7 @@ internal static Type GetTypeFromCLSIDImpl(Guid clsid, string? server, bool throw // Handle arguments that are passed as ByRef and those // arguments that need to be wrapped. - ParameterModifier[] aParamMod = null!; + ParameterModifier[]? aParamMod = null; if (cArgs > 0) { ParameterModifier paramMod = new ParameterModifier(cArgs); @@ -4087,7 +4090,7 @@ internal static Type GetTypeFromCLSIDImpl(Guid clsid, string? server, bool throw for (int i = 0; i < cArgs; i++) { // Determine if the parameter is ByRef. - if (aParamMod[0][i] && aArgs[i] != null) + if (aParamMod![0][i] && aArgs[i] != null) { Type argType = aArgsTypes[i]; if (!ReferenceEquals(argType, aArgs[i].GetType())) diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/ArrayList.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/ArrayList.cs index cb7f2cdde7f68..061672601a022 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/ArrayList.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/ArrayList.cs @@ -28,18 +28,12 @@ namespace System.Collections [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class ArrayList : IList, ICloneable { - private object?[] _items = null!; // Do not rename (binary serialization) + private object?[] _items; // Do not rename (binary serialization) private int _size; // Do not rename (binary serialization) private int _version; // Do not rename (binary serialization) private const int _defaultCapacity = 4; - // Note: this constructor is a bogus constructor that does nothing - // and is for use only with SyncArrayList. - internal ArrayList(bool trash) - { - } - // Constructs a ArrayList. The list is initially empty and has a capacity // of zero. Upon adding the first element to the list the capacity is // increased to _defaultCapacity, and then increased in multiples of two as required. @@ -1196,7 +1190,6 @@ private class SyncArrayList : ArrayList private readonly object _root; internal SyncArrayList(ArrayList list) - : base(false) { _list = list; _root = list.SyncRoot; @@ -2215,7 +2208,7 @@ private class Range : ArrayList private int _baseSize; private int _baseVersion; - internal Range(ArrayList list, int index, int count) : base(false) + internal Range(ArrayList list, int index, int count) { _baseList = list; _baseIndex = index; diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventCounter.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventCounter.cs index 1a41810b25965..2fbe8b40e18ca 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventCounter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventCounter.cs @@ -6,6 +6,7 @@ using System; using System.Diagnostics; #endif +using System.Diagnostics.CodeAnalysis; using System.Threading; #if ES_BUILD_STANDALONE @@ -135,9 +136,10 @@ internal void ResetStatistics() // Values buffering private const int BufferedSize = 10; private const double UnusedBufferSlotValue = double.NegativeInfinity; - private volatile double[] _bufferedValues = null!; + private volatile double[] _bufferedValues; private volatile int _bufferedValuesIndex; + [MemberNotNull(nameof(_bufferedValues))] private void InitializeBuffer() { _bufferedValues = new double[BufferedSize]; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs index 7fb13f2b54625..16bf6d16f4bae 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.cs @@ -45,7 +45,7 @@ public sealed partial class CompareInfo : IDeserializationCallback private IntPtr _sortHandle; [NonSerialized] - private string _sortName = null!; // The name that defines our behavior + private string _sortName; // The name that defines our behavior [OptionalField(VersionAdded = 3)] private SortVersion? m_SortVersion; // Do not rename (binary serialization) @@ -181,6 +181,7 @@ public static bool IsSortable(Rune value) return IsSortable(valueAsUtf16.Slice(0, charCount)); } + [MemberNotNull(nameof(_sortName))] private void InitSort(CultureInfo culture) { _sortName = culture.SortName; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs index 3766ba48be991..f7a7c687966f8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace System.Globalization @@ -87,7 +88,7 @@ public sealed class DateTimeFormatInfo : IFormatProvider, ICloneable private const string sortableDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss"; private const string universalSortableDateTimePattern = "yyyy'-'MM'-'dd HH':'mm':'ss'Z'"; - private Calendar calendar = null!; // initialized in helper called by ctors + private Calendar calendar; private int firstDayOfWeek = -1; private int calendarWeekRule = -1; @@ -389,6 +390,7 @@ public Calendar Calendar Debug.Assert(calendar != null, "DateTimeFormatInfo.Calendar: calendar != null"); return calendar; } + [MemberNotNull(nameof(calendar))] set { if (IsReadOnly) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/StringInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/StringInfo.cs index 2e8cf088cba05..6fa07d94dee63 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/StringInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/StringInfo.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Text.Unicode; namespace System.Globalization @@ -15,7 +16,7 @@ namespace System.Globalization /// public class StringInfo { - private string _str = null!; // initialized in helper called by ctors + private string _str; private int[]? _indexes; @@ -56,6 +57,7 @@ public override bool Equals(object? value) public string String { get => _str; + [MemberNotNull(nameof(_str))] set { _str = value ?? throw new ArgumentNullException(nameof(value)); diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryAccessor.cs b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryAccessor.cs index a2c6bd1764fe0..409e62b87609b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryAccessor.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryAccessor.cs @@ -23,7 +23,7 @@ namespace System.IO /// this gives better throughput; benchmarks showed about 12-15% better. public class UnmanagedMemoryAccessor : IDisposable { - private SafeBuffer _buffer = null!; // initialized in helper called by ctor + private SafeBuffer _buffer = null!; // initialized in helper called by ctor, but also not initialized by protected ctor private long _offset; private long _capacity; private FileAccess _access; diff --git a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceManager.cs b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceManager.cs index 4ab1ecf19efc8..8e3dbf95fcf30 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceManager.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceManager.cs @@ -2,11 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.IO; -using System.Globalization; -using System.Reflection; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Reflection; namespace System.Resources { @@ -120,7 +121,7 @@ internal class CultureNameResourceSetPair private Version? _satelliteContractVersion; private bool _lookedForSatelliteContractVersion; - private IResourceGroveler _resourceGroveler = null!; + private IResourceGroveler _resourceGroveler; public static readonly int MagicNumber = unchecked((int)0xBEEFCACE); // If only hex had a K... @@ -234,6 +235,7 @@ public ResourceManager(Type resourceSource) // Trying to unify code as much as possible, even though having to do a // security check in each constructor prevents it. + [MemberNotNull(nameof(_resourceGroveler))] private void CommonAssemblyInit() { #if FEATURE_APPX diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index 141826bc10e3c..c74821918b165 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -75,7 +75,7 @@ public override IList GetCustomAttributesData() public override MemberInfo[] GetDefaultMembers() { // See if we have cached the default member name - MemberInfo[] members = null!; + MemberInfo[]? members = null; string? defaultMemberName = GetDefaultMemberName(); if (defaultMemberName != null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Security/SecurityElement.cs b/src/libraries/System.Private.CoreLib/src/System/Security/SecurityElement.cs index 541f22dccdcb9..ef0f7bbc00d07 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Security/SecurityElement.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Security/SecurityElement.cs @@ -10,7 +10,7 @@ namespace System.Security { public sealed class SecurityElement { - internal string _tag = null!; + internal string _tag; internal string? _text; private ArrayList? _children; internal ArrayList? _attributes; @@ -34,10 +34,6 @@ public sealed class SecurityElement //-------------------------- Constructors --------------------------- - internal SecurityElement() - { - } - public SecurityElement(string tag) { if (tag == null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs index 203fd784f1ee7..3f0d0350610ba 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs @@ -118,8 +118,8 @@ public abstract partial class Encoding : ICloneable private bool _isReadOnly = true; // Encoding (encoder) fallback - internal EncoderFallback encoderFallback = null!; - internal DecoderFallback decoderFallback = null!; + internal EncoderFallback encoderFallback; + internal DecoderFallback decoderFallback; protected Encoding() : this(0) { @@ -159,6 +159,8 @@ protected Encoding(int codePage, EncoderFallback? encoderFallback, DecoderFallba } // Default fallback that we'll use. + [MemberNotNull(nameof(encoderFallback))] + [MemberNotNull(nameof(decoderFallback))] internal virtual void SetDefaultFallbacks() { // For UTF-X encodings, we use a replacement fallback with an "\xFFFD" string, diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/UTF7Encoding.cs b/src/libraries/System.Private.CoreLib/src/System/Text/UTF7Encoding.cs index 3f697491d218f..feb7a3114c30f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/UTF7Encoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/UTF7Encoding.cs @@ -7,6 +7,7 @@ // using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace System.Text @@ -31,15 +32,15 @@ public class UTF7Encoding : Encoding internal static readonly UTF7Encoding s_default = new UTF7Encoding(); // The set of base 64 characters. - private byte[] _base64Bytes = null!; + private byte[] _base64Bytes; // The decoded bits for every base64 values. This array has a size of 128 elements. // The index is the code point value of the base 64 characters. The value is -1 if // the code point is not a valid base 64 character. Otherwise, the value is a value // from 0 ~ 63. - private sbyte[] _base64Values = null!; + private sbyte[] _base64Values; // The array to decide if a Unicode code point below 0x80 can be directly encoded in UTF7. // This array has a size of 128. - private bool[] _directEncode = null!; + private bool[] _directEncode; private readonly bool _allowOptionals; @@ -60,6 +61,9 @@ public UTF7Encoding(bool allowOptionals) MakeTables(); } + [MemberNotNull(nameof(_base64Bytes))] + [MemberNotNull(nameof(_base64Values))] + [MemberNotNull(nameof(_directEncode))] private void MakeTables() { // Build our tables diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs index 3b590ae738280..98e65d497e92b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Tracing; using System.Threading.Tasks; @@ -695,7 +696,7 @@ public sealed class Timer : MarshalByRefObject, IDisposable, IAsyncDisposable { private const uint MAX_SUPPORTED_TIMEOUT = (uint)0xfffffffe; - private TimerHolder _timer = null!; // initialized in helper called by ctors + private TimerHolder _timer; public Timer(TimerCallback callback, object? state, @@ -774,6 +775,7 @@ public Timer(TimerCallback callback) TimerSetup(callback, this, DueTime, Period); } + [MemberNotNull(nameof(_timer))] private void TimerSetup(TimerCallback callback, object? state, uint dueTime, diff --git a/src/libraries/System.Reflection.Emit.Lightweight/tests/DynamicMethodDefineParameter.cs b/src/libraries/System.Reflection.Emit.Lightweight/tests/DynamicMethodDefineParameter.cs index ad32c3d0bdfca..6334f8c62b7f5 100644 --- a/src/libraries/System.Reflection.Emit.Lightweight/tests/DynamicMethodDefineParameter.cs +++ b/src/libraries/System.Reflection.Emit.Lightweight/tests/DynamicMethodDefineParameter.cs @@ -43,6 +43,15 @@ public void DefineParameter_SetsParameterCorrectly() Assert.Equal(ParameterAttributes.In, parameters[0].Attributes); Assert.Equal(ParameterAttributes.Out, parameters[1].Attributes); + + if (!PlatformDetection.IsMonoRuntime) // [ActiveIssue("https://github.com/dotnet/runtime/issues/36271")] + { + Assert.Empty(parameters[0].GetRequiredCustomModifiers()); + Assert.Empty(parameters[1].GetRequiredCustomModifiers()); + + Assert.Empty(parameters[0].GetOptionalCustomModifiers()); + Assert.Empty(parameters[1].GetOptionalCustomModifiers()); + } } } } From dd1d97785fb53b7e5b279a6ab738f8c3715892f2 Mon Sep 17 00:00:00 2001 From: "Nikola Milosavljevic (CLR)" Date: Wed, 13 May 2020 06:42:07 -0700 Subject: [PATCH 158/420] UI changes for .NET 5 --- .../pkg/projects/netcoreapp/sfx/bundle.thm | 7 +++--- .../pkg/projects/netcoreapp/sfx/bundle.wxl | 8 +++---- .../netcoreapp/sfx/theme/1028/bundle.wxl | 10 ++++----- .../netcoreapp/sfx/theme/1029/bundle.wxl | 18 +++++++-------- .../netcoreapp/sfx/theme/1031/bundle.wxl | 20 ++++++++--------- .../netcoreapp/sfx/theme/1033/bundle.wxl | 6 ++--- .../netcoreapp/sfx/theme/1036/bundle.wxl | 10 ++++----- .../netcoreapp/sfx/theme/1040/bundle.wxl | 10 ++++----- .../netcoreapp/sfx/theme/1041/bundle.wxl | 10 ++++----- .../netcoreapp/sfx/theme/1042/bundle.wxl | 10 ++++----- .../netcoreapp/sfx/theme/1045/bundle.wxl | 8 +++---- .../netcoreapp/sfx/theme/1046/bundle.wxl | 8 +++---- .../netcoreapp/sfx/theme/1049/bundle.wxl | 6 ++--- .../netcoreapp/sfx/theme/1055/bundle.wxl | 12 +++++----- .../netcoreapp/sfx/theme/2052/bundle.wxl | 10 ++++----- .../netcoreapp/sfx/theme/3082/bundle.wxl | 22 +++++++++---------- 16 files changed, 87 insertions(+), 88 deletions(-) diff --git a/src/installer/pkg/projects/netcoreapp/sfx/bundle.thm b/src/installer/pkg/projects/netcoreapp/sfx/bundle.thm index 018459e02fe94..845b5cbd2caf0 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/bundle.thm +++ b/src/installer/pkg/projects/netcoreapp/sfx/bundle.thm @@ -25,10 +25,9 @@ #(loc.WelcomeHeaderMessage) #(loc.WelcomeDescription) - #(loc.LearnMoreTitle) - #(loc.DocumentationLink) - #(loc.PrivacyStatementLink) - #(loc.EulaLink) + #(loc.LicenseAssent) + #(loc.PrivacyStatementLink) + #(loc.EulaLink) diff --git a/src/installer/pkg/projects/netcoreapp/sfx/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/bundle.wxl index 447c17143c2a6..5523036197cf0 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/bundle.wxl @@ -59,7 +59,7 @@ Ready? Set? Let's go! &OK &Cancel .NET Runtime - .NET is a development platform that you can use to build command-line applications, microservices and modern websites. It is open source, cross-platform, and supported by Microsoft. We hope you enjoy it! + The .NET Runtime is used to run .NET applications, on your Windows computer. .NET is open source, cross platform, and supported by Microsoft. We hope you enjoy it! Learn more about .NET The following was installed at [DOTNETHOME] - [BUNDLEMONIKER] @@ -67,8 +67,8 @@ Ready? Set? Let's go! <A HREF="https://aka.ms/dotnet-docs">Documentation</A> <A HREF="https://aka.ms/20-p2-rel-notes">Release Notes</A> <A HREF="https://aka.ms/dotnet-tutorials">Tutorials</A> - <A HREF="https://aka.ms/dotnet-cli-telemetry">.NET SDK Telemetry</A> + <A HREF="https://aka.ms/dotnet-cli-telemetry">.NET Telemetry</A> <A HREF="https://aka.ms/dev-privacy">Privacy Statement</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">.NET Library EULA</A> - + <A HREF="https://aka.ms/dotnet-license-windows">Licensing Information for .NET</A> + By clicking Install, you agree to the following terms. diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/1028/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/1028/bundle.wxl index e2ec688a86be2..e44840f4b1ede 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/1028/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/1028/bundle.wxl @@ -22,7 +22,7 @@ 安裝(&I) 關閉(&C) 安裝選項 - 安裝位置: + 安裝位置: 瀏覽(&B) 確定(&O) 取消(&C) @@ -58,8 +58,8 @@ 不關閉應用程式,需要重新啟動(&D) 確定(&O) 取消(&C) - .NET 執行階段 - .NET 是開發平台,可用來建置命令列應用程式、微服務和新式網站。其為開放原始碼、跨平台且由 Microsoft 支援。希望您喜歡! + .NET Runtime + .NET Runtime 可用於在您的 Windows 電腦上執行 .NET 應用程式。.NET 為開放原始碼形式,且可跨平台運作,同時受到 Microsoft 支援。希望您會喜歡! 深入了解 .NET 下列項目已安裝在 [DOTNETHOME] - [BUNDLEMONIKER] @@ -69,6 +69,6 @@ <A HREF="https://aka.ms/dotnet-tutorials">教學課程</A> <A HREF="https://aka.ms/dotnet-cli-telemetry">.NET 遙測</A> <A HREF="https://aka.ms/dev-privacy">隱私權聲明</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">.NET 程式庫 EULA</A> - + <A HREF="https://aka.ms/dotnet-license-windows">.NET 的授權資訊</A> + 按一下 [\[]安裝[\[] 即表示您同意下列條款。 diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/1029/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/1029/bundle.wxl index 0623b41d2de98..4830781cfddc2 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/1029/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/1029/bundle.wxl @@ -17,11 +17,11 @@ Jste připraveni? Dejme se tedy do toho! /norestart – potlačí všechny pokusy o restartování. Ve výchozím nastavení uživatelské rozhraní před restartováním zobrazí výzvu. /log log.txt – Uloží protokol do konkrétního souboru. Ve výchozím nastavení bude soubor protokolu vytvořen v adresáři %TEMP%. &Zavřít - Souhl&asím s licenčními podmínkami. - M&ožnosti - &Instalovat + &Souhlasím s licenčními podmínkami + &Možnosti + &Nainstalovat &Zavřít - Možnosti instalace + Možnosti nastavení Umístění instalace: &Procházet &OK @@ -42,11 +42,11 @@ Jste připraveni? Dejme se tedy do toho! Před použitím tohoto softwaru musíte restartovat počítač. &Restartovat &Zavřít - Instalace se nepovedla. + Instalace se nezdařila. Instalace se nepovedla. Odinstalace se nepovedla. Oprava se nepovedla. - Instalace se nepovedla kvůli jednomu nebo více problémům. Opravte prosím tyto problémy a zkuste software nainstalovat znovu. Další informace najdete v <a href="#">souboru protokolu</a>. + Instalace se nepovedla kvůli jednomu nebo víc problémům. Opravte tyto problémy a zkuste software znovu nainstalovat. Další informace najdete v <a href="#">souboru protokolu</a>. Pro dokončení vrácení změn tohoto softwaru je potřeba restartovat počítač. &Restartovat &Zavřít @@ -59,7 +59,7 @@ Jste připraveni? Dejme se tedy do toho! &OK &Zrušit Modul runtime .NET - .NET je vývojová platforma, pomocí které lze vytvářet aplikace příkazového řádku, mikroslužby a moderní weby. Je opensourcová, víceplatformová a podporována společností Microsoft. Věříme, že s ní budete spokojeni. + Modul .NET Runtime se používá ke spouštění aplikací .NET na počítači s Windows. .NET je open source, k dispozici pro více platforem a podporovaný Microsoftem. Doufáme, že se vám bude líbit! Další informace o .NET Do [DOTNETHOME] se nainstalovaly následující položky. - [BUNDLEMONIKER] @@ -69,6 +69,6 @@ Jste připraveni? Dejme se tedy do toho! <A HREF="https://aka.ms/dotnet-tutorials">Kurzy</A> <A HREF="https://aka.ms/dotnet-cli-telemetry">Telemetrie pro platformu .NET</A> <A HREF="https://aka.ms/dev-privacy">Prohlášení o zásadách ochrany osobních údajů</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">Smlouva EULA ke knihovně .NET</A> - + <A HREF="https://aka.ms/dotnet-license-windows">Informace o licencování pro .NET</A> + Kliknutím na Nainstalovat vyjadřujete souhlas s následujícími podmínkami. diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/1031/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/1031/bundle.wxl index d3a4daa6622e3..b2798f78a223e 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/1031/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/1031/bundle.wxl @@ -8,21 +8,21 @@ Bereit? Los geht's! Möchten Sie den Vorgang wirklich abbrechen? Vorherige Version Hilfe zum Setup - /install | /repair | /uninstall | /layout [Verzeichnis] - installiert, repariert, deinstalliert oder - erstellt eine vollständige lokale Kopie des Bundles im Verzeichnis. Installieren ist die Standardeinstellung. + /install | /repair | /uninstall | /layout [Verzeichnis]: Installiert, repariert, deinstalliert oder + erstellt eine vollständige lokale Kopie des Bundles im Verzeichnis. "Installieren" ist die Standardeinstellung. -/passive | /quiet - zeigt eine minimale Benutzeroberfläche ohne Eingabeaufforderungen oder keine +/passive | /quiet: Zeigt eine minimale Benutzeroberfläche ohne Eingabeaufforderungen oder keine Benutzeroberfläche und keine Eingabeaufforderungen an. Standardmäßig werden die Benutzeroberfläche und alle Eingabeaufforderungen angezeigt. -/norestart - Unterdrückt alle Neustartversuche. Standardmäßig fordert die Benutzeroberfläche zum Bestätigen eines Neustarts auf. -/log log.txt - Erstellt das Protokoll in einer bestimmten Datei. Standardmäßig wird die Protokolldatei in %TEMP% erstellt. +/norestart: Unterdrückt alle Neustartversuche. Standardmäßig fordert die Benutzeroberfläche zum Bestätigen eines Neustarts auf. +/log log.txt: Erstellt das Protokoll in einer bestimmten Datei. Standardmäßig wird die Protokolldatei in %TEMP% erstellt. S&chließen Ich &stimme den Lizenzbedingungen zu. &Optionen &Installieren S&chließen Setupoptionen - Installationspfad: + Installationsspeicherort: &Durchsuchen &OK &Abbrechen @@ -47,7 +47,7 @@ Bereit? Los geht's! Deinstallationsfehler Reparaturfehler Setup ist aufgrund eines oder mehrerer Probleme fehlgeschlagen. Beheben Sie die Probleme, und führen Sie das Setup erneut aus. Weitere Informationen finden Sie in der <a href="#">Protokolldatei</a>. - Sie müssen den Computer neu starten, um das Zurücksetzen der Software abzuschließen. + Sie müssen Ihren Computer neu starten, um den Rollback der Software abzuschließen. &Neu starten &Schließen [PRODUCT_NAME] wird auf diesem Betriebssystem nicht unterstützt. Weitere Informationen finden Sie unter [LINK_PREREQ_PAGE]. @@ -59,7 +59,7 @@ Bereit? Los geht's! &OK &Abbrechen .NET-Runtime - .NET ist eine Entwicklungsplattform, die Sie zum Erstellen von Befehlszeilenanwendungen, Microservices und modernen Websites verwenden können. Sie ist Open Source und plattformübergreifend und wird von Microsoft unterstützt. Wir wünschen Ihnen viel Spaß! + Die .NET-Runtime wird zum Ausführen von .NET-Anwendungen auf Ihrem Windows-Computer verwendet. .NET ist ein plattformübergreifendes Open-Source-Framework, das von Microsoft unterstützt wird. Wir wünschen Ihnen viel Spaß damit! Weitere Informationen zu .NET Folgendes wurde unter [DOTNETHOME] installiert. - [BUNDLEMONIKER] @@ -69,6 +69,6 @@ Bereit? Los geht's! <A HREF="https://aka.ms/dotnet-tutorials">Tutorials</A> <A HREF="https://aka.ms/dotnet-cli-telemetry">.NET-Telemetrie</A> <A HREF="https://aka.ms/dev-privacy">Datenschutzerklärung</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">Lizenzbedingungen für die .NET-Bibliothek</A> - + <A HREF="https://aka.ms/dotnet-license-windows">Lizenzierungsinformationen für .NET</A> + Durch Klicken auf "Installieren" stimmen Sie den nachstehenden Bedingungen zu. diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/1033/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/1033/bundle.wxl index 3ffba1b580f99..5523036197cf0 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/1033/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/1033/bundle.wxl @@ -59,7 +59,7 @@ Ready? Set? Let's go! &OK &Cancel .NET Runtime - .NET is a development platform that you can use to build command-line applications, microservices and modern websites. It is open source, cross-platform, and supported by Microsoft. We hope you enjoy it! + The .NET Runtime is used to run .NET applications, on your Windows computer. .NET is open source, cross platform, and supported by Microsoft. We hope you enjoy it! Learn more about .NET The following was installed at [DOTNETHOME] - [BUNDLEMONIKER] @@ -69,6 +69,6 @@ Ready? Set? Let's go! <A HREF="https://aka.ms/dotnet-tutorials">Tutorials</A> <A HREF="https://aka.ms/dotnet-cli-telemetry">.NET Telemetry</A> <A HREF="https://aka.ms/dev-privacy">Privacy Statement</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">.NET Library EULA</A> - + <A HREF="https://aka.ms/dotnet-license-windows">Licensing Information for .NET</A> + By clicking Install, you agree to the following terms. diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/1036/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/1036/bundle.wxl index 7e6f1d274dc51..aad9a6e919636 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/1036/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/1036/bundle.wxl @@ -22,7 +22,7 @@ &Installer &Fermer Options d'installation - Emplacement de l'installation : + Emplacement d'installation : &Parcourir &OK &Annuler @@ -54,12 +54,12 @@ [PRODUCT_NAME] n'est pas pris en charge sur les systèmes d'exploitation x86. Effectuez l'installation à l'aide du programme d'installation x86 correspondant. Fichiers en cours d'utilisation Les applications suivantes utilisent des fichiers nécessitant une mise à jour : - &Fermez les applications, puis essayez de les redémarrer. + &Fermer les applications essayez de les ouvrir de nouveau. &Ne pas fermer les applications. Un redémarrage sera nécessaire. &OK &Annuler Runtime .NET - .NET est une plateforme de développement qui vous permet de générer des applications en ligne de commande, des microservices et des sites web modernes. Il s'agit d'un framework open source, multiplateforme et pris en charge par Microsoft. Nous espérons que vous l'apprécierez ! + Le runtime .NET vous permet d'exécuter les applications .NET sur votre ordinateur Windows. .NET est open source, multiplateforme et pris en charge par Microsoft. Nous espérons que vous l'apprécierez ! En savoir plus sur .NET L'élément suivant a été installé sur [DOTNETHOME] - [BUNDLEMONIKER] @@ -69,6 +69,6 @@ <A HREF="https://aka.ms/dotnet-tutorials">Tutoriels</A> <A HREF="https://aka.ms/dotnet-cli-telemetry">Télémétrie .NET</A> <A HREF="https://aka.ms/dev-privacy">Déclaration de confidentialité</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">CLUF de la bibliothèque .NET</A> - + <A HREF="https://aka.ms/dotnet-license-windows">Informations de licence pour .NET</A> + En cliquant sur Installer, vous acceptez les conditions suivantes. diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/1040/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/1040/bundle.wxl index de47d41366b16..ff4a8011e3a1b 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/1040/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/1040/bundle.wxl @@ -19,7 +19,7 @@ Pronti per iniziare? &Chiudi &Accetto i termini e le condizioni di licenza &Opzioni - &Installa + I&nstalla &Chiudi Opzioni di installazione Percorso di installazione: @@ -31,7 +31,7 @@ Pronti per iniziare? Inizializzazione in corso... &Annulla Modifica installazione - &Ripristina + &Ripara &Disinstalla &Chiudi La riparazione è stata completata @@ -59,7 +59,7 @@ Pronti per iniziare? &OK &Annulla Runtime di .NET - NET Core è una piattaforma di sviluppo che è possibile usare per creare microservizi, siti Web moderni e applicazioni dalla riga di comando. È open source, multipiattaforma e supportata da Microsoft. + Runtime di .NET consente di eseguire applicazioni .NET nel computer Windows. .NET è open source, multipiattaforma e supportato da Microsoft. Altre informazioni su .NET I componenti seguenti sono stati installati in [DOTNETHOME] - [BUNDLEMONIKER] @@ -69,6 +69,6 @@ Pronti per iniziare? <A HREF="https://aka.ms/dotnet-tutorials">Esercitazioni</A> <A HREF="https://aka.ms/dotnet-cli-telemetry">Telemetria di .NET</A> <A HREF="https://aka.ms/dev-privacy">Informativa sulla privacy</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">Condizioni di licenza della libreria .NET</A> - + <A HREF="https://aka.ms/dotnet-license-windows">Informazioni sulla licenza per .NET</A> + Facendo clic su Installa, si accettano le condizioni seguenti. diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/1041/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/1041/bundle.wxl index 7005d66672959..14392af22fcf7 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/1041/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/1041/bundle.wxl @@ -23,7 +23,7 @@ インストール(&I) 閉じる(&C) セットアップ オプション - インストール場所: + インストールの場所: 参照(&B) OK(&O) キャンセル(&C) @@ -60,8 +60,8 @@ OK(&O) キャンセル(&C) .NET Runtime - .NET は、コマンドライン アプリケーション、マイクロサービス、および最新の Web サイトをビルドするために使用できる開発プラットフォームです。オープンソースのクロス プラットフォームで、Microsoft によってサポートされています。お楽しみいただければ幸いです。 - .NET の詳細 + .NET Runtime は、Windows コンピューターで .NET アプリケーションを実行するために使用されます。.NET はオープン ソースのクロス プラットフォームで、Microsoft によってサポートされています。ぜひご利用ください。 + .Net の詳細情報 [DOTNETHOME] に以下がインストールされました - [BUNDLEMONIKER] リソース @@ -70,6 +70,6 @@ <A HREF="https://aka.ms/dotnet-tutorials">チュートリアル</A> <A HREF="https://aka.ms/dotnet-cli-telemetry">.NET テレメトリ</A> <A HREF="https://aka.ms/dev-privacy">プライバシーに関する声明</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">.NET ライブラリのライセンス条項</A> - + <A HREF="https://aka.ms/dotnet-license-windows">.NET のライセンス情報</A> + [インストール] をクリックすると、次の条項に同意したものと見なされます。 diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/1042/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/1042/bundle.wxl index a886175d8d91d..f07c56b4a5a42 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/1042/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/1042/bundle.wxl @@ -53,13 +53,13 @@ 이 운영 체제에서는 [PRODUCT_NAME]이(가) 지원되지 않습니다. 자세한 내용은 [LINK_PREREQ_PAGE]을(를) 참조하세요. x86 운영 체제에서는 [PRODUCT_NAME]이(가) 지원되지 않습니다. 해당 x86 설치 관리자를 사용하여 설치하세요. 사용 중인 파일 - 다음의 응용 프로그램이 업데이트해야 할 파일을 사용 중입니다. - 응용 프로그램을 닫고 다시 시작합니다(&A). + 다음의 애플리케이션이 업데이트해야 할 파일을 사용 중입니다. + 애플리케이션을 닫고 다시 시작합니다(&A). 애플리케이션을 닫지 않습니다(&D). 다시 부팅해야 합니다. 확인(&O) 취소(&C) .NET 런타임 - .NET는 명령줄 애플리케이션, 마이크로 서비스 및 최신 웹 사이트를 빌드하는 데 사용할 수 있는 개발 플랫폼입니다. Microsoft가 지원하는 플랫폼 간 오픈 소스입니다. 즐기시기 바랍니다! + .NET 런타임은 Windows 컴퓨터에서 .NET 애플리케이션을 실행하는 데 사용됩니다. .NET은 오픈 소스 및 플랫폼 간이며 Microsoft에서 지원합니다. .NET을 유용하게 사용하시길 바랍니다. .NET에 대한 자세한 정보 다음이 [DOTNETHOME]에 설치되었습니다. - [BUNDLEMONIKER] @@ -69,6 +69,6 @@ <A HREF="https://aka.ms/dotnet-tutorials">자습서</A> <A HREF="https://aka.ms/dotnet-cli-telemetry">.NET 원격 분석</A> <A HREF="https://aka.ms/dev-privacy">개인정보처리방침</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">.NET Library EULA</A> - + <A HREF="https://aka.ms/dotnet-license-windows">.NET에 대한 라이선스 정보</A> + [설치]를 클릭하면 다음 사용 약관에 동의하는 것입니다. diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/1045/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/1045/bundle.wxl index 4694376d5c727..c7f294d950909 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/1045/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/1045/bundle.wxl @@ -59,7 +59,7 @@ Wszystko gotowe? Zaczynamy! &OK &Anuluj Środowisko uruchomieniowe platformy .NET - Platforma .NET to platforma programistyczna, za pomocą której można kompilować aplikacje poziomu wiersza polecenia, mikrousługi i nowoczesne witryny internetowe. Jest to rozwiązanie typu open source, międzyplatformowe i obsługiwane przez firmę Microsoft. Mamy nadzieję, że Ci się spodoba! + Środowisko uruchomieniowe platformy .NET służy do uruchamiania aplikacji platformy .NET na komputerze z systemem Windows. Platforma .NET jest oprogramowaniem typu open source, działa na różnych platformach i jest obsługiwana przez firmę Microsoft. Mamy nadzieję, że Ci się podoba! Dowiedz się więcej o platformie .NET Następujące elementy zainstalowano w [DOTNETHOME] - [BUNDLEMONIKER] @@ -67,8 +67,8 @@ Wszystko gotowe? Zaczynamy! <A HREF="https://aka.ms/dotnet-docs">Dokumentacja</A> <A HREF="https://aka.ms/20-p2-rel-notes">Informacje o wersji</A> <A HREF="https://aka.ms/dotnet-tutorials">Samouczki</A> - <A HREF="https://aka.ms/dotnet-cli-telemetry">Telemetria programu .NET</A> + <A HREF="https://aka.ms/dotnet-cli-telemetry">Telemetria platformy .NET</A> <A HREF="https://aka.ms/dev-privacy">Zasady zachowania poufności informacji</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">Umowa licencyjna użytkownika oprogramowania biblioteki .NET</A> - + <A HREF="https://aka.ms/dotnet-license-windows">Informacje o licencjonowaniu dla platformy .NET</A> + Klikając pozycję Zainstaluj, wyrażasz zgodę na następujące warunki. diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/1046/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/1046/bundle.wxl index 9a86af2423d0a..2de87f08da314 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/1046/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/1046/bundle.wxl @@ -17,7 +17,7 @@ Tudo pronto? Então, vamos nessa! /norestart - suprime qualquer tentativa de reiniciar. Por padrão, a interface do usuário perguntará antes de reiniciar. /log log.txt - registra em um arquivo específico. Por padrão, um arquivo de log é criado em %TEMP%. &Fechar - &Concordo com os termos e condições da licença + Eu &concordo com os termos e condições da licença &Opções &Instalar &Fechar @@ -59,7 +59,7 @@ Tudo pronto? Então, vamos nessa! &OK &Cancelar Runtime do .NET - O .NET é uma plataforma de desenvolvimento que você pode usar para criar aplicativos de linha de comando, microsserviços e sites modernos. Trata-se de um software livre, multiplataforma que conta com o suporte da Microsoft. Esperamos que você goste dele! + O Runtime do .NET é usado para executar aplicativos .NET no seu computador com Windows. O .NET é um software livre, com plataforma cruzada e possui o suporte da Microsoft. Esperamos que você goste! Saiba mais sobre o .NET O seguinte foi instalado em [DOTNETHOME] - [BUNDLEMONIKER] @@ -69,6 +69,6 @@ Tudo pronto? Então, vamos nessa! <A HREF="https://aka.ms/dotnet-tutorials">Tutoriais</A> <A HREF="https://aka.ms/dotnet-cli-telemetry">Telemetria do .NET</A> <A HREF="https://aka.ms/dev-privacy">Política de Privacidade</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">Termos de licença da Biblioteca do .NET</A> - + < A HREF = "https://aka.ms/dotnet-License-Windows" > Informações de licenciamento para .NET</A> + Ao clicar em instalar, você concorda com os termos a seguir. diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/1049/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/1049/bundle.wxl index ffce8692e9cec..fec46b49a5c54 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/1049/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/1049/bundle.wxl @@ -59,7 +59,7 @@ О&К &Отмена Среда выполнения .NET - .NET — это платформа разработки, которую можно использовать для создания приложений командной строки, микрослужб и современных веб-сайтов. Это кроссплатформенная система с открытым исходным кодом, которая поддерживается корпорацией Майкрософт. Надеемся, что она вам понравится! + Среда выполнения .NET используется для запуска приложений .NET на компьютерах с Windows. Среда .NET является открытой, кроссплатформенной и поддерживается Майкрософт. Надеемся, вам понравится! Дополнительные сведения о .NET Следующее было установлено в [DOTNETHOME] - [BUNDLEMONIKER] @@ -69,6 +69,6 @@ <A HREF="https://aka.ms/dotnet-tutorials">Руководства</A> <A HREF="https://aka.ms/dotnet-cli-telemetry">Телеметрия .NET</A> <A HREF="https://aka.ms/dev-privacy">Заявление о конфиденциальности</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">Лицензионное соглашение для библиотеки .NET</A> - + <A HREF="https://aka.ms/dotnet-license-windows">Сведения о лицензировании .NET</A> + Нажимая кнопку "Установить", вы принимаете следующие условия. diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/1055/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/1055/bundle.wxl index 332fb55076f5d..8dbcef0001ee8 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/1055/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/1055/bundle.wxl @@ -32,7 +32,7 @@ Hazır mısınız? Haydi başlayalım! İ&ptal Kurulumu Değiştir &Onar - K&aldır + &Kaldır &Kapat Onarım Başarıyla Tamamlandı Kaldırma Başarıyla Tamamlandı @@ -40,7 +40,7 @@ Hazır mısınız? Haydi başlayalım! Kurulum Başarılı &Başlat Yazılımı kullanabilmek için bilgisayarınızı yeniden başlatmanız gerekiyor. - Yeniden &Başlat + &Yeniden Başlat &Kapat Kurulum Başarısız Kurulum Başarısız @@ -48,7 +48,7 @@ Hazır mısınız? Haydi başlayalım! Onarım Başarısız En az bir sorun nedeniyle kurulum başarısız oldu. Lütfen bu sorunları düzeltin ve kurulumu yeniden deneyin. Daha fazla bilgi için <a href="#">günlük dosyasına</a> bakın. Yazılımın geri alınmasını tamamlamak için bilgisayarınızı yeniden başlatmanız gerekiyor. - Yeniden &Başlat + &Yeniden Başlat &Kapat [PRODUCT_NAME] bu işletim sisteminde desteklenmiyor. Daha fazla bilgi için bkz. [LINK_PREREQ_PAGE]. [PRODUCT_NAME], x86 işletim sistemlerinde desteklenmiyor. Lütfen karşılık gelen x86 yükleyicisini kullanarak yükleyin. @@ -59,7 +59,7 @@ Hazır mısınız? Haydi başlayalım! &Tamam &İptal .NET Çalışma Zamanı - .NET, komut satırı uygulamaları, mikro hizmetler ve modern web siteleri oluşturmak için kullanabileceğiniz bir geliştirme platformudur. Açık kaynaktır, platformlar arası kullanılabilir ve Microsoft tarafından desteklenmektedir. Keyfini çıkarmanızı umuyoruz! + .NET Çalışma Zamanı, Windows bilgisayarınızda .NET uygulamalarını çalıştırmak için kullanılır. .NET açık kaynaktır, platformlar arasında kullanılabilir ve Microsoft tarafından desteklenmektedir. Beğeneceğinizi umuyoruz! .NET hakkında daha fazla bilgi edinin Aşağıdakiler [DOTNETHOME] konumunda yüklendi - [BUNDLEMONIKER] @@ -69,6 +69,6 @@ Hazır mısınız? Haydi başlayalım! <A HREF="https://aka.ms/dotnet-tutorials">Öğreticiler</A> <A HREF="https://aka.ms/dotnet-cli-telemetry">.NET Telemetrisi</A> <A HREF="https://aka.ms/dev-privacy">Gizlilik Bildirimi</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">.NET Kitaplığı EULA</A> - + <A HREF="https://aka.ms/dotnet-license-windows">.NET için Lisans Bilgileri</A> + Yükle'ye tıklayarak aşağıdaki koşulları kabul etmiş olursunuz. diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/2052/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/2052/bundle.wxl index cbc9d9b7f2026..4b3cff08cc0e9 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/2052/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/2052/bundle.wxl @@ -2,7 +2,7 @@ [WixBundleName] 安装程序 [BUNDLEMONIKER] - 你只需要一个 shell、一个文本编辑器,还需花 10 分钟即可。. + 你只需要一个 shell、一个文本编辑器,还需花 10 分钟即可。 准备好了吗? 要设置? 让我们开始吧! 是否确实要取消? @@ -58,8 +58,8 @@ 不关闭应用程序(&D)。需要重启。 确定(&O) 取消(&C) - .NET Runtime - .NET 是一种开发平台,可用于生成命令行应用程序、微服务和新式网站。它是开源、跨平台的,且受 Microsoft 支持。希望你喜欢! + .NET 运行时 + .NET 运行时用于在 Windows 计算机上运行 .NET 应用程序。.NET 是开源、跨平台的,且由 Microsoft 提供支持。希望你喜欢它! 了解有关 .NET 的详细信息 以下项已安装到 [DOTNETHOME] - [BUNDLEMONIKER] @@ -69,6 +69,6 @@ <A HREF="https://aka.ms/dotnet-tutorials">教程</A> <A HREF="https://aka.ms/dotnet-cli-telemetry">.NET 遥测</A> <A HREF="https://aka.ms/dev-privacy">隐私声明</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">.NET 库 EULA</A> - + <A HREF="https://aka.ms/dotnet-license-windows">.NET 的许可信息</A> + 单击“安装”即表示你同意以下条款。 diff --git a/src/installer/pkg/projects/netcoreapp/sfx/theme/3082/bundle.wxl b/src/installer/pkg/projects/netcoreapp/sfx/theme/3082/bundle.wxl index eb4e5711d0da4..611eac88f5a63 100644 --- a/src/installer/pkg/projects/netcoreapp/sfx/theme/3082/bundle.wxl +++ b/src/installer/pkg/projects/netcoreapp/sfx/theme/3082/bundle.wxl @@ -8,21 +8,21 @@ ¿Está seguro de que desea cancelar? Versión anterior Ayuda de configuración - /install | /repair | /uninstall | /layout [directory] - instala, repara, desinstala o - crea una copia local completa del paquete en el directorio. Install es la opción predeterminada. + /install | /repair | /uninstall | /layout [directorio]: Instala, repara, desinstala o + crea una copia local completa del lote de aplicaciones del directorio. La opción predeterminada es /install. -/passive | /quiet - muestra una IU mínima sin peticiones, o bien no muestra la IU - ni las peticiones. De forma predeterminada, se muestran la IU y todas las peticiones. +/passive | /quiet: muestra la interfaz de usuario mínima sin mensajes o no muestra ninguna interfaz de usuario + ni mensajes. De forma predeterminada, se muestra la interfaz de usuario y todos los mensajes. -/norestart - suprime los intentos de reiniciar. De forma predeterminada, la IU preguntará antes de reiniciar. -/log log.txt - se registra en un archivo específico. De forma predeterminada, se crea un archivo de registro en %TEMP%. +/norestart: suprime todos los intentos de reinicio. De forma predeterminada, la interfaz de usuario muestra un mensaje antes de reiniciar el equipo. +/log log.txt: crea un registro en un archivo específico. De forma predeterminada, se crea un archivo de registro en %TEMP%. &Cerrar &Acepto los términos y condiciones de licencia &Opciones &Instalar &Cerrar Opciones de instalación - Ubicación de instalación: + Ubicación de la instalación: E&xaminar &Aceptar &Cancelar @@ -58,8 +58,8 @@ &No cerrar las aplicaciones. Será necesario un reinicio. &Aceptar &Cancelar - .NET Runtime - .NET es una plataforma de desarrollo que se puede usar para compilar aplicaciones de la línea de comandos, microservicios y sitios web modernos. Es de código abierto, multiplataforma y se admite en Microsoft. Esperamos que la disfrute. + Entorno de ejecución .NET + .NET Runtime se usa para ejecutar aplicaciones .NET en un equipo con Windows. Microsoft admite .NET, un código abierto multiplataforma. Esperamos que lo disfrute. Más información sobre .NET Lo siguiente se instaló en [DOTNETHOME] - [BUNDLEMONIKER] @@ -69,6 +69,6 @@ <A HREF="https://aka.ms/dotnet-tutorials">Tutoriales</A> <A HREF="https://aka.ms/dotnet-cli-telemetry">Telemetría de .NET</A> <A HREF="https://aka.ms/dev-privacy">Declaración de privacidad</A> - <A HREF="https://go.microsoft.com/fwlink/?LinkId=329770">CLUF de la biblioteca .NET</A> - + <A HREF="https://aka.ms/dotnet-license-windows">Información de licencias de .NET</A> + Al hacer clic en Instalar, acepta los términos siguientes. From 5615bdaea8ee754f97f53741b00a3c02aa84111b Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Wed, 13 May 2020 09:00:23 -0700 Subject: [PATCH 159/420] Return exit code 1 in android test runner if a test failed (#36319) * Return exit code 1 in android test runner if a test failed * Exit instrumentation with runner exit code --- src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.cs b/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.cs index c223eba130cc7..8500bebd069d9 100644 --- a/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.cs +++ b/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.cs @@ -24,11 +24,18 @@ public static async Task Main(string[] args) Console.WriteLine($"Test libs were not found (*.Tests.dll was not found in {Environment.CurrentDirectory})"); return -1; } + int exitCode = 0; s_MainTestName = Path.GetFileNameWithoutExtension(s_testLibs[0]); var simpleTestRunner = new SimpleAndroidTestRunner(true); + simpleTestRunner.TestsCompleted += (e, result) => + { + if (result.FailedTests > 0) + exitCode = 1; + }; + await simpleTestRunner.RunAsync(); Console.WriteLine("----- Done -----"); - return 0; + return exitCode; } public SimpleAndroidTestRunner(bool verbose) From ba453bd90ccce9848ce95651f0e13413660c09ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Wed, 13 May 2020 18:39:17 +0200 Subject: [PATCH 160/420] Set TargetsMobile=true on Browser TargetOS and build the wasm runtimes earlier during the libs build (#36337) * Set TargetsMobile=true on Browser TargetOS * Build the wasm runtimes earlier during the libs build so they end up in lib-runtime-packs. * Add emsdk_env.sh into .gitignore Co-authored-by: Zoltan Varga --- eng/Configurations.props | 2 +- eng/Subsets.props | 4 ++-- eng/codeOptimization.targets | 2 +- eng/liveBuilds.targets | 4 ++-- src/installer/Directory.Build.props | 3 ++- src/installer/pkg/projects/Directory.Build.targets | 2 +- .../pkg/projects/netcoreapp/src/netcoreapp.depproj | 2 +- src/libraries/Directory.Build.props | 6 +++--- src/libraries/pretest.proj | 8 -------- src/libraries/src.proj | 8 ++++++++ src/mono/wasm/.gitignore | 1 + 11 files changed, 22 insertions(+), 20 deletions(-) create mode 100644 src/mono/wasm/.gitignore diff --git a/eng/Configurations.props b/eng/Configurations.props index 94646e7991b87..06f1aac30eece 100644 --- a/eng/Configurations.props +++ b/eng/Configurations.props @@ -52,7 +52,7 @@ - true + true diff --git a/eng/Subsets.props b/eng/Subsets.props index 801ddb9099483..b6288128d39e3 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -38,7 +38,7 @@ clr+mono+libs+installer - mono+libs+installer + mono+libs+installer @@ -48,7 +48,7 @@ - Mono + Mono Mono CoreCLR diff --git a/eng/codeOptimization.targets b/eng/codeOptimization.targets index 34f89c0807566..6ed7e997487bd 100644 --- a/eng/codeOptimization.targets +++ b/eng/codeOptimization.targets @@ -9,7 +9,7 @@ IBCMerge optimizations on Mac for now to unblock the offical build. See issue https://github.com/dotnet/runtime/issues/33303 --> - false + false true - - diff --git a/src/installer/Directory.Build.props b/src/installer/Directory.Build.props index db4b337749323..1c6c0fbbeebab 100644 --- a/src/installer/Directory.Build.props +++ b/src/installer/Directory.Build.props @@ -217,6 +217,7 @@ true true + true @@ -362,7 +363,7 @@ .map .ni.pdb - + diff --git a/src/installer/pkg/projects/Directory.Build.targets b/src/installer/pkg/projects/Directory.Build.targets index 3617dde42ecad..b2450a84266c1 100644 --- a/src/installer/pkg/projects/Directory.Build.targets +++ b/src/installer/pkg/projects/Directory.Build.targets @@ -26,7 +26,7 @@ - + .Mono diff --git a/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj b/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj index 7f97f90c9b459..4431cd576f29f 100644 --- a/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj +++ b/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj @@ -71,7 +71,7 @@ Include="@(MonoCrossFiles)"> runtimes/$(PackageRID)/native/cross - runtimes/$(PackageRID)/native/include/%(RecursiveDir) diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index 31abeb86bdfe3..c82088bcb6e98 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -41,9 +41,9 @@ x64 x64 - - $(TargetOS.ToLowerInvariant()) + + $(TargetOS.ToLowerInvariant()) Debug diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj index 08b8f5ae1caed..d073141959ef5 100644 --- a/src/libraries/pretest.proj +++ b/src/libraries/pretest.proj @@ -72,14 +72,6 @@ TargetRuntimeIdentifier="$(PackageRID)" /> - - - - - + + + + + diff --git a/src/mono/wasm/.gitignore b/src/mono/wasm/.gitignore new file mode 100644 index 0000000000000..88ea00659140d --- /dev/null +++ b/src/mono/wasm/.gitignore @@ -0,0 +1 @@ +/emsdk_env.sh From f9205c47e57e7f8abb05c9887fa8adba4ed7cc69 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Wed, 13 May 2020 18:57:17 +0200 Subject: [PATCH 161/420] Update -vs removal switch documentation (#36353) --- eng/build.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/build.ps1 b/eng/build.ps1 index 42677b1c7e6dd..6203fee43997b 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -61,7 +61,7 @@ if ($help -or (($null -ne $properties) -and ($properties.Contains('/help') -or $ # VS Test Explorer support for libraries if ($vs) { - Write-Host "!!! VS Test Explorer now works without the -vs switch. The switch will be removed eventually. !!! " + Write-Host "VS Test Explorer now works without needing to call build.cmd. The -vs switch will be removed eventually." . $PSScriptRoot\common\tools.ps1 # Microsoft.DotNet.CoreSetup.sln is special - hosting tests are currently meant to run on the @@ -160,4 +160,4 @@ if ($failedBuilds.Count -ne 0) { exit 1 } -exit 0 \ No newline at end of file +exit 0 From 45af31b2dfe778603c77c7d154f5aa1b6378cd21 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Wed, 13 May 2020 13:10:57 -0400 Subject: [PATCH 162/420] Add a WasmAppBuilder task and a sample. (#36338) --- .../msbuild/WasmAppBuilder/WasmAppBuilder.cs | 115 ++++++ .../WasmAppBuilder/WasmAppBuilder.csproj | 1 + src/mono/netcore/sample/wasm/Makefile | 12 + src/mono/netcore/sample/wasm/Program.cs | 12 + .../netcore/sample/wasm/WasmSample.csproj | 40 +++ src/mono/netcore/sample/wasm/runtime.js | 339 ++++++++++++++++++ 6 files changed, 519 insertions(+) create mode 100644 src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.cs create mode 100644 src/mono/netcore/sample/wasm/Makefile create mode 100644 src/mono/netcore/sample/wasm/Program.cs create mode 100644 src/mono/netcore/sample/wasm/WasmSample.csproj create mode 100644 src/mono/netcore/sample/wasm/runtime.js diff --git a/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.cs b/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.cs new file mode 100644 index 0000000000000..77538e69107da --- /dev/null +++ b/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.cs @@ -0,0 +1,115 @@ +// -*- indent-tabs-mode: nil -*- +// 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. + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Reflection; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +public class WasmAppBuilder : Task +{ + // FIXME: Document + + [Required] + public string? AppDir { get; set; } + [Required] + public string? RuntimePackDir { get; set; } + [Required] + public string? MainAssembly { get; set; } + [Required] + public string? MainJS { get; set; } + [Required] + public ITaskItem[]? AssemblySearchPaths { get; set; } + + Dictionary? Assemblies; + Resolver? Resolver; + + public override bool Execute () { + if (!File.Exists (MainAssembly)) + throw new ArgumentException ($"File MainAssembly='{MainAssembly}' doesn't exist."); + if (!File.Exists (MainJS)) + throw new ArgumentException ($"File MainJS='{MainJS}' doesn't exist."); + + var paths = new List (); + Assemblies = new Dictionary (); + + // Collect and load assemblies used by the app + foreach (var v in AssemblySearchPaths!) { + var dir = v.ItemSpec; + if (!Directory.Exists (dir)) + throw new ArgumentException ($"Directory '{dir}' doesn't exist or not a directory."); + paths.Add (dir); + } + Resolver = new Resolver (paths); + var mlc = new MetadataLoadContext (Resolver, "System.Private.CoreLib"); + + var mainAssembly = mlc.LoadFromAssemblyPath (MainAssembly); + Add (mlc, mainAssembly); + + // Create app + Directory.CreateDirectory (AppDir!); + Directory.CreateDirectory (Path.Join (AppDir, "managed")); + foreach (var assembly in Assemblies!.Values) + File.Copy (assembly.Location, Path.Join (AppDir, "managed", Path.GetFileName (assembly.Location)), true); + foreach (var f in new string [] { "dotnet.wasm", "dotnet.js" }) + File.Copy (Path.Join (RuntimePackDir, "native", "wasm", "release", f), Path.Join (AppDir, f), true); + File.Copy (MainJS!, Path.Join (AppDir, Path.GetFileName (MainJS!)), true); + + using (var sw = File.CreateText (Path.Join (AppDir, "mono-config.js"))) { + sw.WriteLine ("config = {"); + sw.WriteLine ("\tvfs_prefix: \"managed\","); + sw.WriteLine ("\tdeploy_prefix: \"managed\","); + sw.WriteLine ("\tenable_debugging: 0,"); + sw.WriteLine ("\tfile_list: ["); + foreach (var assembly in Assemblies.Values) { + sw.Write ("\"" + Path.GetFileName (assembly.Location) + "\""); + sw.Write (", "); + } + sw.WriteLine ("],"); + sw.WriteLine ("}"); + } + + using (var sw = File.CreateText (Path.Join (AppDir, "run-v8.sh"))) { + sw.WriteLine ("v8 --expose_wasm runtime.js -- --run " + Path.GetFileName (MainAssembly)); + } + + return true; + } + + void Add (MetadataLoadContext mlc, Assembly assembly) { + Assemblies! [assembly.GetName ().Name!] = assembly; + foreach (var aname in assembly.GetReferencedAssemblies ()) { + var refAssembly = mlc.LoadFromAssemblyName (aname); + Add (mlc, refAssembly); + } + } +} + +class Resolver : MetadataAssemblyResolver +{ + List SearchPaths; + + public Resolver (List searchPaths) { + this.SearchPaths = searchPaths; + } + + public override Assembly? Resolve (MetadataLoadContext context, AssemblyName assemblyName) { + var name = assemblyName.Name; + foreach (var dir in SearchPaths) { + var path = Path.Combine (dir, name + ".dll"); + if (File.Exists (path)) { + Console.WriteLine (path); + return context.LoadFromAssemblyPath (path); + } + } + return null; + } +} diff --git a/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.csproj b/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.csproj index 271afb933b491..aa09da974f64a 100644 --- a/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.csproj +++ b/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.csproj @@ -12,5 +12,6 @@ + diff --git a/src/mono/netcore/sample/wasm/Makefile b/src/mono/netcore/sample/wasm/Makefile new file mode 100644 index 0000000000000..09c42a4d3638c --- /dev/null +++ b/src/mono/netcore/sample/wasm/Makefile @@ -0,0 +1,12 @@ +TOP=../../../../.. + +all: build + +build: + $(TOP)/.dotnet/dotnet build /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=Release + +clean: + rm -rf bin + +run: + cd bin/Release/publish && ~/.jsvu/v8 --expose_wasm runtime.js -- --run WasmSample.dll diff --git a/src/mono/netcore/sample/wasm/Program.cs b/src/mono/netcore/sample/wasm/Program.cs new file mode 100644 index 0000000000000..58a6f578393e5 --- /dev/null +++ b/src/mono/netcore/sample/wasm/Program.cs @@ -0,0 +1,12 @@ +// -*- indent-tabs-mode: nil -*- +// 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. +using System; + +public class Test +{ + public static void Main (String[] args) { + Console.WriteLine ("Hello, World!"); + } +} diff --git a/src/mono/netcore/sample/wasm/WasmSample.csproj b/src/mono/netcore/sample/wasm/WasmSample.csproj new file mode 100644 index 0000000000000..588f292924439 --- /dev/null +++ b/src/mono/netcore/sample/wasm/WasmSample.csproj @@ -0,0 +1,40 @@ + + + Exe + bin + false + $(NetCoreAppCurrent) + wasm + Browser + $(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-$(TargetOS)-$(Configuration)-$(TargetArchitecture)\runtimes\browser-wasm + $(MSBuildThisFileDirectory)\obj\$(Configuration)\wasm + $(MSBuildThisFileDirectory)\bin\$(Configuration)\publish + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mono/netcore/sample/wasm/runtime.js b/src/mono/netcore/sample/wasm/runtime.js new file mode 100644 index 0000000000000..10e4fa6ff4816 --- /dev/null +++ b/src/mono/netcore/sample/wasm/runtime.js @@ -0,0 +1,339 @@ +// -*- mode: js; js-indent-level: 4; -*- +// +// Run runtime tests under a JS shell or a browser +// + +//glue code to deal with the differences between chrome, ch, d8, jsc and sm. +var is_browser = typeof window != "undefined"; + +if (is_browser) { + // We expect to be run by tests/runtime/run.js which passes in the arguments using http parameters + var url = new URL (decodeURI (window.location)); + arguments = []; + for (var v of url.searchParams) { + if (v [0] == "arg") { + console.log ("URL ARG: " + v [0] + "=" + v [1]); + arguments.push (v [1]); + } + } +} + +if (is_browser || typeof print === "undefined") + print = console.log; + +// JavaScript core does not have a console defined +if (typeof console === "undefined") { + var Console = function () { + this.log = function(msg){ print(msg) }; + }; + console = new Console(); +} + +if (typeof console !== "undefined") { + if (!console.debug) + console.debug = console.log; + if (!console.trace) + console.trace = console.log; + if (!console.warn) + console.warn = console.log; +} + +if (typeof crypto == 'undefined') { + // /dev/random doesn't work on js shells, so define our own + // See library_fs.js:createDefaultDevices () + var crypto = { + getRandomValues: function (buffer) { + buffer[0] = (Math.random()*256)|0; + } + } +} + +try { + if (typeof arguments == "undefined") + arguments = WScript.Arguments; + load = WScript.LoadScriptFile; + read = WScript.LoadBinaryFile; +} catch (e) { +} + +try { + if (typeof arguments == "undefined") { + if (typeof scriptArgs !== "undefined") + arguments = scriptArgs; + } +} catch (e) { +} +//end of all the nice shell glue code. + +// set up a global variable to be accessed in App.init +var testArguments = arguments; + +function test_exit (exit_code) { + if (is_browser) { + // Notify the puppeteer script + Module.exit_code = exit_code; + print ("WASM EXIT " + exit_code); + } else { + Module.wasm_exit (exit_code); + } +} + +function fail_exec (reason) { + print (reason); + test_exit (1); +} + +function inspect_object (o) { + var r = ""; + for(var p in o) { + var t = typeof o[p]; + r += "'" + p + "' => '" + t + "', "; + } + return r; +} + +// Preprocess arguments +var args = testArguments; +print("Arguments: " + testArguments); +profilers = []; +setenv = {}; +runtime_args = []; +enable_gc = false; +enable_zoneinfo = false; +while (true) { + if (args [0].startsWith ("--profile=")) { + var arg = args [0].substring ("--profile=".length); + + profilers.push (arg); + + args = args.slice (1); + } else if (args [0].startsWith ("--setenv=")) { + var arg = args [0].substring ("--setenv=".length); + var parts = arg.split ('='); + if (parts.length != 2) + fail_exec ("Error: malformed argument: '" + args [0]); + setenv [parts [0]] = parts [1]; + args = args.slice (1); + } else if (args [0].startsWith ("--runtime-arg=")) { + var arg = args [0].substring ("--runtime-arg=".length); + runtime_args.push (arg); + args = args.slice (1); + } else if (args [0] == "--enable-gc") { + enable_gc = true; + args = args.slice (1); + } else if (args [0] == "--enable-zoneinfo") { + enable_zoneinfo = true; + args = args.slice (1); + } else { + break; + } +} +testArguments = args; + +if (typeof window == "undefined") + load ("mono-config.js"); + +var Module = { + mainScriptUrlOrBlob: "dotnet.js", + + print: function(x) { print ("WASM: " + x) }, + printErr: function(x) { print ("WASM-ERR: " + x) }, + + onAbort: function(x) { + print ("ABORT: " + x); + var err = new Error(); + print ("Stacktrace: \n"); + print (err.stack); + test_exit (1); + }, + + onRuntimeInitialized: function () { + // Have to set env vars here to enable setting MONO_LOG_LEVEL etc. + var wasm_setenv = Module.cwrap ('mono_wasm_setenv', 'void', ['string', 'string']); + for (var variable in setenv) { + MONO.mono_wasm_setenv (variable, setenv [variable]); + } + + if (enable_gc) { + var f = Module.cwrap ('mono_wasm_enable_on_demand_gc', 'void', []); + f (); + } + if (enable_zoneinfo) { + // Load the zoneinfo data into the VFS rooted at /zoneinfo + FS.mkdir("zoneinfo"); + Module['FS_createPath']('/', 'zoneinfo', true, true); + Module['FS_createPath']('/zoneinfo', 'Indian', true, true); + Module['FS_createPath']('/zoneinfo', 'Atlantic', true, true); + Module['FS_createPath']('/zoneinfo', 'US', true, true); + Module['FS_createPath']('/zoneinfo', 'Brazil', true, true); + Module['FS_createPath']('/zoneinfo', 'Pacific', true, true); + Module['FS_createPath']('/zoneinfo', 'Arctic', true, true); + Module['FS_createPath']('/zoneinfo', 'America', true, true); + Module['FS_createPath']('/zoneinfo/America', 'Indiana', true, true); + Module['FS_createPath']('/zoneinfo/America', 'Argentina', true, true); + Module['FS_createPath']('/zoneinfo/America', 'Kentucky', true, true); + Module['FS_createPath']('/zoneinfo/America', 'North_Dakota', true, true); + Module['FS_createPath']('/zoneinfo', 'Australia', true, true); + Module['FS_createPath']('/zoneinfo', 'Etc', true, true); + Module['FS_createPath']('/zoneinfo', 'Asia', true, true); + Module['FS_createPath']('/zoneinfo', 'Antarctica', true, true); + Module['FS_createPath']('/zoneinfo', 'Europe', true, true); + Module['FS_createPath']('/zoneinfo', 'Mexico', true, true); + Module['FS_createPath']('/zoneinfo', 'Africa', true, true); + Module['FS_createPath']('/zoneinfo', 'Chile', true, true); + Module['FS_createPath']('/zoneinfo', 'Canada', true, true); + var zoneInfoData = read ('zoneinfo.data', 'binary'); + var metadata = JSON.parse(read ("mono-webassembly-zoneinfo-fs-smd.js.metadata", 'utf-8')); + var files = metadata.files; + for (var i = 0; i < files.length; ++i) { + var byteArray = zoneInfoData.subarray(files[i].start, files[i].end); + var stream = FS.open(files[i].filename, 'w+'); + FS.write(stream, byteArray, 0, byteArray.length, 0); + FS.close(stream); + } + } + MONO.mono_load_runtime_and_bcl ( + config.vfs_prefix, + config.deploy_prefix, + config.enable_debugging, + config.file_list, + function () { + App.init (); + }, + function (asset) + { + if (typeof window != 'undefined') { + return fetch (asset, { credentials: 'same-origin' }); + } else { + // The default mono_load_runtime_and_bcl defaults to using + // fetch to load the assets. It also provides a way to set a + // fetch promise callback. + // Here we wrap the file read in a promise and fake a fetch response + // structure. + return new Promise((resolve, reject) => { + var response = { ok: true, url: asset, + arrayBuffer: function() { + return new Promise((resolve2, reject2) => { + resolve2(new Uint8Array (read (asset, 'binary'))); + } + )} + } + resolve(response) + }) + } + } + ); + }, +}; + +if (typeof window == "undefined") + load ("dotnet.js"); + +const IGNORE_PARAM_COUNT = -1; + +var App = { + init: function () { + + var assembly_load = Module.cwrap ('mono_wasm_assembly_load', 'number', ['string']) + var find_class = Module.cwrap ('mono_wasm_assembly_find_class', 'number', ['number', 'string', 'string']) + var find_method = Module.cwrap ('mono_wasm_assembly_find_method', 'number', ['number', 'string', 'number']) + var runtime_invoke = Module.cwrap ('mono_wasm_invoke_method', 'number', ['number', 'number', 'number', 'number']); + var string_from_js = Module.cwrap ('mono_wasm_string_from_js', 'number', ['string']); + var assembly_get_entry_point = Module.cwrap ('mono_wasm_assembly_get_entry_point', 'number', ['number']); + var string_get_utf8 = Module.cwrap ('mono_wasm_string_get_utf8', 'string', ['number']); + var string_array_new = Module.cwrap ('mono_wasm_string_array_new', 'number', ['number']); + var obj_array_set = Module.cwrap ('mono_wasm_obj_array_set', 'void', ['number', 'number', 'number']); + var exit = Module.cwrap ('mono_wasm_exit', 'void', ['number']); + var wasm_setenv = Module.cwrap ('mono_wasm_setenv', 'void', ['string', 'string']); + var wasm_set_main_args = Module.cwrap ('mono_wasm_set_main_args', 'void', ['number', 'number']); + var wasm_strdup = Module.cwrap ('mono_wasm_strdup', 'number', ['string']); + var unbox_int = Module.cwrap ('mono_unbox_int', 'number', ['number']); + + Module.wasm_exit = Module.cwrap ('mono_wasm_exit', 'void', ['number']); + + Module.print("Initializing....."); + + for (var i = 0; i < profilers.length; ++i) { + var init = Module.cwrap ('mono_wasm_load_profiler_' + profilers [i], 'void', ['string']) + + init (""); + } + + if (args[0] == "--regression") { + var exec_regression = Module.cwrap ('mono_wasm_exec_regression', 'number', ['number', 'string']) + + var res = 0; + try { + res = exec_regression (10, args[1]); + Module.print ("REGRESSION RESULT: " + res); + } catch (e) { + Module.print ("ABORT: " + e); + print (e.stack); + res = 1; + } + + if (res) + fail_exec ("REGRESSION TEST FAILED"); + + return; + } + + if (runtime_args.length > 0) + MONO.mono_wasm_set_runtime_options (runtime_args); + + if (args[0] == "--run") { + // Run an exe + if (args.length == 1) + fail_exec ("Error: Missing main executable argument."); + main_assembly = assembly_load (args[1]); + if (main_assembly == 0) + fail_exec ("Error: Unable to load main executable '" + args[1] + "'"); + main_method = assembly_get_entry_point (main_assembly); + if (main_method == 0) + fail_exec ("Error: Main (string[]) method not found."); + + var app_args = string_array_new (args.length - 2); + for (var i = 2; i < args.length; ++i) { + obj_array_set (app_args, i - 2, string_from_js (args [i])); + } + + var main_argc = args.length - 2 + 1; + var main_argv = Module._malloc (main_argc * 4); + aindex = 0; + Module.setValue (main_argv + (aindex * 4), wasm_strdup (args [1]), "i32") + aindex += 1; + for (var i = 2; i < args.length; ++i) { + Module.setValue (main_argv + (aindex * 4), wasm_strdup (args [i]), "i32"); + aindex += 1; + } + wasm_set_main_args (main_argc, main_argv); + + try { + var invoke_args = Module._malloc (4); + Module.setValue (invoke_args, app_args, "i32"); + var eh_exc = Module._malloc (4); + Module.setValue (eh_exc, 0, "i32"); + var res = runtime_invoke (main_method, 0, invoke_args, eh_exc); + var eh_res = Module.getValue (eh_exc, "i32"); + if (eh_res != 0) { + print ("Exception:" + string_get_utf8 (res)); + test_exit (1); + } + var exit_code = unbox_int (res); + if (exit_code != 0) + test_exit (exit_code); + } catch (ex) { + print ("JS exception: " + ex); + print (ex.stack); + test_exit (1); + } + + if (is_browser) + test_exit (0); + + return; + } else { + fail_exec ("Unhanded argument: " + args [0]); + } + }, +}; From 7af8486e6aa8d73612e36841f87aa42d7f253ea0 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Wed, 13 May 2020 11:02:13 -0700 Subject: [PATCH 163/420] Throttle allocations in BinaryReader (#36348) --- .../src/System/Text/StringBuilderCache.cs | 2 +- .../src/System/IO/BinaryReader.cs | 5 +- .../src/System/Xml/XmlBufferReader.cs | 51 +++++++++++-------- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/libraries/Common/src/System/Text/StringBuilderCache.cs b/src/libraries/Common/src/System/Text/StringBuilderCache.cs index aac2c2e8a9a07..4d96cb301e9e1 100644 --- a/src/libraries/Common/src/System/Text/StringBuilderCache.cs +++ b/src/libraries/Common/src/System/Text/StringBuilderCache.cs @@ -11,7 +11,7 @@ internal static class StringBuilderCache // The value 360 was chosen in discussion with performance experts as a compromise between using // as litle memory per thread as possible and still covering a large part of short-lived // StringBuilder creations on the startup path of VS designers. - private const int MaxBuilderSize = 360; + internal const int MaxBuilderSize = 360; private const int DefaultCapacity = 16; // == StringBuilder.DefaultCapacity // WARNING: We allow diagnostic tools to directly inspect this member (t_cachedInstance). diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/BinaryReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/BinaryReader.cs index 1055013fb6312..8b9a53f3952fc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/BinaryReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/BinaryReader.cs @@ -306,7 +306,10 @@ public virtual string ReadString() return new string(_charBuffer, 0, charsRead); } - sb ??= StringBuilderCache.Acquire(stringLength); // Actual string length in chars may be smaller. + // Since we could be reading from an untrusted data source, limit the initial size of the + // StringBuilder instance we're about to get or create. It'll expand automatically as needed. + + sb ??= StringBuilderCache.Acquire(Math.Min(stringLength, StringBuilderCache.MaxBuilderSize)); // Actual string length in chars may be smaller. sb.Append(_charBuffer, 0, charsRead); currPos += n; } while (currPos < stringLength); diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs index 24920b8c2af61..43d74a87879fb 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs @@ -213,28 +213,37 @@ private bool TryEnsureBytes(int count) { if (_stream == null) return false; - DiagnosticUtility.DebugAssert(_offset <= int.MaxValue - count, ""); - int newOffsetMax = _offset + count; - if (newOffsetMax < _offsetMax) - return true; - DiagnosticUtility.DebugAssert(newOffsetMax <= _windowOffsetMax, ""); - if (newOffsetMax > _buffer.Length) - { - byte[] newBuffer = new byte[Math.Max(newOffsetMax, _buffer.Length * 2)]; - System.Buffer.BlockCopy(_buffer, 0, newBuffer, 0, _offsetMax); - _buffer = newBuffer; - _streamBuffer = newBuffer; - } - int needed = newOffsetMax - _offsetMax; - while (needed > 0) + + // The data could be coming from an untrusted source, so we use a standard + // "multiply by 2" growth algorithm to avoid overly large memory utilization. + // Constant value of 256 comes from MemoryStream implementation. + + do { - int actual = _stream.Read(_buffer, _offsetMax, needed); - if (actual == 0) - return false; - _offsetMax += actual; - needed -= actual; - } - return true; + DiagnosticUtility.DebugAssert(_offset <= int.MaxValue - count, ""); + int newOffsetMax = _offset + count; + if (newOffsetMax <= _offsetMax) + return true; + DiagnosticUtility.DebugAssert(newOffsetMax <= _windowOffsetMax, ""); + if (newOffsetMax > _buffer.Length) + { + byte[] newBuffer = new byte[Math.Max(256, _buffer.Length * 2)]; + System.Buffer.BlockCopy(_buffer, 0, newBuffer, 0, _offsetMax); + newOffsetMax = Math.Min(newOffsetMax, newBuffer.Length); + _buffer = newBuffer; + _streamBuffer = newBuffer; + } + int needed = newOffsetMax - _offsetMax; + DiagnosticUtility.DebugAssert(needed > 0, ""); + do + { + int actual = _stream.Read(_buffer, _offsetMax, needed); + if (actual == 0) + return false; + _offsetMax += actual; + needed -= actual; + } while (needed > 0); + } while (true); } public void Advance(int count) From 9386d507e4459ecc41c4e959828c599c7788dd54 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Wed, 13 May 2020 20:16:03 +0100 Subject: [PATCH 164/420] [CBOR] Implement a proof of concept for ECDsa COSE key serialization (#36002) * Implement a proof of concept for ECDSA cose key serialization * roundtrip COSE all the way to the ECDsa instance * remove comment out code * fix tests failing on Linux * address feedback * fix tests for linux * address feedback * add missing using statement * refactor CoseKey deserializer implementation so that optional fields are supported. --- .../tests/Cbor.Tests/CborReaderTests.cs | 44 +++ .../tests/Cbor.Tests/CborWriterTests.cs | 34 ++ .../tests/Cbor.Tests/CoseKeyHelpers.cs | 319 ++++++++++++++++++ ...ecurity.Cryptography.Encoding.Tests.csproj | 1 + 4 files changed, 398 insertions(+) create mode 100644 src/libraries/System.Security.Cryptography.Encoding/tests/Cbor.Tests/CoseKeyHelpers.cs diff --git a/src/libraries/System.Security.Cryptography.Encoding/tests/Cbor.Tests/CborReaderTests.cs b/src/libraries/System.Security.Cryptography.Encoding/tests/Cbor.Tests/CborReaderTests.cs index 6a86f1572952e..1dbb67d6fe1cf 100644 --- a/src/libraries/System.Security.Cryptography.Encoding/tests/Cbor.Tests/CborReaderTests.cs +++ b/src/libraries/System.Security.Cryptography.Encoding/tests/Cbor.Tests/CborReaderTests.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography; using Test.Cryptography; using Xunit; @@ -182,5 +183,48 @@ public static void InvalidConformanceLevel_ShouldThrowArgumentOutOfRangeExceptio public static IEnumerable EncodedValueInputs => CborReaderTests.SampleCborValues.Select(x => new[] { x }); public static IEnumerable EncodedValueInvalidInputs => CborReaderTests.InvalidCborValues.Select(x => new[] { x }); + + [Theory] + [InlineData("a501020326200121582065eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d2258201e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c", + "65eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d", + "1e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c", + "SHA256", "ECDSA_P256")] + [InlineData("a501020338222002215830ed57d8608c5734a5ed5d22026bad8700636823e45297306479beb61a5bd6b04688c34a2f0de51d91064355eef7548bdd22583024376b4fee60ba65db61de54234575eec5d37e1184fbafa1f49d71e1795bba6bda9cbe2ebb815f9b49b371486b38fa1b", + "ed57d8608c5734a5ed5d22026bad8700636823e45297306479beb61a5bd6b04688c34a2f0de51d91064355eef7548bdd", + "24376b4fee60ba65db61de54234575eec5d37e1184fbafa1f49d71e1795bba6bda9cbe2ebb815f9b49b371486b38fa1b", + "SHA384", "ECDSA_P384")] + [InlineData("a50102033823200321584200b03811bef65e330bb974224ec3ab0a5469f038c92177b4171f6f66f91244d4476e016ee77cf7e155a4f73567627b5d72eaf0cb4a6036c6509a6432d7cd6a3b325c2258420114b597b6c271d8435cfa02e890608c93f5bc118ca7f47bf191e9f9e49a22f8a15962315f0729781e1d78b302970c832db2fa8f7f782a33f8e1514950dc7499035f", + "00b03811bef65e330bb974224ec3ab0a5469f038c92177b4171f6f66f91244d4476e016ee77cf7e155a4f73567627b5d72eaf0cb4a6036c6509a6432d7cd6a3b325c", + "0114b597b6c271d8435cfa02e890608c93f5bc118ca7f47bf191e9f9e49a22f8a15962315f0729781e1d78b302970c832db2fa8f7f782a33f8e1514950dc7499035f", + "SHA512", "ECDSA_P521")] + [InlineData("a40102200121582065eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d2258201e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c", + "65eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d", + "1e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c", + null, "ECDSA_P256")] + public static void CoseKeyHelpers_ECDsaParseCosePublicKey_HappyPath(string hexEncoding, string hexExpectedQx, string hexExpectedQy, string? expectedHashAlgorithmName, string curveFriendlyName) + { + ECPoint q = new ECPoint() { X = hexExpectedQx.HexToByteArray(), Y = hexExpectedQy.HexToByteArray() }; + (ECDsa ecDsa, HashAlgorithmName? name) = CborCoseKeyHelpers.ParseECDsaPublicKey(hexEncoding.HexToByteArray()); + + using ECDsa _ = ecDsa; + + ECParameters ecParams = ecDsa.ExportParameters(includePrivateParameters: false); + + string? expectedCurveFriendlyName = NormalizeCurveForPlatform(curveFriendlyName).Oid.FriendlyName; + + Assert.True(ecParams.Curve.IsNamed); + Assert.Equal(expectedCurveFriendlyName, ecParams.Curve.Oid.FriendlyName); + Assert.Equal(q.X, ecParams.Q.X); + Assert.Equal(q.Y, ecParams.Q.Y); + Assert.Equal(expectedHashAlgorithmName, name?.Name); + + static ECCurve NormalizeCurveForPlatform(string friendlyName) + { + ECCurve namedCurve = ECCurve.CreateFromFriendlyName(friendlyName); + using ECDsa ecDsa = ECDsa.Create(namedCurve); + ECParameters platformParams = ecDsa.ExportParameters(includePrivateParameters: false); + return platformParams.Curve; + } + } } } diff --git a/src/libraries/System.Security.Cryptography.Encoding/tests/Cbor.Tests/CborWriterTests.cs b/src/libraries/System.Security.Cryptography.Encoding/tests/Cbor.Tests/CborWriterTests.cs index c6db6b5b991b4..50999b4f8e1be 100644 --- a/src/libraries/System.Security.Cryptography.Encoding/tests/Cbor.Tests/CborWriterTests.cs +++ b/src/libraries/System.Security.Cryptography.Encoding/tests/Cbor.Tests/CborWriterTests.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography; using Test.Cryptography; using Xunit; @@ -253,5 +254,38 @@ public static void EncodeIndefiniteLengths_UnsupportedConformanceLevel_ShouldThr public static IEnumerable EncodedValueInputs => CborReaderTests.SampleCborValues.Select(x => new [] { x }); public static IEnumerable EncodedValueBadInputs => CborReaderTests.InvalidCborValues.Select(x => new[] { x }); + + [Theory] + [InlineData("a501020326200121582065eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d2258201e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c", + "65eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d", + "1e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c", + "SHA256", "ECDSA_P256")] + [InlineData("a501020338222002215830ed57d8608c5734a5ed5d22026bad8700636823e45297306479beb61a5bd6b04688c34a2f0de51d91064355eef7548bdd22583024376b4fee60ba65db61de54234575eec5d37e1184fbafa1f49d71e1795bba6bda9cbe2ebb815f9b49b371486b38fa1b", + "ed57d8608c5734a5ed5d22026bad8700636823e45297306479beb61a5bd6b04688c34a2f0de51d91064355eef7548bdd", + "24376b4fee60ba65db61de54234575eec5d37e1184fbafa1f49d71e1795bba6bda9cbe2ebb815f9b49b371486b38fa1b", + "SHA384", "ECDSA_P384")] + [InlineData("a50102033823200321584200b03811bef65e330bb974224ec3ab0a5469f038c92177b4171f6f66f91244d4476e016ee77cf7e155a4f73567627b5d72eaf0cb4a6036c6509a6432d7cd6a3b325c2258420114b597b6c271d8435cfa02e890608c93f5bc118ca7f47bf191e9f9e49a22f8a15962315f0729781e1d78b302970c832db2fa8f7f782a33f8e1514950dc7499035f", + "00b03811bef65e330bb974224ec3ab0a5469f038c92177b4171f6f66f91244d4476e016ee77cf7e155a4f73567627b5d72eaf0cb4a6036c6509a6432d7cd6a3b325c", + "0114b597b6c271d8435cfa02e890608c93f5bc118ca7f47bf191e9f9e49a22f8a15962315f0729781e1d78b302970c832db2fa8f7f782a33f8e1514950dc7499035f", + "SHA512", "ECDSA_P521")] + [InlineData("a40102200121582065eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d2258201e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c", + "65eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d", + "1e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c", + null, "ECDSA_P256")] + public static void CoseKeyHelpers_ECDsaExportCosePublicKey_HappyPath(string expectedHexEncoding, string hexQx, string hexQy, string? hashAlgorithmName, string curveFriendlyName) + { + byte[] expectedEncoding = expectedHexEncoding.HexToByteArray(); + var hashAlgName = hashAlgorithmName != null ? new HashAlgorithmName(hashAlgorithmName) : (HashAlgorithmName?)null; + var ecParameters = new ECParameters() + { + Curve = ECCurve.CreateFromFriendlyName(curveFriendlyName), + Q = new ECPoint() { X = hexQx.HexToByteArray(), Y = hexQy.HexToByteArray() }, + }; + + using ECDsa ecDsa = ECDsa.Create(ecParameters); + + byte[] coseKeyEncoding = CborCoseKeyHelpers.ExportECDsaPublicKey(ecDsa, hashAlgName); + AssertHelper.HexEqual(expectedEncoding, coseKeyEncoding); + } } } diff --git a/src/libraries/System.Security.Cryptography.Encoding/tests/Cbor.Tests/CoseKeyHelpers.cs b/src/libraries/System.Security.Cryptography.Encoding/tests/Cbor.Tests/CoseKeyHelpers.cs new file mode 100644 index 0000000000000..a87d7c7706478 --- /dev/null +++ b/src/libraries/System.Security.Cryptography.Encoding/tests/Cbor.Tests/CoseKeyHelpers.cs @@ -0,0 +1,319 @@ +// 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. + +#nullable enable +using System.Diagnostics; +using System.Security.Cryptography; + +// Provides a reference implementation for serializing ECDsa public keys to the COSE_Key format +// according to https://tools.ietf.org/html/rfc8152#section-8.1 + +namespace System.Formats.Cbor.Tests +{ + public static class CborCoseKeyHelpers + { + public static byte[] ExportECDsaPublicKey(ECDsa ecDsa, HashAlgorithmName? hashAlgName) + { + ECParameters ecParams = ecDsa.ExportParameters(includePrivateParameters: false); + using var writer = new CborWriter(CborConformanceLevel.Ctap2Canonical); + WriteECParametersAsCosePublicKey(writer, ecParams, hashAlgName); + return writer.GetEncoding(); + } + + public static (ECDsa ecDsa, HashAlgorithmName? hashAlgName) ParseECDsaPublicKey(byte[] coseKey) + { + var reader = new CborReader(coseKey, CborConformanceLevel.Ctap2Canonical); + (ECParameters ecParams, HashAlgorithmName? hashAlgName) = ReadECParametersAsCosePublicKey(reader); + return (ECDsa.Create(ecParams), hashAlgName); + } + + private static void WriteECParametersAsCosePublicKey(CborWriter writer, ECParameters ecParams, HashAlgorithmName? algorithmName) + { + Debug.Assert(writer.ConformanceLevel == CborConformanceLevel.Ctap2Canonical); + + if (ecParams.Q.X is null || ecParams.Q.Y is null) + { + throw new ArgumentException("does not specify a public key point.", nameof(ecParams)); + } + + // run these first to perform necessary validation + (CoseKeyType kty, CoseCrvId crv) = MapECCurveToCoseKtyAndCrv(ecParams.Curve); + CoseKeyAlgorithm? alg = (algorithmName != null) ? MapHashAlgorithmNameToCoseKeyAlg(algorithmName.Value) : (CoseKeyAlgorithm?)null; + + // Begin writing a CBOR object + writer.WriteStartMap(); + + // NB labels should be sorted according to CTAP2 canonical encoding rules. + // While the CborWriter will attempt to sort the encodings on its own, + // it is generally more efficient if keys are written in sorted order to begin with. + + WriteCoseKeyLabel(writer, CoseKeyLabel.Kty); + writer.WriteInt32((int)kty); + + if (alg != null) + { + WriteCoseKeyLabel(writer, CoseKeyLabel.Alg); + writer.WriteInt32((int)alg); + } + + WriteCoseKeyLabel(writer, CoseKeyLabel.EcCrv); + writer.WriteInt32((int)crv); + + WriteCoseKeyLabel(writer, CoseKeyLabel.EcX); + writer.WriteByteString(ecParams.Q.X); + + WriteCoseKeyLabel(writer, CoseKeyLabel.EcY); + writer.WriteByteString(ecParams.Q.Y); + + writer.WriteEndMap(); + + static (CoseKeyType, CoseCrvId) MapECCurveToCoseKtyAndCrv(ECCurve curve) + { + if (!curve.IsNamed) + { + throw new ArgumentException("EC COSE keys only support named curves.", nameof(curve)); + } + + if (MatchesOid(ECCurve.NamedCurves.nistP256)) + { + return (CoseKeyType.EC2, CoseCrvId.P256); + } + + if (MatchesOid(ECCurve.NamedCurves.nistP384)) + { + return (CoseKeyType.EC2, CoseCrvId.P384); + } + + if (MatchesOid(ECCurve.NamedCurves.nistP521)) + { + return (CoseKeyType.EC2, CoseCrvId.P521); + } + + throw new ArgumentException("Unrecognized named curve", curve.Oid.Value); + + bool MatchesOid(ECCurve namedCurve) => curve.Oid.Value == namedCurve.Oid.Value; + } + + static CoseKeyAlgorithm MapHashAlgorithmNameToCoseKeyAlg(HashAlgorithmName name) + { + if (MatchesName(HashAlgorithmName.SHA256)) + { + return CoseKeyAlgorithm.ES256; + } + + if (MatchesName(HashAlgorithmName.SHA384)) + { + return CoseKeyAlgorithm.ES384; + } + + if (MatchesName(HashAlgorithmName.SHA512)) + { + return CoseKeyAlgorithm.ES512; + } + + throw new ArgumentException("Unrecognized hash algorithm name.", nameof(HashAlgorithmName)); + + bool MatchesName(HashAlgorithmName candidate) => name.Name == candidate.Name; + } + + static void WriteCoseKeyLabel(CborWriter writer, CoseKeyLabel label) + { + writer.WriteInt32((int)label); + } + } + + private static (ECParameters, HashAlgorithmName?) ReadECParametersAsCosePublicKey(CborReader reader) + { + Debug.Assert(reader.ConformanceLevel == CborConformanceLevel.Ctap2Canonical); + + // CTAP2 conformance mode requires that fields are sorted by key encoding. + // We take advantage of this by reading keys in that order. + // NB1. COSE labels are not sorted according to canonical integer ordering, + // negative labels must always follow positive labels. + // NB2. Any unrecognized keys will result in the reader failing. + // NB3. in order to support optional fields, we need to store the latest read label. + CoseKeyLabel? latestReadLabel = null; + + int? remainingKeys = reader.ReadStartMap(); + Debug.Assert(remainingKeys != null); // guaranteed by CTAP2 conformance + + try + { + var ecParams = new ECParameters(); + + ReadCoseKeyLabel(CoseKeyLabel.Kty); + CoseKeyType kty = (CoseKeyType)reader.ReadInt32(); + + HashAlgorithmName? algName = null; + if (TryReadCoseKeyLabel(CoseKeyLabel.Alg)) + { + CoseKeyAlgorithm alg = (CoseKeyAlgorithm)reader.ReadInt32(); + algName = MapCoseKeyAlgToHashAlgorithmName(alg); + } + + if (TryReadCoseKeyLabel(CoseKeyLabel.KeyOps)) + { + // No-op, simply tolerate potential key_ops labels + reader.SkipValue(validateConformance: true); + } + + ReadCoseKeyLabel(CoseKeyLabel.EcCrv); + CoseCrvId crv = (CoseCrvId)reader.ReadInt32(); + + if (IsValidKtyCrvCombination(kty, crv)) + { + ecParams.Curve = MapCoseCrvToECCurve(crv); + } + else + { + throw new FormatException("Invalid kty/crv combination in COSE key."); + } + + ReadCoseKeyLabel(CoseKeyLabel.EcX); + ecParams.Q.X = reader.ReadByteString(); + + ReadCoseKeyLabel(CoseKeyLabel.EcY); + ecParams.Q.Y = reader.ReadByteString(); + + if (TryReadCoseKeyLabel(CoseKeyLabel.EcD)) + { + throw new FormatException("COSE key encodes a private key."); + } + + if (remainingKeys > 0) + { + throw new FormatException("COSE_key contains unrecognized trailing data."); + } + + reader.ReadEndMap(); + + return (ecParams, algName); + } + catch (InvalidOperationException e) + { + throw new FormatException("Invalid COSE_key format in CBOR document", e); + } + + static bool IsValidKtyCrvCombination(CoseKeyType kty, CoseCrvId crv) + { + return (kty, crv) switch + { + (CoseKeyType.EC2, CoseCrvId.P256 or CoseCrvId.P384 or CoseCrvId.P521) => true, + (CoseKeyType.OKP, CoseCrvId.X255519 or CoseCrvId.X448 or CoseCrvId.Ed25519 or CoseCrvId.Ed448) => true, + _ => false, + }; + ; + } + + static ECCurve MapCoseCrvToECCurve(CoseCrvId crv) + { + return crv switch + { + CoseCrvId.P256 => ECCurve.NamedCurves.nistP256, + CoseCrvId.P384 => ECCurve.NamedCurves.nistP384, + CoseCrvId.P521 => ECCurve.NamedCurves.nistP521, + CoseCrvId.X255519 or + CoseCrvId.X448 or + CoseCrvId.Ed25519 or + CoseCrvId.Ed448 => throw new NotImplementedException("OKP type curves not implemented."), + _ => throw new FormatException("Unrecognized COSE crv value."), + }; + } + + static HashAlgorithmName MapCoseKeyAlgToHashAlgorithmName(CoseKeyAlgorithm alg) + { + return alg switch + { + CoseKeyAlgorithm.ES256 => HashAlgorithmName.SHA256, + CoseKeyAlgorithm.ES384 => HashAlgorithmName.SHA384, + CoseKeyAlgorithm.ES512 => HashAlgorithmName.SHA512, + _ => throw new FormatException("Unrecognized COSE alg value."), + }; + } + + // Handles optional labels + bool TryReadCoseKeyLabel(CoseKeyLabel expectedLabel) + { + // The `currentLabel` parameter can hold a label that + // was read when handling a previous optional field. + // We only need to read the next label if uninhabited. + if (latestReadLabel == null) + { + // check that we have not reached the end of the COSE key object + if (remainingKeys == 0) + { + return false; + } + + latestReadLabel = (CoseKeyLabel)reader.ReadInt32(); + } + + if (expectedLabel != latestReadLabel.Value) + { + return false; + } + + // read was successful, vacate the `currentLabel` parameter to advance reads. + latestReadLabel = null; + remainingKeys--; + return true; + } + + // Handles required labels + void ReadCoseKeyLabel(CoseKeyLabel expectedLabel) + { + if (!TryReadCoseKeyLabel(expectedLabel)) + { + throw new FormatException("Unexpected COSE key label."); + } + } + } + + private enum CoseKeyLabel : int + { + // cf. https://tools.ietf.org/html/rfc8152#section-7.1 table 3 + Kty = 1, + Kid = 2, + Alg = 3, + KeyOps = 4, + BaseIv = 5, + + // cf. https://tools.ietf.org/html/rfc8152#section-13.1.1 table 23 + EcCrv = -1, + EcX = -2, + EcY = -3, + EcD = -4, + }; + + private enum CoseCrvId : int + { + // cf. https://tools.ietf.org/html/rfc8152#section-13.1 table 22 + P256 = 1, + P384 = 2, + P521 = 3, + X255519 = 4, + X448 = 5, + Ed25519 = 6, + Ed448 = 7, + } + + private enum CoseKeyType : int + { + // cf. https://tools.ietf.org/html/rfc8152#section-13 table 21 + OKP = 1, + EC2 = 2, + + Symmetric = 4, + Reserved = 0, + } + + private enum CoseKeyAlgorithm : int + { + // cf. https://tools.ietf.org/html/rfc8152#section-8.1 table 5 + ES256 = -7, + ES384 = -35, + ES512 = -36, + } + } +} diff --git a/src/libraries/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.csproj b/src/libraries/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.csproj index 8ca393597862f..e89c8cf8318ff 100644 --- a/src/libraries/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.csproj @@ -76,5 +76,6 @@ + From 61c658183231100a5836e833c86446ff51a4654b Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Lopez <1175054+carlossanlop@users.noreply.github.com> Date: Wed, 13 May 2020 12:24:01 -0700 Subject: [PATCH 165/420] Fix Path.GetPathRoot wrong check in Unix (#35734) * Fix Path.GetPathRoot wrong check in Unix * Return .Empty instead of null * Update src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs Co-authored-by: Jan Kotas * Address unit test comments Co-authored-by: Jan Kotas --- .../src/System/IO/Path.Unix.cs | 3 +- .../tests/System/IO/PathTests.cs | 12 +++++-- .../tests/System/IO/PathTests_Unix.cs | 34 ++++++++++++++++++- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs index 25cec9463f3f2..752eca8306394 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.Unix.cs @@ -122,13 +122,12 @@ public static bool IsPathRooted(ReadOnlySpan path) public static string? GetPathRoot(string? path) { if (PathInternal.IsEffectivelyEmpty(path)) return null; - return IsPathRooted(path) ? PathInternal.DirectorySeparatorCharAsString : string.Empty; } public static ReadOnlySpan GetPathRoot(ReadOnlySpan path) { - return PathInternal.IsEffectivelyEmpty(path) && IsPathRooted(path) ? PathInternal.DirectorySeparatorCharAsString.AsSpan() : ReadOnlySpan.Empty; + return IsPathRooted(path) ? PathInternal.DirectorySeparatorCharAsString.AsSpan() : ReadOnlySpan.Empty; } /// Gets whether the system is case-sensitive. diff --git a/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests.cs index dc0fd48a6297e..6d618f756c7ff 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests.cs @@ -52,6 +52,7 @@ public void GetDirectoryName_CurrentDirectory() Assert.Equal(curDir, Path.GetDirectoryName(Path.Combine(curDir, "baz"))); Assert.Null(Path.GetDirectoryName(Path.GetPathRoot(curDir))); + Assert.True(Path.GetDirectoryName(Path.GetPathRoot(curDir.AsSpan())).IsEmpty); } [Fact] @@ -108,10 +109,16 @@ public void GetPathRoot_Null() public void GetPathRoot_Basic() { string cwd = Directory.GetCurrentDirectory(); - Assert.Equal(cwd.Substring(0, cwd.IndexOf(Path.DirectorySeparatorChar) + 1), Path.GetPathRoot(cwd)); + string substring = cwd.Substring(0, cwd.IndexOf(Path.DirectorySeparatorChar) + 1); + + Assert.Equal(substring, Path.GetPathRoot(cwd)); + PathAssert.Equal(substring.AsSpan(), Path.GetPathRoot(cwd.AsSpan())); + Assert.True(Path.IsPathRooted(cwd)); Assert.Equal(string.Empty, Path.GetPathRoot(@"file.exe")); + Assert.True(Path.GetPathRoot(@"file.exe".AsSpan()).IsEmpty); + Assert.False(Path.IsPathRooted("file.exe")); } @@ -417,6 +424,7 @@ public void GetInvalidPathChars() Assert.EndsWith(bad, Path.GetFullPath(bad)); } Assert.Equal(string.Empty, Path.GetPathRoot(bad)); + Assert.True(Path.GetPathRoot(bad.AsSpan()).IsEmpty); Assert.False(Path.IsPathRooted(bad)); }); } @@ -431,7 +439,7 @@ public void GetInvalidPathChars_Span() Assert.Equal(string.Empty, new string(Path.GetExtension(bad.AsSpan()))); Assert.Equal(bad, new string(Path.GetFileName(bad.AsSpan()))); Assert.Equal(bad, new string(Path.GetFileNameWithoutExtension(bad.AsSpan()))); - Assert.Equal(string.Empty, new string(Path.GetPathRoot(bad.AsSpan()))); + Assert.True(Path.GetPathRoot(bad.AsSpan()).IsEmpty); Assert.False(Path.IsPathRooted(bad.AsSpan())); }); } diff --git a/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests_Unix.cs b/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests_Unix.cs index 39e3edb01eae8..7f57a8d659ced 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests_Unix.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests_Unix.cs @@ -19,6 +19,7 @@ public static void GetPathRoot(string value, string expected) // UNCs and device paths have no special meaning in Unix _ = expected; Assert.Empty(Path.GetPathRoot(value)); + Assert.True(Path.GetPathRoot(value.AsSpan()).IsEmpty); } [Theory, @@ -115,13 +116,44 @@ public void GetFullPath_Unix_Whitespace() { @"../../../tmp/bar/..", @"/home/git", @"/tmp" }, { @"../../././tmp/..", @"/home/git", @"/" }, { @"././../../../", @"/home/git", @"/" }, + { @"../tmp/../..", @"/home", @"/" } }; [Theory, MemberData(nameof(GetFullPath_BasePath_BasicExpansions_TestData_Unix))] public static void GetFullPath_BasicExpansions_Unix(string path, string basePath, string expected) { - Assert.Equal(expected, Path.GetFullPath(path, basePath)); + string fullPath = Path.GetFullPath(path, basePath); + Assert.Equal(expected, fullPath); + } + + [Theory] + [InlineData(@"/../../.././tmp/..")] + [InlineData(@"/../../../")] + [InlineData(@"/../../../tmp/bar/..")] + [InlineData(@"/../.././././bar/../../../")] + [InlineData(@"/../../././tmp/..")] + [InlineData(@"/../../tmp/../../")] + [InlineData(@"/../../tmp/bar/..")] + [InlineData(@"/../tmp/../..")] + [InlineData(@"/././../../../../")] + [InlineData(@"/././../../../")] + [InlineData(@"/./././bar/../../../")] + [InlineData(@"/")] + [InlineData(@"/bar")] + [InlineData(@"/bar/././././../../..")] + [InlineData(@"/bar/tmp")] + [InlineData(@"/tmp/..")] + [InlineData(@"/tmp/../../../../../bar")] + [InlineData(@"/tmp/../../../bar")] + [InlineData(@"/tmp/../bar/../..")] + [InlineData(@"/tmp/bar")] + [InlineData(@"/tmp/bar/..")] + public static void GePathRoot_Unix(string path) + { + string expected = @"/"; + Assert.Equal(expected, Path.GetPathRoot(path)); + PathAssert.Equal(expected.AsSpan(), Path.GetPathRoot(path.AsSpan())); } [Fact] From f876095ba232312c4ec3eda5794c7cb1809018ff Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Wed, 13 May 2020 13:07:30 -0700 Subject: [PATCH 166/420] Move serializer KeyValuePair tests to dedicated file --- .../CollectionTests.Generic.Read.cs | 161 ---------- .../CollectionTests.Generic.Write.cs | 111 ------- .../CollectionTests.KeyValuePair.cs | 283 ++++++++++++++++++ .../tests/System.Text.Json.Tests.csproj | 12 +- 4 files changed, 288 insertions(+), 279 deletions(-) create mode 100644 src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.KeyValuePair.cs diff --git a/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Generic.Read.cs b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Generic.Read.cs index d1cb10248613a..3e9eae828e837 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Generic.Read.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Generic.Read.cs @@ -962,167 +962,6 @@ public static void ReadSimpleSortedSetT() Assert.Equal(0, result.Count()); } - [Fact] - public static void ReadSimpleKeyValuePairFail() - { - // Invalid form: no Value - Assert.Throws(() => JsonSerializer.Deserialize>(@"{""Key"": 123}")); - - // Invalid form: extra property - Assert.Throws(() => JsonSerializer.Deserialize>(@"{""Key"": ""Key"", ""Value"": 123, ""Value2"": 456}")); - - // Invalid form: does not contain both Key and Value properties - Assert.Throws(() => JsonSerializer.Deserialize>(@"{""Key"": ""Key"", ""Val"": 123")); - } - - [Fact] - public static void ReadListOfKeyValuePair() - { - List> input = JsonSerializer.Deserialize>>(@"[{""Key"": ""123"", ""Value"": 123},{""Key"": ""456"", ""Value"": 456}]"); - - Assert.Equal(2, input.Count); - Assert.Equal("123", input[0].Key); - Assert.Equal(123, input[0].Value); - Assert.Equal("456", input[1].Key); - Assert.Equal(456, input[1].Value); - } - - [Fact] - public static void ReadKeyValuePairOfList() - { - KeyValuePair> input = JsonSerializer.Deserialize>>(@"{""Key"":""Key"", ""Value"":[1, 2, 3]}"); - - Assert.Equal("Key", input.Key); - Assert.Equal(3, input.Value.Count); - Assert.Equal(1, input.Value[0]); - Assert.Equal(2, input.Value[1]); - Assert.Equal(3, input.Value[2]); - } - - [Theory] - [InlineData(@"{""Key"":""Key"", ""Value"":{""Key"":1, ""Value"":2}}")] - [InlineData(@"{""Key"":""Key"", ""Value"":{""Value"":2, ""Key"":1}}")] - [InlineData(@"{""Value"":{""Key"":1, ""Value"":2}, ""Key"":""Key""}")] - [InlineData(@"{""Value"":{""Value"":2, ""Key"":1}, ""Key"":""Key""}")] - public static void ReadKeyValuePairOfKeyValuePair(string json) - { - KeyValuePair> input = JsonSerializer.Deserialize>>(json); - - Assert.Equal("Key", input.Key); - Assert.Equal(1, input.Value.Key); - Assert.Equal(2, input.Value.Value); - } - - [Fact] - public static void ReadKeyValuePairWithNullValues() - { - { - KeyValuePair kvp = JsonSerializer.Deserialize>(@"{""Key"":""key"",""Value"":null}"); - Assert.Equal("key", kvp.Key); - Assert.Null(kvp.Value); - } - - { - KeyValuePair kvp = JsonSerializer.Deserialize>(@"{""Key"":""key"",""Value"":null}"); - Assert.Equal("key", kvp.Key); - Assert.Null(kvp.Value); - } - - { - KeyValuePair kvp = JsonSerializer.Deserialize>(@"{""Key"":""key"",""Value"":null}"); - Assert.Equal("key", kvp.Key); - Assert.Null(kvp.Value); - } - - { - KeyValuePair> kvp = JsonSerializer.Deserialize>>(@"{""Key"":""key"",""Value"":{""Key"":""key"",""Value"":null}}"); - Assert.Equal("key", kvp.Key); - Assert.Equal("key", kvp.Value.Key); - Assert.Null(kvp.Value.Value); - } - - { - KeyValuePair> kvp = JsonSerializer.Deserialize>>(@"{""Key"":""key"",""Value"":{""Key"":""key"",""Value"":null}}"); - Assert.Equal("key", kvp.Key); - Assert.Equal("key", kvp.Value.Key); - Assert.Null(kvp.Value.Value); - } - - { - KeyValuePair> kvp = JsonSerializer.Deserialize>>(@"{""Key"":""key"",""Value"":{""Key"":""key"",""Value"":null}}"); - Assert.Equal("key", kvp.Key); - Assert.Equal("key", kvp.Value.Key); - Assert.Null(kvp.Value.Value); - } - } - - [Fact] - public static void ReadClassWithNullKeyValuePairValues() - { - string json = - @"{" + - @"""KvpWStrVal"":{" + - @"""Key"":""key""," + - @"""Value"":null" + - @"}," + - @"""KvpWObjVal"":{" + - @"""Key"":""key""," + - @"""Value"":null" + - @"}," + - @"""KvpWClassVal"":{" + - @"""Key"":""key""," + - @"""Value"":null" + - @"}," + - @"""KvpWStrKvpVal"":{" + - @"""Key"":""key""," + - @"""Value"":{" + - @"""Key"":""key""," + - @"""Value"":null" + - @"}" + - @"}," + - @"""KvpWObjKvpVal"":{" + - @"""Key"":""key""," + - @"""Value"":{" + - @"""Key"":""key""," + - @"""Value"":null" + - @"}" + - @"}," + - @"""KvpWClassKvpVal"":{" + - @"""Key"":""key""," + - @"""Value"":{" + - @"""Key"":""key""," + - @"""Value"":null" + - @"}" + - @"}" + - @"}"; - SimpleClassWithKeyValuePairs obj = JsonSerializer.Deserialize(json); - - Assert.Equal("key", obj.KvpWStrVal.Key); - Assert.Equal("key", obj.KvpWObjVal.Key); - Assert.Equal("key", obj.KvpWClassVal.Key); - Assert.Equal("key", obj.KvpWStrKvpVal.Key); - Assert.Equal("key", obj.KvpWObjKvpVal.Key); - Assert.Equal("key", obj.KvpWClassKvpVal.Key); - Assert.Equal("key", obj.KvpWStrKvpVal.Value.Key); - Assert.Equal("key", obj.KvpWObjKvpVal.Value.Key); - Assert.Equal("key", obj.KvpWClassKvpVal.Value.Key); - - Assert.Null(obj.KvpWStrVal.Value); - Assert.Null(obj.KvpWObjVal.Value); - Assert.Null(obj.KvpWClassVal.Value); - Assert.Null(obj.KvpWStrKvpVal.Value.Value); - Assert.Null(obj.KvpWObjKvpVal.Value.Value); - Assert.Null(obj.KvpWClassKvpVal.Value.Value); - } - - [Fact] - public static void Kvp_NullKeyIsFine() - { - KeyValuePair kvp = JsonSerializer.Deserialize>(@"{""Key"":null,""Value"":null}"); - Assert.Null(kvp.Key); - Assert.Null(kvp.Value); - } - [Fact] public static void ReadSimpleTestClass_GenericCollectionWrappers() { diff --git a/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Generic.Write.cs b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Generic.Write.cs index e408f09b0e7fd..2c2c61819d1ac 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Generic.Write.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.Generic.Write.cs @@ -750,117 +750,6 @@ public static void WritePrimitiveSortedSetT() Assert.Equal("[1,2]", json); } - [Fact] - public static void WritePrimitiveKeyValuePair() - { - KeyValuePair input = new KeyValuePair("Key", 123) ; - - string json = JsonSerializer.Serialize(input); - Assert.Equal(@"{""Key"":""Key"",""Value"":123}", json); - } - - [Fact] - public static void WriteListOfKeyValuePair() - { - List> input = new List> - { - new KeyValuePair("123", 123), - new KeyValuePair("456", 456) - }; - - string json = JsonSerializer.Serialize(input); - Assert.Equal(@"[{""Key"":""123"",""Value"":123},{""Key"":""456"",""Value"":456}]", json); - } - - [Fact] - public static void WriteKeyValuePairOfList() - { - KeyValuePair> input = new KeyValuePair>("Key", new List { 1, 2, 3 }); - - string json = JsonSerializer.Serialize(input); - Assert.Equal(@"{""Key"":""Key"",""Value"":[1,2,3]}", json); - } - - [Fact] - public static void WriteKeyValuePairOfKeyValuePair() - { - KeyValuePair> input = new KeyValuePair>( - "Key", new KeyValuePair("Key", 1)); - - string json = JsonSerializer.Serialize(input); - Assert.Equal(@"{""Key"":""Key"",""Value"":{""Key"":""Key"",""Value"":1}}", json); - } - - [Fact] - public static void WriteKeyValuePairWithNullValues() - { - { - KeyValuePair kvp = new KeyValuePair("key", null); - Assert.Equal(@"{""Key"":""key"",""Value"":null}", JsonSerializer.Serialize(kvp)); - } - - { - KeyValuePair kvp = new KeyValuePair("key", null); - Assert.Equal(@"{""Key"":""key"",""Value"":null}", JsonSerializer.Serialize(kvp)); - } - - { - KeyValuePair kvp = new KeyValuePair("key", null); - Assert.Equal(@"{""Key"":""key"",""Value"":null}", JsonSerializer.Serialize(kvp)); - } - - { - KeyValuePair> kvp = new KeyValuePair>("key", new KeyValuePair("key", null)); - Assert.Equal(@"{""Key"":""key"",""Value"":{""Key"":""key"",""Value"":null}}", JsonSerializer.Serialize(kvp)); - } - - { - KeyValuePair> kvp = new KeyValuePair>("key", new KeyValuePair("key", null)); - Assert.Equal(@"{""Key"":""key"",""Value"":{""Key"":""key"",""Value"":null}}", JsonSerializer.Serialize(kvp)); - } - - { - KeyValuePair> kvp = new KeyValuePair>("key", new KeyValuePair("key", null)); - Assert.Equal(@"{""Key"":""key"",""Value"":{""Key"":""key"",""Value"":null}}", JsonSerializer.Serialize(kvp)); - } - } - - // https://github.com/dotnet/runtime/issues/30388 - [Fact] - public static void WriteClassWithNullKeyValuePairValues_NullWrittenAsEmptyObject() - { - var value = new SimpleClassWithKeyValuePairs() - { - KvpWStrVal = new KeyValuePair("key", null), - KvpWObjVal = new KeyValuePair("key", null), - KvpWClassVal = new KeyValuePair("key", null), - KvpWStrKvpVal = new KeyValuePair>("key", new KeyValuePair("key", null)), - KvpWObjKvpVal = new KeyValuePair>("key", new KeyValuePair("key", null)), - KvpWClassKvpVal = new KeyValuePair>("key", new KeyValuePair("key", null)), - }; - - string result = JsonSerializer.Serialize(value); - - // Roundtrip to ensure serialize was correct. - value = JsonSerializer.Deserialize(result); - Assert.Equal("key", value.KvpWStrVal.Key); - Assert.Equal("key", value.KvpWObjVal.Key); - Assert.Equal("key", value.KvpWClassVal.Key); - Assert.Equal("key", value.KvpWStrKvpVal.Key); - Assert.Equal("key", value.KvpWObjKvpVal.Key); - Assert.Equal("key", value.KvpWClassKvpVal.Key); - Assert.Equal("key", value.KvpWStrKvpVal.Value.Key); - Assert.Equal("key", value.KvpWObjKvpVal.Value.Key); - Assert.Equal("key", value.KvpWClassKvpVal.Value.Key); - - Assert.Null(value.KvpWStrVal.Value); - Assert.Null(value.KvpWObjVal.Value); - Assert.Null(value.KvpWClassVal.Value); - Assert.Null(value.KvpWStrKvpVal.Value.Value); - Assert.Null(value.KvpWObjKvpVal.Value.Value); - Assert.Null(value.KvpWClassKvpVal.Value.Value); - } - [Fact] public static void WriteGenericCollectionWrappers() { diff --git a/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.KeyValuePair.cs b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.KeyValuePair.cs new file mode 100644 index 0000000000000..9e295d5d5188e --- /dev/null +++ b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.KeyValuePair.cs @@ -0,0 +1,283 @@ +// 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. + +using System.Collections.Generic; +using Xunit; + +namespace System.Text.Json.Serialization.Tests +{ + public static partial class CollectionTests + { + [Fact] + public static void ReadSimpleKeyValuePairFail() + { + // Invalid form: no Value + Assert.Throws(() => JsonSerializer.Deserialize>(@"{""Key"": 123}")); + + // Invalid form: extra property + Assert.Throws(() => JsonSerializer.Deserialize>(@"{""Key"": ""Key"", ""Value"": 123, ""Value2"": 456}")); + + // Invalid form: does not contain both Key and Value properties + Assert.Throws(() => JsonSerializer.Deserialize>(@"{""Key"": ""Key"", ""Val"": 123")); + } + + [Fact] + public static void ReadListOfKeyValuePair() + { + List> input = JsonSerializer.Deserialize>>(@"[{""Key"": ""123"", ""Value"": 123},{""Key"": ""456"", ""Value"": 456}]"); + + Assert.Equal(2, input.Count); + Assert.Equal("123", input[0].Key); + Assert.Equal(123, input[0].Value); + Assert.Equal("456", input[1].Key); + Assert.Equal(456, input[1].Value); + } + + [Fact] + public static void ReadKeyValuePairOfList() + { + KeyValuePair> input = JsonSerializer.Deserialize>>(@"{""Key"":""Key"", ""Value"":[1, 2, 3]}"); + + Assert.Equal("Key", input.Key); + Assert.Equal(3, input.Value.Count); + Assert.Equal(1, input.Value[0]); + Assert.Equal(2, input.Value[1]); + Assert.Equal(3, input.Value[2]); + } + + [Theory] + [InlineData(@"{""Key"":""Key"", ""Value"":{""Key"":1, ""Value"":2}}")] + [InlineData(@"{""Key"":""Key"", ""Value"":{""Value"":2, ""Key"":1}}")] + [InlineData(@"{""Value"":{""Key"":1, ""Value"":2}, ""Key"":""Key""}")] + [InlineData(@"{""Value"":{""Value"":2, ""Key"":1}, ""Key"":""Key""}")] + public static void ReadKeyValuePairOfKeyValuePair(string json) + { + KeyValuePair> input = JsonSerializer.Deserialize>>(json); + + Assert.Equal("Key", input.Key); + Assert.Equal(1, input.Value.Key); + Assert.Equal(2, input.Value.Value); + } + + [Fact] + public static void ReadKeyValuePairWithNullValues() + { + { + KeyValuePair kvp = JsonSerializer.Deserialize>(@"{""Key"":""key"",""Value"":null}"); + Assert.Equal("key", kvp.Key); + Assert.Null(kvp.Value); + } + + { + KeyValuePair kvp = JsonSerializer.Deserialize>(@"{""Key"":""key"",""Value"":null}"); + Assert.Equal("key", kvp.Key); + Assert.Null(kvp.Value); + } + + { + KeyValuePair kvp = JsonSerializer.Deserialize>(@"{""Key"":""key"",""Value"":null}"); + Assert.Equal("key", kvp.Key); + Assert.Null(kvp.Value); + } + + { + KeyValuePair> kvp = JsonSerializer.Deserialize>>(@"{""Key"":""key"",""Value"":{""Key"":""key"",""Value"":null}}"); + Assert.Equal("key", kvp.Key); + Assert.Equal("key", kvp.Value.Key); + Assert.Null(kvp.Value.Value); + } + + { + KeyValuePair> kvp = JsonSerializer.Deserialize>>(@"{""Key"":""key"",""Value"":{""Key"":""key"",""Value"":null}}"); + Assert.Equal("key", kvp.Key); + Assert.Equal("key", kvp.Value.Key); + Assert.Null(kvp.Value.Value); + } + + { + KeyValuePair> kvp = JsonSerializer.Deserialize>>(@"{""Key"":""key"",""Value"":{""Key"":""key"",""Value"":null}}"); + Assert.Equal("key", kvp.Key); + Assert.Equal("key", kvp.Value.Key); + Assert.Null(kvp.Value.Value); + } + } + + [Fact] + public static void ReadClassWithNullKeyValuePairValues() + { + string json = + @"{" + + @"""KvpWStrVal"":{" + + @"""Key"":""key""," + + @"""Value"":null" + + @"}," + + @"""KvpWObjVal"":{" + + @"""Key"":""key""," + + @"""Value"":null" + + @"}," + + @"""KvpWClassVal"":{" + + @"""Key"":""key""," + + @"""Value"":null" + + @"}," + + @"""KvpWStrKvpVal"":{" + + @"""Key"":""key""," + + @"""Value"":{" + + @"""Key"":""key""," + + @"""Value"":null" + + @"}" + + @"}," + + @"""KvpWObjKvpVal"":{" + + @"""Key"":""key""," + + @"""Value"":{" + + @"""Key"":""key""," + + @"""Value"":null" + + @"}" + + @"}," + + @"""KvpWClassKvpVal"":{" + + @"""Key"":""key""," + + @"""Value"":{" + + @"""Key"":""key""," + + @"""Value"":null" + + @"}" + + @"}" + + @"}"; + SimpleClassWithKeyValuePairs obj = JsonSerializer.Deserialize(json); + + Assert.Equal("key", obj.KvpWStrVal.Key); + Assert.Equal("key", obj.KvpWObjVal.Key); + Assert.Equal("key", obj.KvpWClassVal.Key); + Assert.Equal("key", obj.KvpWStrKvpVal.Key); + Assert.Equal("key", obj.KvpWObjKvpVal.Key); + Assert.Equal("key", obj.KvpWClassKvpVal.Key); + Assert.Equal("key", obj.KvpWStrKvpVal.Value.Key); + Assert.Equal("key", obj.KvpWObjKvpVal.Value.Key); + Assert.Equal("key", obj.KvpWClassKvpVal.Value.Key); + + Assert.Null(obj.KvpWStrVal.Value); + Assert.Null(obj.KvpWObjVal.Value); + Assert.Null(obj.KvpWClassVal.Value); + Assert.Null(obj.KvpWStrKvpVal.Value.Value); + Assert.Null(obj.KvpWObjKvpVal.Value.Value); + Assert.Null(obj.KvpWClassKvpVal.Value.Value); + } + + [Fact] + public static void Kvp_NullKeyIsFine() + { + KeyValuePair kvp = JsonSerializer.Deserialize>(@"{""Key"":null,""Value"":null}"); + Assert.Null(kvp.Key); + Assert.Null(kvp.Value); + } + + [Fact] + public static void WritePrimitiveKeyValuePair() + { + KeyValuePair input = new KeyValuePair("Key", 123); + + string json = JsonSerializer.Serialize(input); + Assert.Equal(@"{""Key"":""Key"",""Value"":123}", json); + } + + [Fact] + public static void WriteListOfKeyValuePair() + { + List> input = new List> + { + new KeyValuePair("123", 123), + new KeyValuePair("456", 456) + }; + + string json = JsonSerializer.Serialize(input); + Assert.Equal(@"[{""Key"":""123"",""Value"":123},{""Key"":""456"",""Value"":456}]", json); + } + + [Fact] + public static void WriteKeyValuePairOfList() + { + KeyValuePair> input = new KeyValuePair>("Key", new List { 1, 2, 3 }); + + string json = JsonSerializer.Serialize(input); + Assert.Equal(@"{""Key"":""Key"",""Value"":[1,2,3]}", json); + } + + [Fact] + public static void WriteKeyValuePairOfKeyValuePair() + { + KeyValuePair> input = new KeyValuePair>( + "Key", new KeyValuePair("Key", 1)); + + string json = JsonSerializer.Serialize(input); + Assert.Equal(@"{""Key"":""Key"",""Value"":{""Key"":""Key"",""Value"":1}}", json); + } + + [Fact] + public static void WriteKeyValuePairWithNullValues() + { + { + KeyValuePair kvp = new KeyValuePair("key", null); + Assert.Equal(@"{""Key"":""key"",""Value"":null}", JsonSerializer.Serialize(kvp)); + } + + { + KeyValuePair kvp = new KeyValuePair("key", null); + Assert.Equal(@"{""Key"":""key"",""Value"":null}", JsonSerializer.Serialize(kvp)); + } + + { + KeyValuePair kvp = new KeyValuePair("key", null); + Assert.Equal(@"{""Key"":""key"",""Value"":null}", JsonSerializer.Serialize(kvp)); + } + + { + KeyValuePair> kvp = new KeyValuePair>("key", new KeyValuePair("key", null)); + Assert.Equal(@"{""Key"":""key"",""Value"":{""Key"":""key"",""Value"":null}}", JsonSerializer.Serialize(kvp)); + } + + { + KeyValuePair> kvp = new KeyValuePair>("key", new KeyValuePair("key", null)); + Assert.Equal(@"{""Key"":""key"",""Value"":{""Key"":""key"",""Value"":null}}", JsonSerializer.Serialize(kvp)); + } + + { + KeyValuePair> kvp = new KeyValuePair>("key", new KeyValuePair("key", null)); + Assert.Equal(@"{""Key"":""key"",""Value"":{""Key"":""key"",""Value"":null}}", JsonSerializer.Serialize(kvp)); + } + } + + [Fact] + public static void WriteClassWithNullKeyValuePairValues_NullWrittenAsEmptyObject() + { + var value = new SimpleClassWithKeyValuePairs() + { + KvpWStrVal = new KeyValuePair("key", null), + KvpWObjVal = new KeyValuePair("key", null), + KvpWClassVal = new KeyValuePair("key", null), + KvpWStrKvpVal = new KeyValuePair>("key", new KeyValuePair("key", null)), + KvpWObjKvpVal = new KeyValuePair>("key", new KeyValuePair("key", null)), + KvpWClassKvpVal = new KeyValuePair>("key", new KeyValuePair("key", null)), + }; + + string result = JsonSerializer.Serialize(value); + + // Roundtrip to ensure serialize was correct. + value = JsonSerializer.Deserialize(result); + Assert.Equal("key", value.KvpWStrVal.Key); + Assert.Equal("key", value.KvpWObjVal.Key); + Assert.Equal("key", value.KvpWClassVal.Key); + Assert.Equal("key", value.KvpWStrKvpVal.Key); + Assert.Equal("key", value.KvpWObjKvpVal.Key); + Assert.Equal("key", value.KvpWClassKvpVal.Key); + Assert.Equal("key", value.KvpWStrKvpVal.Value.Key); + Assert.Equal("key", value.KvpWObjKvpVal.Value.Key); + Assert.Equal("key", value.KvpWClassKvpVal.Value.Key); + + Assert.Null(value.KvpWStrVal.Value); + Assert.Null(value.KvpWObjVal.Value); + Assert.Null(value.KvpWClassVal.Value); + Assert.Null(value.KvpWStrKvpVal.Value.Value); + Assert.Null(value.KvpWObjKvpVal.Value.Value); + Assert.Null(value.KvpWClassKvpVal.Value.Value); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj index c55cc68b8500d..2693078629bfc 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);$(NetFrameworkCurrent) true @@ -8,8 +8,7 @@ $(DefineConstants);BUILDING_INBOX_LIBRARY - + @@ -45,6 +44,7 @@ + @@ -137,12 +137,10 @@ - + - + From 83e56c474af7127d2909e5d4a11400964abb3ac9 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Wed, 13 May 2020 17:07:11 -0400 Subject: [PATCH 167/420] Update to v3.0.0 of Microsoft.CodeAnalysis.FxCopAnalyzers (#36318) --- eng/Analyzers.props | 2 +- eng/CodeAnalysis.ruleset | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/eng/Analyzers.props b/eng/Analyzers.props index 8d2cb20609f2b..4ed7e3cb9a96d 100644 --- a/eng/Analyzers.props +++ b/eng/Analyzers.props @@ -6,7 +6,7 @@ - + diff --git a/eng/CodeAnalysis.ruleset b/eng/CodeAnalysis.ruleset index cf97025667a2b..bc11bd3b6d58a 100644 --- a/eng/CodeAnalysis.ruleset +++ b/eng/CodeAnalysis.ruleset @@ -4,7 +4,7 @@ - + @@ -210,6 +210,7 @@ + From 6ba94993c7646ee0cee7e821d28271259ba36a16 Mon Sep 17 00:00:00 2001 From: Swaroop Sridhar Date: Wed, 13 May 2020 14:09:18 -0700 Subject: [PATCH 168/420] BundleProbeTest: Enable disabled tests (#36327) A few of the bundle probe tests were failing on Linux-musl-x64-release. This change adjusts the test to circumvent the failure. Fixes #35755 --- .../TestProjects/BundleProbeTester/Program.cs | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/installer/test/Assets/TestProjects/BundleProbeTester/Program.cs b/src/installer/test/Assets/TestProjects/BundleProbeTester/Program.cs index 966f197ef090c..bd98ffe8a7f4d 100644 --- a/src/installer/test/Assets/TestProjects/BundleProbeTester/Program.cs +++ b/src/installer/test/Assets/TestProjects/BundleProbeTester/Program.cs @@ -9,13 +9,17 @@ namespace BundleProbeTester { public static class Program { + // The return type on BundleProbeDelegate is byte instead of bool because + // using non-blitable bool type caused a failure (incorrect value) on linux-musl-x64. + // The bundle-probe callback is only called from native code in the product + // Therefore the type on this test is adjusted to circumvent the failure. [UnmanagedFunctionPointer(CallingConvention.StdCall)] - public delegate bool BundleProbeDelegate([MarshalAs(UnmanagedType.LPWStr)] string path, IntPtr size, IntPtr offset); + public delegate byte BundleProbeDelegate([MarshalAs(UnmanagedType.LPWStr)] string path, IntPtr size, IntPtr offset); unsafe static bool Probe(BundleProbeDelegate bundleProbe, string path, bool isExpected) { Int64 size, offset; - bool exists = bundleProbe(path, (IntPtr)(&offset), (IntPtr)(&size)); + bool exists = bundleProbe(path, (IntPtr)(&offset), (IntPtr)(&size)) != 0; switch (exists, isExpected) { @@ -39,8 +43,6 @@ unsafe static bool Probe(BundleProbeDelegate bundleProbe, string path, bool isEx case (false, false): return true; } - - return false; // dummy } public static int Main(string[] args) @@ -72,13 +74,10 @@ public static int Main(string[] args) bool success = Probe(bundleProbeDelegate, "BundleProbeTester.dll", isExpected: true) && Probe(bundleProbeDelegate, "BundleProbeTester.runtimeconfig.json", isExpected: true) && - Probe(bundleProbeDelegate, "System.Private.CoreLib.dll", isExpected: true); - // The following test is failing on Linux-musl-x64-release. - // The test is temporarily disabled to keep rolling builds green until the bug is fixed. - // https://github.com/dotnet/runtime/issues/35755 - // Probe(bundleProbeDelegate, "hostpolicy.dll", isExpected: false) && - // Probe(bundleProbeDelegate, "--", isExpected: false) && - // Probe(bundleProbeDelegate, "", isExpected: false); + Probe(bundleProbeDelegate, "System.Private.CoreLib.dll", isExpected: true) && + Probe(bundleProbeDelegate, "hostpolicy.dll", isExpected: false) && + Probe(bundleProbeDelegate, "--", isExpected: false) && + Probe(bundleProbeDelegate, "", isExpected: false); if (!success) { From 2f75e690cbdee79108ebc5f765581504025c7430 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Wed, 13 May 2020 14:28:55 -0700 Subject: [PATCH 169/420] Disable System.Diagnostics.Tests.EventLogSourceCreationTests (#36138) * Disable System.Diagnostics.Tests.EventLogSourceCreationTests.CheckSourceExistenceAndDeletion * Fix trait to skip tests in CI * Use ActiveIssue instead --- .../tests/EventLogTests/EventLogSourceCreationTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Diagnostics.EventLog/tests/EventLogTests/EventLogSourceCreationTests.cs b/src/libraries/System.Diagnostics.EventLog/tests/EventLogTests/EventLogSourceCreationTests.cs index 29bfba9dcbe8b..fc2e0f33ce959 100644 --- a/src/libraries/System.Diagnostics.EventLog/tests/EventLogTests/EventLogSourceCreationTests.cs +++ b/src/libraries/System.Diagnostics.EventLog/tests/EventLogTests/EventLogSourceCreationTests.cs @@ -9,7 +9,7 @@ namespace System.Diagnostics.Tests { public class EventLogSourceCreationTests { - [Trait(XunitConstants.Category, "EventLog")] // Unreliable Win32 API call + [ActiveIssue("https://github.com/dotnet/runtime/issues/36135")] [ConditionalFact(typeof(Helpers), nameof(Helpers.IsElevatedAndSupportsEventLogs))] public void CheckSourceExistenceAndDeletion() { @@ -29,7 +29,7 @@ public void CheckSourceExistenceAndDeletion() Assert.False(EventLog.SourceExists(source)); } - [Trait(XunitConstants.Category, "EventLog")] // Unreliable Win32 API call + [ActiveIssue("https://github.com/dotnet/runtime/issues/36135")] [ConditionalFact(typeof(Helpers), nameof(Helpers.IsElevatedAndSupportsEventLogs))] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] public void LogNameWithSame8FirstChars_NetCore() @@ -56,7 +56,7 @@ public void LogNameWithSame8FirstChars_NetCore() } } - [Trait(XunitConstants.Category, "EventLog")] // Unreliable Win32 API call + [ActiveIssue("https://github.com/dotnet/runtime/issues/36135")] [ConditionalFact(typeof(Helpers), nameof(Helpers.IsElevatedAndSupportsEventLogs))] [SkipOnTargetFramework(~TargetFrameworkMonikers.NetFramework)] public void LogNameWithSame8FirstChars_NetFramework() @@ -145,7 +145,7 @@ public void SourceDataNull() Assert.Throws(() => EventLog.CreateEventSource(null)); } - [Trait(XunitConstants.Category, "EventLog")] // Unreliable Win32 API call + [ActiveIssue("https://github.com/dotnet/runtime/issues/36135")] [ConditionalFact(typeof(Helpers), nameof(Helpers.IsElevatedAndSupportsEventLogs))] public void SourceAlreadyExistsWhenCreatingSource() { From 5859dadf20a9dae44624e0a79e48f1b3f1f26a0a Mon Sep 17 00:00:00 2001 From: Adeel Mujahid Date: Thu, 14 May 2020 00:46:33 +0300 Subject: [PATCH 170/420] Add configurations for SunOS in installer (#36316) --- eng/native/configurecompiler.cmake | 2 +- .../JIT/Directed/StructABI/StructABI.csproj | 2 +- src/installer/Directory.Build.props | 18 ++++++++++++++++-- .../projects/netcoreapp/Directory.Build.props | 2 ++ .../pkg/projects/netcoreappRIDs.props | 2 ++ 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index e0301cb6b3fc1..a6e6ba45808d2 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -233,7 +233,7 @@ if (CLR_CMAKE_HOST_UNIX) message("Detected NetBSD amd64") elseif(CLR_CMAKE_HOST_SUNOS) message("Detected SunOS amd64") - endif(CLR_CMAKE_HOST_SUNOS) + endif(CLR_CMAKE_HOST_OSX) endif(CLR_CMAKE_HOST_UNIX) if (CLR_CMAKE_HOST_WIN32) diff --git a/src/coreclr/tests/src/JIT/Directed/StructABI/StructABI.csproj b/src/coreclr/tests/src/JIT/Directed/StructABI/StructABI.csproj index 440413d3e2853..696b406cf0b98 100644 --- a/src/coreclr/tests/src/JIT/Directed/StructABI/StructABI.csproj +++ b/src/coreclr/tests/src/JIT/Directed/StructABI/StructABI.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/installer/Directory.Build.props b/src/installer/Directory.Build.props index 1c6c0fbbeebab..17505ae82a849 100644 --- a/src/installer/Directory.Build.props +++ b/src/installer/Directory.Build.props @@ -86,6 +86,8 @@ osx-$(TargetArchitecture) linux-$(TargetArchitecture) freebsd-$(TargetArchitecture) + netbsd-$(TargetArchitecture) + sunos-$(TargetArchitecture) ios-$(TargetArchitecture) tvos-$(TargetArchitecture) android-$(TargetArchitecture) @@ -128,8 +130,8 @@ false true - - true + + true $(AssetOutputPath)sharedfx_$(OutputRid)_$(Configuration)_version_badge.svg @@ -289,6 +291,18 @@ true + + + true + true + + + + + true + true + + true diff --git a/src/installer/pkg/projects/netcoreapp/Directory.Build.props b/src/installer/pkg/projects/netcoreapp/Directory.Build.props index 32f632cbe656f..59ac9e4269092 100644 --- a/src/installer/pkg/projects/netcoreapp/Directory.Build.props +++ b/src/installer/pkg/projects/netcoreapp/Directory.Build.props @@ -14,6 +14,8 @@ Android Browser FreeBSD + NetBSD + SunOS $(CoreCLRTargetOS) diff --git a/src/installer/pkg/projects/netcoreappRIDs.props b/src/installer/pkg/projects/netcoreappRIDs.props index 7d8711cbccfbb..6826d6cd71c22 100644 --- a/src/installer/pkg/projects/netcoreappRIDs.props +++ b/src/installer/pkg/projects/netcoreappRIDs.props @@ -11,6 +11,8 @@ + + x86 From 2e20457a3eb505f4aa9e713416af31492890c6f8 Mon Sep 17 00:00:00 2001 From: Anirudh Agnihotry Date: Wed, 13 May 2020 15:37:34 -0700 Subject: [PATCH 171/420] Adding sdlConfig file to move policheck out of the build (#36142) * sdlfile * add the variable names --- eng/sdl-tsa-vars.config | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 eng/sdl-tsa-vars.config diff --git a/eng/sdl-tsa-vars.config b/eng/sdl-tsa-vars.config new file mode 100644 index 0000000000000..0b4659a0fe4f7 --- /dev/null +++ b/eng/sdl-tsa-vars.config @@ -0,0 +1,11 @@ +-SourceToolsList @("policheck","credscan") +-TsaInstanceURL https://devdiv.visualstudio.com/ +-TsaProjectName DEVDIV +-TsaNotificationEmail runtimerepo-infra@microsoft.com +-TsaCodebaseAdmin REDMOND\danmose +-TsaBugAreaPath "DevDiv\NET Runtime\Reliability\Docs" +-TsaIterationPath DevDiv +-TsaRepositoryName Runtime +-TsaCodebaseName Runtime +-TsaOnboard $True +-TsaPublish $True \ No newline at end of file From b221687a2556901bfb0e6c1dad006a41fdb732c8 Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Wed, 13 May 2020 16:16:53 -0700 Subject: [PATCH 172/420] Incorrect CALLSITE macro usage. (#36357) --- src/coreclr/src/vm/interoplibinterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/vm/interoplibinterface.cpp b/src/coreclr/src/vm/interoplibinterface.cpp index 94e7402f09533..774953233789f 100644 --- a/src/coreclr/src/vm/interoplibinterface.cpp +++ b/src/coreclr/src/vm/interoplibinterface.cpp @@ -470,7 +470,7 @@ namespace args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(*implPROTECTED); args[ARGNUM_2] = PTR_TO_ARGHOLDER(externalComObject); args[ARGNUM_3] = DWORD_TO_ARGHOLDER(flags); - CALL_MANAGED_METHOD(retObjRef, OBJECTREF, args); + CALL_MANAGED_METHOD_RETREF(retObjRef, OBJECTREF, args); return retObjRef; } From 992470572b92ae0c55709ca2812d21cd2b880a72 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Wed, 13 May 2020 16:51:20 -0700 Subject: [PATCH 173/420] Optimize Vector64 and Vector128.Create methods (#36267) * Updating the Vector64 and Vector128 Create methods to be marked Intrinsic on ARM64 * Updating the JIT to emit constants for Vector64 and Vector128.Create * Fixing lookupNamedIntrinsic and impIntrinsic to throw PNSE for unsupported mustExpand intrinsics * Fixing impIntrinsic to directly use gtNewMustThrowException * Move gtNewMustThrowException to not depend on FEATURE_HW_INTRINSICS * Applying formatting patch * Add basic support for GT_CLS_VAR_ADDR to the ARM64 JIT * Update lookupNamedIntrinsic to handle System.Runtime.Intrinsics for unsupported platforms * Fixing INS_ldr in emitIns_R_C to use isValidVectorLSDatasize * Elaborate on why we specially recognize the HWIntrinsics even on platforms that don't support them --- src/coreclr/src/jit/compiler.h | 11 +- src/coreclr/src/jit/emitarm64.cpp | 13 +- src/coreclr/src/jit/gentree.cpp | 68 +-- src/coreclr/src/jit/hwintrinsic.cpp | 44 -- src/coreclr/src/jit/hwintrinsicarm64.cpp | 41 ++ .../src/jit/hwintrinsiccodegenarm64.cpp | 8 +- src/coreclr/src/jit/hwintrinsiclistarm64.h | 5 +- src/coreclr/src/jit/hwintrinsiclistxarch.h | 4 +- src/coreclr/src/jit/importer.cpp | 113 ++++- src/coreclr/src/jit/lower.h | 133 ++++++ src/coreclr/src/jit/lowerarmarch.cpp | 269 +++++++++++- src/coreclr/src/jit/lowerxarch.cpp | 135 +----- src/coreclr/src/jit/lsraarmarch.cpp | 33 +- src/coreclr/src/jit/namedintrinsiclist.h | 5 +- .../System/Runtime/Intrinsics/Vector128.cs | 150 +------ .../src/System/Runtime/Intrinsics/Vector64.cs | 399 ++++++++++++------ 16 files changed, 898 insertions(+), 533 deletions(-) diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 917dbbb9751a7..a8e6220db3d61 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -2657,7 +2657,6 @@ class Compiler NamedIntrinsic hwIntrinsicID); GenTreeHWIntrinsic* gtNewScalarHWIntrinsicNode( var_types type, GenTree* op1, GenTree* op2, GenTree* op3, NamedIntrinsic hwIntrinsicID); - GenTree* gtNewMustThrowException(unsigned helper, var_types type, CORINFO_CLASS_HANDLE clsHnd); CORINFO_CLASS_HANDLE gtGetStructHandleForHWSIMD(var_types simdType, var_types simdBaseType); var_types getBaseTypeFromArgIfNeeded(NamedIntrinsic intrinsic, CORINFO_CLASS_HANDLE clsHnd, @@ -2665,6 +2664,8 @@ class Compiler var_types baseType); #endif // FEATURE_HW_INTRINSICS + GenTree* gtNewMustThrowException(unsigned helper, var_types type, CORINFO_CLASS_HANDLE clsHnd); + GenTreeLclFld* gtNewLclFldNode(unsigned lnum, var_types type, unsigned offset); GenTree* gtNewInlineCandidateReturnExpr(GenTree* inlineCandidate, var_types type); @@ -3713,6 +3714,10 @@ class Compiler CorInfoIntrinsics intrinsicID, bool tailCall); NamedIntrinsic lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method); + GenTree* impUnsupportedNamedIntrinsic(unsigned helper, + CORINFO_METHOD_HANDLE method, + CORINFO_SIG_INFO* sig, + bool mustExpand); #ifdef FEATURE_HW_INTRINSICS GenTree* impHWIntrinsic(NamedIntrinsic intrinsic, @@ -3720,10 +3725,6 @@ class Compiler CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig, bool mustExpand); - GenTree* impUnsupportedHWIntrinsic(unsigned helper, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand); GenTree* impSimdAsHWIntrinsic(NamedIntrinsic intrinsic, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, diff --git a/src/coreclr/src/jit/emitarm64.cpp b/src/coreclr/src/jit/emitarm64.cpp index 81bca4118a9ff..5780ffbe70be7 100644 --- a/src/coreclr/src/jit/emitarm64.cpp +++ b/src/coreclr/src/jit/emitarm64.cpp @@ -7548,7 +7548,7 @@ void emitter::emitIns_R_C( fmt = IF_LARGELDC; if (isVectorRegister(reg)) { - assert(isValidScalarDatasize(size)); + assert(isValidVectorLSDatasize(size)); // For vector (float/double) register, we should have an integer address reg to // compute long address which consists of page address and page offset. // For integer constant, this is not needed since the dest reg can be used to @@ -7561,6 +7561,7 @@ void emitter::emitIns_R_C( assert(isValidGeneralDatasize(size)); } break; + default: unreached(); } @@ -12718,7 +12719,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR if (addr->isContained()) { - assert(addr->OperGet() == GT_LCL_VAR_ADDR || addr->OperGet() == GT_LEA); + assert(addr->OperGet() == GT_CLS_VAR_ADDR || addr->OperGet() == GT_LCL_VAR_ADDR || addr->OperGet() == GT_LEA); int offset = 0; DWORD lsl = 0; @@ -12795,7 +12796,13 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR } else // no Index register { - if (emitIns_valid_imm_for_ldst_offset(offset, emitTypeSize(indir->TypeGet()))) + if (addr->OperGet() == GT_CLS_VAR_ADDR) + { + // Get a temp integer register to compute long address. + regNumber addrReg = indir->GetSingleTempReg(); + emitIns_R_C(ins, attr, dataReg, addrReg, addr->AsClsVar()->gtClsVarHnd, 0); + } + else if (emitIns_valid_imm_for_ldst_offset(offset, emitTypeSize(indir->TypeGet()))) { // Then load/store dataReg from/to [memBase + offset] emitIns_R_R_I(ins, attr, dataReg, memBase->GetRegNum(), offset); diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index 8e341ce7dab5a..afeb708a2725b 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -18659,40 +18659,6 @@ GenTreeHWIntrinsic* Compiler::gtNewScalarHWIntrinsicNode( GenTreeHWIntrinsic(type, gtNewArgList(op1, op2, op3), hwIntrinsicID, TYP_UNKNOWN, 0); } -//--------------------------------------------------------------------------------------- -// gtNewMustThrowException: -// create a throw node (calling into JIT helper) that must be thrown. -// The result would be a comma node: COMMA(jithelperthrow(void), x) where x's type should be specified. -// -// Arguments -// helper - JIT helper ID -// type - return type of the node -// -// Return Value -// pointer to the throw node -// -GenTree* Compiler::gtNewMustThrowException(unsigned helper, var_types type, CORINFO_CLASS_HANDLE clsHnd) -{ - GenTreeCall* node = gtNewHelperCallNode(helper, TYP_VOID); - node->gtCallMoreFlags |= GTF_CALL_M_DOES_NOT_RETURN; - if (type != TYP_VOID) - { - unsigned dummyTemp = lvaGrabTemp(true DEBUGARG("dummy temp of must thrown exception")); - if (type == TYP_STRUCT) - { - lvaSetStruct(dummyTemp, clsHnd, false); - type = lvaTable[dummyTemp].lvType; // struct type is normalized - } - else - { - lvaTable[dummyTemp].lvType = type; - } - GenTree* dummyNode = gtNewLclvNode(dummyTemp, type); - return gtNewOperNode(GT_COMMA, type, node, dummyNode); - } - return node; -} - // Returns true for the HW Instrinsic instructions that have MemoryLoad semantics, false otherwise bool GenTreeHWIntrinsic::OperIsMemoryLoad() const { @@ -18782,6 +18748,40 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoadOrStore() const #endif // FEATURE_HW_INTRINSICS +//--------------------------------------------------------------------------------------- +// gtNewMustThrowException: +// create a throw node (calling into JIT helper) that must be thrown. +// The result would be a comma node: COMMA(jithelperthrow(void), x) where x's type should be specified. +// +// Arguments +// helper - JIT helper ID +// type - return type of the node +// +// Return Value +// pointer to the throw node +// +GenTree* Compiler::gtNewMustThrowException(unsigned helper, var_types type, CORINFO_CLASS_HANDLE clsHnd) +{ + GenTreeCall* node = gtNewHelperCallNode(helper, TYP_VOID); + node->gtCallMoreFlags |= GTF_CALL_M_DOES_NOT_RETURN; + if (type != TYP_VOID) + { + unsigned dummyTemp = lvaGrabTemp(true DEBUGARG("dummy temp of must thrown exception")); + if (type == TYP_STRUCT) + { + lvaSetStruct(dummyTemp, clsHnd, false); + type = lvaTable[dummyTemp].lvType; // struct type is normalized + } + else + { + lvaTable[dummyTemp].lvType = type; + } + GenTree* dummyNode = gtNewLclvNode(dummyTemp, type); + return gtNewOperNode(GT_COMMA, type, node, dummyNode); + } + return node; +} + //--------------------------------------------------------------------------------------- // InitializeStructReturnType: // Initialize the Return Type Descriptor for a method that returns a struct type diff --git a/src/coreclr/src/jit/hwintrinsic.cpp b/src/coreclr/src/jit/hwintrinsic.cpp index 8f33c4851771b..e0e835043dd39 100644 --- a/src/coreclr/src/jit/hwintrinsic.cpp +++ b/src/coreclr/src/jit/hwintrinsic.cpp @@ -89,50 +89,6 @@ var_types Compiler::getBaseTypeFromArgIfNeeded(NamedIntrinsic intrinsic, return baseType; } -//------------------------------------------------------------------------ -// impUnsupportedHWIntrinsic: returns a node for an unsupported HWIntrinsic -// -// Arguments: -// helper - JIT helper ID for the exception to be thrown -// method - method handle of the intrinsic function. -// sig - signature of the intrinsic call -// mustExpand - true if the intrinsic must return a GenTree*; otherwise, false -// -// Return Value: -// a gtNewMustThrowException if mustExpand is true; otherwise, nullptr -// -GenTree* Compiler::impUnsupportedHWIntrinsic(unsigned helper, - CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig, - bool mustExpand) -{ - // We've hit some error case and may need to return a node for the given error. - // - // When `mustExpand=false`, we are attempting to inline the intrinsic directly into another method. In this - // scenario, we need to return `nullptr` so that a GT_CALL to the intrinsic is emitted instead. This is to - // ensure that everything continues to behave correctly when optimizations are enabled (e.g. things like the - // inliner may expect the node we return to have a certain signature, and the `MustThrowException` node won't - // match that). - // - // When `mustExpand=true`, we are in a GT_CALL to the intrinsic and are attempting to JIT it. This will generally - // be in response to an indirect call (e.g. done via reflection) or in response to an earlier attempt returning - // `nullptr` (under `mustExpand=false`). In that scenario, we are safe to return the `MustThrowException` node. - - if (mustExpand) - { - for (unsigned i = 0; i < sig->numArgs; i++) - { - impPopStack(); - } - - return gtNewMustThrowException(helper, JITtype2varType(sig->retType), sig->retTypeClass); - } - else - { - return nullptr; - } -} - CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleForHWSIMD(var_types simdType, var_types simdBaseType) { if (simdType == TYP_SIMD16) diff --git a/src/coreclr/src/jit/hwintrinsicarm64.cpp b/src/coreclr/src/jit/hwintrinsicarm64.cpp index 45efb8a68a58b..7127b69e850d1 100644 --- a/src/coreclr/src/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/src/jit/hwintrinsicarm64.cpp @@ -357,6 +357,47 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(retNode->gtType == getSIMDTypeForSize(getSIMDTypeSizeInBytes(sig->retTypeSigClass))); break; } + + case NI_Vector64_Create: + case NI_Vector128_Create: + { + // We shouldn't handle this as an intrinsic if the + // respective ISAs have been disabled by the user. + + if (!compExactlyDependsOn(InstructionSet_AdvSimd)) + { + break; + } + + if (sig->numArgs == 1) + { + op1 = impPopStack().val; + retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, baseType, simdSize); + } + else if (sig->numArgs == 2) + { + op2 = impPopStack().val; + op1 = impPopStack().val; + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, intrinsic, baseType, simdSize); + } + else + { + assert(sig->numArgs >= 3); + + GenTreeArgList* tmp = nullptr; + + for (unsigned i = 0; i < sig->numArgs; i++) + { + tmp = gtNewArgList(impPopStack().val); + tmp->gtOp2 = op1; + op1 = tmp; + } + + retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, baseType, simdSize); + } + break; + } + case NI_Vector64_get_Count: case NI_Vector128_get_Count: { diff --git a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp index 71ac68f759ce8..7aca22290f00d 100644 --- a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp @@ -583,10 +583,9 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GetEmitter()->emitIns_R_I(ins, emitSize, targetReg, 0, INS_OPTS_4S); break; - case NI_Vector64_Create: - case NI_Vector128_Create: case NI_AdvSimd_DuplicateToVector64: case NI_AdvSimd_DuplicateToVector128: + case NI_AdvSimd_Arm64_DuplicateToVector64: case NI_AdvSimd_Arm64_DuplicateToVector128: { if (varTypeIsFloating(intrin.baseType)) @@ -596,6 +595,11 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) const double dataValue = intrin.op1->AsDblCon()->gtDconVal; GetEmitter()->emitIns_R_F(INS_fmov, emitSize, targetReg, dataValue, opt); } + else if (intrin.id == NI_AdvSimd_Arm64_DuplicateToVector64) + { + assert(intrin.baseType == TYP_DOUBLE); + GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg, opt); + } else { GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, op1Reg, 0, opt); diff --git a/src/coreclr/src/jit/hwintrinsiclistarm64.h b/src/coreclr/src/jit/hwintrinsiclistarm64.h index f798a17d26e42..0ca6f8d918abc 100644 --- a/src/coreclr/src/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/src/jit/hwintrinsiclistarm64.h @@ -23,7 +23,7 @@ HARDWARE_INTRINSIC(Vector64, AsSByte, HARDWARE_INTRINSIC(Vector64, AsSingle, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector64, AsUInt16, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector64, AsUInt32, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector64, Create, 8, 1, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_mov, INS_mov, INS_dup, INS_dup}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector64, Create, 8, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mov, INS_mov, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector64, CreateScalarUnsafe, 8, 1, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_invalid, INS_invalid, INS_fmov, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector64, get_AllBitsSet, 8, 0, {INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector64, get_Count, 8, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) @@ -45,7 +45,7 @@ HARDWARE_INTRINSIC(Vector128, AsSingle, 1 HARDWARE_INTRINSIC(Vector128, AsUInt16, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, AsUInt32, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, AsUInt64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, Create, 16, 1, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector128, Create, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, CreateScalarUnsafe, 16, 1, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_fmov, INS_fmov}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, 16, 0, {INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector128, get_Count, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) @@ -197,6 +197,7 @@ HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareTest, 1 HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareTestScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmtst, INS_cmtst, INS_invalid, INS_cmtst}, HW_Category_SIMDScalar, HW_Flag_Commutative) HARDWARE_INTRINSIC(AdvSimd_Arm64, Divide, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fdiv, INS_fdiv}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd_Arm64, DuplicateSelectedScalarToVector128, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_dup, INS_dup, INS_invalid, INS_dup}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, DuplicateToVector64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mov, INS_mov, INS_invalid, INS_fmov}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AdvSimd_Arm64, DuplicateToVector128, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_dup, INS_dup, INS_invalid, INS_dup}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AdvSimd_Arm64, FusedMultiplyAdd, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmla}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(AdvSimd_Arm64, FusedMultiplySubtract, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmls}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) diff --git a/src/coreclr/src/jit/hwintrinsiclistxarch.h b/src/coreclr/src/jit/hwintrinsiclistxarch.h index db2bacbbb6457..c041364c966bf 100644 --- a/src/coreclr/src/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/src/jit/hwintrinsiclistxarch.h @@ -43,7 +43,7 @@ HARDWARE_INTRINSIC(Vector128, AsVector2, HARDWARE_INTRINSIC(Vector128, AsVector3, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector128, AsVector4, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector128, AsVector128, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) -HARDWARE_INTRINSIC(Vector128, Create, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(Vector128, Create, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, CreateScalarUnsafe, 16, 1, {INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_movss, INS_movsdsse2}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) // The instruction generated for float/double depends on which ISAs are supported HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, 16, 0, {INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_cmpps, INS_cmppd}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics) @@ -77,7 +77,7 @@ HARDWARE_INTRINSIC(Vector256, AsVector256, HARDWARE_INTRINSIC(Vector256, get_AllBitsSet, 32, 0, {INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_cmpps, INS_cmppd}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector256, get_Count, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector256, get_Zero, 32, 0, {INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics) -HARDWARE_INTRINSIC(Vector256, Create, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(Vector256, Create, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector256, CreateScalarUnsafe, 32, 1, {INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_movss, INS_movsdsse2}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector256, GetElement, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector256, WithElement, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg) diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 52501b346e928..014e42a1293d7 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -3478,29 +3478,34 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, { ni = lookupNamedIntrinsic(method); -#ifdef FEATURE_HW_INTRINSICS + // We specially support the following on all platforms to allow for dead + // code optimization and to more generally support recursive intrinsics. + if (ni == NI_IsSupported_True) { + assert(sig->numArgs == 0); return gtNewIconNode(true); } if (ni == NI_IsSupported_False) { + assert(sig->numArgs == 0); return gtNewIconNode(false); } if (ni == NI_Throw_PlatformNotSupportedException) { - return impUnsupportedHWIntrinsic(CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED, method, sig, mustExpand); + return impUnsupportedNamedIntrinsic(CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED, method, sig, mustExpand); } +#ifdef FEATURE_HW_INTRINSICS if ((ni > NI_HW_INTRINSIC_START) && (ni < NI_HW_INTRINSIC_END)) { GenTree* hwintrinsic = impHWIntrinsic(ni, clsHnd, method, sig, mustExpand); if (mustExpand && (hwintrinsic == nullptr)) { - return impUnsupportedHWIntrinsic(CORINFO_HELP_THROW_NOT_IMPLEMENTED, method, sig, mustExpand); + return impUnsupportedNamedIntrinsic(CORINFO_HELP_THROW_NOT_IMPLEMENTED, method, sig, mustExpand); } return hwintrinsic; @@ -4272,7 +4277,8 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, if (mustExpand && (retNode == nullptr)) { - NO_WAY("JIT must expand the intrinsic!"); + assert(!"Unhandled must expand intrinsic, throwing PlatformNotSupportedException"); + return impUnsupportedNamedIntrinsic(CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED, method, sig, mustExpand); } // Optionally report if this intrinsic is special @@ -4489,8 +4495,30 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) result = SimdAsHWIntrinsicInfo::lookupId(&sig, className, methodName, enclosingClassName, sizeOfVectorT); } +#endif // FEATURE_HW_INTRINSICS else if (strncmp(namespaceName, "System.Runtime.Intrinsics", 25) == 0) { + // We go down this path even when FEATURE_HW_INTRINSICS isn't enabled + // so we can specially handle IsSupported and recursive calls. + + // This is required to appropriately handle the intrinsics on platforms + // which don't support them. On such a platform methods like Vector64.Create + // will be seen as `Intrinsic` and `mustExpand` due to having a code path + // which is recursive. When such a path is hit we expect it to be handled by + // the importer and we fire an assert if it wasn't and in previous versions + // of the JIT would fail fast. This was changed to throw a PNSE instead but + // we still assert as most intrinsics should have been recognized/handled. + + // In order to avoid the assert, we specially handle the IsSupported checks + // (to better allow dead-code optimizations) and we explicitly throw a PNSE + // as we know that is the desired behavior for the HWIntrinsics when not + // supported. For cases like Vector64.Create, this is fine because it will + // be behind a relevant IsSupported check and will never be hit and the + // software fallback will be executed instead. + + CLANG_FORMAT_COMMENT_ANCHOR; + +#ifdef FEATURE_HW_INTRINSICS namespaceName += 25; const char* platformNamespaceName; @@ -4509,21 +4537,40 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) result = HWIntrinsicInfo::lookupId(this, &sig, className, methodName, enclosingClassName); } - else if (strcmp(methodName, "get_IsSupported") == 0) - { - return NI_IsSupported_False; - } - else +#endif // FEATURE_HW_INTRINSICS + + if (result == NI_Illegal) { - return gtIsRecursiveCall(method) ? NI_Throw_PlatformNotSupportedException : NI_Illegal; + if (strcmp(methodName, "get_IsSupported") == 0) + { + // This allows the relevant code paths to be dropped as dead code even + // on platforms where FEATURE_HW_INTRINSICS is not supported. + + result = NI_IsSupported_False; + } + else if (gtIsRecursiveCall(method)) + { + // For the framework itself, any recursive intrinsics will either be + // only supported on a single platform or will be guarded by a relevant + // IsSupported check so the throw PNSE will be valid or dropped. + + result = NI_Throw_PlatformNotSupportedException; + } } } -#endif // FEATURE_HW_INTRINSICS if (result == NI_Illegal) { JITDUMP("Not recognized\n"); } + else if (result == NI_IsSupported_False) + { + JITDUMP("Unsupported - return false"); + } + else if (result == NI_Throw_PlatformNotSupportedException) + { + JITDUMP("Unsupported - throw PlatformNotSupportedException"); + } else { JITDUMP("Recognized\n"); @@ -4531,6 +4578,50 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) return result; } +//------------------------------------------------------------------------ +// impUnsupportedNamedIntrinsic: Throws an exception for an unsupported named intrinsic +// +// Arguments: +// helper - JIT helper ID for the exception to be thrown +// method - method handle of the intrinsic function. +// sig - signature of the intrinsic call +// mustExpand - true if the intrinsic must return a GenTree*; otherwise, false +// +// Return Value: +// a gtNewMustThrowException if mustExpand is true; otherwise, nullptr +// +GenTree* Compiler::impUnsupportedNamedIntrinsic(unsigned helper, + CORINFO_METHOD_HANDLE method, + CORINFO_SIG_INFO* sig, + bool mustExpand) +{ + // We've hit some error case and may need to return a node for the given error. + // + // When `mustExpand=false`, we are attempting to inline the intrinsic directly into another method. In this + // scenario, we need to return `nullptr` so that a GT_CALL to the intrinsic is emitted instead. This is to + // ensure that everything continues to behave correctly when optimizations are enabled (e.g. things like the + // inliner may expect the node we return to have a certain signature, and the `MustThrowException` node won't + // match that). + // + // When `mustExpand=true`, we are in a GT_CALL to the intrinsic and are attempting to JIT it. This will generally + // be in response to an indirect call (e.g. done via reflection) or in response to an earlier attempt returning + // `nullptr` (under `mustExpand=false`). In that scenario, we are safe to return the `MustThrowException` node. + + if (mustExpand) + { + for (unsigned i = 0; i < sig->numArgs; i++) + { + impPopStack(); + } + + return gtNewMustThrowException(helper, JITtype2varType(sig->retType), sig->retTypeClass); + } + else + { + return nullptr; + } +} + /*****************************************************************************/ GenTree* Compiler::impArrayAccessIntrinsic( diff --git a/src/coreclr/src/jit/lower.h b/src/coreclr/src/jit/lower.h index 2fa26918e30f4..ae19cd29c3c3b 100644 --- a/src/coreclr/src/jit/lower.h +++ b/src/coreclr/src/jit/lower.h @@ -317,6 +317,139 @@ class Lowering final : public Phase void LowerHWIntrinsicCC(GenTreeHWIntrinsic* node, NamedIntrinsic newIntrinsicId, GenCondition condition); void LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node); void LowerFusedMultiplyAdd(GenTreeHWIntrinsic* node); + + union VectorConstant { + int8_t i8[32]; + uint8_t u8[32]; + int16_t i16[16]; + uint16_t u16[16]; + int32_t i32[8]; + uint32_t u32[8]; + int64_t i64[4]; + uint64_t u64[4]; + float f32[8]; + double f64[4]; + }; + + //---------------------------------------------------------------------------------------------- + // ProcessArgForHWIntrinsicCreate: Processes an argument for the Lowering::LowerHWIntrinsicCreate method + // + // Arguments: + // arg - The argument to process + // argIdx - The index of the argument being processed + // vecCns - The vector constant being constructed + // baseType - The base type of the vector constant + // + // Returns: + // true if arg was a constant; otherwise, false + static bool HandleArgForHWIntrinsicCreate(GenTree* arg, int argIdx, VectorConstant& vecCns, var_types baseType) + { + switch (baseType) + { + case TYP_BYTE: + case TYP_UBYTE: + { + if (arg->IsCnsIntOrI()) + { + vecCns.i8[argIdx] = static_cast(arg->AsIntCon()->gtIconVal); + return true; + } + else + { + // We expect the VectorConstant to have been already zeroed + assert(vecCns.i8[argIdx] == 0); + } + break; + } + + case TYP_SHORT: + case TYP_USHORT: + { + if (arg->IsCnsIntOrI()) + { + vecCns.i16[argIdx] = static_cast(arg->AsIntCon()->gtIconVal); + return true; + } + else + { + // We expect the VectorConstant to have been already zeroed + assert(vecCns.i16[argIdx] == 0); + } + break; + } + + case TYP_INT: + case TYP_UINT: + { + if (arg->IsCnsIntOrI()) + { + vecCns.i32[argIdx] = static_cast(arg->AsIntCon()->gtIconVal); + return true; + } + else + { + // We expect the VectorConstant to have been already zeroed + assert(vecCns.i32[argIdx] == 0); + } + break; + } + + case TYP_LONG: + case TYP_ULONG: + { + if (arg->OperIs(GT_CNS_LNG)) + { + vecCns.i64[argIdx] = static_cast(arg->AsLngCon()->gtLconVal); + return true; + } + else + { + // We expect the VectorConstant to have been already zeroed + assert(vecCns.i64[argIdx] == 0); + } + break; + } + + case TYP_FLOAT: + { + if (arg->IsCnsFltOrDbl()) + { + vecCns.f32[argIdx] = static_cast(arg->AsDblCon()->gtDconVal); + return true; + } + else + { + // We expect the VectorConstant to have been already zeroed + // We check against the i32, rather than f32, to account for -0.0 + assert(vecCns.i32[argIdx] == 0); + } + break; + } + + case TYP_DOUBLE: + { + if (arg->IsCnsFltOrDbl()) + { + vecCns.f64[argIdx] = static_cast(arg->AsDblCon()->gtDconVal); + return true; + } + else + { + // We expect the VectorConstant to have been already zeroed + // We check against the i64, rather than f64, to account for -0.0 + assert(vecCns.i64[argIdx] == 0); + } + break; + } + + default: + { + unreached(); + } + } + + return false; + } #endif // FEATURE_HW_INTRINSICS // Utility functions diff --git a/src/coreclr/src/jit/lowerarmarch.cpp b/src/coreclr/src/jit/lowerarmarch.cpp index 7b7706e9b1caa..d5272abb25c99 100644 --- a/src/coreclr/src/jit/lowerarmarch.cpp +++ b/src/coreclr/src/jit/lowerarmarch.cpp @@ -535,8 +535,255 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) node->gtType = TYP_SIMD16; } + NamedIntrinsic intrinsicId = node->gtHWIntrinsicId; + + switch (intrinsicId) + { + case NI_Vector64_Create: + case NI_Vector128_Create: + { + // We don't directly support the Vector64.Create or Vector128.Create methods in codegen + // and instead lower them to other intrinsic nodes in LowerHWIntrinsicCreate so we expect + // that the node is modified to either not be a HWIntrinsic node or that it is no longer + // the same intrinsic as when it came in. + + LowerHWIntrinsicCreate(node); + assert(!node->OperIsHWIntrinsic() || (node->gtHWIntrinsicId != intrinsicId)); + LowerNode(node); + return; + } + + default: + break; + } + ContainCheckHWIntrinsic(node); } + +//---------------------------------------------------------------------------------------------- +// Lowering::LowerHWIntrinsicCreate: Lowers a Vector64 or Vector128 Create call +// +// Arguments: +// node - The hardware intrinsic node. +// +void Lowering::LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node) +{ + NamedIntrinsic intrinsicId = node->gtHWIntrinsicId; + var_types simdType = node->gtType; + var_types baseType = node->gtSIMDBaseType; + unsigned simdSize = node->gtSIMDSize; + VectorConstant vecCns = {}; + + if ((simdSize == 8) && (simdType == TYP_DOUBLE)) + { + simdType = TYP_SIMD8; + } + + assert(varTypeIsSIMD(simdType)); + assert(varTypeIsArithmetic(baseType)); + assert(simdSize != 0); + + GenTreeArgList* argList = nullptr; + GenTree* op1 = node->gtGetOp1(); + GenTree* op2 = node->gtGetOp2(); + + // Spare GenTrees to be used for the lowering logic below + // Defined upfront to avoid naming conflicts, etc... + GenTree* idx = nullptr; + GenTree* tmp1 = nullptr; + GenTree* tmp2 = nullptr; + GenTree* tmp3 = nullptr; + + assert(op1 != nullptr); + + unsigned argCnt = 0; + unsigned cnsArgCnt = 0; + + if (op1->OperIsList()) + { + assert(op2 == nullptr); + + for (argList = op1->AsArgList(); argList != nullptr; argList = argList->Rest()) + { + if (HandleArgForHWIntrinsicCreate(argList->Current(), argCnt, vecCns, baseType)) + { + cnsArgCnt += 1; + } + argCnt += 1; + } + } + else + { + if (HandleArgForHWIntrinsicCreate(op1, argCnt, vecCns, baseType)) + { + cnsArgCnt += 1; + } + argCnt += 1; + + if (op2 != nullptr) + { + if (HandleArgForHWIntrinsicCreate(op2, argCnt, vecCns, baseType)) + { + cnsArgCnt += 1; + } + argCnt += 1; + } + else if (cnsArgCnt == 1) + { + // These intrinsics are meant to set the same value to every element + // so we'll just specially handle it here and copy it into the remaining + // indices. + + for (unsigned i = 1; i < simdSize / genTypeSize(baseType); i++) + { + HandleArgForHWIntrinsicCreate(op1, i, vecCns, baseType); + } + } + } + assert((argCnt == 1) || (argCnt == (simdSize / genTypeSize(baseType)))); + + if (argCnt == cnsArgCnt) + { + if (op1->OperIsList()) + { + for (argList = op1->AsArgList(); argList != nullptr; argList = argList->Rest()) + { + BlockRange().Remove(argList->Current()); + } + } + else + { + BlockRange().Remove(op1); + + if (op2 != nullptr) + { + BlockRange().Remove(op2); + } + } + + CORINFO_FIELD_HANDLE hnd = comp->GetEmitter()->emitAnyConst(&vecCns, simdSize, emitDataAlignment::Required); + GenTree* clsVarAddr = new (comp, GT_CLS_VAR_ADDR) GenTreeClsVar(GT_CLS_VAR_ADDR, TYP_I_IMPL, hnd, nullptr); + BlockRange().InsertBefore(node, clsVarAddr); + + node->ChangeOper(GT_IND); + node->gtOp1 = clsVarAddr; + + // TODO-ARM64-CQ: We should be able to modify at least the paths that use Insert to trivially support partial + // vector constants. With this, we can create a constant if say 50% of the inputs are also constant and just + // insert the non-constant values which should still allow some gains. + + return; + } + else if (argCnt == 1) + { + // We have the following (where simd is simd8 or simd16): + // /--* op1 T + // node = * HWINTRINSIC simd T Create + + // We will be constructing the following parts: + // /--* op1 T + // node = * HWINTRINSIC simd T DuplicateToVector + + // This is roughly the following managed code: + // return AdvSimd.Arm64.DuplicateToVector(op1); + + if (varTypeIsLong(baseType) || (baseType == TYP_DOUBLE)) + { + node->gtHWIntrinsicId = + (simdType == TYP_SIMD8) ? NI_AdvSimd_Arm64_DuplicateToVector64 : NI_AdvSimd_Arm64_DuplicateToVector128; + } + else + { + node->gtHWIntrinsicId = + (simdType == TYP_SIMD8) ? NI_AdvSimd_DuplicateToVector64 : NI_AdvSimd_DuplicateToVector128; + } + return; + } + + // We have the following (where simd is simd8 or simd16): + // /--* op1 T + // +--* ... T + // +--* opN T + // node = * HWINTRINSIC simd T Create + + if (op1->OperIsList()) + { + argList = op1->AsArgList(); + op1 = argList->Current(); + argList = argList->Rest(); + } + + // We will be constructing the following parts: + // /--* op1 T + // tmp1 = * HWINTRINSIC simd8 T CreateScalarUnsafe + // ... + + // This is roughly the following managed code: + // var tmp1 = Vector64.CreateScalarUnsafe(op1); + // ... + + NamedIntrinsic createScalarUnsafe = + (simdType == TYP_SIMD8) ? NI_Vector64_CreateScalarUnsafe : NI_Vector128_CreateScalarUnsafe; + + tmp1 = comp->gtNewSimdHWIntrinsicNode(simdType, op1, createScalarUnsafe, baseType, simdSize); + BlockRange().InsertAfter(op1, tmp1); + LowerNode(tmp1); + + unsigned N = 0; + GenTree* opN = nullptr; + + for (N = 1; N < argCnt - 1; N++) + { + // We will be constructing the following parts: + // ... + // idx = CNS_INT int N + // /--* tmp1 simd + // +--* idx int + // +--* opN T + // tmp1 = * HWINTRINSIC simd T Insert + // ... + + // This is roughly the following managed code: + // ... + // tmp1 = AdvSimd.Insert(tmp1, N, opN); + // ... + + opN = argList->Current(); + + idx = comp->gtNewIconNode(N, TYP_INT); + BlockRange().InsertBefore(opN, idx); + + tmp1 = comp->gtNewSimdHWIntrinsicNode(simdType, tmp1, idx, opN, NI_AdvSimd_Insert, baseType, simdSize); + BlockRange().InsertAfter(opN, tmp1); + LowerNode(tmp1); + + argList = argList->Rest(); + } + + assert(N == (argCnt - 1)); + + // We will be constructing the following parts: + // idx = CNS_INT int N + // /--* tmp1 simd + // +--* idx int + // +--* opN T + // node = * HWINTRINSIC simd T Insert + + // This is roughly the following managed code: + // ... + // tmp1 = AdvSimd.Insert(tmp1, N, opN); + // ... + + opN = (argCnt == 2) ? op2 : argList->Current(); + + idx = comp->gtNewIconNode(N, TYP_INT); + BlockRange().InsertBefore(opN, idx); + + node->gtOp1 = comp->gtNewArgList(tmp1, idx, opN); + node->gtOp2 = nullptr; + + node->gtHWIntrinsicId = NI_AdvSimd_Insert; +} #endif // FEATURE_HW_INTRINSICS //------------------------------------------------------------------------ @@ -610,10 +857,12 @@ void Lowering::ContainCheckIndir(GenTreeIndir* indirNode) } #endif // FEATURE_SIMD - GenTree* addr = indirNode->Addr(); - bool makeContained = true; + GenTree* addr = indirNode->Addr(); + if ((addr->OperGet() == GT_LEA) && IsSafeToContainMem(indirNode, addr)) { + bool makeContained = true; + #ifdef TARGET_ARM // ARM floating-point load/store doesn't support a form similar to integer // ldr Rdst, [Rbase + Roffset] with offset in a register. The only supported @@ -637,12 +886,23 @@ void Lowering::ContainCheckIndir(GenTreeIndir* indirNode) } } } -#endif +#endif // TARGET_ARM + if (makeContained) { MakeSrcContained(indirNode, addr); } } +#ifdef TARGET_ARM64 + else if (addr->OperGet() == GT_CLS_VAR_ADDR) + { + // These nodes go into an addr mode: + // - GT_CLS_VAR_ADDR turns into a constant. + + // make this contained, it turns into a constant that goes into an addr mode + MakeSrcContained(indirNode, addr); + } +#endif // TARGET_ARM64 } //------------------------------------------------------------------------ @@ -933,12 +1193,11 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) } break; - case NI_Vector64_Create: - case NI_Vector128_Create: case NI_Vector64_CreateScalarUnsafe: case NI_Vector128_CreateScalarUnsafe: case NI_AdvSimd_DuplicateToVector64: case NI_AdvSimd_DuplicateToVector128: + case NI_AdvSimd_Arm64_DuplicateToVector64: case NI_AdvSimd_Arm64_DuplicateToVector128: if (intrin.op1->IsCnsIntOrI()) { diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index 14672d16aaaac..f2a66d1166f76 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -1100,141 +1100,8 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) ContainCheckHWIntrinsic(node); } -union VectorConstant { - int8_t i8[32]; - uint8_t u8[32]; - int16_t i16[16]; - uint16_t u16[16]; - int32_t i32[8]; - uint32_t u32[8]; - int64_t i64[4]; - uint64_t u64[4]; - float f32[8]; - double f64[4]; -}; - -//---------------------------------------------------------------------------------------------- -// ProcessArgForHWIntrinsicCreate: Processes an argument for the Lowering::LowerHWIntrinsicCreate method -// -// Arguments: -// arg - The argument to process -// argIdx - The index of the argument being processed -// vecCns - The vector constant being constructed -// baseType - The base type of the vector constant -// -// Returns: -// true if arg was a constant; otherwise, false -static bool HandleArgForHWIntrinsicCreate(GenTree* arg, int argIdx, VectorConstant& vecCns, var_types baseType) -{ - switch (baseType) - { - case TYP_BYTE: - case TYP_UBYTE: - { - if (arg->IsCnsIntOrI()) - { - vecCns.i8[argIdx] = static_cast(arg->AsIntCon()->gtIconVal); - return true; - } - else - { - // We expect the VectorConstant to have been already zeroed - assert(vecCns.i8[argIdx] == 0); - } - break; - } - - case TYP_SHORT: - case TYP_USHORT: - { - if (arg->IsCnsIntOrI()) - { - vecCns.i16[argIdx] = static_cast(arg->AsIntCon()->gtIconVal); - return true; - } - else - { - // We expect the VectorConstant to have been already zeroed - assert(vecCns.i16[argIdx] == 0); - } - break; - } - - case TYP_INT: - case TYP_UINT: - { - if (arg->IsCnsIntOrI()) - { - vecCns.i32[argIdx] = static_cast(arg->AsIntCon()->gtIconVal); - return true; - } - else - { - // We expect the VectorConstant to have been already zeroed - assert(vecCns.i32[argIdx] == 0); - } - break; - } - - case TYP_LONG: - case TYP_ULONG: - { - if (arg->OperIs(GT_CNS_LNG)) - { - vecCns.i64[argIdx] = static_cast(arg->AsLngCon()->gtLconVal); - return true; - } - else - { - // We expect the VectorConstant to have been already zeroed - assert(vecCns.i64[argIdx] == 0); - } - break; - } - - case TYP_FLOAT: - { - if (arg->IsCnsFltOrDbl()) - { - vecCns.f32[argIdx] = static_cast(arg->AsDblCon()->gtDconVal); - return true; - } - else - { - // We expect the VectorConstant to have been already zeroed - // We check against the i32, rather than f32, to account for -0.0 - assert(vecCns.i32[argIdx] == 0); - } - break; - } - - case TYP_DOUBLE: - { - if (arg->IsCnsFltOrDbl()) - { - vecCns.f64[argIdx] = static_cast(arg->AsDblCon()->gtDconVal); - return true; - } - else - { - // We expect the VectorConstant to have been already zeroed - // We check against the i64, rather than f64, to account for -0.0 - assert(vecCns.i64[argIdx] == 0); - } - break; - } - - default: - { - unreached(); - } - } - - return false; -} - //---------------------------------------------------------------------------------------------- -// Lowering::LowerHWIntrinsicCreate: Lowers a Vector64, Vector128, or Vector256 Create call +// Lowering::LowerHWIntrinsicCreate: Lowers a Vector128 or Vector256 Create call // // Arguments: // node - The hardware intrinsic node. diff --git a/src/coreclr/src/jit/lsraarmarch.cpp b/src/coreclr/src/jit/lsraarmarch.cpp index fab94aaf11252..af7557807035a 100644 --- a/src/coreclr/src/jit/lsraarmarch.cpp +++ b/src/coreclr/src/jit/lsraarmarch.cpp @@ -74,23 +74,32 @@ int LinearScan::BuildIndir(GenTreeIndir* indirTree) if (addr->isContained()) { - assert(addr->OperGet() == GT_LEA); - GenTreeAddrMode* lea = addr->AsAddrMode(); - index = lea->Index(); - cns = lea->Offset(); - - // On ARM we may need a single internal register - // (when both conditions are true then we still only need a single internal register) - if ((index != nullptr) && (cns != 0)) + if (addr->OperGet() == GT_LEA) { - // ARM does not support both Index and offset so we need an internal register - buildInternalIntRegisterDefForNode(indirTree); + GenTreeAddrMode* lea = addr->AsAddrMode(); + index = lea->Index(); + cns = lea->Offset(); + + // On ARM we may need a single internal register + // (when both conditions are true then we still only need a single internal register) + if ((index != nullptr) && (cns != 0)) + { + // ARM does not support both Index and offset so we need an internal register + buildInternalIntRegisterDefForNode(indirTree); + } + else if (!emitter::emitIns_valid_imm_for_ldst_offset(cns, emitTypeSize(indirTree))) + { + // This offset can't be contained in the ldr/str instruction, so we need an internal register + buildInternalIntRegisterDefForNode(indirTree); + } } - else if (!emitter::emitIns_valid_imm_for_ldst_offset(cns, emitTypeSize(indirTree))) +#ifdef TARGET_ARM64 + else if (addr->OperGet() == GT_CLS_VAR_ADDR) { - // This offset can't be contained in the ldr/str instruction, so we need an internal register + // Reserve int to load constant from memory (IF_LARGELDC) buildInternalIntRegisterDefForNode(indirTree); } +#endif // TARGET_ARM64 } #ifdef FEATURE_SIMD diff --git a/src/coreclr/src/jit/namedintrinsiclist.h b/src/coreclr/src/jit/namedintrinsiclist.h index d105eabdbb3dd..457d434898c9b 100644 --- a/src/coreclr/src/jit/namedintrinsiclist.h +++ b/src/coreclr/src/jit/namedintrinsiclist.h @@ -22,11 +22,14 @@ enum NamedIntrinsic : unsigned short NI_System_Type_get_IsValueType, NI_System_Type_IsAssignableFrom, -#ifdef FEATURE_HW_INTRINSICS + // These are used by HWIntrinsics but are defined more generally + // to allow dead code optimization and handle the recursion case + NI_IsSupported_True, NI_IsSupported_False, NI_Throw_PlatformNotSupportedException, +#ifdef FEATURE_HW_INTRINSICS NI_HW_INTRINSIC_START, #if defined(TARGET_XARCH) #define HARDWARE_INTRINSIC(isa, name, size, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, category, flag) \ diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs index db15743c6dcba..5caec4828975a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs @@ -388,7 +388,7 @@ static Vector128 SoftwareFallback(int value) [Intrinsic] public static unsafe Vector128 Create(long value) { - if (Sse2.X64.IsSupported || AdvSimd.IsSupported) + if (Sse2.X64.IsSupported || AdvSimd.Arm64.IsSupported) { return Create(value); } @@ -546,7 +546,7 @@ static Vector128 SoftwareFallback(uint value) [CLSCompliant(false)] public static unsafe Vector128 Create(ulong value) { - if (Sse2.X64.IsSupported || AdvSimd.IsSupported) + if (Sse2.X64.IsSupported || AdvSimd.Arm64.IsSupported) { return Create(value); } @@ -587,32 +587,10 @@ static Vector128 SoftwareFallback(ulong value) [Intrinsic] public static unsafe Vector128 Create(byte e0, byte e1, byte e2, byte e3, byte e4, byte e5, byte e6, byte e7, byte e8, byte e9, byte e10, byte e11, byte e12, byte e13, byte e14, byte e15) { -#if !TARGET_ARM && !TARGET_ARM64 - if (Sse2.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { return Create(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); } -#else - if (AdvSimd.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); - result = AdvSimd.Insert(result, 1, e1); - result = AdvSimd.Insert(result, 2, e2); - result = AdvSimd.Insert(result, 3, e3); - result = AdvSimd.Insert(result, 4, e4); - result = AdvSimd.Insert(result, 5, e5); - result = AdvSimd.Insert(result, 6, e6); - result = AdvSimd.Insert(result, 7, e7); - result = AdvSimd.Insert(result, 8, e8); - result = AdvSimd.Insert(result, 9, e9); - result = AdvSimd.Insert(result, 10, e10); - result = AdvSimd.Insert(result, 11, e11); - result = AdvSimd.Insert(result, 12, e12); - result = AdvSimd.Insert(result, 13, e13); - result = AdvSimd.Insert(result, 14, e14); - return AdvSimd.Insert(result, 15, e15); - } -#endif return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); @@ -650,18 +628,10 @@ static Vector128 SoftwareFallback(byte e0, byte e1, byte e2, byte e3, byte [Intrinsic] public static unsafe Vector128 Create(double e0, double e1) { -#if !TARGET_ARM && !TARGET_ARM64 - if (Sse2.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { return Create(e0, e1); } -#else - if (AdvSimd.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); - return AdvSimd.Insert(result, 1, e1); - } -#endif return SoftwareFallback(e0, e1); @@ -691,24 +661,10 @@ static Vector128 SoftwareFallback(double e0, double e1) [Intrinsic] public static unsafe Vector128 Create(short e0, short e1, short e2, short e3, short e4, short e5, short e6, short e7) { -#if !TARGET_ARM && !TARGET_ARM64 - if (Sse2.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { return Create(e0, e1, e2, e3, e4, e5, e6, e7); } -#else - if (AdvSimd.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); - result = AdvSimd.Insert(result, 1, e1); - result = AdvSimd.Insert(result, 2, e2); - result = AdvSimd.Insert(result, 3, e3); - result = AdvSimd.Insert(result, 4, e4); - result = AdvSimd.Insert(result, 5, e5); - result = AdvSimd.Insert(result, 6, e6); - return AdvSimd.Insert(result, 7, e7); - } -#endif return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7); @@ -740,20 +696,10 @@ static Vector128 SoftwareFallback(short e0, short e1, short e2, short e3, [Intrinsic] public static unsafe Vector128 Create(int e0, int e1, int e2, int e3) { -#if !TARGET_ARM && !TARGET_ARM64 - if (Sse2.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { return Create(e0, e1, e2, e3); } -#else - if (AdvSimd.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); - result = AdvSimd.Insert(result, 1, e1); - result = AdvSimd.Insert(result, 2, e2); - return AdvSimd.Insert(result, 3, e3); - } -#endif return SoftwareFallback(e0, e1, e2, e3); @@ -779,18 +725,10 @@ static Vector128 SoftwareFallback(int e0, int e1, int e2, int e3) [Intrinsic] public static unsafe Vector128 Create(long e0, long e1) { -#if !TARGET_ARM && !TARGET_ARM64 - if (Sse2.X64.IsSupported) + if (Sse2.X64.IsSupported || AdvSimd.Arm64.IsSupported) { return Create(e0, e1); } -#else - if (AdvSimd.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); - return AdvSimd.Insert(result, 1, e1); - } -#endif return SoftwareFallback(e0, e1); @@ -829,32 +767,10 @@ static Vector128 SoftwareFallback(long e0, long e1) [CLSCompliant(false)] public static unsafe Vector128 Create(sbyte e0, sbyte e1, sbyte e2, sbyte e3, sbyte e4, sbyte e5, sbyte e6, sbyte e7, sbyte e8, sbyte e9, sbyte e10, sbyte e11, sbyte e12, sbyte e13, sbyte e14, sbyte e15) { -#if !TARGET_ARM && !TARGET_ARM64 - if (Sse2.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { return Create(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); } -#else - if (AdvSimd.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); - result = AdvSimd.Insert(result, 1, e1); - result = AdvSimd.Insert(result, 2, e2); - result = AdvSimd.Insert(result, 3, e3); - result = AdvSimd.Insert(result, 4, e4); - result = AdvSimd.Insert(result, 5, e5); - result = AdvSimd.Insert(result, 6, e6); - result = AdvSimd.Insert(result, 7, e7); - result = AdvSimd.Insert(result, 8, e8); - result = AdvSimd.Insert(result, 9, e9); - result = AdvSimd.Insert(result, 10, e10); - result = AdvSimd.Insert(result, 11, e11); - result = AdvSimd.Insert(result, 12, e12); - result = AdvSimd.Insert(result, 13, e13); - result = AdvSimd.Insert(result, 14, e14); - return AdvSimd.Insert(result, 15, e15); - } -#endif return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15); @@ -894,20 +810,10 @@ static Vector128 SoftwareFallback(sbyte e0, sbyte e1, sbyte e2, sbyte e3, [Intrinsic] public static unsafe Vector128 Create(float e0, float e1, float e2, float e3) { -#if !TARGET_ARM && !TARGET_ARM64 - if (Sse.IsSupported) + if (Sse.IsSupported || AdvSimd.IsSupported) { return Create(e0, e1, e2, e3); } -#else - if (AdvSimd.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); - result = AdvSimd.Insert(result, 1, e1); - result = AdvSimd.Insert(result, 2, e2); - return AdvSimd.Insert(result, 3, e3); - } -#endif return SoftwareFallback(e0, e1, e2, e3); @@ -940,24 +846,10 @@ static Vector128 SoftwareFallback(float e0, float e1, float e2, float e3) [CLSCompliant(false)] public static unsafe Vector128 Create(ushort e0, ushort e1, ushort e2, ushort e3, ushort e4, ushort e5, ushort e6, ushort e7) { -#if !TARGET_ARM && !TARGET_ARM64 - if (Sse2.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { return Create(e0, e1, e2, e3, e4, e5, e6, e7); } -#else - if (AdvSimd.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); - result = AdvSimd.Insert(result, 1, e1); - result = AdvSimd.Insert(result, 2, e2); - result = AdvSimd.Insert(result, 3, e3); - result = AdvSimd.Insert(result, 4, e4); - result = AdvSimd.Insert(result, 5, e5); - result = AdvSimd.Insert(result, 6, e6); - return AdvSimd.Insert(result, 7, e7); - } -#endif return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7); @@ -990,20 +882,10 @@ static Vector128 SoftwareFallback(ushort e0, ushort e1, ushort e2, ushor [CLSCompliant(false)] public static unsafe Vector128 Create(uint e0, uint e1, uint e2, uint e3) { -#if !TARGET_ARM && !TARGET_ARM64 - if (Sse2.IsSupported) + if (Sse2.IsSupported || AdvSimd.IsSupported) { return Create(e0, e1, e2, e3); } -#else - if (AdvSimd.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); - result = AdvSimd.Insert(result, 1, e1); - result = AdvSimd.Insert(result, 2, e2); - return AdvSimd.Insert(result, 3, e3); - } -#endif return SoftwareFallback(e0, e1, e2, e3); @@ -1030,18 +912,10 @@ static Vector128 SoftwareFallback(uint e0, uint e1, uint e2, uint e3) [CLSCompliant(false)] public static unsafe Vector128 Create(ulong e0, ulong e1) { -#if !TARGET_ARM && !TARGET_ARM64 - if (Sse2.X64.IsSupported) + if (Sse2.X64.IsSupported || AdvSimd.Arm64.IsSupported) { return Create(e0, e1); } -#else - if (AdvSimd.IsSupported) - { - Vector128 result = CreateScalarUnsafe(e0); - return AdvSimd.Insert(result, 1, e1); - } -#endif return SoftwareFallback(e0, e1); 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 56cf62d2f8805..f376ebf3bce52 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 @@ -160,19 +160,29 @@ public static Vector64 AsUInt64(this Vector64 vector) [Intrinsic] public static unsafe Vector64 Create(byte value) { - byte* pResult = stackalloc byte[8] - { - value, - value, - value, - value, - value, - value, - value, - value, - }; + if (AdvSimd.IsSupported) + { + return Create(value); + } - return Unsafe.AsRef>(pResult); + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(byte value) + { + byte* pResult = stackalloc byte[8] + { + value, + value, + value, + value, + value, + value, + value, + value, + }; + + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with all elements initialized to the specified value. @@ -181,7 +191,17 @@ public static unsafe Vector64 Create(byte value) [Intrinsic] public static unsafe Vector64 Create(double value) { - return Unsafe.As>(ref 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 all elements initialized to the specified value. @@ -191,15 +211,25 @@ public static unsafe Vector64 Create(double value) [Intrinsic] public static unsafe Vector64 Create(short value) { - short* pResult = stackalloc short[4] + if (AdvSimd.IsSupported) { - value, - value, - value, - value, - }; + return Create(value); + } - return Unsafe.AsRef>(pResult); + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(short value) + { + short* pResult = stackalloc short[4] + { + value, + value, + value, + value, + }; + + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with all elements initialized to the specified value. @@ -209,13 +239,23 @@ public static unsafe Vector64 Create(short value) [Intrinsic] public static unsafe Vector64 Create(int value) { - int* pResult = stackalloc int[2] + if (AdvSimd.IsSupported) { - value, - value, - }; + return Create(value); + } - return Unsafe.AsRef>(pResult); + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(int value) + { + int* pResult = stackalloc int[2] + { + value, + value, + }; + + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with all elements initialized to the specified value. @@ -224,30 +264,50 @@ public static unsafe Vector64 Create(int value) [Intrinsic] public static unsafe Vector64 Create(long value) { - return Unsafe.As>(ref 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 all elements initialized to the specified value. /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m64 _mm_set1_pi8 /// A new with all elements initialized to . - [CLSCompliant(false)] [Intrinsic] + [CLSCompliant(false)] public static unsafe Vector64 Create(sbyte value) { - sbyte* pResult = stackalloc sbyte[8] + if (AdvSimd.IsSupported) { - value, - value, - value, - value, - value, - value, - value, - value, - }; + return Create(value); + } - return Unsafe.AsRef>(pResult); + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(sbyte value) + { + sbyte* pResult = stackalloc sbyte[8] + { + value, + value, + value, + value, + value, + value, + value, + value, + }; + + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with all elements initialized to the specified value. @@ -256,59 +316,99 @@ public static unsafe Vector64 Create(sbyte value) [Intrinsic] public static unsafe Vector64 Create(float value) { - float* pResult = stackalloc float[2] + if (AdvSimd.IsSupported) { - value, - value, - }; + return Create(value); + } - return Unsafe.AsRef>(pResult); + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(float value) + { + float* pResult = stackalloc float[2] + { + value, + value, + }; + + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with all elements initialized to the specified value. /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m64 _mm_set1_pi16 /// A new with all elements initialized to . - [CLSCompliant(false)] [Intrinsic] + [CLSCompliant(false)] public static unsafe Vector64 Create(ushort value) { - ushort* pResult = stackalloc ushort[4] + if (AdvSimd.IsSupported) { - value, - value, - value, - value, - }; + return Create(value); + } - return Unsafe.AsRef>(pResult); + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(ushort value) + { + ushort* pResult = stackalloc ushort[4] + { + value, + value, + value, + value, + }; + + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with all elements initialized to the specified value. /// The value that all elements will be initialized to. /// On x86, this method corresponds to __m64 _mm_set1_pi32 /// A new with all elements initialized to . - [CLSCompliant(false)] [Intrinsic] + [CLSCompliant(false)] public static unsafe Vector64 Create(uint value) { - uint* pResult = stackalloc uint[2] + if (AdvSimd.IsSupported) { - value, - value, - }; + return Create(value); + } - return Unsafe.AsRef>(pResult); + return SoftwareFallback(value); + + static Vector64 SoftwareFallback(uint value) + { + uint* pResult = stackalloc uint[2] + { + value, + value, + }; + + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with all elements initialized to the specified value. /// The value that all elements will be initialized to. /// A new with all elements initialized to . - [CLSCompliant(false)] [Intrinsic] + [CLSCompliant(false)] public static unsafe Vector64 Create(ulong value) { - return Unsafe.As>(ref 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 each element initialized to the corresponding specified value. @@ -322,33 +422,32 @@ public static unsafe Vector64 Create(ulong value) /// The value that element 7 will be initialized to. /// On x86, this method corresponds to __m64 _mm_setr_pi8 /// A new with each element initialized to corresponding specified value. + [Intrinsic] public static unsafe Vector64 Create(byte e0, byte e1, byte e2, byte e3, byte e4, byte e5, byte e6, byte e7) { if (AdvSimd.IsSupported) { - Vector64 result = Vector64.CreateScalarUnsafe(e0); - result = AdvSimd.Insert(result, 1, e1); - result = AdvSimd.Insert(result, 2, e2); - result = AdvSimd.Insert(result, 3, e3); - result = AdvSimd.Insert(result, 4, e4); - result = AdvSimd.Insert(result, 5, e5); - result = AdvSimd.Insert(result, 6, e6); - return AdvSimd.Insert(result, 7, e7); + return Create(e0, e1, e2, e3, e4, e5, e6, e7); } - byte* pResult = stackalloc byte[8] + return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7); + + static Vector64 SoftwareFallback(byte e0, byte e1, byte e2, byte e3, byte e4, byte e5, byte e6, byte e7) { - e0, - e1, - e2, - e3, - e4, - e5, - e6, - e7, - }; + byte* pResult = stackalloc byte[8] + { + e0, + e1, + e2, + e3, + e4, + e5, + e6, + e7, + }; - return Unsafe.AsRef>(pResult); + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with each element initialized to the corresponding specified value. @@ -358,25 +457,28 @@ public static unsafe Vector64 Create(byte e0, byte e1, byte e2, byte e3, b /// The value that element 3 will be initialized to. /// On x86, this method corresponds to __m64 _mm_setr_pi16 /// A new with each element initialized to corresponding specified value. + [Intrinsic] public static unsafe Vector64 Create(short e0, short e1, short e2, short e3) { if (AdvSimd.IsSupported) { - Vector64 result = Vector64.CreateScalarUnsafe(e0); - result = AdvSimd.Insert(result, 1, e1); - result = AdvSimd.Insert(result, 2, e2); - return AdvSimd.Insert(result, 3, e3); + return Create(e0, e1, e2, e3); } - short* pResult = stackalloc short[4] + return SoftwareFallback(e0, e1, e2, e3); + + static Vector64 SoftwareFallback(short e0, short e1, short e2, short e3) { - e0, - e1, - e2, - e3, - }; + short* pResult = stackalloc short[4] + { + e0, + e1, + e2, + e3, + }; - return Unsafe.AsRef>(pResult); + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with each element initialized to the corresponding specified value. @@ -384,21 +486,26 @@ public static unsafe Vector64 Create(short e0, short e1, short e2, short /// The value that element 1 will be initialized to. /// On x86, this method corresponds to __m64 _mm_setr_pi32 /// A new with each element initialized to corresponding specified value. + [Intrinsic] public static unsafe Vector64 Create(int e0, int e1) { if (AdvSimd.IsSupported) { - Vector64 result = Vector64.CreateScalarUnsafe(e0); - return AdvSimd.Insert(result, 1, e1); + return Create(e0, e1); } - int* pResult = stackalloc int[2] + return SoftwareFallback(e0, e1); + + static Vector64 SoftwareFallback(int e0, int e1) { - e0, - e1, - }; + int* pResult = stackalloc int[2] + { + e0, + e1, + }; - return Unsafe.AsRef>(pResult); + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with each element initialized to the corresponding specified value. @@ -412,55 +519,59 @@ public static unsafe Vector64 Create(int e0, int e1) /// The value that element 7 will be initialized to. /// On x86, this method corresponds to __m64 _mm_setr_pi8 /// A new with each element initialized to corresponding specified value. + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector64 Create(sbyte e0, sbyte e1, sbyte e2, sbyte e3, sbyte e4, sbyte e5, sbyte e6, sbyte e7) { if (AdvSimd.IsSupported) { - Vector64 result = Vector64.CreateScalarUnsafe(e0); - result = AdvSimd.Insert(result, 1, e1); - result = AdvSimd.Insert(result, 2, e2); - result = AdvSimd.Insert(result, 3, e3); - result = AdvSimd.Insert(result, 4, e4); - result = AdvSimd.Insert(result, 5, e5); - result = AdvSimd.Insert(result, 6, e6); - return AdvSimd.Insert(result, 7, e7); + return Create(e0, e1, e2, e3, e4, e5, e6, e7); } - sbyte* pResult = stackalloc sbyte[8] + return SoftwareFallback(e0, e1, e2, e3, e4, e5, e6, e7); + + static Vector64 SoftwareFallback(sbyte e0, sbyte e1, sbyte e2, sbyte e3, sbyte e4, sbyte e5, sbyte e6, sbyte e7) { - e0, - e1, - e2, - e3, - e4, - e5, - e6, - e7, - }; + sbyte* pResult = stackalloc sbyte[8] + { + e0, + e1, + e2, + e3, + e4, + e5, + e6, + e7, + }; - return Unsafe.AsRef>(pResult); + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with each element initialized to the corresponding specified value. /// The value that element 0 will be initialized to. /// The value that element 1 will be initialized to. /// A new with each element initialized to corresponding specified value. + [Intrinsic] public static unsafe Vector64 Create(float e0, float e1) { if (AdvSimd.IsSupported) { - Vector64 result = Vector64.CreateScalarUnsafe(e0); - return AdvSimd.Insert(result, 1, e1); + return Create(e0, e1); } - float* pResult = stackalloc float[2] + return SoftwareFallback(e0, e1); + + static Vector64 SoftwareFallback(float e0, float e1) { - e0, - e1, - }; + float* pResult = stackalloc float[2] + { + e0, + e1, + }; - return Unsafe.AsRef>(pResult); + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with each element initialized to the corresponding specified value. @@ -470,26 +581,29 @@ public static unsafe Vector64 Create(float e0, float e1) /// The value that element 3 will be initialized to. /// On x86, this method corresponds to __m64 _mm_setr_pi16 /// A new with each element initialized to corresponding specified value. + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector64 Create(ushort e0, ushort e1, ushort e2, ushort e3) { if (AdvSimd.IsSupported) { - Vector64 result = Vector64.CreateScalarUnsafe(e0); - result = AdvSimd.Insert(result, 1, e1); - result = AdvSimd.Insert(result, 2, e2); - return AdvSimd.Insert(result, 3, e3); + return Create(e0, e1, e2, e3); } - ushort* pResult = stackalloc ushort[4] + return SoftwareFallback(e0, e1, e2, e3); + + static Vector64 SoftwareFallback(ushort e0, ushort e1, ushort e2, ushort e3) { - e0, - e1, - e2, - e3, - }; + ushort* pResult = stackalloc ushort[4] + { + e0, + e1, + e2, + e3, + }; - return Unsafe.AsRef>(pResult); + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with each element initialized to the corresponding specified value. @@ -497,22 +611,27 @@ public static unsafe Vector64 Create(ushort e0, ushort e1, ushort e2, us /// The value that element 1 will be initialized to. /// On x86, this method corresponds to __m64 _mm_setr_pi32 /// A new with each element initialized to corresponding specified value. + [Intrinsic] [CLSCompliant(false)] public static unsafe Vector64 Create(uint e0, uint e1) { if (AdvSimd.IsSupported) { - Vector64 result = Vector64.CreateScalarUnsafe(e0); - return AdvSimd.Insert(result, 1, e1); + return Create(e0, e1); } - uint* pResult = stackalloc uint[2] + return SoftwareFallback(e0, e1); + + static Vector64 SoftwareFallback(uint e0, uint e1) { - e0, - e1, - }; + uint* pResult = stackalloc uint[2] + { + e0, + e1, + }; - return Unsafe.AsRef>(pResult); + return Unsafe.AsRef>(pResult); + } } /// Creates a new instance with the first element initialized to the specified value and the remaining elements initialized to zero. From 3b4440317ad5d870b5bc5497bacb368e7e7ec8b8 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Wed, 13 May 2020 16:20:04 -0700 Subject: [PATCH 174/420] Honor PropertyNamingPolicy, PropertyNameCaseInsensitive, & Encoder options when (de)serializing KeyValuePair instances --- .../src/Resources/Strings.resx | 5 +- .../Converters/Value/KeyValuePairConverter.cs | 91 +++++++--- .../Value/KeyValuePairConverterFactory.cs | 2 + .../Text/Json/Serialization/JsonConverter.cs | 2 + .../Text/Json/ThrowHelper.Serialization.cs | 7 + .../CollectionTests.KeyValuePair.cs | 171 ++++++++++++++++++ 6 files changed, 252 insertions(+), 26 deletions(-) diff --git a/src/libraries/System.Text.Json/src/Resources/Strings.resx b/src/libraries/System.Text.Json/src/Resources/Strings.resx index 3f54adaab7447..4ee750fe9d6bd 100644 --- a/src/libraries/System.Text.Json/src/Resources/Strings.resx +++ b/src/libraries/System.Text.Json/src/Resources/Strings.resx @@ -521,4 +521,7 @@ The collection type '{0}' is abstract, an interface, or is read only, and could not be instantiated and populated. - \ No newline at end of file + + The naming policy '{0}' returned an invalid value for a 'KeyValuePair' property name. The value cannot be 'null', cannot be a case-insensitive match for the literal 'Value' when converting the 'Key' property name, and cannot be a case-insensitive match for the literal 'Key' when converting the 'Value' property name. + + diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs index f74a7de0cdbe1..095613e1fc816 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs @@ -3,23 +3,55 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Text.Encodings.Web; namespace System.Text.Json.Serialization.Converters { internal sealed class KeyValuePairConverter : JsonValueConverter> { - private const string KeyName = "Key"; - private const string ValueName = "Value"; + private const string KeyNameCLR = "Key"; + private const string ValueNameCLR = "Value"; - // todo: https://github.com/dotnet/runtime/issues/1197 - // move these to JsonSerializerOptions and use the proper encoding. - private static readonly JsonEncodedText _keyName = JsonEncodedText.Encode(KeyName, encoder: null); - private static readonly JsonEncodedText _valueName = JsonEncodedText.Encode(ValueName, encoder: null); + // Property name for "Key" and "Value" with Options.PropertyNamingPolicy applied. + private string _keyName = null!; + private string _valueName = null!; + + // _keyName and _valueName as JsonEncodedText. + private JsonEncodedText _keyNameEncoded; + private JsonEncodedText _valueNameEncoded; // todo: https://github.com/dotnet/runtime/issues/32352 // it is possible to cache the underlying converters since this is an internal converter and // an instance is created only once for each JsonSerializerOptions instance. + internal override void Initialize(JsonSerializerOptions options) + { + JsonNamingPolicy? namingPolicy = options.PropertyNamingPolicy; + + if (namingPolicy == null) + { + _keyName = KeyNameCLR; + _valueName = ValueNameCLR; + } + else + { + _keyName = namingPolicy.ConvertName(KeyNameCLR); + _valueName = namingPolicy.ConvertName(ValueNameCLR); + + if (_keyName == null || + _valueName == null || + string.Equals(_keyName, ValueNameCLR, StringComparison.OrdinalIgnoreCase) || + string.Equals(_valueName, KeyNameCLR, StringComparison.OrdinalIgnoreCase)) + { + ThrowHelper.ThrowInvalidOperationException_KeyValuePairPropertyNameInvalid(namingPolicy); + } + } + + JavaScriptEncoder? encoder = options.Encoder; + _keyNameEncoded = JsonEncodedText.Encode(_keyName, encoder); + _valueNameEncoded = JsonEncodedText.Encode(_valueName, encoder); + } + internal override bool OnTryRead( ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, @@ -44,17 +76,19 @@ internal sealed class KeyValuePairConverter : JsonValueConverter(ref reader, options, ref state, KeyName); + k = JsonSerializer.Deserialize(ref reader, options, ref state, _keyName); keySet = true; } - else if (propertyName == ValueName) + else if (FoundValueProperty(propertyName, caseInsensitiveMatch)) { reader.ReadWithVerify(); - v = JsonSerializer.Deserialize(ref reader, options, ref state, ValueName); + v = JsonSerializer.Deserialize(ref reader, options, ref state, _valueName); valueSet = true; } else @@ -70,28 +104,21 @@ internal sealed class KeyValuePairConverter : JsonValueConverter(ref reader, options, ref state, KeyName); - keySet = true; + k = JsonSerializer.Deserialize(ref reader, options, ref state, _keyName); } - else if (propertyName == ValueName) + else if (!valueSet && FoundValueProperty(propertyName, caseInsensitiveMatch)) { reader.ReadWithVerify(); - v = JsonSerializer.Deserialize(ref reader, options, ref state, ValueName); - valueSet = true; + v = JsonSerializer.Deserialize(ref reader, options, ref state, _valueName); } else { ThrowHelper.ThrowJsonException(); } - if (!keySet || !valueSet) - { - ThrowHelper.ThrowJsonException(); - } - reader.ReadWithVerify(); if (reader.TokenType != JsonTokenType.EndObject) @@ -107,14 +134,28 @@ internal override bool OnTryWrite(Utf8JsonWriter writer, KeyValuePair false; internal ConstructorInfo? ConstructorInfo { get; set; } + + internal virtual void Initialize(JsonSerializerOptions options) { } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs index 8d0bb4d01b403..4ef3ab641e420 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs @@ -168,6 +168,13 @@ public static void ThrowInvalidOperationException_SerializerDictionaryKeyNull(Ty throw new InvalidOperationException(SR.Format(SR.SerializerDictionaryKeyNull, policyType)); } + [DoesNotReturn] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ThrowInvalidOperationException_KeyValuePairPropertyNameInvalid(JsonNamingPolicy namingPolicy) + { + throw new InvalidOperationException(SR.Format(SR.KeyValuePairPropertyNameInvalid, namingPolicy.GetType())); + } + [DoesNotReturn] public static void ThrowInvalidOperationException_SerializerConverterFactoryReturnsNull(Type converterType) { diff --git a/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.KeyValuePair.cs b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.KeyValuePair.cs index 9e295d5d5188e..08f679f62ab27 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.KeyValuePair.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.KeyValuePair.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Text.Encodings.Web; using Xunit; namespace System.Text.Json.Serialization.Tests @@ -279,5 +280,175 @@ public static void WriteClassWithNullKeyValuePairValues_NullWrittenAsEmptyObject Assert.Null(value.KvpWObjKvpVal.Value.Value); Assert.Null(value.KvpWClassKvpVal.Value.Value); } + + [Fact] + public static void HonorNamingPolicy() + { + var kvp = new KeyValuePair("Hello, World!", 1); + + var options = new JsonSerializerOptions + { + PropertyNamingPolicy = new LeadingUnderscorePolicy() + }; + + string serialized = JsonSerializer.Serialize(kvp, options); + // We know serializer writes the key first. + Assert.Equal(@"{""_Key"":""Hello, World!"",""_Value"":1}", serialized); + + kvp = JsonSerializer.Deserialize>(serialized, options); + Assert.Equal("Hello, World!", kvp.Key); + Assert.Equal(1, kvp.Value); + } + + [Fact] + public static void HonorNamingPolicy_CaseInsensitive() + { + const string json = @"{""key"":""Hello, World!"",""value"":1}"; + + // Baseline - with case-sensitive matching, the payload doesn't have mapping properties. + Assert.Throws(() => JsonSerializer.Deserialize>(json)); + + // Test - with case-insensitivity on, we have property matches. + var options = new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true + }; + + KeyValuePair kvp = JsonSerializer.Deserialize>(json, options); + Assert.Equal("Hello, World!", kvp.Key); + Assert.Equal(1, kvp.Value); + } + + [Fact] + public static void HonorCLRProperties() + { + var options = new JsonSerializerOptions + { + PropertyNamingPolicy = new LeadingUnderscorePolicy() // Key -> _Key, Value -> _Value + }; + + // Although policy won't produce this JSON string, the serializer parses the properties + // as "Key" and "Value" are special cased to accomodate content serialized with previous + // versions of the serializer (.NET Core 3.x/System.Text.Json 4.7.x). + string json = @"{""Key"":""Hello, World!"",""Value"":1}"; + KeyValuePair kvp = JsonSerializer.Deserialize>(json, options); + Assert.Equal("Hello, World!", kvp.Key); + Assert.Equal(1, kvp.Value); + + // "Key" and "Value" matching is case sensitive. + json = @"{""key"":""Hello, World!"",""value"":1}"; + Assert.Throws(() => JsonSerializer.Deserialize>(json, options)); + + // "Key" and "Value" matching is case sensitive, even when case sensitivity is on. + // Case sensitivity only applies to the result of converting the CLR property names + // (Key -> _Key, Value -> _Value) with the naming policy. + options = new JsonSerializerOptions + { + PropertyNamingPolicy = new LeadingUnderscorePolicy(), + PropertyNameCaseInsensitive = true + }; + + Assert.Throws(() => JsonSerializer.Deserialize>(json, options)); + } + + private class LeadingUnderscorePolicy : JsonNamingPolicy + { + public override string ConvertName(string name) => "_" + name; + } + + [Fact] + public static void HonorCustomEncoder() + { + var kvp = new KeyValuePair(1, 2); + + JsonNamingPolicy namingPolicy = new TrailingAngleBracketPolicy(); + + // Baseline - properties serialized with default encoder if none specified. + var options = new JsonSerializerOptions + { + PropertyNamingPolicy = namingPolicy, + }; + + Assert.Equal(@"{""Key\u003C"":1,""Value\u003C"":2}", JsonSerializer.Serialize(kvp, options)); + + // Test - serializer honors custom encoder. + options = new JsonSerializerOptions + { + PropertyNamingPolicy = namingPolicy, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }; + + Assert.Equal(@"{""Key<"":1,""Value<"":2}", JsonSerializer.Serialize(kvp, options)); + } + + private class TrailingAngleBracketPolicy : JsonNamingPolicy + { + public override string ConvertName(string name) => name + "<"; + } + + [Theory] + [InlineData(typeof(KeyNameNullPolicy))] + [InlineData(typeof(ValueNameNullPolicy))] + [InlineData(typeof(KeyNameMapsToValuePolicy))] + [InlineData(typeof(ValueNameMapsToKeyPolicy))] + public static void InvalidPropertyNameFail(Type policyType) + { + var options = new JsonSerializerOptions + { + PropertyNamingPolicy = (JsonNamingPolicy)Activator.CreateInstance(policyType) + }; + + InvalidOperationException ex = Assert.Throws(() => JsonSerializer.Deserialize>("", options)); + string exAsStr = ex.ToString(); + + Assert.Contains(policyType.ToString(), exAsStr); + Assert.Contains("'Key'", exAsStr); + Assert.Contains("'Value'", exAsStr); + Assert.Contains("'KeyValuePair'", exAsStr); + + Assert.Throws(() => JsonSerializer.Serialize(new KeyValuePair("", ""), options)); + } + + private class KeyNameNullPolicy : JsonNamingPolicy + { + public override string ConvertName(string name) => name == "Key" ? null : name; + } + + private class ValueNameNullPolicy : JsonNamingPolicy + { + public override string ConvertName(string name) => name == "Value" ? null : name; + } + + private class KeyNameMapsToValuePolicy : JsonNamingPolicy + { + public override string ConvertName(string name) => name == "Key" ? "Value" : name; + } + + private class ValueNameMapsToKeyPolicy : JsonNamingPolicy + { + public override string ConvertName(string name) => name == "Value" ? "k\u0045y" : name; // kEy + } + + [Theory] + [InlineData("")] + [InlineData("1")] + [InlineData("[")] + [InlineData("}")] + [InlineData("{")] + [InlineData("{}")] + [InlineData("{Key")] + [InlineData("{0")] + [InlineData(@"{""Random"":")] + [InlineData(@"{""Value"":1}")] + [InlineData(@"{""Value"":1,2")] + [InlineData(@"{""Value"":1,""Random"":")] + [InlineData(@"{""Key"":1,""Key"":1}")] + [InlineData(@"{""Key"":1,""Key"":2}")] + [InlineData(@"{""Value"":1,""Value"":1}")] + [InlineData(@"{""Value"":1,""Value"":2}")] + public static void InvalidJsonFail(string json) + { + Assert.Throws(() => JsonSerializer.Deserialize>(json)); + } } } From 91c5fd0389a1369ce03db8b087a7f816b1a85f09 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Thu, 14 May 2020 04:17:13 +0200 Subject: [PATCH 175/420] Fix cross-compiling argument validation for Linux (#36368) * Fix cross-compiling argument validation for Linux https://github.com/dotnet/runtime/commit/7c66b6fb6fb00dd86d969ec622a9bb2830016375 added a ValidateSet for Windows_NT and Unix even though we don't support building for just "Unix" but for the more concrete OS which is "Linux". * Update build.ps1 --- eng/build.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/build.ps1 b/eng/build.ps1 index 6203fee43997b..c5c0031b8d21e 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -5,7 +5,7 @@ Param( [ValidateSet("Debug","Release","Checked")][string[]][Alias('c')]$configuration = @("Debug"), [string][Alias('f')]$framework, [string]$vs, - [ValidateSet("Windows_NT","Unix")][string]$os, + [ValidateSet("Windows_NT","Linux","OSX")][string]$os, [switch]$allconfigurations, [switch]$coverage, [string]$testscope, @@ -21,7 +21,7 @@ function Get-Help() { Write-Host "Common settings:" Write-Host " -subset Build a subset, print available subsets with -subset help (short: -s)" Write-Host " -vs Open the solution with VS for Test Explorer support. Path or solution name (ie -vs Microsoft.CSharp)" - Write-Host " -os Build operating system: Windows_NT or Unix" + Write-Host " -os Build operating system: Windows_NT, Linux or OSX" Write-Host " -arch Build platform: x86, x64, arm or arm64 (short: -a). Pass a comma-separated list to build for multiple architectures." Write-Host " -configuration Build configuration: Debug, Release or [CoreCLR]Checked (short: -c). Pass a comma-separated list to build for multiple configurations" Write-Host " -runtimeConfiguration Runtime build configuration: Debug, Release or [CoreCLR]Checked (short: -rc)" From b80043b9384603460430469fa497a726471ccb00 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 13 May 2020 19:18:18 -0700 Subject: [PATCH 176/420] Disable test GitHub_35821 (#36419) --- src/coreclr/tests/issues.targets | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index cbfe9f0323b91..16851f03a2797 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -324,6 +324,9 @@ needs triage + + https://github.com/dotnet/runtime/issues/36418 + https://github.com/dotnet/runtime/issues/12216 From 8ebf86bd40bf5c0437177f83fea4ab3bfc51844f Mon Sep 17 00:00:00 2001 From: imhameed Date: Wed, 13 May 2020 20:17:07 -0700 Subject: [PATCH 177/420] Improve Sse41.Multiply compatibility with LLVM 9. (#36369) The llvm.x86.sse41.pmuldq intrinsic is no longer available as of https://github.com/dotnet/llvm-project/commit/254ed028a4bd4fa81d0049d90e6ab23d704dd366. This also adds a convenience wrapper for creating constant LLVM IR vectors, up to 16 elements long, of arbitrary integral type. Finally, fix a latent bug in init_function_pass_manager; llvm::StringRef::size returns a value of type size_t, but the printf precision specifier requires a value of type int. --- src/mono/mono/mini/llvm-intrinsics.h | 3 +++ src/mono/mono/mini/llvm-jit.cpp | 2 +- src/mono/mono/mini/mini-llvm-cpp.cpp | 7 ++++++ src/mono/mono/mini/mini-llvm-cpp.h | 3 +++ src/mono/mono/mini/mini-llvm.c | 34 +++++++++++++++++++++------- 5 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/mono/mono/mini/llvm-intrinsics.h b/src/mono/mono/mini/llvm-intrinsics.h index 74b2ed3d62eff..f937df8bb8bf5 100644 --- a/src/mono/mono/mini/llvm-intrinsics.h +++ b/src/mono/mono/mini/llvm-intrinsics.h @@ -206,7 +206,10 @@ INTRINS(SSE_TESTZ, x86_sse41_ptestz) INTRINS(SSE_PBLENDVB, x86_sse41_pblendvb) INTRINS(SSE_BLENDVPS, x86_sse41_blendvps) INTRINS(SSE_BLENDVPD, x86_sse41_blendvpd) +#if LLVM_API_VERSION < 700 +// Clang 7 and above use a sequence of IR operations to represent pmuldq. INTRINS(SSE_PMULDQ, x86_sse41_pmuldq) +#endif INTRINS(SSE_PHMINPOSUW, x86_sse41_phminposuw) INTRINS(SSE_MPSADBW, x86_sse41_mpsadbw) INTRINS(PCLMULQDQ, x86_pclmulqdq) diff --git a/src/mono/mono/mini/llvm-jit.cpp b/src/mono/mono/mini/llvm-jit.cpp index 325e09c2cc383..1c16963c2909f 100644 --- a/src/mono/mono/mini/llvm-jit.cpp +++ b/src/mono/mono/mini/llvm-jit.cpp @@ -185,7 +185,7 @@ init_function_pass_manager (legacy::FunctionPassManager &fpm) } else { auto info = reg->getPassInfo (pass->getPassID()); auto name = info->getPassArgument (); - printf("Opt pass is ignored: %.*s\n", name.size(), name.data()); + printf("Opt pass is ignored: %.*s\n", (int) name.size(), name.data()); } } // -place-safepoints pass is mandatory diff --git a/src/mono/mono/mini/mini-llvm-cpp.cpp b/src/mono/mono/mini/mini-llvm-cpp.cpp index cbe40546561f7..e9ef878222294 100644 --- a/src/mono/mono/mini/mini-llvm-cpp.cpp +++ b/src/mono/mono/mini/mini-llvm-cpp.cpp @@ -229,6 +229,13 @@ mono_llvm_build_weighted_branch (LLVMBuilderRef builder, LLVMValueRef cond, LLVM return wrap (ins); } +LLVMValueRef +mono_llvm_build_exact_ashr (LLVMBuilderRef builder, LLVMValueRef lhs, LLVMValueRef rhs) { + auto b = unwrap (builder); + auto ins = b->CreateAShr (unwrap (lhs), unwrap (rhs), "", true); + return wrap (ins); +} + void mono_llvm_add_string_metadata (LLVMValueRef insref, const char* label, const char* text) { diff --git a/src/mono/mono/mini/mini-llvm-cpp.h b/src/mono/mono/mini/mini-llvm-cpp.h index d9b2e427c7932..9173b6341e4f6 100644 --- a/src/mono/mono/mini/mini-llvm-cpp.h +++ b/src/mono/mono/mini/mini-llvm-cpp.h @@ -104,6 +104,9 @@ mono_llvm_build_cmpxchg (LLVMBuilderRef builder, LLVMValueRef addr, LLVMValueRef LLVMValueRef mono_llvm_build_weighted_branch (LLVMBuilderRef builder, LLVMValueRef cond, LLVMBasicBlockRef t, LLVMBasicBlockRef f, uint32_t t_weight, uint32_t f_weight); +LLVMValueRef +mono_llvm_build_exact_ashr (LLVMBuilderRef builder, LLVMValueRef lhs, LLVMValueRef rhs); + void mono_llvm_add_string_metadata (LLVMValueRef insref, const char* label, const char* text); diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index f5aef1fd1b396..fa99c276130ed 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -4572,14 +4572,19 @@ emit_landing_pad (EmitContext *ctx, int group_index, int group_size) } static LLVMValueRef -create_const_vector_i32 (const int *mask, int count) +create_const_vector (LLVMTypeRef t, const int *vals, int count) { - LLVMValueRef *llvm_mask = g_new (LLVMValueRef, count); + g_assert (count <= 16); + LLVMValueRef llvm_vals [16]; for (int i = 0; i < count; i++) - llvm_mask [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE); - LLVMValueRef vec = LLVMConstVector (llvm_mask, count); - g_free (llvm_mask); - return vec; + llvm_vals [i] = LLVMConstInt (t, vals [i], FALSE); + return LLVMConstVector (llvm_vals, count); +} + +static LLVMValueRef +create_const_vector_i32 (const int *mask, int count) +{ + return create_const_vector (LLVMInt32Type (), mask, count); } static LLVMValueRef @@ -8582,10 +8587,23 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) } case OP_SSE41_MUL: { - // NOTE: LLVM 7 and later use shifts here - // however, pmuldq is still available so I guess it's fine to keep using it +#if LLVM_API_VERSION < 700 LLVMValueRef args [] = { lhs, rhs }; values [ins->dreg] = call_intrins (ctx, INTRINS_SSE_PMULDQ, args, dname); +#else + const int shift_vals [] = { 32, 32 }; + const LLVMValueRef args [] = { + convert (ctx, lhs, sse_i8_t), + convert (ctx, rhs, sse_i8_t), + }; + LLVMValueRef mul_args [2] = { 0 }; + LLVMValueRef shift_vec = create_const_vector (LLVMInt64Type (), shift_vals, 2); + for (int i = 0; i < 2; ++i) { + LLVMValueRef padded = LLVMBuildShl (builder, args [i], shift_vec, ""); + mul_args[i] = mono_llvm_build_exact_ashr (builder, padded, shift_vec); + } + values [ins->dreg] = LLVMBuildNSWMul (builder, mul_args [0], mul_args [1], dname); +#endif break; } From 5372ee9dbe48058ca8d3591763e989d3b2e65581 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Wed, 13 May 2020 20:25:40 -0700 Subject: [PATCH 178/420] Move Mobile test runners to libraries/common and use P2P references (#36411) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Move Mobile test runners to libraries/common and use P2P references * PR Feedback Co-authored-by: Alexander Köplinger Co-authored-by: Alexander Köplinger --- eng/testing/tests.mobile.targets | 13 ------------- eng/testing/tests.props | 2 -- .../tests}/AndroidTestRunner/AndroidTestRunner.cs | 4 ++++ .../AndroidTestRunner/AndroidTestRunner.csproj | 13 +++++++++++++ .../tests}/AppleTestRunner/AppleTestRunner.cs | 4 ++++ .../tests/AppleTestRunner/AppleTestRunner.csproj | 13 +++++++++++++ src/libraries/Directory.Build.props | 3 +++ .../tests/System.Runtime.Tests.csproj | 2 +- .../tests/System/ArgumentExceptionTests.cs | 10 +++++----- .../tests/System/ArgumentNullExceptionTests.cs | 8 ++++---- .../System/ArgumentOutOfRangeExceptionTests.cs | 10 +++++----- .../tests/System/ArithmeticExceptionTests.cs | 6 +++--- .../tests/System/ArrayTypeMismatchExceptionTests.cs | 6 +++--- .../tests/System/BadImageFormatExceptionTests.cs | 10 +++++----- .../Generic/KeyNotFoundExceptionTests.cs | 6 +++--- .../tests/System/DivideByZeroExceptionTests.cs | 6 +++--- .../{Exceptions.Utility.cs => Exception.Helpers.cs} | 2 +- .../System.Runtime/tests/System/ExceptionTests.cs | 6 +++--- .../tests/System/FormatExceptionTests.cs | 6 +++--- .../IO/DirectoryNotFoundException.InteropTests.cs | 2 +- .../System/IO/DirectoryNotFoundExceptionTests.cs | 6 +++--- .../System/IO/FileLoadException.InteropTests.cs | 2 +- .../tests/System/IO/FileLoadExceptionTests.cs | 10 +++++----- .../System/IO/FileNotFoundException.InteropTests.cs | 2 +- .../tests/System/IO/FileNotFoundExceptionTests.cs | 10 +++++----- .../tests/System/IO/IOExceptionTests.cs | 8 ++++---- .../System/IO/PathTooLongException.InteropTests.cs | 2 +- .../tests/System/IO/PathTooLongExceptionTests.cs | 6 +++--- .../tests/System/IndexOutOfRangeExceptionTests.cs | 6 +++--- .../tests/System/InvalidCastExceptionTests.cs | 8 ++++---- .../tests/System/InvalidOperationExceptionTests.cs | 6 +++--- .../tests/System/InvalidProgramExceptionTests.cs | 6 +++--- .../tests/System/MemberAccessExceptionTests.cs | 6 +++--- .../tests/System/NotImplementedExceptionTests.cs | 6 +++--- .../tests/System/NotSupportedExceptionTests.cs | 6 +++--- .../tests/System/ObjectDisposedExceptionTests.cs | 6 +++--- .../tests/System/OutOfMemoryExceptionTests.cs | 6 +++--- .../tests/System/OverflowExceptionTests.cs | 6 +++--- .../System/PlatformNotSupportedExceptionTests.cs | 6 +++--- .../tests/System/RankExceptionTests.cs | 6 +++--- .../tests/System/Security/SecurityExceptionTests.cs | 10 +++++----- .../tests/System/TimeoutExceptionTests.cs | 6 +++--- .../tests/System/TypeLoadExceptionTests.cs | 6 +++--- src/mono/mono.proj | 6 ------ .../AndroidTestRunner/AndroidTestRunner.csproj | 8 -------- .../msbuild/AppleTestRunner/AppleTestRunner.csproj | 8 -------- 46 files changed, 148 insertions(+), 148 deletions(-) rename src/{mono/msbuild => libraries/Common/tests}/AndroidTestRunner/AndroidTestRunner.cs (93%) create mode 100644 src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.csproj rename src/{mono/msbuild => libraries/Common/tests}/AppleTestRunner/AppleTestRunner.cs (95%) create mode 100644 src/libraries/Common/tests/AppleTestRunner/AppleTestRunner.csproj rename src/libraries/System.Runtime/tests/System/{Exceptions.Utility.cs => Exception.Helpers.cs} (96%) delete mode 100644 src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.csproj delete mode 100644 src/mono/msbuild/AppleTestRunner/AppleTestRunner.csproj diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 90a18f86ca84e..4e6ceb20b1955 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -17,15 +17,9 @@ x86_64 x86 - - - - - - - - - - - - - diff --git a/eng/testing/tests.props b/eng/testing/tests.props index 382ffe67684d9..50ff37c891a4f 100644 --- a/eng/testing/tests.props +++ b/eng/testing/tests.props @@ -23,9 +23,7 @@ $(NetCoreAppCurrent)-$(MonoConfiguration) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder', '$(MobileHelpersDirSuffix)')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleTestRunner', '$(MobileHelpersDirSuffix)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', '$(MobileHelpersDirSuffix)')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidTestRunner', '$(MobileHelpersDirSuffix)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'MonoAOTCompiler', '$(MobileHelpersDirSuffix)')) $(PackageRID) diff --git a/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.cs b/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs similarity index 93% rename from src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.cs rename to src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs index 8500bebd069d9..9f232f549ba92 100644 --- a/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.cs +++ b/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs @@ -1,3 +1,7 @@ +// 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. + using System; using System.Linq; using System.Text; diff --git a/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.csproj b/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.csproj new file mode 100644 index 0000000000000..24fde08ba8a65 --- /dev/null +++ b/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.csproj @@ -0,0 +1,13 @@ + + + Exe + enable + $(NetCoreAppCurrent);$(NetFrameworkCurrent) + + + + + + + diff --git a/src/mono/msbuild/AppleTestRunner/AppleTestRunner.cs b/src/libraries/Common/tests/AppleTestRunner/AppleTestRunner.cs similarity index 95% rename from src/mono/msbuild/AppleTestRunner/AppleTestRunner.cs rename to src/libraries/Common/tests/AppleTestRunner/AppleTestRunner.cs index 9fa35b6cc15fa..22979b7d4cf37 100644 --- a/src/mono/msbuild/AppleTestRunner/AppleTestRunner.cs +++ b/src/libraries/Common/tests/AppleTestRunner/AppleTestRunner.cs @@ -1,3 +1,7 @@ +// 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. + using System; using System.Linq; using System.Text; diff --git a/src/libraries/Common/tests/AppleTestRunner/AppleTestRunner.csproj b/src/libraries/Common/tests/AppleTestRunner/AppleTestRunner.csproj new file mode 100644 index 0000000000000..078bf94a1172a --- /dev/null +++ b/src/libraries/Common/tests/AppleTestRunner/AppleTestRunner.csproj @@ -0,0 +1,13 @@ + + + Exe + enable + $(NetCoreAppCurrent);$(NetFrameworkCurrent) + + + + + + + diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index c82088bcb6e98..67d25c68cd05b 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -323,6 +323,9 @@ + + + diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj index 95118ff34a34c..e9dd22e302f7a 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj @@ -70,7 +70,7 @@ - + diff --git a/src/libraries/System.Runtime/tests/System/ArgumentExceptionTests.cs b/src/libraries/System.Runtime/tests/System/ArgumentExceptionTests.cs index c0832946be83e..d93235c129929 100644 --- a/src/libraries/System.Runtime/tests/System/ArgumentExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/ArgumentExceptionTests.cs @@ -14,7 +14,7 @@ public static class ArgumentExceptionTests public static void Ctor_Empty() { var exception = new ArgumentException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENT, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENT, validateMessage: false); Assert.Null(exception.ParamName); } @@ -23,7 +23,7 @@ public static void Ctor_String() { string message = "the argument is wrong"; var exception = new ArgumentException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENT, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENT, message: message); Assert.Null(exception.ParamName); } @@ -33,7 +33,7 @@ public static void Ctor_String_Exception() string message = "the argument is wrong"; var innerException = new Exception("Inner exception"); var exception = new ArgumentException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENT, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENT, innerException: innerException, message: message); Assert.Null(exception.ParamName); } @@ -43,7 +43,7 @@ public static void Ctor_String_String() string message = "the argument is wrong"; string argumentName = "theArgument"; var exception = new ArgumentException(message, argumentName); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENT, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENT, validateMessage: false); Assert.Equal(argumentName, exception.ParamName); Assert.Contains(message, exception.Message); Assert.Contains(argumentName, exception.Message); @@ -56,7 +56,7 @@ public static void Ctor_String_String_Exception() string argumentName = "theArgument"; var innerException = new Exception("Inner exception"); var exception = new ArgumentException(message, argumentName, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENT, innerException: innerException, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENT, innerException: innerException, validateMessage: false); Assert.Equal(argumentName, exception.ParamName); Assert.Contains(message, exception.Message); Assert.Contains(argumentName, exception.Message); diff --git a/src/libraries/System.Runtime/tests/System/ArgumentNullExceptionTests.cs b/src/libraries/System.Runtime/tests/System/ArgumentNullExceptionTests.cs index f872b36d441dc..91520e0a93669 100644 --- a/src/libraries/System.Runtime/tests/System/ArgumentNullExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/ArgumentNullExceptionTests.cs @@ -14,7 +14,7 @@ public static class ArgumentNullExceptionTests public static void Ctor_Empty() { var exception = new ArgumentNullException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: E_POINTER, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: E_POINTER, validateMessage: false); Assert.Null(exception.ParamName); } @@ -23,7 +23,7 @@ public static void Ctor_String() { string argumentName = "theNullArgument"; var exception = new ArgumentNullException(argumentName); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: E_POINTER, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: E_POINTER, validateMessage: false); Assert.Contains(argumentName, exception.Message); } @@ -33,7 +33,7 @@ public static void Ctor_String_Exception() string message = "the argument is null"; var innerException = new Exception("Inner exception"); var exception = new ArgumentNullException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: E_POINTER, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: E_POINTER, innerException: innerException, message: message); Assert.Null(exception.ParamName); } @@ -43,7 +43,7 @@ public static void Ctor_String_String() string message = "the argument is null"; string argumentName = "theNullArgument"; var exception = new ArgumentNullException(argumentName, message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: E_POINTER, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: E_POINTER, validateMessage: false); Assert.Equal(argumentName, exception.ParamName); Assert.Contains(message, exception.Message); Assert.Contains(argumentName, exception.Message); diff --git a/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs b/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs index d3785552eb390..ba14619ae82f1 100644 --- a/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs @@ -14,7 +14,7 @@ public static class ArgumentOutOfRangeExceptionTests public static void Ctor_Empty() { var exception = new ArgumentOutOfRangeException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENTOUTOFRANGE, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENTOUTOFRANGE, validateMessage: false); Assert.Null(exception.ParamName); Assert.Null(exception.ActualValue); } @@ -24,7 +24,7 @@ public static void Ctor_String() { string argumentName = "theArgument"; var exception = new ArgumentOutOfRangeException(argumentName); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENTOUTOFRANGE, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENTOUTOFRANGE, validateMessage: false); Assert.Equal(argumentName, exception.ParamName); Assert.Null(exception.ActualValue); } @@ -35,7 +35,7 @@ public static void Ctor_String_Exception() string message = "the argument is out of range"; var innerException = new Exception("Inner exception"); var exception = new ArgumentOutOfRangeException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENTOUTOFRANGE, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENTOUTOFRANGE, innerException: innerException, message: message); Assert.Null(exception.ParamName); Assert.Null(exception.ActualValue); } @@ -46,7 +46,7 @@ public static void Ctor_String_String() string message = "the argument is out of range"; string argumentName = "theArgument"; var exception = new ArgumentOutOfRangeException(argumentName, message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENTOUTOFRANGE, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENTOUTOFRANGE, validateMessage: false); Assert.Equal(argumentName, exception.ParamName); Assert.Null(exception.ActualValue); Assert.Contains(message, exception.Message); @@ -60,7 +60,7 @@ public static void Ctor_String_Object_String() string argumentName = "theArgument"; int argumentValue = Int32.MaxValue; var exception = new ArgumentOutOfRangeException(argumentName, argumentValue, message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENTOUTOFRANGE, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARGUMENTOUTOFRANGE, validateMessage: false); Assert.Equal(argumentName, exception.ParamName); Assert.Contains(message, exception.Message); Assert.Contains(argumentName, exception.Message); diff --git a/src/libraries/System.Runtime/tests/System/ArithmeticExceptionTests.cs b/src/libraries/System.Runtime/tests/System/ArithmeticExceptionTests.cs index bd1ede2f2656e..7a8eb22dc97bb 100644 --- a/src/libraries/System.Runtime/tests/System/ArithmeticExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/ArithmeticExceptionTests.cs @@ -14,7 +14,7 @@ public static class ArithmeticExceptionTests public static void Ctor_Empty() { var exception = new ArithmeticException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARITHMETIC, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARITHMETIC, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "arithmetic operation error"; var exception = new ArithmeticException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARITHMETIC, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARITHMETIC, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "arithmetic operation error"; var innerException = new Exception("Inner exception"); var exception = new ArithmeticException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARITHMETIC, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARITHMETIC, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/ArrayTypeMismatchExceptionTests.cs b/src/libraries/System.Runtime/tests/System/ArrayTypeMismatchExceptionTests.cs index d017250e38711..d59b91470d3ad 100644 --- a/src/libraries/System.Runtime/tests/System/ArrayTypeMismatchExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/ArrayTypeMismatchExceptionTests.cs @@ -14,7 +14,7 @@ public static class ArrayTypeMismatchExceptionTests public static void Ctor_Empty() { var exception = new ArrayTypeMismatchException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARRAYTYPEMISMATCH, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARRAYTYPEMISMATCH, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "array type mismatch"; var exception = new ArrayTypeMismatchException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARRAYTYPEMISMATCH, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARRAYTYPEMISMATCH, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "array type mismatch"; var innerException = new Exception("Inner exception"); var exception = new ArrayTypeMismatchException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_ARRAYTYPEMISMATCH, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_ARRAYTYPEMISMATCH, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/BadImageFormatExceptionTests.cs b/src/libraries/System.Runtime/tests/System/BadImageFormatExceptionTests.cs index 497f515f6e1cb..70be2d0677899 100644 --- a/src/libraries/System.Runtime/tests/System/BadImageFormatExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/BadImageFormatExceptionTests.cs @@ -14,7 +14,7 @@ public static class BadImageFormatExceptionTests public static void Ctor_Empty() { var exception = new BadImageFormatException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_BADIMAGEFORMAT, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_BADIMAGEFORMAT, validateMessage: false); Assert.Null(exception.FileName); } @@ -23,7 +23,7 @@ public static void Ctor_String() { string message = "this is not the file you're looking for"; var exception = new BadImageFormatException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_BADIMAGEFORMAT, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_BADIMAGEFORMAT, message: message); Assert.Null(exception.FileName); } @@ -33,7 +33,7 @@ public static void Ctor_String_Exception() string message = "this is not the file you're looking for"; var innerException = new Exception("Inner exception"); var exception = new BadImageFormatException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_BADIMAGEFORMAT, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_BADIMAGEFORMAT, innerException: innerException, message: message); Assert.Null(exception.FileName); } @@ -43,7 +43,7 @@ public static void Ctor_String_String() string message = "this is not the file you're looking for"; string fileName = "file.txt"; var exception = new BadImageFormatException(message, fileName); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_BADIMAGEFORMAT, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_BADIMAGEFORMAT, message: message); Assert.Equal(fileName, exception.FileName); } @@ -54,7 +54,7 @@ public static void Ctor_String_String_Exception() string fileName = "file.txt"; var innerException = new Exception("Inner exception"); var exception = new BadImageFormatException(message, fileName, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_BADIMAGEFORMAT, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_BADIMAGEFORMAT, innerException: innerException, message: message); Assert.Equal(fileName, exception.FileName); } diff --git a/src/libraries/System.Runtime/tests/System/Collections/Generic/KeyNotFoundExceptionTests.cs b/src/libraries/System.Runtime/tests/System/Collections/Generic/KeyNotFoundExceptionTests.cs index c3cf6a6c4e491..e3013ab165a33 100644 --- a/src/libraries/System.Runtime/tests/System/Collections/Generic/KeyNotFoundExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/Collections/Generic/KeyNotFoundExceptionTests.cs @@ -16,7 +16,7 @@ public static class KeyNotFoundExceptionTests public static void Ctor_Empty() { var exception = new KeyNotFoundException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_KEYNOTFOUND, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_KEYNOTFOUND, validateMessage: false); } [Fact] @@ -24,7 +24,7 @@ public static void Ctor_String() { string message = "this is not the key you're looking for"; var exception = new KeyNotFoundException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_KEYNOTFOUND, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_KEYNOTFOUND, message: message); } [Fact] @@ -33,7 +33,7 @@ public static void Ctor_String_Exception() string message = "this is not the key you're looking for"; var innerException = new Exception("Inner exception"); var exception = new KeyNotFoundException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_KEYNOTFOUND, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_KEYNOTFOUND, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/DivideByZeroExceptionTests.cs b/src/libraries/System.Runtime/tests/System/DivideByZeroExceptionTests.cs index 0e86ae49b4b86..a9117b7083338 100644 --- a/src/libraries/System.Runtime/tests/System/DivideByZeroExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/DivideByZeroExceptionTests.cs @@ -14,7 +14,7 @@ public static class DivideByZeroExceptionTests public static void Ctor_Empty() { var exception = new DivideByZeroException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_DIVIDEBYZERO, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_DIVIDEBYZERO, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "divide by zero"; var exception = new DivideByZeroException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_DIVIDEBYZERO, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_DIVIDEBYZERO, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "divide by zero"; var innerException = new Exception("Inner exception"); var exception = new DivideByZeroException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_DIVIDEBYZERO, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_DIVIDEBYZERO, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/Exceptions.Utility.cs b/src/libraries/System.Runtime/tests/System/Exception.Helpers.cs similarity index 96% rename from src/libraries/System.Runtime/tests/System/Exceptions.Utility.cs rename to src/libraries/System.Runtime/tests/System/Exception.Helpers.cs index d7d0967c94dca..a39cd04998828 100644 --- a/src/libraries/System.Runtime/tests/System/Exceptions.Utility.cs +++ b/src/libraries/System.Runtime/tests/System/Exception.Helpers.cs @@ -7,7 +7,7 @@ namespace System.Tests { - public static class ExceptionUtility + public static class ExceptionHelpers { public static void ValidateExceptionProperties(Exception e, int hResult, diff --git a/src/libraries/System.Runtime/tests/System/ExceptionTests.cs b/src/libraries/System.Runtime/tests/System/ExceptionTests.cs index 6d663486205a3..4704368e6b9a5 100644 --- a/src/libraries/System.Runtime/tests/System/ExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/ExceptionTests.cs @@ -21,7 +21,7 @@ public static class ExceptionTests public static void Ctor_Empty() { var exception = new Exception(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_EXCEPTION, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_EXCEPTION, validateMessage: false); } [Fact] @@ -29,7 +29,7 @@ public static void Ctor_String() { string message = "something went wrong"; var exception = new Exception(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_EXCEPTION, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_EXCEPTION, message: message); } [Fact] @@ -38,7 +38,7 @@ public static void Ctor_String_Exception() string message = "something went wrong"; var innerException = new Exception("Inner exception"); var exception = new Exception(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_EXCEPTION, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_EXCEPTION, innerException: innerException, message: message); } [Fact] diff --git a/src/libraries/System.Runtime/tests/System/FormatExceptionTests.cs b/src/libraries/System.Runtime/tests/System/FormatExceptionTests.cs index 79924d6b53b5b..a5f78ae97a36e 100644 --- a/src/libraries/System.Runtime/tests/System/FormatExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/FormatExceptionTests.cs @@ -14,7 +14,7 @@ public static class FormatExceptionTests public static void Ctor_Empty() { var exception = new FormatException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_FORMAT, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_FORMAT, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "bad format"; var exception = new FormatException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_FORMAT, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_FORMAT, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "bad format"; var innerException = new Exception("Inner exception"); var exception = new FormatException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_FORMAT, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_FORMAT, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/IO/DirectoryNotFoundException.InteropTests.cs b/src/libraries/System.Runtime/tests/System/IO/DirectoryNotFoundException.InteropTests.cs index 37c4c89c4ba93..5a1a533ba0702 100644 --- a/src/libraries/System.Runtime/tests/System/IO/DirectoryNotFoundException.InteropTests.cs +++ b/src/libraries/System.Runtime/tests/System/IO/DirectoryNotFoundException.InteropTests.cs @@ -19,7 +19,7 @@ public static void From_HR(int hr) DirectoryNotFoundException exception = Assert.IsAssignableFrom(Marshal.GetExceptionForHR(hr, new IntPtr(-1))); // Don't validate the message. Currently .NET Native does not produce HR-specific messages - ExceptionUtility.ValidateExceptionProperties(exception, hResult: hr, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: hr, validateMessage: false); } } } diff --git a/src/libraries/System.Runtime/tests/System/IO/DirectoryNotFoundExceptionTests.cs b/src/libraries/System.Runtime/tests/System/IO/DirectoryNotFoundExceptionTests.cs index 229acd4b0d2d4..f510afd9d1ca0 100644 --- a/src/libraries/System.Runtime/tests/System/IO/DirectoryNotFoundExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/IO/DirectoryNotFoundExceptionTests.cs @@ -15,7 +15,7 @@ public static class DirectoryNotFoundExceptionTests public static void Ctor_Empty() { var exception = new DirectoryNotFoundException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, validateMessage: false); } [Fact] @@ -23,7 +23,7 @@ public static void Ctor_String() { string message = "That page was missing from the directory."; var exception = new DirectoryNotFoundException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, message: message); } [Fact] @@ -32,7 +32,7 @@ public static void Ctor_String_Exception() string message = "That page was missing from the directory."; var innerException = new Exception("Inner exception"); var exception = new DirectoryNotFoundException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_DIRECTORYNOTFOUND, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/IO/FileLoadException.InteropTests.cs b/src/libraries/System.Runtime/tests/System/IO/FileLoadException.InteropTests.cs index 6cb7e62e7542d..4072851e06706 100644 --- a/src/libraries/System.Runtime/tests/System/IO/FileLoadException.InteropTests.cs +++ b/src/libraries/System.Runtime/tests/System/IO/FileLoadException.InteropTests.cs @@ -44,7 +44,7 @@ public static void Fom_HR(int hr) Assert.NotNull(fileLoadException); // Don't validate the message. Currently .NET Native does not produce HR-specific messages - ExceptionUtility.ValidateExceptionProperties(fileLoadException, hResult: hr, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(fileLoadException, hResult: hr, validateMessage: false); Assert.Null(fileLoadException.FileName); } } diff --git a/src/libraries/System.Runtime/tests/System/IO/FileLoadExceptionTests.cs b/src/libraries/System.Runtime/tests/System/IO/FileLoadExceptionTests.cs index 9d4549742e8a1..b7479e868dadd 100644 --- a/src/libraries/System.Runtime/tests/System/IO/FileLoadExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/IO/FileLoadExceptionTests.cs @@ -13,7 +13,7 @@ public static class FileLoadExceptionTests public static void Ctor_Empty() { var exception = new FileLoadException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILELOAD, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILELOAD, validateMessage: false); Assert.Null(exception.FileName); } @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "this is not the file you're looking for"; var exception = new FileLoadException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILELOAD, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILELOAD, message: message); Assert.Null(exception.FileName); } @@ -32,7 +32,7 @@ public static void Ctor_String_Exception() string message = "this is not the file you're looking for"; var innerException = new Exception("Inner exception"); var exception = new FileLoadException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILELOAD, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILELOAD, innerException: innerException, message: message); Assert.Null(exception.FileName); } @@ -42,7 +42,7 @@ public static void Ctor_String_String() string message = "this is not the file you're looking for"; string fileName = "file.txt"; var exception = new FileLoadException(message, fileName); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILELOAD, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILELOAD, message: message); Assert.Equal(fileName, exception.FileName); } @@ -53,7 +53,7 @@ public static void Ctor_String_String_Exception() string fileName = "file.txt"; var innerException = new Exception("Inner exception"); var exception = new FileLoadException(message, fileName, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILELOAD, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILELOAD, innerException: innerException, message: message); Assert.Equal(fileName, exception.FileName); } diff --git a/src/libraries/System.Runtime/tests/System/IO/FileNotFoundException.InteropTests.cs b/src/libraries/System.Runtime/tests/System/IO/FileNotFoundException.InteropTests.cs index bd6887359f06a..5ccc505f93a16 100644 --- a/src/libraries/System.Runtime/tests/System/IO/FileNotFoundException.InteropTests.cs +++ b/src/libraries/System.Runtime/tests/System/IO/FileNotFoundException.InteropTests.cs @@ -18,7 +18,7 @@ public static void From_HR(int hr) FileNotFoundException exception = Assert.IsAssignableFrom(Marshal.GetExceptionForHR(hr, new IntPtr(-1))); // Don't validate the message. Currently .NET Native does not produce HR-specific messages - ExceptionUtility.ValidateExceptionProperties(exception, hResult: hr, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: hr, validateMessage: false); } } } diff --git a/src/libraries/System.Runtime/tests/System/IO/FileNotFoundExceptionTests.cs b/src/libraries/System.Runtime/tests/System/IO/FileNotFoundExceptionTests.cs index c9e8ae9368f9c..73f39702f1655 100644 --- a/src/libraries/System.Runtime/tests/System/IO/FileNotFoundExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/IO/FileNotFoundExceptionTests.cs @@ -13,7 +13,7 @@ public static class FileNotFoundExceptionTests public static void Ctor_Empty() { var exception = new FileNotFoundException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILENOTFOUND, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILENOTFOUND, validateMessage: false); Assert.Null(exception.FileName); } @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "this is not the file you're looking for"; var exception = new FileNotFoundException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILENOTFOUND, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILENOTFOUND, message: message); Assert.Null(exception.FileName); } @@ -32,7 +32,7 @@ public static void Ctor_String_Exception() string message = "this is not the file you're looking for"; var innerException = new Exception("Inner exception"); var exception = new FileNotFoundException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILENOTFOUND, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILENOTFOUND, innerException: innerException, message: message); Assert.Null(exception.FileName); } @@ -42,7 +42,7 @@ public static void Ctor_String_String() string message = "this is not the file you're looking for"; string fileName = "file.txt"; var exception = new FileNotFoundException(message, fileName); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILENOTFOUND, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILENOTFOUND, message: message); Assert.Equal(fileName, exception.FileName); } @@ -53,7 +53,7 @@ public static void Ctor_String_String_Exception() string fileName = "file.txt"; var innerException = new Exception("Inner exception"); var exception = new FileNotFoundException(message, fileName, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILENOTFOUND, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_FILENOTFOUND, innerException: innerException, message: message); Assert.Equal(fileName, exception.FileName); } diff --git a/src/libraries/System.Runtime/tests/System/IO/IOExceptionTests.cs b/src/libraries/System.Runtime/tests/System/IO/IOExceptionTests.cs index ab5258c266857..14b769eb1f360 100644 --- a/src/libraries/System.Runtime/tests/System/IO/IOExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/IO/IOExceptionTests.cs @@ -16,7 +16,7 @@ public static class IOExceptionTests public static void Ctor_Empty() { var exception = new IOException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_IO, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_IO, validateMessage: false); } [Fact] @@ -24,7 +24,7 @@ public static void Ctor_String() { string message = "IO failure"; var exception = new IOException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_IO, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_IO, message: message); } [Fact] @@ -33,7 +33,7 @@ public static void Ctor_String_Exception() string message = "IO failure"; var innerException = new Exception("Inner exception"); var exception = new IOException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_IO, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_IO, innerException: innerException, message: message); } [Fact] @@ -42,7 +42,7 @@ public static void Ctor_String_Int32() string message = "IO failure"; int hResult = unchecked((int)0x80424242); var exception = new IOException(message, hResult); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: hResult, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: hResult, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/IO/PathTooLongException.InteropTests.cs b/src/libraries/System.Runtime/tests/System/IO/PathTooLongException.InteropTests.cs index 1a21cad4a34ed..11c93f5fcf54d 100644 --- a/src/libraries/System.Runtime/tests/System/IO/PathTooLongException.InteropTests.cs +++ b/src/libraries/System.Runtime/tests/System/IO/PathTooLongException.InteropTests.cs @@ -15,7 +15,7 @@ public static void From_HR() { int hr = HResults.COR_E_PATHTOOLONG; PathTooLongException exception = Assert.IsAssignableFrom(Marshal.GetExceptionForHR(hr, new IntPtr(-1))); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: hr, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: hr, validateMessage: false); } } } diff --git a/src/libraries/System.Runtime/tests/System/IO/PathTooLongExceptionTests.cs b/src/libraries/System.Runtime/tests/System/IO/PathTooLongExceptionTests.cs index 8bf3dd2ab5f1f..5d05b283cbedb 100644 --- a/src/libraries/System.Runtime/tests/System/IO/PathTooLongExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/IO/PathTooLongExceptionTests.cs @@ -16,7 +16,7 @@ public static class PathTooLongExceptionTests public static void Ctor_Empty() { var exception = new PathTooLongException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_PATHTOOLONG, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_PATHTOOLONG, validateMessage: false); } [Fact] @@ -24,7 +24,7 @@ public static void Ctor_String() { string message = "This path is too long to hike in a single day."; var exception = new PathTooLongException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_PATHTOOLONG, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_PATHTOOLONG, message: message); } [Fact] @@ -33,7 +33,7 @@ public static void Ctor_String_Exception() string message = "This path is too long to hike in a single day."; var innerException = new Exception("Inner exception"); var exception = new PathTooLongException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: HResults.COR_E_PATHTOOLONG, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: HResults.COR_E_PATHTOOLONG, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/IndexOutOfRangeExceptionTests.cs b/src/libraries/System.Runtime/tests/System/IndexOutOfRangeExceptionTests.cs index 69d83851efcda..98314f591f501 100644 --- a/src/libraries/System.Runtime/tests/System/IndexOutOfRangeExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/IndexOutOfRangeExceptionTests.cs @@ -14,7 +14,7 @@ public static class IndexOutOfRangeExceptionTests public static void Ctor_Empty() { var exception = new IndexOutOfRangeException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_INDEXOUTOFRANGE, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_INDEXOUTOFRANGE, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "out of range"; var exception = new IndexOutOfRangeException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_INDEXOUTOFRANGE, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_INDEXOUTOFRANGE, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "out of range"; var innerException = new Exception("Inner exception"); var exception = new IndexOutOfRangeException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_INDEXOUTOFRANGE, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_INDEXOUTOFRANGE, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/InvalidCastExceptionTests.cs b/src/libraries/System.Runtime/tests/System/InvalidCastExceptionTests.cs index ac0bb5ae408f6..291d5137a7e2b 100644 --- a/src/libraries/System.Runtime/tests/System/InvalidCastExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/InvalidCastExceptionTests.cs @@ -14,7 +14,7 @@ public static class InvalidCastExceptionTests public static void Ctor_Empty() { var exception = new InvalidCastException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDCAST, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDCAST, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "wrong type"; var exception = new InvalidCastException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDCAST, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDCAST, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "wrong type"; var innerException = new Exception("Inner exception"); var exception = new InvalidCastException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDCAST, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDCAST, innerException: innerException, message: message); } [Fact] @@ -40,7 +40,7 @@ public static void Ctor_String_Int32() string message = "wrong type"; int errorCode = unchecked((int)0x80424242); var exception = new InvalidCastException(message, errorCode); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: errorCode, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: errorCode, message: message); } } diff --git a/src/libraries/System.Runtime/tests/System/InvalidOperationExceptionTests.cs b/src/libraries/System.Runtime/tests/System/InvalidOperationExceptionTests.cs index d1a877aca2516..7448b5bb8e25e 100644 --- a/src/libraries/System.Runtime/tests/System/InvalidOperationExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/InvalidOperationExceptionTests.cs @@ -14,7 +14,7 @@ public static class InvalidOperationExceptionTests public static void Ctor_Empty() { var exception = new InvalidOperationException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDOPERATION, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDOPERATION, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "invalid operation"; var exception = new InvalidOperationException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDOPERATION, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDOPERATION, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "invalid operation"; var innerException = new Exception("Inner exception"); var exception = new InvalidOperationException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDOPERATION, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDOPERATION, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/InvalidProgramExceptionTests.cs b/src/libraries/System.Runtime/tests/System/InvalidProgramExceptionTests.cs index 17488ceb1e40e..98ae359537af2 100644 --- a/src/libraries/System.Runtime/tests/System/InvalidProgramExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/InvalidProgramExceptionTests.cs @@ -14,7 +14,7 @@ public static class InvalidProgramExceptionTests public static void Ctor_Empty() { var exception = new InvalidProgramException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDPROGRAM, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDPROGRAM, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "bad program"; var exception = new InvalidProgramException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDPROGRAM, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDPROGRAM, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "bad program"; var innerException = new Exception("Inner exception"); var exception = new InvalidProgramException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDPROGRAM, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_INVALIDPROGRAM, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/MemberAccessExceptionTests.cs b/src/libraries/System.Runtime/tests/System/MemberAccessExceptionTests.cs index 6ffc2912009f6..46b268ff311e4 100644 --- a/src/libraries/System.Runtime/tests/System/MemberAccessExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/MemberAccessExceptionTests.cs @@ -14,7 +14,7 @@ public static class MemberAccessExceptionTests public static void Ctor_Empty() { var exception = new MemberAccessException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_MEMBERACCESS, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_MEMBERACCESS, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "you cannot access this member"; var exception = new MemberAccessException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_MEMBERACCESS, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_MEMBERACCESS, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "you cannot access this member"; var innerException = new Exception("Inner exception"); var exception = new MemberAccessException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_MEMBERACCESS, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_MEMBERACCESS, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/NotImplementedExceptionTests.cs b/src/libraries/System.Runtime/tests/System/NotImplementedExceptionTests.cs index f2a19dddafedf..dfc8ab299a9f0 100644 --- a/src/libraries/System.Runtime/tests/System/NotImplementedExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/NotImplementedExceptionTests.cs @@ -14,7 +14,7 @@ public static class NotImplementedExceptionTests public static void Ctor_Empty() { var exception = new NotImplementedException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: E_NOTIMPL, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: E_NOTIMPL, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "not implemented"; var exception = new NotImplementedException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: E_NOTIMPL, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: E_NOTIMPL, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "not implemented"; var innerException = new Exception("Inner exception"); var exception = new NotImplementedException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: E_NOTIMPL, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: E_NOTIMPL, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/NotSupportedExceptionTests.cs b/src/libraries/System.Runtime/tests/System/NotSupportedExceptionTests.cs index a5aa0905d74b0..6aa28beffbd87 100644 --- a/src/libraries/System.Runtime/tests/System/NotSupportedExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/NotSupportedExceptionTests.cs @@ -14,7 +14,7 @@ public static class NotSupportedExceptionTests public static void Ctor_Empty() { var exception = new NotSupportedException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_NOTSUPPORTED, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_NOTSUPPORTED, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "not supported"; var exception = new NotSupportedException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_NOTSUPPORTED, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_NOTSUPPORTED, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "not supported"; var innerException = new Exception("Inner exception"); var exception = new NotSupportedException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_NOTSUPPORTED, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_NOTSUPPORTED, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/ObjectDisposedExceptionTests.cs b/src/libraries/System.Runtime/tests/System/ObjectDisposedExceptionTests.cs index 8345a782fe7bc..4334b9f29c690 100644 --- a/src/libraries/System.Runtime/tests/System/ObjectDisposedExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/ObjectDisposedExceptionTests.cs @@ -15,7 +15,7 @@ public static void Ctor_String() { string objectName = "theObject"; var exception = new ObjectDisposedException(objectName); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_OBJECTDISPOSED, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_OBJECTDISPOSED, validateMessage: false); Assert.Contains(objectName, exception.Message); var exceptionNullObjectName = new ObjectDisposedException(null); @@ -28,7 +28,7 @@ public static void Ctor_String_Exception() string message = "object disposed"; var innerException = new Exception("Inner exception"); var exception = new ObjectDisposedException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_OBJECTDISPOSED, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_OBJECTDISPOSED, innerException: innerException, message: message); Assert.Equal("", exception.ObjectName); } @@ -38,7 +38,7 @@ public static void Ctor_String_String() string message = "object disposed"; string objectName = "theObject"; var exception = new ObjectDisposedException(objectName, message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_OBJECTDISPOSED, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_OBJECTDISPOSED, validateMessage: false); Assert.Equal(objectName, exception.ObjectName); Assert.Contains(message, exception.Message); Assert.Contains(objectName, exception.Message); diff --git a/src/libraries/System.Runtime/tests/System/OutOfMemoryExceptionTests.cs b/src/libraries/System.Runtime/tests/System/OutOfMemoryExceptionTests.cs index 39c3fd1e9b6a2..7585bceb30528 100644 --- a/src/libraries/System.Runtime/tests/System/OutOfMemoryExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/OutOfMemoryExceptionTests.cs @@ -14,7 +14,7 @@ public static class OutOfMemoryExceptionTests public static void Ctor_Empty() { var exception = new OutOfMemoryException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_OUTOFMEMORY, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_OUTOFMEMORY, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "out of memory"; var exception = new OutOfMemoryException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_OUTOFMEMORY, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_OUTOFMEMORY, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "out of memory"; var innerException = new Exception("Inner exception"); var exception = new OutOfMemoryException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_OUTOFMEMORY, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_OUTOFMEMORY, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/OverflowExceptionTests.cs b/src/libraries/System.Runtime/tests/System/OverflowExceptionTests.cs index 2c239b180c6a3..348fc7b15aa99 100644 --- a/src/libraries/System.Runtime/tests/System/OverflowExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/OverflowExceptionTests.cs @@ -14,7 +14,7 @@ public static class OverflowExceptionTests public static void Ctor_Empty() { var exception = new OverflowException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_OVERFLOW, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_OVERFLOW, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "overflow"; var exception = new OverflowException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_OVERFLOW, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_OVERFLOW, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "overflow"; var innerException = new Exception("Inner exception"); var exception = new OverflowException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_OVERFLOW, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_OVERFLOW, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/PlatformNotSupportedExceptionTests.cs b/src/libraries/System.Runtime/tests/System/PlatformNotSupportedExceptionTests.cs index 1e0fc9452e969..0897004bd2cce 100644 --- a/src/libraries/System.Runtime/tests/System/PlatformNotSupportedExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/PlatformNotSupportedExceptionTests.cs @@ -14,7 +14,7 @@ public static class PlatformNotSupportedExceptionTests public static void Ctor_Empty() { var exception = new PlatformNotSupportedException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_PLATFORMNOTSUPPORTED, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_PLATFORMNOTSUPPORTED, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "platform not supported"; var exception = new PlatformNotSupportedException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_PLATFORMNOTSUPPORTED, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_PLATFORMNOTSUPPORTED, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "platform not supported"; var innerException = new Exception("Inner exception"); var exception = new PlatformNotSupportedException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_PLATFORMNOTSUPPORTED, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_PLATFORMNOTSUPPORTED, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/RankExceptionTests.cs b/src/libraries/System.Runtime/tests/System/RankExceptionTests.cs index 6a3bad220dcdd..6da6e3f614f58 100644 --- a/src/libraries/System.Runtime/tests/System/RankExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/RankExceptionTests.cs @@ -14,7 +14,7 @@ public static class RankExceptionTests public static void Ctor_Empty() { var exception = new RankException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_RANK, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_RANK, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "bad rank"; var exception = new RankException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_RANK, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_RANK, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "bad rank"; var innerException = new Exception("Inner exception"); var exception = new RankException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_RANK, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_RANK, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/Security/SecurityExceptionTests.cs b/src/libraries/System.Runtime/tests/System/Security/SecurityExceptionTests.cs index 57596cb863b8b..f6462cb5ca332 100644 --- a/src/libraries/System.Runtime/tests/System/Security/SecurityExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/Security/SecurityExceptionTests.cs @@ -17,7 +17,7 @@ public static class SecurityExceptionTests public static void Ctor_Empty() { var exception = new SecurityException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_SECURITY, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_SECURITY, validateMessage: false); } [Fact] @@ -25,7 +25,7 @@ public static void Ctor_String() { string message = "security problem"; var exception = new SecurityException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_SECURITY, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_SECURITY, message: message); } [Fact] @@ -34,7 +34,7 @@ public static void Ctor_String_Exception() string message = "security problem"; var innerException = new Exception("Inner exception"); var exception = new SecurityException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_SECURITY, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_SECURITY, innerException: innerException, message: message); } [Fact] @@ -42,7 +42,7 @@ public static void Ctor_String_Type() { string message = "security problem"; var exception = new SecurityException(message, typeof(SecurityExceptionTests)); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_SECURITY, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_SECURITY, message: message); Assert.Equal(typeof(SecurityExceptionTests), exception.PermissionType); } @@ -51,7 +51,7 @@ public static void Ctor_String_Type_String() { string message = "security problem"; var exception = new SecurityException(message, typeof(SecurityExceptionTests), "permission state"); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_SECURITY, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_SECURITY, message: message); Assert.Equal(typeof(SecurityExceptionTests), exception.PermissionType); Assert.Equal("permission state", exception.PermissionState); } diff --git a/src/libraries/System.Runtime/tests/System/TimeoutExceptionTests.cs b/src/libraries/System.Runtime/tests/System/TimeoutExceptionTests.cs index 652fe1f0b238e..3a4a9722441b8 100644 --- a/src/libraries/System.Runtime/tests/System/TimeoutExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/TimeoutExceptionTests.cs @@ -14,7 +14,7 @@ public static class TimeoutExceptionTests public static void Ctor_Empty() { var exception = new TimeoutException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_TIMEOUT, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_TIMEOUT, validateMessage: false); } [Fact] @@ -22,7 +22,7 @@ public static void Ctor_String() { string message = "timeout"; var exception = new TimeoutException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_TIMEOUT, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_TIMEOUT, message: message); } [Fact] @@ -31,7 +31,7 @@ public static void Ctor_String_Exception() string message = "timeout"; var innerException = new Exception("Inner exception"); var exception = new TimeoutException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_TIMEOUT, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_TIMEOUT, innerException: innerException, message: message); } } } diff --git a/src/libraries/System.Runtime/tests/System/TypeLoadExceptionTests.cs b/src/libraries/System.Runtime/tests/System/TypeLoadExceptionTests.cs index 2fe5e13fd7649..31e80b39ef20e 100644 --- a/src/libraries/System.Runtime/tests/System/TypeLoadExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/TypeLoadExceptionTests.cs @@ -15,7 +15,7 @@ public static class TypeLoadExceptionTests public static void Ctor_Empty() { var exception = new TypeLoadException(); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_TYPELOAD, validateMessage: false); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_TYPELOAD, validateMessage: false); Assert.Equal("", exception.TypeName); } @@ -24,7 +24,7 @@ public static void Ctor_String() { string message = "type failed to load"; var exception = new TypeLoadException(message); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_TYPELOAD, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_TYPELOAD, message: message); Assert.Equal("", exception.TypeName); } @@ -34,7 +34,7 @@ public static void Ctor_String_Exception() string message = "type failed to load"; var innerException = new Exception("Inner exception"); var exception = new TypeLoadException(message, innerException); - ExceptionUtility.ValidateExceptionProperties(exception, hResult: COR_E_TYPELOAD, innerException: innerException, message: message); + ExceptionHelpers.ValidateExceptionProperties(exception, hResult: COR_E_TYPELOAD, innerException: innerException, message: message); Assert.Equal("", exception.TypeName); } } diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 834b513f5ec38..e0224d5b0c30d 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -887,18 +887,12 @@ - - diff --git a/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.csproj b/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.csproj deleted file mode 100644 index 6ab597f0b08ad..0000000000000 --- a/src/mono/msbuild/AndroidTestRunner/AndroidTestRunner.csproj +++ /dev/null @@ -1,8 +0,0 @@ - - - Exe - - - - - diff --git a/src/mono/msbuild/AppleTestRunner/AppleTestRunner.csproj b/src/mono/msbuild/AppleTestRunner/AppleTestRunner.csproj deleted file mode 100644 index 6ab597f0b08ad..0000000000000 --- a/src/mono/msbuild/AppleTestRunner/AppleTestRunner.csproj +++ /dev/null @@ -1,8 +0,0 @@ - - - Exe - - - - - From 466513449069d2a7d11fb25986707af05bfbf26d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Thu, 14 May 2020 08:24:22 +0200 Subject: [PATCH 179/420] Fix execution of large version bubble composite images (#36373) Large-bubble composite images are special in having more entries in the manifest metadata than in the component assembly table: When the build starts, all component assemblies get hard-injected into the manifest metadata and subsequently we lazily add those additional reference assemblies (within the same version bubble) as we need for encoding signatures. Thanks Tomas --- src/coreclr/src/vm/ceeload.cpp | 2 +- src/coreclr/src/vm/nativeimage.cpp | 13 +++++++++---- src/coreclr/src/vm/nativeimage.h | 4 +++- src/coreclr/src/vm/zapsig.cpp | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/coreclr/src/vm/ceeload.cpp b/src/coreclr/src/vm/ceeload.cpp index 9b9c59449c954..30f6eeef79e52 100644 --- a/src/coreclr/src/vm/ceeload.cpp +++ b/src/coreclr/src/vm/ceeload.cpp @@ -503,7 +503,7 @@ uint32_t Module::GetNativeMetadataAssemblyCount() NativeImage *compositeImage = GetCompositeNativeImage(); if (compositeImage != NULL) { - return compositeImage->GetComponentAssemblyCount(); + return compositeImage->GetManifestAssemblyCount(); } else { diff --git a/src/coreclr/src/vm/nativeimage.cpp b/src/coreclr/src/vm/nativeimage.cpp index 7cda61993ddb9..70ad31ff1a9c1 100644 --- a/src/coreclr/src/vm/nativeimage.cpp +++ b/src/coreclr/src/vm/nativeimage.cpp @@ -61,14 +61,19 @@ void NativeImage::Initialize(READYTORUN_HEADER *pHeader, LoaderAllocator *pLoade HENUMInternal assemblyEnum; HRESULT hr = m_pManifestMetadata->EnumAllInit(mdtAssemblyRef, &assemblyEnum); mdAssemblyRef assemblyRef; - int assemblyIndex = 0; + m_manifestAssemblyCount = 0; while (m_pManifestMetadata->EnumNext(&assemblyEnum, &assemblyRef)) { LPCSTR assemblyName; hr = m_pManifestMetadata->GetAssemblyRefProps(assemblyRef, NULL, NULL, &assemblyName, NULL, NULL, NULL, NULL); - m_assemblySimpleNameToIndexMap.Add(AssemblyNameIndex(assemblyName, assemblyIndex)); - assemblyIndex++; + m_assemblySimpleNameToIndexMap.Add(AssemblyNameIndex(assemblyName, m_manifestAssemblyCount)); + m_manifestAssemblyCount++; } + + // When a composite image contributes to a larger version bubble, its manifest assembly + // count may exceed its component assembly count as it may contain references to + // assemblies outside of the composite image that are part of its version bubble. + _ASSERTE(m_manifestAssemblyCount >= m_componentAssemblyCount); } NativeImage::~NativeImage() @@ -115,7 +120,7 @@ NativeImage *NativeImage::Open( #endif #ifndef DACCESS_COMPILE -Assembly *NativeImage::LoadComponentAssembly(uint32_t rowid) +Assembly *NativeImage::LoadManifestAssembly(uint32_t rowid) { STANDARD_VM_CONTRACT; diff --git a/src/coreclr/src/vm/nativeimage.h b/src/coreclr/src/vm/nativeimage.h index 2c3f538043bb0..64cbf5410c64d 100644 --- a/src/coreclr/src/vm/nativeimage.h +++ b/src/coreclr/src/vm/nativeimage.h @@ -65,6 +65,7 @@ class NativeImage IMAGE_DATA_DIRECTORY *m_pComponentAssemblies; uint32_t m_componentAssemblyCount; + uint32_t m_manifestAssemblyCount; SHash m_assemblySimpleNameToIndexMap; Crst m_eagerFixupsLock; @@ -93,8 +94,9 @@ class NativeImage uint32_t GetComponentAssemblyCount() const { return m_componentAssemblyCount; } ReadyToRunInfo *GetReadyToRunInfo() const { return m_pReadyToRunInfo; } IMDInternalImport *GetManifestMetadata() const { return m_pManifestMetadata; } + uint32_t GetManifestAssemblyCount() const { return m_manifestAssemblyCount; } - Assembly *LoadComponentAssembly(uint32_t rowid); + Assembly *LoadManifestAssembly(uint32_t rowid); PTR_READYTORUN_CORE_HEADER GetComponentAssemblyHeader(LPCUTF8 assemblySimpleName); diff --git a/src/coreclr/src/vm/zapsig.cpp b/src/coreclr/src/vm/zapsig.cpp index f0b836182f725..515ea2fb4dc1f 100644 --- a/src/coreclr/src/vm/zapsig.cpp +++ b/src/coreclr/src/vm/zapsig.cpp @@ -650,7 +650,7 @@ Module *ZapSig::DecodeModuleFromIndex(Module *fromModule, { if (nativeImage != NULL) { - pAssembly = nativeImage->LoadComponentAssembly(index); + pAssembly = nativeImage->LoadManifestAssembly(index); } else { From 5d055b9575c8c3abbb15ac8ca6f1d6b1db6eee1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Thu, 14 May 2020 09:20:14 +0200 Subject: [PATCH 180/420] Remove Microsoft.NETCore.Platforms.Future project (#36407) It's no longer used. --- ...Microsoft.NETCore.Platforms.Future.pkgproj | 18 ------------- .../Microsoft.NETCore.Platforms.Future.proj | 9 ------- .../readme.md | 1 - .../runtime.compatibility.json | 15 ----------- .../runtime.json | 18 ------------- .../runtimeGroups.props | 26 ------------------- src/libraries/pkg/descriptions.json | 5 ---- 7 files changed, 92 deletions(-) delete mode 100644 src/libraries/pkg/Microsoft.NETCore.Platforms.Future/Microsoft.NETCore.Platforms.Future.pkgproj delete mode 100644 src/libraries/pkg/Microsoft.NETCore.Platforms.Future/Microsoft.NETCore.Platforms.Future.proj delete mode 100644 src/libraries/pkg/Microsoft.NETCore.Platforms.Future/readme.md delete mode 100644 src/libraries/pkg/Microsoft.NETCore.Platforms.Future/runtime.compatibility.json delete mode 100644 src/libraries/pkg/Microsoft.NETCore.Platforms.Future/runtime.json delete mode 100644 src/libraries/pkg/Microsoft.NETCore.Platforms.Future/runtimeGroups.props diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/Microsoft.NETCore.Platforms.Future.pkgproj b/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/Microsoft.NETCore.Platforms.Future.pkgproj deleted file mode 100644 index be13ea21ac232..0000000000000 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/Microsoft.NETCore.Platforms.Future.pkgproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - true - - false - - - - - - lib/netstandard1.0 - - - - - - diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/Microsoft.NETCore.Platforms.Future.proj b/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/Microsoft.NETCore.Platforms.Future.proj deleted file mode 100644 index 24c9f63af136b..0000000000000 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/Microsoft.NETCore.Platforms.Future.proj +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/readme.md b/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/readme.md deleted file mode 100644 index 1e8e216fd6409..0000000000000 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/readme.md +++ /dev/null @@ -1 +0,0 @@ -see ..\Microsoft.NETCore.Platforms\readme.md \ No newline at end of file diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/runtime.compatibility.json b/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/runtime.compatibility.json deleted file mode 100644 index 278b1bcc7e614..0000000000000 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/runtime.compatibility.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "unix-wasm": [ - "unix-wasm" - ], - "webassembly": [ - "webassembly", - "unix" - ], - "webassembly-wasm": [ - "webassembly-wasm", - "webassembly", - "unix-wasm", - "unix" - ] -} \ No newline at end of file diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/runtime.json b/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/runtime.json deleted file mode 100644 index 07393a3db820f..0000000000000 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/runtime.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "runtimes": { - "unix-wasm": { - "#import": [] - }, - "webassembly": { - "#import": [ - "unix" - ] - }, - "webassembly-wasm": { - "#import": [ - "webassembly", - "unix-wasm" - ] - } - } -} \ No newline at end of file diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/runtimeGroups.props b/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/runtimeGroups.props deleted file mode 100644 index ff4c96a23b829..0000000000000 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms.Future/runtimeGroups.props +++ /dev/null @@ -1,26 +0,0 @@ - - - - wasm - - unix - - - unix - wasm - - - - - - - - - diff --git a/src/libraries/pkg/descriptions.json b/src/libraries/pkg/descriptions.json index 87b23a37dad8c..6d2b58594de82 100644 --- a/src/libraries/pkg/descriptions.json +++ b/src/libraries/pkg/descriptions.json @@ -260,11 +260,6 @@ "Description": "Provides runtime information required to resolve target framework, platform, and runtime specific implementations of .NETCore packages.", "CommonTypes": [] }, - { - "Name": "Microsoft.NETCore.Platforms.Future", - "Description": "Provides runtime information required to resolve target framework, platform, and runtime specific implementations of .NETCore packages. This package represents future platforms not yet supported in .NETCore stable release and is subject to change.", - "CommonTypes": [] - }, { "Name": "Microsoft.NETCore.Portable.Compatibility", "Description": "Enables compatibility with portable libraries targeting previous .NET releases like .NET Framework 4.0 and Silverlight.\nThis package supports retargeting references to classic reference assemblies (mscorlib.dll, system.dll, etc) to new contract assemblies (System.Runtime.dll, System.IO, etc). It does this in a pay-for-play way to prevent consuming assemblies from having to reference all of the contracts that happen to overlap with mscorlib. As such, when using this package you may encounter errors like\n\terror CS0012: The type 'WebRequest' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Net.Requests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.\nTo resolve these errors install the package with the same name as the missing assembly.", From 518d36145281435b2e46138506a8411fb3a40017 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 14 May 2020 08:03:12 +0000 Subject: [PATCH 181/420] [master] Update dependencies from mono/linker dotnet/llvm-project dotnet/xharness (#36336) * Update dependencies from https://github.com/mono/linker build 20200512.1 - Microsoft.NET.ILLink.Tasks: 5.0.0-preview.3.20261.2 -> 5.0.0-preview.3.20262.1 * Update dependencies from https://github.com/dotnet/llvm-project build 20200512.1 - runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: 6.0.1-alpha.1.20261.3 -> 9.0.1-alpha.1.20262.1 - runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: 6.0.1-alpha.1.20261.3 -> 9.0.1-alpha.1.20262.1 - runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: 6.0.1-alpha.1.20261.3 -> 9.0.1-alpha.1.20262.1 - runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools: 6.0.1-alpha.1.20261.3 -> 9.0.1-alpha.1.20262.1 - runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: 6.0.1-alpha.1.20261.3 -> 9.0.1-alpha.1.20262.1 - runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk: 6.0.1-alpha.1.20261.3 -> 9.0.1-alpha.1.20262.1 * Update dependencies from https://github.com/dotnet/xharness build 20200513.4 - Microsoft.DotNet.XHarness.Tests.Runners: 1.0.0-prerelease.20261.4 -> 1.0.0-prerelease.20263.4 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 32 ++++++++++++++++---------------- eng/Versions.props | 16 ++++++++-------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b6e8267ae4427..5cd35c4340f98 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -118,29 +118,29 @@ https://github.com/dotnet/runtime-assets 71b9284907ebc69e5f80b491a51084c75e0ef7d3 - + https://github.com/dotnet/llvm-project - 921922eeae800011ab13ddb5402644b86d832df0 + 783010917d17a9c8e9955d2be149deb40c8362f9 - + https://github.com/dotnet/llvm-project - 921922eeae800011ab13ddb5402644b86d832df0 + 783010917d17a9c8e9955d2be149deb40c8362f9 - + https://github.com/dotnet/llvm-project - 921922eeae800011ab13ddb5402644b86d832df0 + 783010917d17a9c8e9955d2be149deb40c8362f9 - + https://github.com/dotnet/llvm-project - 921922eeae800011ab13ddb5402644b86d832df0 + 783010917d17a9c8e9955d2be149deb40c8362f9 - + https://github.com/dotnet/llvm-project - 921922eeae800011ab13ddb5402644b86d832df0 + 783010917d17a9c8e9955d2be149deb40c8362f9 - + https://github.com/dotnet/llvm-project - 921922eeae800011ab13ddb5402644b86d832df0 + 783010917d17a9c8e9955d2be149deb40c8362f9 https://github.com/dotnet/runtime @@ -170,13 +170,13 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - ffec224a2a69f0cde4c43d9c90090dcb294ca6c6 + df72dcfc27e27735c84c68507426a568799b66e9 - + https://github.com/dotnet/xharness - 5365f3db98459bc56b1faa2d73657269ab5b8956 + 1111899797c23fe4039cad22afd640522519306d diff --git a/eng/Versions.props b/eng/Versions.props index 457e9a4a90704..1fc593d2792ea 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -113,7 +113,7 @@ 4.8.0 16.7.0-preview-20200429-01 - 1.0.0-prerelease.20261.4 + 1.0.0-prerelease.20263.4 2.4.1 1.2.1 2.0.5 @@ -122,14 +122,14 @@ 3.1.0-preview-20200129.1 - 5.0.0-preview.3.20261.2 + 5.0.0-preview.3.20262.1 - 6.0.1-alpha.1.20261.3 - 6.0.1-alpha.1.20261.3 - 6.0.1-alpha.1.20261.3 - 6.0.1-alpha.1.20261.3 - 6.0.1-alpha.1.20261.3 - 6.0.1-alpha.1.20261.3 + 9.0.1-alpha.1.20262.1 + 9.0.1-alpha.1.20262.1 + 9.0.1-alpha.1.20262.1 + 9.0.1-alpha.1.20262.1 + 9.0.1-alpha.1.20262.1 + 9.0.1-alpha.1.20262.1 From bdd7235c43d762cea051cfc2071e14de48175f0c Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Thu, 14 May 2020 01:09:25 -0700 Subject: [PATCH 182/420] Rework rejit test to ensure subprocess environment is suitable (#36420) This test is optimization sensitive, but it invokes a subprocess that will inherit environment variables like `COMPlus_JITMinOpts` that can impact optimization of code jitted in the subprocess and cause the test to fail. So, update the parent process code to override `COMPlus_JITMinOpts` and `COMPlus_JitStress` for the child process. Closes #35742. --- .../tests/src/profiler/common/ProfilerTestRunner.cs | 8 +++++--- src/coreclr/tests/src/profiler/rejit/rejit.cs | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/coreclr/tests/src/profiler/common/ProfilerTestRunner.cs b/src/coreclr/tests/src/profiler/common/ProfilerTestRunner.cs index d425d4f544cf6..6b5bb26e0fa59 100644 --- a/src/coreclr/tests/src/profiler/common/ProfilerTestRunner.cs +++ b/src/coreclr/tests/src/profiler/common/ProfilerTestRunner.cs @@ -15,7 +15,7 @@ namespace Profiler.Tests public enum ProfileeOptions { None = 0, - DisableTieredCompilation, + OptimizationSensitive, NoStartupAttach } @@ -41,10 +41,12 @@ public class ProfilerTestRunner envVars.Add("CORECLR_PROFILER", "{" + profilerClsid + "}"); } - if (profileeOptions.HasFlag(ProfileeOptions.DisableTieredCompilation)) + if (profileeOptions.HasFlag(ProfileeOptions.OptimizationSensitive)) { - Console.WriteLine("Disabling tiered compilation."); + Console.WriteLine("Disabling tiered compilation, jitstress, and minopts."); envVars.Add("COMPlus_TieredCompilation", "0"); + envVars.Add("COMPlus_JitStress", "0"); + envVars.Add("COMPlus_JITMinOpts", "0"); } string profilerPath = GetProfilerPath(); diff --git a/src/coreclr/tests/src/profiler/rejit/rejit.cs b/src/coreclr/tests/src/profiler/rejit/rejit.cs index da7ff60f9f731..ec5cddc1bf9f0 100644 --- a/src/coreclr/tests/src/profiler/rejit/rejit.cs +++ b/src/coreclr/tests/src/profiler/rejit/rejit.cs @@ -100,7 +100,7 @@ public static int Main(string[] args) return ProfilerTestRunner.Run(profileePath: System.Reflection.Assembly.GetExecutingAssembly().Location, testName: "ReJITWithInlining", profilerClsid: ReJitProfilerGuid, - profileeOptions: ProfileeOptions.DisableTieredCompilation); + profileeOptions: ProfileeOptions.OptimizationSensitive); } } } From 9c5c657efab8fe8d8d0ed019dbe7c75c9568a058 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid Date: Thu, 14 May 2020 12:44:50 +0300 Subject: [PATCH 183/420] Implement GetEntrypointExecutableAbsPath on SunOS (#36430) * Implement `GetEntrypointExecutableAbsolutePath`. * Fix a warning from newer gawk (v5.0.1 from 2019): > ```sh > awk: /runtime/src/coreclr/src/nativeresources/processrc.awk:54: > warning: regexp escape sequence `\"' is not a known regexp operator > ``` --- .../hosts/unixcoreruncommon/coreruncommon.cpp | 37 +++++++++++++++++++ src/coreclr/src/nativeresources/processrc.awk | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp b/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp index aac6e24ecea11..b927f3802e683 100644 --- a/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp +++ b/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp @@ -116,6 +116,43 @@ bool GetEntrypointExecutableAbsolutePath(std::string& entrypointExecutable) { result = false; } +#elif defined(__sun) + const char *path; + if ((path = getexecname()) == NULL) + { + result = false; + } + else if (*path != '/') + { + char *cwd; + if ((cwd = getcwd(NULL, PATH_MAX)) == NULL) + { + result = false; + } + else + { + char *joined; + if (asprintf(&joined, "%s/%s", cwd, path) < 0) + { + result = false; + } + else + { + entrypointExecutable.assign(joined); + result = true; + free(joined); + } + + free(cwd); + } + } + else + { + entrypointExecutable.assign(path); + result = true; + } + + free((void*)path); #else #if HAVE_GETAUXVAL && defined(AT_EXECFN) diff --git a/src/coreclr/src/nativeresources/processrc.awk b/src/coreclr/src/nativeresources/processrc.awk index 4e6ad55c45871..f8eec8d091d92 100644 --- a/src/coreclr/src/nativeresources/processrc.awk +++ b/src/coreclr/src/nativeresources/processrc.awk @@ -51,7 +51,7 @@ BEGIN { var = var + 0; # Extract string content starting with either " or L" - idx = match($0, /L?\"/); + idx = match($0, /L?"/); content = substr($0, idx); # remove the L prefix from strings From a93f9ef8f80f0ad6ccf5d09c9e01fe0756e88442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Thu, 14 May 2020 12:12:56 +0200 Subject: [PATCH 184/420] Fix mono runtime build warnings when building iOS config (#36435) ``` /Users/alexander/dev/runtime/src/mono/mono/mini/aot-runtime.c:5647:13: warning: unused variable 'image' [-Wunused-variable] /Users/alexander/dev/runtime/src/mono/mono/mini/simd-intrinsics-netcore.c:11:1: warning: no previous prototype for function 'mono_simd_intrinsics_init' [-Wmissing-prototypes] /Users/alexander/dev/runtime/src/mono/mono/utils/mono-state.c:1230:1: warning: no previous prototype for function 'mono_crash_save_failfast_msg' [-Wmissing-prototypes] /Users/alexander/dev/runtime/src/mono/mono/utils/mono-state.c:1236:1: warning: no previous prototype for function 'mono_crash_get_failfast_msg' [-Wmissing-prototypes] ``` --- src/mono/mono/mini/aot-runtime.c | 1 - src/mono/mono/mini/simd-intrinsics-netcore.c | 2 +- src/mono/mono/utils/mono-state.c | 32 ++++++++++---------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index 1c04902fcc8d2..cd7ff7bc4c8fb 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -5644,7 +5644,6 @@ read_page_trampoline_uwinfo (MonoTrampInfo *info, int tramp_type, gboolean is_ge static unsigned char* get_new_trampoline_from_page (int tramp_type) { - MonoImage *image; TrampolinePage *page; int count; void *tpage; diff --git a/src/mono/mono/mini/simd-intrinsics-netcore.c b/src/mono/mono/mini/simd-intrinsics-netcore.c index ea4c1a9574c02..50f904bcd0fee 100644 --- a/src/mono/mono/mini/simd-intrinsics-netcore.c +++ b/src/mono/mono/mini/simd-intrinsics-netcore.c @@ -4,6 +4,7 @@ #include #include +#include "mini.h" #if defined(DISABLE_JIT) @@ -18,7 +19,6 @@ mono_simd_intrinsics_init (void) * Only LLVM is supported as a backend. */ -#include "mini.h" #include "mini-runtime.h" #include "ir-emit.h" #ifdef ENABLE_LLVM diff --git a/src/mono/mono/utils/mono-state.c b/src/mono/mono/utils/mono-state.c index 717c88cfb07a9..7333818f3a2a7 100644 --- a/src/mono/mono/utils/mono-state.c +++ b/src/mono/mono/utils/mono-state.c @@ -1202,22 +1202,6 @@ mono_crash_dump (const char *jsonFile, MonoStackHash *hashes) return; } -#endif // DISABLE_CRASH_REPORTING - -static volatile int32_t dump_status; - -gboolean -mono_dump_start (void) -{ - return (mono_atomic_xchg_i32(&dump_status, 1) == 0); // return true if we started the dump -} - -gboolean -mono_dump_complete (void) -{ - return (mono_atomic_xchg_i32(&dump_status, 0) == 1); // return true if we completed the dump -} - static char *saved_failfast_msg; /** @@ -1237,3 +1221,19 @@ mono_crash_get_failfast_msg (void) { return saved_failfast_msg; } + +#endif // DISABLE_CRASH_REPORTING + +static volatile int32_t dump_status; + +gboolean +mono_dump_start (void) +{ + return (mono_atomic_xchg_i32(&dump_status, 1) == 0); // return true if we started the dump +} + +gboolean +mono_dump_complete (void) +{ + return (mono_atomic_xchg_i32(&dump_status, 0) == 1); // return true if we completed the dump +} From 622341ecc2d43ef81c509bde53de8513727d626d Mon Sep 17 00:00:00 2001 From: Ganbarukamo41 Date: Thu, 14 May 2020 19:21:02 +0900 Subject: [PATCH 185/420] Update windows prerequisites to be more specific about SDK (#36438) * Update windows prerequisites to be more specific about SDK * Global installation of nightly SDK is required to normally browse the solution files in VS, as there is no way to supply SDKs when the solution files are opened through VS. * Update windows prerequisites * allow newer versions of VS workloads --- docs/workflow/requirements/windows-requirements.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/workflow/requirements/windows-requirements.md b/docs/workflow/requirements/windows-requirements.md index dc928b0d55d83..0035887b2d6cb 100644 --- a/docs/workflow/requirements/windows-requirements.md +++ b/docs/workflow/requirements/windows-requirements.md @@ -26,11 +26,11 @@ Visual Studio 2019 installation process: - .NET Desktop Development with all default components. - Desktop Development with C++ with all default components. - To build for Arm32 or Arm64, make sure that you have the right architecture specific compilers installed: - - In addition, ensure you install the ARM tools. In the "Individual components" window, in the "Compilers, build tools, and runtimes" section, check the box for "MSVC v142 - VS 2019 C++ ARM build tools (v14.23)". - - Also, ensure you install the ARM64 tools. In the "Individual components" window, in the "Compilers, build tools, and runtimes" section, check the box for "MSVC v142 - VS 2019 C++ ARM64 build tools (v14.23)". + - In addition, ensure you install the ARM tools. In the "Individual components" window, in the "Compilers, build tools, and runtimes" section, check the box for "MSVC v142 - VS 2019 C++ ARM build tools" (v14.23 or newer). + - Also, ensure you install the ARM64 tools. In the "Individual components" window, in the "Compilers, build tools, and runtimes" section, check the box for "MSVC v142 - VS 2019 C++ ARM64 build tools (v14.23 or newer)". - To build the tests, you will need some additional components: - Windows 10 SDK component version 10.0.18362 or newer. This component is installed by default as a part of 'Desktop Development with C++' workload. - - C++/CLI support for v142 build tools (14.23) + - C++/CLI support for v142 build tools (v14.23 or newer) A `.vsconfig` file is included in the root of the dotnet/runtime repository that includes all components needed to build the dotnet/runtime repository. You can [import `.vsconfig` in your Visual Studio installer](https://docs.microsoft.com/en-us/visualstudio/install/import-export-installation-configurations?view=vs-2019#import-a-configuration) to install all necessary components. @@ -67,9 +67,9 @@ The dotnet/runtime repository requires at least Git 2.22.0. ## .NET SDK -While not strictly needed to build or test this repository, having the .NET SDK installed lets you use the dotnet.exe command to run .NET applications in the 'normal' way. +While not strictly needed to build or test this repository, having the .NET SDK installed lets you browse solution files in this repository with Visual Studio and use the dotnet.exe command to run .NET applications in the 'normal' way. We use this in the [Using Your Build](../testing/using-your-build.md) instructions. -Visual Studio should have installed the .NET SDK, but in case it did not you can get it from the [Installing the .NET SDK](https://dotnet.microsoft.com/download) page. +The minimum required version of the SDK is specified in the [global.json file](https://github.com/dotnet/runtime/blob/master/global.json#L3). [You can find the installers and binaries for nightly builds of .NET SDK here](https://github.com/dotnet/installer#installers-and-binaries). ## Adding to the default PATH variable From c71192037385c343c0d8c19e934cd7e179ca1770 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Thu, 14 May 2020 08:16:41 -0400 Subject: [PATCH 186/420] [debugger] Removing some asserts (#36234) Removing some asserts and returning err_invalid_argument with an error message when it's possible. Fixes https://github.com/mono/mono/issues/19651 Co-authored-by: thaystg --- src/mono/mono/mini/debugger-agent.c | 83 +++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 17 deletions(-) diff --git a/src/mono/mono/mini/debugger-agent.c b/src/mono/mono/mini/debugger-agent.c index 9e61992328189..f76e887e6db88 100644 --- a/src/mono/mono/mini/debugger-agent.c +++ b/src/mono/mono/mini/debugger-agent.c @@ -4589,7 +4589,16 @@ get_object_id_for_debugger_method (MonoClass* async_builder_class) ERROR_DECL (error); GPtrArray *array = mono_class_get_methods_by_name (async_builder_class, "get_ObjectIdForDebugger", 0x24, 1, FALSE, error); mono_error_assert_ok (error); - g_assert (array->len == 1); + if (array->len != 1) { + g_ptr_array_free (array, TRUE); + //if we don't find method get_ObjectIdForDebugger we try to find the property Task to continue async debug. + MonoProperty *prop = mono_class_get_property_from_name_internal (async_builder_class, "Task"); + if (!prop) { + DEBUG_PRINTF (1, "Impossible to debug async methods.\n"); + return NULL; + } + return prop->get; + } MonoMethod *method = (MonoMethod *)g_ptr_array_index (array, 0); g_ptr_array_free (array, TRUE); return method; @@ -4607,7 +4616,9 @@ get_class_to_get_builder_field(DbgEngineStackFrame *frame) MonoGenericContext context; MonoType *inflated_type; - g_assert (this_obj); + if (!this_obj) + return NULL; + context = mono_get_generic_context_from_stack_frame (frame->ji, this_obj->vtable); inflated_type = mono_class_inflate_generic_type_checked (m_class_get_byval_arg (original_class), &context, error); mono_error_assert_ok (error); /* FIXME don't swallow the error */ @@ -4632,7 +4643,8 @@ get_async_method_builder (DbgEngineStackFrame *frame) klass = get_class_to_get_builder_field(frame); builder_field = mono_class_get_field_from_name_full (klass, "<>t__builder", NULL); - g_assert (builder_field); + if (!builder_field) + return NULL; this_addr = get_this_addr (frame); if (!this_addr) @@ -4671,7 +4683,8 @@ get_this_async_id (DbgEngineStackFrame *frame) return 0; builder_field = mono_class_get_field_from_name_full (get_class_to_get_builder_field(frame), "<>t__builder", NULL); - g_assert (builder_field); + if (!builder_field) + return 0; tls = (DebuggerTlsData *)mono_native_tls_get_value (debugger_tls_id); if (tls) { @@ -4680,6 +4693,11 @@ get_this_async_id (DbgEngineStackFrame *frame) } method = get_object_id_for_debugger_method (mono_class_from_mono_type_internal (builder_field->type)); + if (!method) { + if (tls) + tls->disable_breakpoints = old_disable_breakpoints; + return 0; + } obj = mono_runtime_try_invoke (method, builder, NULL, &ex, error); mono_error_assert_ok (error); @@ -4695,9 +4713,11 @@ static gboolean set_set_notification_for_wait_completion_flag (DbgEngineStackFrame *frame) { MonoClassField *builder_field = mono_class_get_field_from_name_full (get_class_to_get_builder_field(frame), "<>t__builder", NULL); - g_assert (builder_field); + if (!builder_field) + return FALSE; gpointer builder = get_async_method_builder (frame); - g_assert (builder); + if (!builder) + return FALSE; MonoMethod* method = get_set_notification_method (mono_class_from_mono_type_internal (builder_field->type)); if (method == NULL) @@ -5071,7 +5091,10 @@ ss_create_init_args (SingleStepReq *ss_req, SingleStepArgs *args) * We are stopped at a throw site. Stepping should go to the catch site. */ frame = tls->catch_frame; - g_assert (frame.type == FRAME_TYPE_MANAGED || frame.type == FRAME_TYPE_INTERP); + if (frame.type != FRAME_TYPE_MANAGED && frame.type != FRAME_TYPE_INTERP) { + DEBUG_PRINTF (1, "Current frame is not managed nor interpreter.\n"); + return ERR_INVALID_ARGUMENT; + } /* * Find the seq point corresponding to the landing site ip, which is the first seq @@ -5080,7 +5103,10 @@ ss_create_init_args (SingleStepReq *ss_req, SingleStepArgs *args) found_sp = mono_find_next_seq_point_for_native_offset (frame.domain, frame.method, frame.native_offset, &info, &args->sp); if (!found_sp) no_seq_points_found (frame.method, frame.native_offset); - g_assert (found_sp); + if (!found_sp) { + DEBUG_PRINTF (1, "Could not find next sequence point.\n"); + return ERR_INVALID_ARGUMENT; + } method = frame.method; @@ -5125,7 +5151,10 @@ ss_create_init_args (SingleStepReq *ss_req, SingleStepArgs *args) found_sp = mono_find_prev_seq_point_for_native_offset (frame->de.domain, frame->de.method, frame->de.native_offset, &info, &args->sp); if (!found_sp) no_seq_points_found (frame->de.method, frame->de.native_offset); - g_assert (found_sp); + if (!found_sp) { + DEBUG_PRINTF (1, "Could not find next sequence point.\n"); + return ERR_INVALID_ARGUMENT; + } method = frame->de.method; } } @@ -8861,7 +8890,11 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g if (mono_class_get_context (klass)) { ERROR_DECL (error); result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), error); - g_assert (is_ok (error)); /* FIXME don't swallow the error */ + if (!is_ok (error)) { + add_error_string (buf, mono_error_get_message (error)); + mono_error_cleanup (error); + return ERR_INVALID_ARGUMENT; + } } } } @@ -8999,7 +9032,12 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g char *s; s = mono_string_to_utf8_checked_internal ((MonoString *)val, error); - mono_error_assert_ok (error); + if (!is_ok (error)) { + add_error_string (buf, mono_error_get_message (error)); + mono_error_cleanup (error); + g_free (s); + return ERR_INVALID_ARGUMENT; + } buffer_add_byte (buf, TOKEN_TYPE_STRING); buffer_add_string (buf, s); g_free (s); @@ -9062,7 +9100,11 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g tmp_context.method_inst = ginst; inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, error); - g_assert (is_ok (error)); /* FIXME don't swallow the error */ + if (!is_ok (error)) { + add_error_string (buf, mono_error_get_message (error)); + mono_error_cleanup (error); + return ERR_INVALID_ARGUMENT; + } if (!mono_verifier_is_method_valid_generic_instantiation (inflated)) return ERR_INVALID_ARGUMENT; buffer_add_methodid (buf, domain, inflated); @@ -9489,7 +9531,10 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) set_interp_var (m_class_get_this_arg (frame->actual_method->klass), addr, val_buf); } else { var = jit->this_var; - g_assert (var); + if (!var) { + add_error_string (buf, "Invalid this object"); + return ERR_INVALID_ARGUMENT; + } set_var (m_class_get_this_arg (frame->actual_method->klass), var, &frame->ctx, frame->de.domain, val_buf, frame->reg_locations, &tls->restore_state.ctx); } @@ -9532,9 +9577,11 @@ array_commands (int command, guint8 *p, guint8 *end, Buffer *buf) index = decode_int (p, &p, end); len = decode_int (p, &p, end); - g_assert (index >= 0 && len >= 0); + if (index < 0 || len < 0) + return ERR_INVALID_ARGUMENT; // Reordered to avoid integer overflow - g_assert (!(index > arr->max_length - len)); + if (index > arr->max_length - len) + return ERR_INVALID_ARGUMENT; esize = mono_array_element_size (arr->obj.vtable->klass); for (i = index; i < index + len; ++i) { @@ -9546,9 +9593,11 @@ array_commands (int command, guint8 *p, guint8 *end, Buffer *buf) index = decode_int (p, &p, end); len = decode_int (p, &p, end); - g_assert (index >= 0 && len >= 0); + if (index < 0 || len < 0) + return ERR_INVALID_ARGUMENT; // Reordered to avoid integer overflow - g_assert (!(index > arr->max_length - len)); + if (index > arr->max_length - len) + return ERR_INVALID_ARGUMENT; esize = mono_array_element_size (arr->obj.vtable->klass); for (i = index; i < index + len; ++i) { From 0c39507daafc57e515e454709b991312f2ccc0b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Thu, 14 May 2020 14:48:51 +0200 Subject: [PATCH 187/420] Work around -no_weak_imports issue with recent Xcode (#36436) See https://github.com/mono/mono/issues/19393. We can use the `-Werror=partial-availability` as a good alternative until the Xcode bug is fixed. --- src/mono/mono.proj | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index e0224d5b0c30d..76f5dba28afce 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -134,6 +134,7 @@ <_MonoCFLAGS Condition="'$(Platform)' == 'arm64'" Include="-arch arm64" /> <_MonoCFLAGS Include="-isysroot $(XcodeDir)/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS$(tvOSVersion).sdk" /> <_MonoCFLAGS Include="-mtvos-version-min=$(tvOSVersionMin)" /> + <_MonoCFLAGS Include="-Werror=partial-availability" /> <_MonoCFLAGS Include="-Wl,-application_extension" /> <_MonoCFLAGS Include="-fexceptions" /> <_MonoCFLAGS Include="-fembed-bitcode" /> @@ -158,7 +159,7 @@ <_MonoCPPFLAGS Include="-DHAVE_LARGE_FILE_SUPPORT=1" /> <_MonoLDFLAGS Condition="'$(Platform)' == 'arm64'" Include="-arch arm64" /> - <_MonoLDFLAGS Include="-Wl,-no_weak_imports" /> + <_MonoLDFLAGS Include="-Wl,-bitcode_bundle" /> <_MonoLDFLAGS Include="-framework CoreFoundation" /> <_MonoLDFLAGS Include="-lobjc" /> @@ -278,6 +279,7 @@ <_MonoCFLAGS Condition="'$(Platform)' == 'arm'" Include="-arch armv7s" /> <_MonoCFLAGS Include="-isysroot $(XcodeDir)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS$(iOSVersion).sdk" /> <_MonoCFLAGS Include="-miphoneos-version-min=$(iOSVersionMin)" /> + <_MonoCFLAGS Include="-Werror=partial-availability" /> <_MonoCFLAGS Include="-Wl,-application_extension" /> <_MonoCFLAGS Include="-fexceptions" /> @@ -303,7 +305,7 @@ <_MonoLDFLAGS Condition="'$(Platform)' == 'arm64'" Include="-arch arm64" /> <_MonoLDFLAGS Condition="'$(Platform)' == 'arm'" Include="-arch armv7" /> <_MonoLDFLAGS Condition="'$(Platform)' == 'arm'" Include="-arch armv7s" /> - <_MonoLDFLAGS Include="-Wl,-no_weak_imports" /> + <_MonoLDFLAGS Include="-framework CoreFoundation" /> <_MonoLDFLAGS Include="-lobjc" /> <_MonoLDFLAGS Include="-lc++" /> From 4c3ca5988e1e7208d3e57e4e67f5eebea5dc4f00 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Thu, 14 May 2020 15:42:18 +0200 Subject: [PATCH 188/420] Remove duplicate configuration properties (#36442) --- src/libraries/Directory.Build.targets | 7 ------- src/libraries/restore/runtime/runtime.depproj | 4 ---- src/libraries/shims/manual/Directory.Build.props | 2 -- 3 files changed, 13 deletions(-) diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index 0efc8a53b0aca..cad6c2ed4803a 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -2,13 +2,6 @@ $([MSBuild]::NormalizeDirectory('$(RefRootPath)', '$(TargetFramework)')) - - - $(TargetOS) - $(Configuration) - $(TargetOS) - $(Configuration) - diff --git a/src/libraries/restore/runtime/runtime.depproj b/src/libraries/restore/runtime/runtime.depproj index 827dec91df7da..c89e37e8c77b2 100644 --- a/src/libraries/restore/runtime/runtime.depproj +++ b/src/libraries/restore/runtime/runtime.depproj @@ -5,10 +5,6 @@ $(ToolRuntimeRID) $(NoWarn);NU1603;NU1605 true - $(TargetOS) - $(Configuration) - $(TargetOS) - $(Configuration) false netcoreapp3.0-Windows_NT;netcoreapp3.0-Unix;$(netcoreappCurrent)-Windows_NT;$(netcoreappCurrent)-Unix diff --git a/src/libraries/shims/manual/Directory.Build.props b/src/libraries/shims/manual/Directory.Build.props index 3b6d8565f4799..e227dbfe58c93 100644 --- a/src/libraries/shims/manual/Directory.Build.props +++ b/src/libraries/shims/manual/Directory.Build.props @@ -13,8 +13,6 @@ true $([MSBuild]::NormalizeDirectory('$(ArtifactsObjDir)', '$(OutDirName)')) $(BaseIntermediateOutputPath)$(TargetFramework)-$(Configuration) - $(TargetOS) - $(TargetOS) $(NetCoreAppCurrent) From ed79f41c71c882ee420e14eb040b2fa33a56d45b Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Thu, 14 May 2020 06:54:10 -0700 Subject: [PATCH 189/420] Update message for generic type. (#36434) --- src/libraries/System.Private.CoreLib/src/Resources/Strings.resx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index 5957640bac106..c5c6a8603e8df 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -1343,7 +1343,7 @@ The specified object must not be an instance of a generic type. - The specified Type must not be a generic type definition. + The specified Type must not be a generic type. The specified Type must be a struct containing no references. From f53c15657a99e6c72cd360e9795e03cf7c9421b1 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Thu, 14 May 2020 16:05:38 +0200 Subject: [PATCH 190/420] Consolidate subset projects into ProjectToBuild (#36441) Consolidating subset projects into a single ProjectToBuild item type to allow specifying projects to build from different subsets after the subset was already built. --- Build.proj | 5 +-- eng/Subsets.props | 93 +++++++++++++++++++++-------------------------- 2 files changed, 42 insertions(+), 56 deletions(-) diff --git a/Build.proj b/Build.proj index 047ec19ac493d..ef12cca9de1cc 100644 --- a/Build.proj +++ b/Build.proj @@ -5,10 +5,7 @@ Reference the projects for traversal build. Ordering matters here. --> - - - - + - + false false false false - Configuration=$(CoreCLRConfiguration) - - - false - false - false - false - Configuration=$(MonoConfiguration) - - - false - false - false - false - Configuration=$(LibrariesConfiguration) - - - false - true - false - + - + - + - + - + - + - - - - - + + - + - + - + - + @@ -197,65 +177,65 @@ - + - + - + - + - + - + - + - + - - + + - - + + - + - + @@ -265,11 +245,20 @@ - + - + + + + + + + Configuration=$(CoreCLRConfiguration) + Configuration=$(MonoConfiguration) + Configuration=$(LibrariesConfiguration) + From ef528e56f27f48d2a06f9d6da8e181107194376b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 14 May 2020 16:24:31 +0200 Subject: [PATCH 191/420] [master] Update dependencies from dotnet/arcade mono/linker dotnet/xharness (#36445) * Update dependencies from https://github.com/dotnet/arcade build 20200511.9 Microsoft.DotNet.XUnitExtensions , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.ApiCompat , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk , Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.GenAPI , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.GenFacades From Version 5.0.0-beta.20258.8 -> To Version 5.0.0-beta.20261.9 * Update dependencies from https://github.com/mono/linker build 20200514.1 Microsoft.NET.ILLink.Tasks From Version 5.0.0-preview.3.20262.1 -> To Version 5.0.0-preview.3.20264.1 * Update dependencies from https://github.com/dotnet/xharness build 20200514.1 Microsoft.DotNet.XHarness.Tests.Runners From Version 1.0.0-prerelease.20263.4 -> To Version 1.0.0-prerelease.20264.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 64 ++++++++++++++-------------- eng/Versions.props | 24 +++++------ eng/common/native/CommonLibrary.psm1 | 24 ++++++++--- global.json | 8 ++-- 4 files changed, 65 insertions(+), 55 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5cd35c4340f98..668b9bba02fb9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -6,61 +6,61 @@ - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d - + https://github.com/dotnet/arcade - 8078d8f3f77b7e8b7f6e289cf82cfdfa9c7a9355 + 898e51ed5fdcc4871087ac5754ca9056e58e575d https://dev.azure.com/dnceng/internal/_git/dotnet-optimization @@ -170,13 +170,13 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - df72dcfc27e27735c84c68507426a568799b66e9 + e9f0009b3bd7e42fdc7db6e416b9182828006309 - + https://github.com/dotnet/xharness - 1111899797c23fe4039cad22afd640522519306d + c6fd4f291bfc2a8dfb7d46577959e3a9ba0fa132 diff --git a/eng/Versions.props b/eng/Versions.props index 1fc593d2792ea..3588f19c0d159 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -57,16 +57,16 @@ - 5.0.0-beta.20258.8 - 5.0.0-beta.20258.8 - 5.0.0-beta.20258.8 - 5.0.0-beta.20258.8 - 5.0.0-beta.20258.8 - 5.0.0-beta.20258.8 - 2.5.1-beta.20258.8 - 5.0.0-beta.20258.8 - 5.0.0-beta.20258.8 - 5.0.0-beta.20258.8 + 5.0.0-beta.20261.9 + 5.0.0-beta.20261.9 + 5.0.0-beta.20261.9 + 5.0.0-beta.20261.9 + 5.0.0-beta.20261.9 + 5.0.0-beta.20261.9 + 2.5.1-beta.20261.9 + 5.0.0-beta.20261.9 + 5.0.0-beta.20261.9 + 5.0.0-beta.20261.9 5.0.0-preview.4.20202.18 5.0.0-preview.4.20202.18 @@ -113,7 +113,7 @@ 4.8.0 16.7.0-preview-20200429-01 - 1.0.0-prerelease.20263.4 + 1.0.0-prerelease.20264.1 2.4.1 1.2.1 2.0.5 @@ -122,7 +122,7 @@ 3.1.0-preview-20200129.1 - 5.0.0-preview.3.20262.1 + 5.0.0-preview.3.20264.1 9.0.1-alpha.1.20262.1 9.0.1-alpha.1.20262.1 diff --git a/eng/common/native/CommonLibrary.psm1 b/eng/common/native/CommonLibrary.psm1 index 41416862d9132..d7d1a6510949a 100644 --- a/eng/common/native/CommonLibrary.psm1 +++ b/eng/common/native/CommonLibrary.psm1 @@ -145,9 +145,12 @@ function Get-File { New-Item -path $DownloadDirectory -force -itemType "Directory" | Out-Null } + $TempPath = "$Path.tmp" if (Test-Path -IsValid -Path $Uri) { - Write-Verbose "'$Uri' is a file path, copying file to '$Path'" - Copy-Item -Path $Uri -Destination $Path + Write-Verbose "'$Uri' is a file path, copying temporarily to '$TempPath'" + Copy-Item -Path $Uri -Destination $TempPath + Write-Verbose "Moving temporary file to '$Path'" + Move-Item -Path $TempPath -Destination $Path return $? } else { @@ -157,8 +160,10 @@ function Get-File { while($Attempt -Lt $DownloadRetries) { try { - Invoke-WebRequest -UseBasicParsing -Uri $Uri -OutFile $Path - Write-Verbose "Downloaded to '$Path'" + Invoke-WebRequest -UseBasicParsing -Uri $Uri -OutFile $TempPath + Write-Verbose "Downloaded to temporary location '$TempPath'" + Move-Item -Path $TempPath -Destination $Path + Write-Verbose "Moved temporary file to '$Path'" return $True } catch { @@ -359,16 +364,21 @@ function Expand-Zip { return $False } } - if (-Not (Test-Path $OutputDirectory)) { - New-Item -path $OutputDirectory -Force -itemType "Directory" | Out-Null + + $TempOutputDirectory = Join-Path "$(Split-Path -Parent $OutputDirectory)" "$(Split-Path -Leaf $OutputDirectory).tmp" + if (Test-Path $TempOutputDirectory) { + Remove-Item $TempOutputDirectory -Force -Recurse } + New-Item -Path $TempOutputDirectory -Force -ItemType "Directory" | Out-Null Add-Type -assembly "system.io.compression.filesystem" - [io.compression.zipfile]::ExtractToDirectory("$ZipPath", "$OutputDirectory") + [io.compression.zipfile]::ExtractToDirectory("$ZipPath", "$TempOutputDirectory") if ($? -Eq $False) { Write-Error "Unable to extract '$ZipPath'" return $False } + + Move-Item -Path $TempOutputDirectory -Destination $OutputDirectory } catch { Write-Host $_ diff --git a/global.json b/global.json index e4fb17844fd35..1f55cf7ca46f2 100644 --- a/global.json +++ b/global.json @@ -12,10 +12,10 @@ "python3": "3.7.1" }, "msbuild-sdks": { - "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20258.8", - "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20258.8", - "Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.20258.8", - "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20258.8", + "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20261.9", + "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20261.9", + "Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.20261.9", + "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20261.9", "FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0", "Microsoft.NET.Sdk.IL": "5.0.0-preview.4.20202.18", "Microsoft.Build.NoTargets": "1.0.53", From ea6a008bad1737aa7df28973434504a6bca7c9c8 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 14 May 2020 11:28:44 -0400 Subject: [PATCH 192/420] Support additional friendly names on ECC OIDs Expand the name/OID table to support a m:m relationship (secp256r1 and nistP256 are both 1.2.840.10045.3.1.7; 1.3.14.7.2.3.1 and 1.2.840.113549.1.1.4 are both md5RSA) and add in the alternative names for the secp{size}r1 curves (size in 256, 384, 521). --- .../Internal/Cryptography/OidLookup.OSX.cs | 10 + .../src/Internal/Cryptography/OidLookup.cs | 282 +++++++++--------- .../tests/Oid.cs | 15 + 3 files changed, 171 insertions(+), 136 deletions(-) diff --git a/src/libraries/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.OSX.cs b/src/libraries/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.OSX.cs index ee9cbb6c5b9a9..fb055ca797c13 100644 --- a/src/libraries/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.OSX.cs +++ b/src/libraries/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.OSX.cs @@ -67,6 +67,16 @@ private static bool ShouldUseCache(OidGroup oidGroup) private static readonly Dictionary s_extraOidToFriendlyName = InvertWithDefaultComparer(s_extraFriendlyNameToOid); + private static Dictionary InvertWithDefaultComparer(Dictionary source) + { + var result = new Dictionary(source.Count); + foreach (KeyValuePair item in source) + { + result.Add(item.Value, item.Key); + } + return result; + } + #if DEBUG static partial void ExtraStaticDebugValidation() { diff --git a/src/libraries/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.cs b/src/libraries/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.cs index ca743d28adbcf..e852b14a020ad 100644 --- a/src/libraries/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.cs +++ b/src/libraries/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.cs @@ -94,132 +94,16 @@ internal static partial class OidLookup } /// Expected size of . - private const int FriendlyNameToOidCount = 103; + private const int FriendlyNameToOidCount = 110; + + /// Expected size of . + private const int OidToFriendlyNameCount = 103; - // This table was originally built by extracting every szOID #define out of wincrypt.h, - // and running them through new Oid(string) on Windows 10. Then, take the list of everything - // which produced a FriendlyName value, and run it through two other languages. If all 3 agree - // on the mapping, consider the value to be non-localized. - // - // This original list was produced on English (Win10), cross-checked with Spanish (Win8.1) and - // Japanese (Win10). - // - // Sometimes wincrypt.h has more than one OID which results in the same name. The OIDs whose value - // doesn't roundtrip (new Oid(new Oid(value).FriendlyName).Value) are contained in s_compatOids. - // - // X-Plat: The names (and casing) in this table come from Windows. Part of the intent of this table - // is to prevent issues wherein an identifier is different between Windows and Unix; - // since any existing code would be using the Windows identifier, it is the de facto standard. private static readonly Dictionary s_friendlyNameToOid = - new Dictionary(FriendlyNameToOidCount, StringComparer.OrdinalIgnoreCase) - { - { "3des", "1.2.840.113549.3.7" }, - { "aes128", "2.16.840.1.101.3.4.1.2" }, - { "aes128wrap", "2.16.840.1.101.3.4.1.5" }, - { "aes192", "2.16.840.1.101.3.4.1.22" }, - { "aes192wrap", "2.16.840.1.101.3.4.1.25" }, - { "aes256", "2.16.840.1.101.3.4.1.42" }, - { "aes256wrap", "2.16.840.1.101.3.4.1.45" }, - { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" }, - { "brainpoolP160t1", "1.3.36.3.3.2.8.1.1.2" }, - { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" }, - { "brainpoolP192t1", "1.3.36.3.3.2.8.1.1.4" }, - { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" }, - { "brainpoolP224t1", "1.3.36.3.3.2.8.1.1.6" }, - { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7" }, - { "brainpoolP256t1", "1.3.36.3.3.2.8.1.1.8" }, - { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" }, - { "brainpoolP320t1", "1.3.36.3.3.2.8.1.1.10" }, - { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11" }, - { "brainpoolP384t1", "1.3.36.3.3.2.8.1.1.12" }, - { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13" }, - { "brainpoolP512t1", "1.3.36.3.3.2.8.1.1.14" }, - { "C", "2.5.4.6" }, - { "CMS3DESwrap", "1.2.840.113549.1.9.16.3.6" }, - { "CMSRC2wrap", "1.2.840.113549.1.9.16.3.7" }, - { "CN", "2.5.4.3" }, - { "CPS", "1.3.6.1.5.5.7.2.1" }, - { "DC", "0.9.2342.19200300.100.1.25" }, - { "des", "1.3.14.3.2.7" }, - { "Description", "2.5.4.13" }, - { "DH", "1.2.840.10046.2.1" }, - { "dnQualifier", "2.5.4.46" }, - { "DSA", "1.2.840.10040.4.1" }, - { "dsaSHA1", "1.3.14.3.2.27" }, - { "E", "1.2.840.113549.1.9.1" }, - { "ec192wapi", "1.2.156.11235.1.1.2.1" }, - { "ECC", "1.2.840.10045.2.1" }, - { "ECDH_STD_SHA1_KDF", "1.3.133.16.840.63.0.2" }, - { "ECDH_STD_SHA256_KDF", "1.3.132.1.11.1" }, - { "ECDH_STD_SHA384_KDF", "1.3.132.1.11.2" }, - { "ECDSA_P256", "1.2.840.10045.3.1.7" }, - { "ECDSA_P384", "1.3.132.0.34" }, - { "ECDSA_P521", "1.3.132.0.35" }, - { "ESDH", "1.2.840.113549.1.9.16.3.5" }, - { "G", "2.5.4.42" }, - { "I", "2.5.4.43" }, - { "L", "2.5.4.7" }, - { "md2", "1.2.840.113549.2.2" }, - { "md2RSA", "1.2.840.113549.1.1.2" }, - { "md4", "1.2.840.113549.2.4" }, - { "md4RSA", "1.2.840.113549.1.1.3" }, - { "md5", "1.2.840.113549.2.5" }, - { "md5RSA", "1.2.840.113549.1.1.4" }, - { "mgf1", "1.2.840.113549.1.1.8" }, - { "mosaicKMandUpdSig", "2.16.840.1.101.2.1.1.20" }, - { "mosaicUpdatedSig", "2.16.840.1.101.2.1.1.19" }, - { "nistP192", "1.2.840.10045.3.1.1" }, - { "nistP224", "1.3.132.0.33" }, - { "NO_SIGN", "1.3.6.1.5.5.7.6.2" }, - { "O", "2.5.4.10" }, - { "OU", "2.5.4.11" }, - { "Phone", "2.5.4.20" }, - { "POBox", "2.5.4.18" }, - { "PostalCode", "2.5.4.17" }, - { "rc2", "1.2.840.113549.3.2" }, - { "rc4", "1.2.840.113549.3.4" }, - { "RSA", "1.2.840.113549.1.1.1" }, - { "RSAES_OAEP", "1.2.840.113549.1.1.7" }, - { "RSASSA-PSS", "1.2.840.113549.1.1.10" }, - { "S", "2.5.4.8" }, - { "secP160k1", "1.3.132.0.9" }, - { "secP160r1", "1.3.132.0.8" }, - { "secP160r2", "1.3.132.0.30" }, - { "secP192k1", "1.3.132.0.31" }, - { "secP224k1", "1.3.132.0.32" }, - { "secP256k1", "1.3.132.0.10" }, - { "SERIALNUMBER", "2.5.4.5" }, - { "sha1", "1.3.14.3.2.26" }, - { "sha1DSA", "1.2.840.10040.4.3" }, - { "sha1ECDSA", "1.2.840.10045.4.1" }, - { "sha1RSA", "1.2.840.113549.1.1.5" }, - { "sha256", "2.16.840.1.101.3.4.2.1" }, - { "sha256ECDSA", "1.2.840.10045.4.3.2" }, - { "sha256RSA", "1.2.840.113549.1.1.11" }, - { "sha384", "2.16.840.1.101.3.4.2.2" }, - { "sha384ECDSA", "1.2.840.10045.4.3.3" }, - { "sha384RSA", "1.2.840.113549.1.1.12" }, - { "sha512", "2.16.840.1.101.3.4.2.3" }, - { "sha512ECDSA", "1.2.840.10045.4.3.4" }, - { "sha512RSA", "1.2.840.113549.1.1.13" }, - { "SN", "2.5.4.4" }, - { "specifiedECDSA", "1.2.840.10045.4.3" }, - { "STREET", "2.5.4.9" }, - { "T", "2.5.4.12" }, - { "TPMManufacturer", "2.23.133.2.1" }, - { "TPMModel", "2.23.133.2.2" }, - { "TPMVersion", "2.23.133.2.3" }, - { "wtls9", "2.23.43.1.4.9" }, - { "X21Address", "2.5.4.24" }, - { "x962P192v2", "1.2.840.10045.3.1.2" }, - { "x962P192v3", "1.2.840.10045.3.1.3" }, - { "x962P239v1", "1.2.840.10045.3.1.4" }, - { "x962P239v2", "1.2.840.10045.3.1.5" }, - { "x962P239v3", "1.2.840.10045.3.1.6" }, - }; + new Dictionary(FriendlyNameToOidCount, StringComparer.OrdinalIgnoreCase); private static readonly Dictionary s_oidToFriendlyName = - InvertWithDefaultComparer(s_friendlyNameToOid); + new Dictionary(OidToFriendlyNameCount, StringComparer.Ordinal); private static readonly Dictionary s_compatOids = new Dictionary @@ -237,29 +121,155 @@ internal static partial class OidLookup { "1.3.14.7.2.3.1", "md2RSA" }, }; - private static Dictionary InvertWithDefaultComparer(Dictionary source) - { - var result = new Dictionary(source.Count); - foreach (KeyValuePair item in source) - { - result.Add(item.Value, item.Key); - } - return result; - } - -#if DEBUG static OidLookup() { + InitializeLookupDictionaries(); +#if DEBUG // Validate we hardcoded the right dictionary size Debug.Assert(s_friendlyNameToOid.Count == FriendlyNameToOidCount, $"Expected {nameof(s_friendlyNameToOid)}.{nameof(s_friendlyNameToOid.Count)} == {FriendlyNameToOidCount}, got {s_friendlyNameToOid.Count}"); - Debug.Assert(s_oidToFriendlyName.Count == FriendlyNameToOidCount, - $"Expected {nameof(s_oidToFriendlyName)}.{nameof(s_oidToFriendlyName.Count)} == {FriendlyNameToOidCount}, got {s_oidToFriendlyName.Count}"); + Debug.Assert(s_oidToFriendlyName.Count == OidToFriendlyNameCount, + $"Expected {nameof(s_oidToFriendlyName)}.{nameof(s_oidToFriendlyName.Count)} == {OidToFriendlyNameCount}, got {s_oidToFriendlyName.Count}"); ExtraStaticDebugValidation(); +#endif + } + + private static void InitializeLookupDictionaries() + { + void AddEntry(string oid, string primaryFriendlyName, string[]? additionalFriendlyNames = null) + { + s_oidToFriendlyName.Add(oid, primaryFriendlyName); + s_friendlyNameToOid.Add(primaryFriendlyName, oid); + + if (additionalFriendlyNames != null) + { + foreach (var additionalName in additionalFriendlyNames) + { + s_friendlyNameToOid.Add(additionalName, oid); + } + } + } + + // This lookup was originally built by extracting every szOID #define out of wincrypt.h, + // and running them through new Oid(string) on Windows 10. Then, take the list of everything + // which produced a FriendlyName value, and run it through two other languages. If all 3 agree + // on the mapping, consider the value to be non-localized. + // + // This original list was produced on English (Win10), cross-checked with Spanish (Win8.1) and + // Japanese (Win10). + // + // Sometimes wincrypt.h has more than one OID which results in the same name. The OIDs whose value + // doesn't roundtrip (new Oid(new Oid(value).FriendlyName).Value) are contained in s_compatOids. + // + // X-Plat: The names (and casing) in this table come from Windows. Part of the intent of this table + // is to prevent issues wherein an identifier is different between Windows and Unix; + // since any existing code would be using the Windows identifier, it is the de facto standard. + AddEntry("1.2.840.113549.3.7", "3des"); + AddEntry("2.16.840.1.101.3.4.1.2", "aes128"); + AddEntry("2.16.840.1.101.3.4.1.5", "aes128wrap"); + AddEntry("2.16.840.1.101.3.4.1.22", "aes192"); + AddEntry("2.16.840.1.101.3.4.1.25", "aes192wrap"); + AddEntry("2.16.840.1.101.3.4.1.42", "aes256"); + AddEntry("2.16.840.1.101.3.4.1.45", "aes256wrap"); + AddEntry("1.3.36.3.3.2.8.1.1.1", "brainpoolP160r1"); + AddEntry("1.3.36.3.3.2.8.1.1.2", "brainpoolP160t1"); + AddEntry("1.3.36.3.3.2.8.1.1.3", "brainpoolP192r1"); + AddEntry("1.3.36.3.3.2.8.1.1.4", "brainpoolP192t1"); + AddEntry("1.3.36.3.3.2.8.1.1.5", "brainpoolP224r1"); + AddEntry("1.3.36.3.3.2.8.1.1.6", "brainpoolP224t1"); + AddEntry("1.3.36.3.3.2.8.1.1.7", "brainpoolP256r1"); + AddEntry("1.3.36.3.3.2.8.1.1.8", "brainpoolP256t1"); + AddEntry("1.3.36.3.3.2.8.1.1.9", "brainpoolP320r1"); + AddEntry("1.3.36.3.3.2.8.1.1.10", "brainpoolP320t1"); + AddEntry("1.3.36.3.3.2.8.1.1.11", "brainpoolP384r1"); + AddEntry("1.3.36.3.3.2.8.1.1.12", "brainpoolP384t1"); + AddEntry("1.3.36.3.3.2.8.1.1.13", "brainpoolP512r1"); + AddEntry("1.3.36.3.3.2.8.1.1.14", "brainpoolP512t1"); + AddEntry("2.5.4.6", "C"); + AddEntry("1.2.840.113549.1.9.16.3.6", "CMS3DESwrap"); + AddEntry("1.2.840.113549.1.9.16.3.7", "CMSRC2wrap"); + AddEntry("2.5.4.3", "CN"); + AddEntry("1.3.6.1.5.5.7.2.1", "CPS"); + AddEntry("0.9.2342.19200300.100.1.25", "DC"); + AddEntry("1.3.14.3.2.7", "des"); + AddEntry("2.5.4.13", "Description"); + AddEntry("1.2.840.10046.2.1", "DH"); + AddEntry("2.5.4.46", "dnQualifier"); + AddEntry("1.2.840.10040.4.1", "DSA"); + AddEntry("1.3.14.3.2.27", "dsaSHA1"); + AddEntry("1.2.840.113549.1.9.1", "E"); + AddEntry("1.2.156.11235.1.1.2.1", "ec192wapi"); + AddEntry("1.2.840.10045.2.1", "ECC"); + AddEntry("1.3.133.16.840.63.0.2", "ECDH_STD_SHA1_KDF"); + AddEntry("1.3.132.1.11.1", "ECDH_STD_SHA256_KDF"); + AddEntry("1.3.132.1.11.2", "ECDH_STD_SHA384_KDF"); + AddEntry("1.2.840.10045.3.1.7", "ECDSA_P256", new[] { "nistP256", "secP256r1", "x962P256v1" } ); + AddEntry("1.3.132.0.34", "ECDSA_P384", new[] { "nistP384", "secP384r1" }); + AddEntry("1.3.132.0.35", "ECDSA_P521", new[] { "nistP521", "secP521r1" }); + AddEntry("1.2.840.113549.1.9.16.3.5", "ESDH"); + AddEntry("2.5.4.42", "G"); + AddEntry("2.5.4.43", "I"); + AddEntry("2.5.4.7", "L"); + AddEntry("1.2.840.113549.2.2", "md2"); + AddEntry("1.2.840.113549.1.1.2", "md2RSA"); + AddEntry("1.2.840.113549.2.4", "md4"); + AddEntry("1.2.840.113549.1.1.3", "md4RSA"); + AddEntry("1.2.840.113549.2.5", "md5"); + AddEntry("1.2.840.113549.1.1.4", "md5RSA"); + AddEntry("1.2.840.113549.1.1.8", "mgf1"); + AddEntry("2.16.840.1.101.2.1.1.20", "mosaicKMandUpdSig"); + AddEntry("2.16.840.1.101.2.1.1.19", "mosaicUpdatedSig"); + AddEntry("1.2.840.10045.3.1.1", "nistP192"); + AddEntry("1.3.132.0.33", "nistP224"); + AddEntry("1.3.6.1.5.5.7.6.2", "NO_SIGN"); + AddEntry("2.5.4.10", "O"); + AddEntry("2.5.4.11", "OU"); + AddEntry("2.5.4.20", "Phone"); + AddEntry("2.5.4.18", "POBox"); + AddEntry("2.5.4.17", "PostalCode"); + AddEntry("1.2.840.113549.3.2", "rc2"); + AddEntry("1.2.840.113549.3.4", "rc4"); + AddEntry("1.2.840.113549.1.1.1", "RSA"); + AddEntry("1.2.840.113549.1.1.7", "RSAES_OAEP"); + AddEntry("1.2.840.113549.1.1.10", "RSASSA-PSS"); + AddEntry("2.5.4.8", "S"); + AddEntry("1.3.132.0.9", "secP160k1"); + AddEntry("1.3.132.0.8", "secP160r1"); + AddEntry("1.3.132.0.30", "secP160r2"); + AddEntry("1.3.132.0.31", "secP192k1"); + AddEntry("1.3.132.0.32", "secP224k1"); + AddEntry("1.3.132.0.10", "secP256k1"); + AddEntry("2.5.4.5", "SERIALNUMBER"); + AddEntry("1.3.14.3.2.26", "sha1"); + AddEntry("1.2.840.10040.4.3", "sha1DSA"); + AddEntry("1.2.840.10045.4.1", "sha1ECDSA"); + AddEntry("1.2.840.113549.1.1.5", "sha1RSA"); + AddEntry("2.16.840.1.101.3.4.2.1", "sha256"); + AddEntry("1.2.840.10045.4.3.2", "sha256ECDSA"); + AddEntry("1.2.840.113549.1.1.11", "sha256RSA"); + AddEntry("2.16.840.1.101.3.4.2.2", "sha384"); + AddEntry("1.2.840.10045.4.3.3", "sha384ECDSA"); + AddEntry("1.2.840.113549.1.1.12", "sha384RSA"); + AddEntry("2.16.840.1.101.3.4.2.3", "sha512"); + AddEntry("1.2.840.10045.4.3.4", "sha512ECDSA"); + AddEntry("1.2.840.113549.1.1.13", "sha512RSA"); + AddEntry("2.5.4.4", "SN"); + AddEntry("1.2.840.10045.4.3", "specifiedECDSA"); + AddEntry("2.5.4.9", "STREET"); + AddEntry("2.5.4.12", "T"); + AddEntry("2.23.133.2.1", "TPMManufacturer"); + AddEntry("2.23.133.2.2", "TPMModel"); + AddEntry("2.23.133.2.3", "TPMVersion"); + AddEntry("2.23.43.1.4.9", "wtls9"); + AddEntry("2.5.4.24", "X21Address"); + AddEntry("1.2.840.10045.3.1.2", "x962P192v2"); + AddEntry("1.2.840.10045.3.1.3", "x962P192v3"); + AddEntry("1.2.840.10045.3.1.4", "x962P239v1"); + AddEntry("1.2.840.10045.3.1.5", "x962P239v2"); + AddEntry("1.2.840.10045.3.1.6", "x962P239v3"); } static partial void ExtraStaticDebugValidation(); -#endif } } diff --git a/src/libraries/System.Security.Cryptography.Encoding/tests/Oid.cs b/src/libraries/System.Security.Cryptography.Encoding/tests/Oid.cs index 6e6b04f6549df..cafaa03caed90 100644 --- a/src/libraries/System.Security.Cryptography.Encoding/tests/Oid.cs +++ b/src/libraries/System.Security.Cryptography.Encoding/tests/Oid.cs @@ -330,6 +330,21 @@ public static void LookupOidByFriendlyName_Method_UnixOnly() Assert.Equal(ObsoleteSmime3desWrap_Name, oid.FriendlyName); } + [Theory] + [InlineData("nistP256", "1.2.840.10045.3.1.7")] + [InlineData("secP256r1", "1.2.840.10045.3.1.7")] + [InlineData("x962P256v1", "1.2.840.10045.3.1.7")] + [InlineData("nistP384", "1.3.132.0.34")] + [InlineData("secP384r1", "1.3.132.0.34")] + [InlineData("nistP521", "1.3.132.0.35")] + [InlineData("secP521r1", "1.3.132.0.35")] + public static void LookupOidByFriendlyName_AdditionalNames(string friendlyName, string expectedOid) + { + Oid oid = Oid.FromFriendlyName(friendlyName, OidGroup.All); + Assert.Equal(friendlyName, oid.FriendlyName); + Assert.Equal(expectedOid, oid.Value); + } + public static IEnumerable ValidOidFriendlyNamePairs { get From 359218ea6312d74e98cafb5253934eea3a5ca539 Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Thu, 14 May 2020 08:29:32 -0700 Subject: [PATCH 193/420] Add an atexit handler to bypass calls into ERR_ string routines. This works around Ubuntu's apparent lack of NO_ATEXIT support in their build of OpenSSL. --- .../openssl.c | 22 ++++++++++ .../pal_err.c | 42 ++++++++++++++++++- .../pal_err.h | 7 ++++ 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/openssl.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native/openssl.c index 1a9ea04839756..21820f8f443a1 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/openssl.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/openssl.c @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#include "pal_err.h" #include "pal_types.h" #include "pal_utilities.h" #include "pal_safecrt.h" @@ -1263,6 +1264,23 @@ static int32_t EnsureOpenSsl10Initialized() #define OPENSSL_INIT_NO_ATEXIT 0x00080000L #endif +pthread_mutex_t g_err_mutex = PTHREAD_MUTEX_INITIALIZER; +int volatile g_err_unloaded = 0; + +static void HandleShutdown() +{ + // Generally, a mutex to set a boolean is overkill, but this lock + // ensures that there are no callers already inside the string table + // when the unload (possibly) executes. + int result = pthread_mutex_lock(&g_err_mutex); + assert(!result && "Acquiring the error string table mutex failed."); + + g_err_unloaded = 1; + + result = pthread_mutex_unlock(&g_err_mutex); + assert(!result && "Releasing the error string table mutex failed."); +} + static int32_t EnsureOpenSsl11Initialized() { // In OpenSSL 1.0 we call OPENSSL_add_all_algorithms_conf() and ERR_load_crypto_strings(), @@ -1279,6 +1297,10 @@ static int32_t EnsureOpenSsl11Initialized() OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); + // As a fallback for when the NO_ATEXIT isn't respected, register a later + // atexit handler, so we will indicate that we're in the shutdown state + // and stop asking problematic questions from other threads. + atexit(HandleShutdown); return 0; } diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_err.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_err.c index 252e7be59ce29..e38aaf71f7aec 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_err.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_err.c @@ -34,10 +34,48 @@ uint64_t CryptoNative_ErrPeekLastError() const char* CryptoNative_ErrReasonErrorString(uint64_t error) { - return ERR_reason_error_string((unsigned long)error); + const char* errStr = NULL; + +#ifdef NEED_OPENSSL_1_1 + int result = pthread_mutex_lock(&g_err_mutex); + assert(!result && "Acquiring the error string table mutex failed."); + + if (!g_err_unloaded) + { +#endif + errStr = ERR_reason_error_string((unsigned long)error); +#ifdef NEED_OPENSSL_1_1 + } + + result = pthread_mutex_unlock(&g_err_mutex); + assert(!result && "Releasing the error string table mutex failed."); +#endif + + return errStr; } void CryptoNative_ErrErrorStringN(uint64_t e, char* buf, int32_t len) { - ERR_error_string_n((unsigned long)e, buf, Int32ToSizeT(len)); +#ifdef NEED_OPENSSL_1_1 + int result = pthread_mutex_lock(&g_err_mutex); + assert(!result && "Acquiring the error string table mutex failed."); + + if (!g_err_unloaded) + { +#endif + ERR_error_string_n((unsigned long)e, buf, Int32ToSizeT(len)); +#ifdef NEED_OPENSSL_1_1 + } + else + { + // If there's no string table, just make it be the empty string. + if (buf != NULL && len > 0) + { + buf[0] = 0; + } + } + + result = pthread_mutex_unlock(&g_err_mutex); + assert(!result && "Releasing the error string table mutex failed."); +#endif } diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_err.h b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_err.h index 3610c263d0af1..1c7470251e411 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_err.h +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/pal_err.h @@ -6,6 +6,13 @@ #include #include "opensslshim.h" +#include + +#ifdef NEED_OPENSSL_1_1 +extern pthread_mutex_t g_err_mutex; +extern int volatile g_err_unloaded; +#endif + /* Shims the ERR_clear_error method. */ From 0cc1ac858fe85aef7e47562736e254c87f284b3b Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Thu, 14 May 2020 19:56:11 +0300 Subject: [PATCH 194/420] [mono] Shrink Android APK size (#36437) * Shrink Android apk size * bump xharness cli, use cmake config --- .config/dotnet-tools.json | 2 +- eng/testing/tests.mobile.targets | 1 + .../AndroidAppBuilder/AndroidAppBuilder.cs | 3 + .../msbuild/AndroidAppBuilder/ApkBuilder.cs | 56 ++++++++++++++++--- 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 49e475046f79c..73baf5d1e3a84 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "1.0.0-prerelease.20254.3", + "version": "1.0.0-prerelease.20264.2", "commands": [ "xharness" ] diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 4e6ceb20b1955..da84cdf37a6d0 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -36,6 +36,7 @@ ProjectName="$(AssemblyName)" MonoRuntimeHeaders="$(RuntimePackNativeDir)include\mono-2.0" MainLibraryFileName="AndroidTestRunner.dll" + StripDebugSymbols="False" OutputDir="$(BundleDir)" SourceDir="$(PublishDir)"> diff --git a/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.cs b/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.cs index 57e1f90aba85d..cc915aeaf69ef 100644 --- a/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.cs +++ b/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.cs @@ -41,6 +41,8 @@ public class AndroidAppBuilderTask : Task public string? BuildToolsVersion { get; set; } + public bool StripDebugSymbols { get; set; } + [Output] public string ApkBundlePath { get; set; } = ""!; @@ -59,6 +61,7 @@ public override bool Execute() apkBuilder.MinApiLevel = MinApiLevel; apkBuilder.BuildApiLevel = BuildApiLevel; apkBuilder.BuildToolsVersion = BuildToolsVersion; + apkBuilder.StripDebugSymbols = StripDebugSymbols; (ApkBundlePath, ApkPackageId) = apkBuilder.BuildApk(SourceDir, Abi, MainLibraryFileName, MonoRuntimeHeaders); return true; diff --git a/src/mono/msbuild/AndroidAppBuilder/ApkBuilder.cs b/src/mono/msbuild/AndroidAppBuilder/ApkBuilder.cs index 715d4e70b10d4..4330c7451f027 100644 --- a/src/mono/msbuild/AndroidAppBuilder/ApkBuilder.cs +++ b/src/mono/msbuild/AndroidAppBuilder/ApkBuilder.cs @@ -14,6 +14,7 @@ public class ApkBuilder public string? BuildApiLevel { get; set; } public string? BuildToolsVersion { get; set; } public string? OutputDir { get; set; } + public bool StripDebugSymbols { get; set; } public (string apk, string packageId) BuildApk( string sourceDir, string abi, string entryPointLib, string monoRuntimeHeaders) @@ -81,15 +82,28 @@ public class ApkBuilder Directory.CreateDirectory(Path.Combine(OutputDir, "obj")); Directory.CreateDirectory(Path.Combine(OutputDir, "assets")); + var extensionsToIgnore = new List { ".so", ".a", ".gz" }; + if (StripDebugSymbols) + { + extensionsToIgnore.Add(".pdb"); + extensionsToIgnore.Add(".dbg"); + } + // Copy AppDir to OutputDir/assets (ignore native files) Utils.DirectoryCopy(sourceDir, Path.Combine(OutputDir, "assets"), file => { string fileName = Path.GetFileName(file); string extension = Path.GetExtension(file); - // ignore native files, those go to lib/%abi% - if (extension == ".so" || extension == ".a") + + if (file.Any(s => s >= 128)) + { + // non-ascii files/folders are not allowed + return false; + } + if (extensionsToIgnore.Contains(extension)) { - // ignore ".pdb" and ".dbg" to make APK smaller + // ignore native files, those go to lib/%abi% + // also, aapt is not happy about zip files return false; } if (fileName.StartsWith(".")) @@ -129,10 +143,25 @@ public class ApkBuilder .Replace("%EntryPointLibName%", Path.GetFileName(entryPointLib)); File.WriteAllText(Path.Combine(OutputDir, "runtime-android.c"), runtimeAndroidSrc); - Utils.RunProcess(cmake, workingDir: OutputDir, - args: $"-DCMAKE_TOOLCHAIN_FILE={androidToolchain} -DANDROID_ABI=\"{abi}\" -DANDROID_STL=none " + - $"-DANDROID_NATIVE_API_LEVEL={MinApiLevel} -B runtime-android"); - Utils.RunProcess("make", workingDir: Path.Combine(OutputDir, "runtime-android")); + string cmakeGenArgs = $"-DCMAKE_TOOLCHAIN_FILE={androidToolchain} -DANDROID_ABI=\"{abi}\" -DANDROID_STL=none " + + $"-DANDROID_NATIVE_API_LEVEL={MinApiLevel} -B runtime-android"; + + string cmakeBuildArgs = "--build runtime-android"; + + if (StripDebugSymbols) + { + // Use "-s" to strip debug symbols, it complains it's unused but it works + cmakeGenArgs+= " -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_C_FLAGS=\"-s -Wno-unused-command-line-argument\""; + cmakeBuildArgs += " --config MinSizeRel"; + } + else + { + cmakeGenArgs += " -DCMAKE_BUILD_TYPE=Debug"; + cmakeBuildArgs += " --config Debug"; + } + + Utils.RunProcess(cmake, workingDir: OutputDir, args: cmakeGenArgs); + Utils.RunProcess(cmake, workingDir: OutputDir, args: cmakeBuildArgs); // 2. Compile Java files @@ -168,7 +197,16 @@ public class ApkBuilder Directory.CreateDirectory(Path.Combine(OutputDir, "lib", abi)); foreach (var dynamicLib in dynamicLibs) { - string destRelative = Path.Combine("lib", abi, Path.GetFileName(dynamicLib)); + string dynamicLibName = Path.GetFileName(dynamicLib); + if (dynamicLibName == "libmonosgen-2.0.so") + { + // we link mono runtime statically into libruntime-android.so + continue; + } + + // NOTE: we can run android-strip tool from NDK to shrink native binaries here even more. + + string destRelative = Path.Combine("lib", abi, dynamicLibName); File.Copy(dynamicLib, Path.Combine(OutputDir, destRelative), true); Utils.RunProcess(aapt, $"add {apkFile} {destRelative}", workingDir: OutputDir); } @@ -194,6 +232,8 @@ public class ApkBuilder Utils.RunProcess(apksigner, $"sign --min-sdk-version {MinApiLevel} --ks debug.keystore " + $"--ks-pass pass:android --key-pass pass:android {alignedApk}", workingDir: OutputDir); + Utils.LogInfo($"\nAPK size: {(new FileInfo(alignedApk).Length / 1000_000.0):0.#} Mb.\n"); + return (alignedApk, packageId); } From cf0fcdc1b8e42bb96343d3c2ee47256c7b0e6354 Mon Sep 17 00:00:00 2001 From: Simon Nattress Date: Thu, 14 May 2020 11:12:30 -0700 Subject: [PATCH 195/420] Update Linux docker instructions (#36370) * Update linux-instructions.md to use root build.sh --- docs/workflow/building/coreclr/linux-instructions.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/workflow/building/coreclr/linux-instructions.md b/docs/workflow/building/coreclr/linux-instructions.md index 8ebbb3b2e1906..7f2e046a781fd 100644 --- a/docs/workflow/building/coreclr/linux-instructions.md +++ b/docs/workflow/building/coreclr/linux-instructions.md @@ -19,7 +19,7 @@ Please note that when choosing an image choosing the same image as the host os y Once you have chosen an image the build is one command run from the root of the runtime repository: ```sh -docker run --rm -v :/runtime -w /runtime mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-16.04-a50a721-20191120200116 ./src/coreclr/build.sh -clang9 +docker run --rm -v :/runtime -w /runtime mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-16.04-20200508132555-78cbb55 ./build.sh --subset clr -clang9 ``` Dissecting the command: @@ -30,16 +30,18 @@ Dissecting the command: `-w: /runtime`: set /runtime as working directory for the container -`mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-16.04-a50a721-20191120200116`: image name. +`mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-16.04-20200508132555-78cbb55`: image name. -`./src/coreclr/build.sh`: command to be run in the container, run the build to coreclr. +`./build.sh`: command to be run in the container, run the build to coreclr. + +`--subset clr`: build the runtime subset (excluding libraries and installers) `-clang9`: argument to use clang 9 for the build, only compiler in the build image. -If you are attempting to cross build for arm/arm64 then use the crossrootfs location to set the ROOTFS_DIR. The command would add `-e ROOTFS_DIR=`. See [Docker Images](#Docker-Images) for the crossrootfs location. In addition you will need to specify `cross`. +If you are attempting to cross build for arm/arm64 then use the crossrootfs location to set the ROOTFS_DIR. The command would add `-e ROOTFS_DIR=`. See [Docker Images](#Docker-Images) for the crossrootfs location. In addition you will need to specify `--cross`. ```sh -docker run --rm -v :/runtime -w /runtime -e ROOTFS_DIR=/crossrootfs/arm64 mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-16.04-cross-arm64-20200413125008-cfdd435 ./src/coreclr/build.sh arm64 cross +docker run --rm -v :/runtime -w /runtime -e ROOTFS_DIR=/crossrootfs/arm64 mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-16.04-cross-arm64-20200508132638-b2c2436 ./build.sh --arch arm64 --cross --subset clr ``` Note that instructions on building the crossrootfs location can be found at [cross-building.md](cross-building.md). These instructions are suggested only if there are plans to change the rootfs, or the Docker images for arm/arm64 are insufficient for you build. From 459102612815c06dece8542b0a8b6c5e3eb42537 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Thu, 14 May 2020 20:50:17 +0200 Subject: [PATCH 196/420] Make depproj intermediate output paths unique again (#36451) Fixes https://github.com/dotnet/runtime/issues/36255 Depprojs depend on IntermediateOutputPath being set in a props file early enough as restore is happening per configuration. Even though it isn't recommended that the TargetFramework property is read before the project is loaded, we currently encode the TargetFramework in the IntermediateOutputPath for depproj files. The long-term fix is to get rid of per configuration restores by getting rid of our depproj files. --- src/libraries/restore/Directory.Build.props | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libraries/restore/Directory.Build.props b/src/libraries/restore/Directory.Build.props index 059f4b48d8ca2..359dfd63da6af 100644 --- a/src/libraries/restore/Directory.Build.props +++ b/src/libraries/restore/Directory.Build.props @@ -2,10 +2,13 @@ - + + $([MSBuild]::NormalizeDirectory('$(BaseIntermediateOutputPath)', '$(TargetFramework)-$(TargetFrameworkSuffix)-$(Configuration)')) + $([MSBuild]::NormalizeDirectory('$(BaseIntermediateOutputPath)', '$(TargetFramework)-$(Configuration)')) $(IntermediateOutputPath) $(RestoreOutputPath)/project.assets.json $(IntermediateOutputPath) + true false netstandard2.0 @@ -18,4 +21,4 @@ Build - \ No newline at end of file + From 04708d5b5d25795fac25663886e3b5fa68f3fa3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Thu, 14 May 2020 15:57:32 -0400 Subject: [PATCH 197/420] [Mono] Don't set thread name of main thread on Linux (#36116) * [mono] Record MonoNativeThreadId of the main thread We would like to know the MonoNativeThreadId (pthread_t on Linux) of the main thread of the application. We can identify the main thread (on linux) because it is the one for which `gettid () == getpid ()`. (`gettid()` returns a `pid_t` which is not the same thing as a `pthread_t`, hence this roundabout way of detecting it.) A complication arises in embedding scenarios: the main thread is not necessarily the one that calls `mono_jit_init` or otherwise interacts with the runtime. Therefore we do the `gettid() == getpid ()` test at `MonoThreadInfo` creation time when we call `register_thread`. If the main thread never interacts with Mono, the main thread is not known to us. * [mono] Don't set name of main thread on Linux Setting the name of the main thread also changes the name of the process. Fixes https://github.com/dotnet/runtime/issues/35908 The corresponding fix for CoreCLR is https://github.com/dotnet/runtime/pull/34064 * Re-enable test from https://github.com/dotnet/runtime/pull/34064 --- .../tests/ThreadTests.cs | 1 - src/mono/mono/utils/mono-threads-posix.c | 9 ++++ src/mono/mono/utils/mono-threads.c | 48 +++++++++++++++++++ src/mono/mono/utils/mono-threads.h | 3 ++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Threading.Thread/tests/ThreadTests.cs b/src/libraries/System.Threading.Thread/tests/ThreadTests.cs index 797629521a807..97356a400e7f3 100644 --- a/src/libraries/System.Threading.Thread/tests/ThreadTests.cs +++ b/src/libraries/System.Threading.Thread/tests/ThreadTests.cs @@ -652,7 +652,6 @@ public static void NameTest() } [Fact] - [ActiveIssue ("https://github.com/dotnet/runtime/issues/35908", TestRuntimes.Mono)] public static void ThreadNameDoesNotAffectProcessName() { // On Linux, changing the main thread name affects ProcessName. diff --git a/src/mono/mono/utils/mono-threads-posix.c b/src/mono/mono/utils/mono-threads-posix.c index 61d31fdeaae2b..c3ddb64d56523 100644 --- a/src/mono/mono/utils/mono-threads-posix.c +++ b/src/mono/mono/utils/mono-threads-posix.c @@ -308,6 +308,15 @@ mono_native_thread_set_name (MonoNativeThreadId tid, const char *name) pthread_setname_np (tid, "%s", (void*)n); } #elif defined (HAVE_PTHREAD_SETNAME_NP) +#if defined (__linux__) + /* Ignore requests to set the main thread name because it causes the + * value returned by Process.ProcessName to change. + */ + MonoNativeThreadId main_thread_tid; + if (mono_native_thread_id_main_thread_known (&main_thread_tid) && + mono_native_thread_id_equals (tid, main_thread_tid)) + return; +#endif if (!name) { pthread_setname_np (tid, ""); } else { diff --git a/src/mono/mono/utils/mono-threads.c b/src/mono/mono/utils/mono-threads.c index a4cec2c3be1a0..8fb5deefd8608 100644 --- a/src/mono/mono/utils/mono-threads.c +++ b/src/mono/mono/utils/mono-threads.c @@ -442,6 +442,53 @@ thread_handle_destroy (gpointer data) g_free (thread_handle); } +static gboolean native_thread_id_main_thread_known; +static MonoNativeThreadId native_thread_id_main_thread; + +/** + * mono_native_thread_id_main_thread_known: + * + * If the main thread of the process has interacted with Mono (in the sense + * that it has a MonoThreadInfo associated with it), return \c TRUE and write + * its MonoNativeThreadId to \c main_thread_tid. + * + * Otherwise return \c FALSE. + */ +gboolean +mono_native_thread_id_main_thread_known (MonoNativeThreadId *main_thread_tid) +{ + if (!native_thread_id_main_thread_known) + return FALSE; + g_assert (main_thread_tid); + *main_thread_tid = native_thread_id_main_thread; + return TRUE; +} + +/* + * Saves the MonoNativeThreadId (on Linux pthread_t) of the current thread if + * it is the main thread. + * + * The main thread is (on Linux) the one whose OS thread id (on Linux pid_t) is + * equal to the process id. + * + * We have to do this at thread registration time because in embedding + * scenarios we can't count on the main thread to be the one that calls + * mono_jit_init, or other runtime initialization functions. + */ +static void +native_thread_set_main_thread (void) +{ + if (native_thread_id_main_thread_known) + return; +#if defined(__linux__) + if (mono_native_thread_os_id_get () == (guint64)getpid ()) { + native_thread_id_main_thread = mono_native_thread_id_get (); + mono_memory_barrier (); + native_thread_id_main_thread_known = TRUE; + } +#endif +} + static gboolean register_thread (MonoThreadInfo *info) { @@ -451,6 +498,7 @@ register_thread (MonoThreadInfo *info) info->small_id = mono_thread_info_register_small_id (); mono_thread_info_set_tid (info, mono_native_thread_id_get ()); + native_thread_set_main_thread (); info->handle = g_new0 (MonoThreadHandle, 1); mono_refcount_init (info->handle, thread_handle_destroy); diff --git a/src/mono/mono/utils/mono-threads.h b/src/mono/mono/utils/mono-threads.h index a949b42f659a8..c47a33d977446 100644 --- a/src/mono/mono/utils/mono-threads.h +++ b/src/mono/mono/utils/mono-threads.h @@ -643,6 +643,9 @@ void mono_threads_coop_end_global_suspend (void); MONO_API MonoNativeThreadId mono_native_thread_id_get (void); +gboolean +mono_native_thread_id_main_thread_known (MonoNativeThreadId *main_thread_tid); + /* * This does _not_ return the same value as mono_native_thread_id_get, except on Windows. * On POSIX, mono_native_thread_id_get returns the value from pthread_self, which is then From 7debfe4b605a743b61eced52970563b59a4967ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Thu, 14 May 2020 22:19:08 +0200 Subject: [PATCH 198/420] Startup optimization w.r.t. manifest access in composite mode (#36446) During my work on fixing runtime crashes in composite build with large version bubble enabled I noticed room for startup perf improvement and a very slight working set optimization: For component assemblies of a composite image, we can basically share the cache of those manifest assembly references that have already been resolved (GetNativeMetadataAssemblyRefFromCache) within the native image because that is the logical owner of the manifest metadata. In the "asymptotic" case of composite images with many components, the pre-existing behavior was basically a quadratic O(n^2) algorithm in the number of component assemblies. This change reduces it to linear in the sense that all assembly references from the composite image get resolved only once. Thanks Tomas --- src/coreclr/src/vm/ceeload.cpp | 40 +++++++++++++++++++++--------- src/coreclr/src/vm/ceeload.h | 11 ++++---- src/coreclr/src/vm/nativeimage.cpp | 5 ++++ src/coreclr/src/vm/nativeimage.h | 2 ++ 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/coreclr/src/vm/ceeload.cpp b/src/coreclr/src/vm/ceeload.cpp index 30f6eeef79e52..acd979f6cb3cd 100644 --- a/src/coreclr/src/vm/ceeload.cpp +++ b/src/coreclr/src/vm/ceeload.cpp @@ -99,10 +99,10 @@ BOOL Module::HasNativeOrReadyToRunInlineTrackingMap() { LIMITED_METHOD_DAC_CONTRACT; #ifdef FEATURE_READYTORUN - if (IsReadyToRun() && GetReadyToRunInfo()->GetInlineTrackingMap() != NULL) - { - return TRUE; - } + if (IsReadyToRun() && GetReadyToRunInfo()->GetInlineTrackingMap() != NULL) + { + return TRUE; + } #endif return (m_pPersistentInlineTrackingMapNGen != NULL); } @@ -500,10 +500,9 @@ BOOL Module::IsPersistedObject(void *address) uint32_t Module::GetNativeMetadataAssemblyCount() { - NativeImage *compositeImage = GetCompositeNativeImage(); - if (compositeImage != NULL) + if (m_pNativeImage != NULL) { - return compositeImage->GetManifestAssemblyCount(); + return m_pNativeImage->GetManifestAssemblyCount(); } else { @@ -593,15 +592,25 @@ void Module::Initialize(AllocMemTracker *pamTracker, LPCWSTR szName) #endif // FEATURE_COLLECTIBLE_TYPES #ifdef FEATURE_READYTORUN + m_pNativeImage = NULL; if (!HasNativeImage() && !IsResource()) { if ((m_pReadyToRunInfo = ReadyToRunInfo::Initialize(this, pamTracker)) != NULL) { - COUNT_T cMeta = 0; - if (GetFile()->GetOpenedILimage()->GetNativeManifestMetadata(&cMeta) != NULL) + m_pNativeImage = m_pReadyToRunInfo->GetNativeImage(); + if (m_pNativeImage != NULL) + { + m_NativeMetadataAssemblyRefMap = m_pNativeImage->GetManifestMetadataAssemblyRefMap(); + } + else { - // Load the native assembly import - GetNativeAssemblyImport(TRUE /* loadAllowed */); + // For composite images, manifest metadata gets loaded as part of the native image + COUNT_T cMeta = 0; + if (GetFile()->GetOpenedILimage()->GetNativeManifestMetadata(&cMeta) != NULL) + { + // Load the native assembly import + GetNativeAssemblyImport(TRUE /* loadAllowed */); + } } } } @@ -9619,7 +9628,14 @@ void Module::Fixup(DataImage *image) image->ZeroField(this, offsetof(Module, m_AssemblyRefByNameCount), sizeof(m_AssemblyRefByNameCount)); image->ZeroPointerField(this, offsetof(Module, m_AssemblyRefByNameTable)); - image->ZeroPointerField(this,offsetof(Module, m_NativeMetadataAssemblyRefMap)); +#ifdef FEATURE_READYTORUN + // For composite ready-to-run images, the manifest assembly ref map is stored in the native image + // and shared by all its component images. + if (m_pNativeImage == NULL) +#endif + { + image->ZeroPointerField(this,offsetof(Module, m_NativeMetadataAssemblyRefMap)); + } // // Fixup statics diff --git a/src/coreclr/src/vm/ceeload.h b/src/coreclr/src/vm/ceeload.h index 9c11aa4bb5c05..361937847fd8f 100644 --- a/src/coreclr/src/vm/ceeload.h +++ b/src/coreclr/src/vm/ceeload.h @@ -1615,6 +1615,7 @@ class Module #ifdef FEATURE_READYTORUN private: PTR_ReadyToRunInfo m_pReadyToRunInfo; + PTR_NativeImage m_pNativeImage; #endif private: @@ -2924,17 +2925,17 @@ class Module #endif } - NativeImage *GetCompositeNativeImage() const +#ifdef FEATURE_READYTORUN + PTR_ReadyToRunInfo GetReadyToRunInfo() const { LIMITED_METHOD_DAC_CONTRACT; - return (m_pReadyToRunInfo != NULL ? m_pReadyToRunInfo->GetNativeImage() : NULL); + return m_pReadyToRunInfo; } -#ifdef FEATURE_READYTORUN - PTR_ReadyToRunInfo GetReadyToRunInfo() const + PTR_NativeImage GetCompositeNativeImage() const { LIMITED_METHOD_DAC_CONTRACT; - return m_pReadyToRunInfo; + return m_pNativeImage; } #endif diff --git a/src/coreclr/src/vm/nativeimage.cpp b/src/coreclr/src/vm/nativeimage.cpp index 70ad31ff1a9c1..e181bfb06446f 100644 --- a/src/coreclr/src/vm/nativeimage.cpp +++ b/src/coreclr/src/vm/nativeimage.cpp @@ -74,6 +74,11 @@ void NativeImage::Initialize(READYTORUN_HEADER *pHeader, LoaderAllocator *pLoade // count may exceed its component assembly count as it may contain references to // assemblies outside of the composite image that are part of its version bubble. _ASSERTE(m_manifestAssemblyCount >= m_componentAssemblyCount); + + S_SIZE_T dwAllocSize = S_SIZE_T(sizeof(PTR_Assembly)) * S_SIZE_T(m_manifestAssemblyCount); + + // Note: Memory allocated on loader heap is zero filled + m_pNativeMetadataAssemblyRefMap = (PTR_Assembly*)pamTracker->Track(pLoaderAllocator->GetLowFrequencyHeap()->AllocMem(dwAllocSize)); } NativeImage::~NativeImage() diff --git a/src/coreclr/src/vm/nativeimage.h b/src/coreclr/src/vm/nativeimage.h index 64cbf5410c64d..323a509ecbc83 100644 --- a/src/coreclr/src/vm/nativeimage.h +++ b/src/coreclr/src/vm/nativeimage.h @@ -62,6 +62,7 @@ class NativeImage ReadyToRunInfo *m_pReadyToRunInfo; IMDInternalImport *m_pManifestMetadata; PEImageLayout *m_pImageLayout; + PTR_Assembly *m_pNativeMetadataAssemblyRefMap; IMAGE_DATA_DIRECTORY *m_pComponentAssemblies; uint32_t m_componentAssemblyCount; @@ -95,6 +96,7 @@ class NativeImage ReadyToRunInfo *GetReadyToRunInfo() const { return m_pReadyToRunInfo; } IMDInternalImport *GetManifestMetadata() const { return m_pManifestMetadata; } uint32_t GetManifestAssemblyCount() const { return m_manifestAssemblyCount; } + PTR_Assembly *GetManifestMetadataAssemblyRefMap() { return m_pNativeMetadataAssemblyRefMap; } Assembly *LoadManifestAssembly(uint32_t rowid); From dfb2b42b968d2a820215e4d147c688423aef33fd Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Thu, 14 May 2020 14:00:32 -0700 Subject: [PATCH 199/420] Replace System.Native call in Interop.Errors.cs --- .../Common/src/Interop/Unix/Interop.Errors.cs | 11 + .../Native/Unix/Common/pal_error_common.h | 257 ++++++++++++++++++ .../Unix/System.IO.Ports.Native/pal_serial.c | 15 + .../Unix/System.IO.Ports.Native/pal_serial.h | 4 +- .../Native/Unix/System.Native/pal_errno.c | 252 +---------------- .../src/System.IO.Ports.csproj | 2 +- 6 files changed, 289 insertions(+), 252 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/Interop.Errors.cs b/src/libraries/Common/src/Interop/Unix/Interop.Errors.cs index dad796280e71a..e6de6c91723c3 100644 --- a/src/libraries/Common/src/Interop/Unix/Interop.Errors.cs +++ b/src/libraries/Common/src/Interop/Unix/Interop.Errors.cs @@ -182,6 +182,16 @@ internal static unsafe string StrError(int platformErrno) return Marshal.PtrToStringAnsi((IntPtr)message)!; } +#if SERIAL_PORTS + [DllImport(Libraries.IOPortsNative, EntryPoint = "SystemIoPortsNative_ConvertErrorPlatformToPal")] + internal static extern Error ConvertErrorPlatformToPal(int platformErrno); + + [DllImport(Libraries.IOPortsNative, EntryPoint = "SystemIoPortsNative_ConvertErrorPalToPlatform")] + internal static extern int ConvertErrorPalToPlatform(Error error); + + [DllImport(Libraries.IOPortsNative, EntryPoint = "SystemIoPortsNative_StrErrorR")] + private static extern unsafe byte* StrErrorR(int platformErrno, byte* buffer, int bufferSize); +#else [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_ConvertErrorPlatformToPal")] internal static extern Error ConvertErrorPlatformToPal(int platformErrno); @@ -190,6 +200,7 @@ internal static unsafe string StrError(int platformErrno) [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_StrErrorR")] private static extern unsafe byte* StrErrorR(int platformErrno, byte* buffer, int bufferSize); +#endif } } diff --git a/src/libraries/Native/Unix/Common/pal_error_common.h b/src/libraries/Native/Unix/Common/pal_error_common.h index d45bc21775ecb..f185811e6fb22 100644 --- a/src/libraries/Native/Unix/Common/pal_error_common.h +++ b/src/libraries/Native/Unix/Common/pal_error_common.h @@ -6,7 +6,12 @@ #include "pal_compiler.h" #include "pal_types.h" +#include "pal_config.h" +#include "pal_utilities.h" +#include +#include #include +#include // ENODATA is not defined in FreeBSD 10.3 but is defined in 11.0 #if defined(__FreeBSD__) & !defined(ENODATA) @@ -321,3 +326,255 @@ inline static int32_t ConvertErrorPlatformToPal(int32_t platformErrno) return Error_ENONSTANDARD; } + +inline static int32_t ConvertErrorPalToPlatform(int32_t error) +{ + switch (error) + { + case Error_SUCCESS: + return 0; + case Error_E2BIG: + return E2BIG; + case Error_EACCES: + return EACCES; + case Error_EADDRINUSE: + return EADDRINUSE; + case Error_EADDRNOTAVAIL: + return EADDRNOTAVAIL; + case Error_EAFNOSUPPORT: + return EAFNOSUPPORT; + case Error_EAGAIN: + return EAGAIN; + case Error_EALREADY: + return EALREADY; + case Error_EBADF: + return EBADF; + case Error_EBADMSG: + return EBADMSG; + case Error_EBUSY: + return EBUSY; + case Error_ECANCELED: + return ECANCELED; + case Error_ECHILD: + return ECHILD; + case Error_ECONNABORTED: + return ECONNABORTED; + case Error_ECONNREFUSED: + return ECONNREFUSED; + case Error_ECONNRESET: + return ECONNRESET; + case Error_EDEADLK: + return EDEADLK; + case Error_EDESTADDRREQ: + return EDESTADDRREQ; + case Error_EDOM: + return EDOM; + case Error_EDQUOT: + return EDQUOT; + case Error_EEXIST: + return EEXIST; + case Error_EFAULT: + return EFAULT; + case Error_EFBIG: + return EFBIG; + case Error_EHOSTUNREACH: + return EHOSTUNREACH; + case Error_EIDRM: + return EIDRM; + case Error_EILSEQ: + return EILSEQ; + case Error_EINPROGRESS: + return EINPROGRESS; + case Error_EINTR: + return EINTR; + case Error_EINVAL: + return EINVAL; + case Error_EIO: + return EIO; + case Error_EISCONN: + return EISCONN; + case Error_EISDIR: + return EISDIR; + case Error_ELOOP: + return ELOOP; + case Error_EMFILE: + return EMFILE; + case Error_EMLINK: + return EMLINK; + case Error_EMSGSIZE: + return EMSGSIZE; + case Error_EMULTIHOP: + return EMULTIHOP; + case Error_ENAMETOOLONG: + return ENAMETOOLONG; + case Error_ENETDOWN: + return ENETDOWN; + case Error_ENETRESET: + return ENETRESET; + case Error_ENETUNREACH: + return ENETUNREACH; + case Error_ENFILE: + return ENFILE; + case Error_ENOBUFS: + return ENOBUFS; + case Error_ENODEV: + return ENODEV; + case Error_ENOENT: + return ENOENT; + case Error_ENOEXEC: + return ENOEXEC; + case Error_ENOLCK: + return ENOLCK; + case Error_ENOLINK: + return ENOLINK; + case Error_ENOMEM: + return ENOMEM; + case Error_ENOMSG: + return ENOMSG; + case Error_ENOPROTOOPT: + return ENOPROTOOPT; + case Error_ENOSPC: + return ENOSPC; + case Error_ENOSYS: + return ENOSYS; + case Error_ENOTCONN: + return ENOTCONN; + case Error_ENOTDIR: + return ENOTDIR; + case Error_ENOTEMPTY: + return ENOTEMPTY; +#ifdef ENOTRECOVERABLE // not available in NetBSD + case Error_ENOTRECOVERABLE: + return ENOTRECOVERABLE; +#endif + case Error_ENOTSOCK: + return ENOTSOCK; + case Error_ENOTSUP: + return ENOTSUP; + case Error_ENOTTY: + return ENOTTY; + case Error_ENXIO: + return ENXIO; + case Error_EOVERFLOW: + return EOVERFLOW; +#ifdef EOWNERDEAD // not available in NetBSD + case Error_EOWNERDEAD: + return EOWNERDEAD; +#endif + case Error_EPERM: + return EPERM; + case Error_EPIPE: + return EPIPE; + case Error_EPROTO: + return EPROTO; + case Error_EPROTONOSUPPORT: + return EPROTONOSUPPORT; + case Error_EPROTOTYPE: + return EPROTOTYPE; + case Error_ERANGE: + return ERANGE; + case Error_EROFS: + return EROFS; + case Error_ESPIPE: + return ESPIPE; + case Error_ESRCH: + return ESRCH; + case Error_ESTALE: + return ESTALE; + case Error_ETIMEDOUT: + return ETIMEDOUT; + case Error_ETXTBSY: + return ETXTBSY; + case Error_EXDEV: + return EXDEV; + case Error_EPFNOSUPPORT: + return EPFNOSUPPORT; +#ifdef ESOCKTNOSUPPORT + case Error_ESOCKTNOSUPPORT: + return ESOCKTNOSUPPORT; +#endif + case Error_ESHUTDOWN: + return ESHUTDOWN; + case Error_EHOSTDOWN: + return EHOSTDOWN; + case Error_ENODATA: + return ENODATA; + case Error_EHOSTNOTFOUND: + return -(Error_EHOSTNOTFOUND); + case Error_ENONSTANDARD: + break; // fall through to assert + } + + // We should not use this function to round-trip platform -> pal + // -> platform. It's here only to synthesize a platform number + // from the fixed set above. Note that the assert is outside the + // switch rather than in a default case block because not + // having a default will trigger a warning (as error) if there's + // an enum value we haven't handled. Should that trigger, make + // note that there is probably a corresponding missing case in the + // other direction above, but the compiler can't warn in that case + // because the platform values are not part of an enum. + assert_err(false, "Unknown error code", (int) error); + return -1; +} + +static int32_t ConvertErrorPalToGai(int32_t error) +{ + switch (error) + { + case -(Error_EHOSTNOTFOUND): + return EAI_NONAME; + } + // Fall-through for unknown codes. gai_strerror() will handle that. + + return error; +} + + + +inline static const char* StrErrorR(int32_t platformErrno, char* buffer, int32_t bufferSize) +{ + assert(buffer != NULL); + assert(bufferSize > 0); + + if (bufferSize < 0) + return NULL; + + if (platformErrno < 0) + { + // Not a system error + SafeStringCopy(buffer, (size_t)bufferSize, gai_strerror(ConvertErrorPalToGai(platformErrno))); + return buffer; + } + +// Note that we must use strerror_r because plain strerror is not +// thread-safe. +// +// However, there are two versions of strerror_r: +// - GNU: char* strerror_r(int, char*, size_t); +// - POSIX: int strerror_r(int, char*, size_t); +// +// The former may or may not use the supplied buffer, and returns +// the error message string. The latter stores the error message +// string into the supplied buffer and returns an error code. + +#if HAVE_GNU_STRERROR_R + const char* message = strerror_r(platformErrno, buffer, (uint32_t) bufferSize); + assert(message != NULL); + return message; +#else + int error = strerror_r(platformErrno, buffer, (uint32_t) bufferSize); + if (error == ERANGE) + { + // Buffer is too small to hold the entire message, but has + // still been filled to the extent possible and null-terminated. + return NULL; + } + + // The only other valid error codes are 0 for success or EINVAL for + // an unknown error, but in the latter case a reasonable string (e.g + // "Unknown error: 0x123") is returned. + assert_err(error == 0 || error == EINVAL, "invalid error", error); + return buffer; +#endif +} diff --git a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c index 9eceb7e6b11ea..4a4babd185448 100644 --- a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c +++ b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.c @@ -72,3 +72,18 @@ int32_t SystemIoPortsNative_Shutdown(intptr_t socket, int32_t socketShutdown) { return Common_Shutdown(socket, socketShutdown); } + +int32_t SystemIoPortsNative_ConvertErrorPlatformToPal(int32_t platformErrno) +{ + return ConvertErrorPlatformToPal(platformErrno); +} + +int32_t SystemIoPortsNative_ConvertErrorPalToPlatform(int32_t error) +{ + return ConvertErrorPalToPlatform(error); +} + +const char* SystemIoPortsNative_StrErrorR(int32_t platformErrno, char* buffer, int32_t bufferSize) +{ + return StrErrorR(platformErrno, buffer, bufferSize); +} diff --git a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.h b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.h index 30a2d244b907b..371ceba0e8f70 100644 --- a/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.h +++ b/src/libraries/Native/Unix/System.IO.Ports.Native/pal_serial.h @@ -4,10 +4,12 @@ #include - PALEXPORT intptr_t SystemIoPortsNative_SerialPortOpen(const char * name); PALEXPORT int SystemIoPortsNative_SerialPortClose(intptr_t fd); PALEXPORT int32_t SystemIoPortsNative_Read(intptr_t fd, void* buffer, int32_t bufferSize); PALEXPORT int32_t SystemIoPortsNative_Write(intptr_t fd, const void* buffer, int32_t bufferSize); PALEXPORT int32_t SystemIoPortsNative_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t milliseconds, uint32_t* triggered); PALEXPORT int32_t SystemIoPortsNative_Shutdown(intptr_t socket, int32_t socketShutdown); +PALEXPORT int32_t SystemIoPortsNative_ConvertErrorPlatformToPal(int32_t platformErrno); +PALEXPORT int32_t SystemIoPortsNative_ConvertErrorPalToPlatform(int32_t error); +PALEXPORT const char* SystemIoPortsNative_StrErrorR(int32_t platformErrno, char* buffer, int32_t bufferSize); diff --git a/src/libraries/Native/Unix/System.Native/pal_errno.c b/src/libraries/Native/Unix/System.Native/pal_errno.c index 9ee754b3a3a8d..b0da1ec1f548e 100644 --- a/src/libraries/Native/Unix/System.Native/pal_errno.c +++ b/src/libraries/Native/Unix/System.Native/pal_errno.c @@ -2,13 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#include "pal_config.h" #include "pal_errno.h" -#include "pal_utilities.h" - -#include -#include -#include int32_t SystemNative_ConvertErrorPlatformToPal(int32_t platformErrno) { @@ -17,252 +11,10 @@ int32_t SystemNative_ConvertErrorPlatformToPal(int32_t platformErrno) int32_t SystemNative_ConvertErrorPalToPlatform(int32_t error) { - switch (error) - { - case Error_SUCCESS: - return 0; - case Error_E2BIG: - return E2BIG; - case Error_EACCES: - return EACCES; - case Error_EADDRINUSE: - return EADDRINUSE; - case Error_EADDRNOTAVAIL: - return EADDRNOTAVAIL; - case Error_EAFNOSUPPORT: - return EAFNOSUPPORT; - case Error_EAGAIN: - return EAGAIN; - case Error_EALREADY: - return EALREADY; - case Error_EBADF: - return EBADF; - case Error_EBADMSG: - return EBADMSG; - case Error_EBUSY: - return EBUSY; - case Error_ECANCELED: - return ECANCELED; - case Error_ECHILD: - return ECHILD; - case Error_ECONNABORTED: - return ECONNABORTED; - case Error_ECONNREFUSED: - return ECONNREFUSED; - case Error_ECONNRESET: - return ECONNRESET; - case Error_EDEADLK: - return EDEADLK; - case Error_EDESTADDRREQ: - return EDESTADDRREQ; - case Error_EDOM: - return EDOM; - case Error_EDQUOT: - return EDQUOT; - case Error_EEXIST: - return EEXIST; - case Error_EFAULT: - return EFAULT; - case Error_EFBIG: - return EFBIG; - case Error_EHOSTUNREACH: - return EHOSTUNREACH; - case Error_EIDRM: - return EIDRM; - case Error_EILSEQ: - return EILSEQ; - case Error_EINPROGRESS: - return EINPROGRESS; - case Error_EINTR: - return EINTR; - case Error_EINVAL: - return EINVAL; - case Error_EIO: - return EIO; - case Error_EISCONN: - return EISCONN; - case Error_EISDIR: - return EISDIR; - case Error_ELOOP: - return ELOOP; - case Error_EMFILE: - return EMFILE; - case Error_EMLINK: - return EMLINK; - case Error_EMSGSIZE: - return EMSGSIZE; - case Error_EMULTIHOP: - return EMULTIHOP; - case Error_ENAMETOOLONG: - return ENAMETOOLONG; - case Error_ENETDOWN: - return ENETDOWN; - case Error_ENETRESET: - return ENETRESET; - case Error_ENETUNREACH: - return ENETUNREACH; - case Error_ENFILE: - return ENFILE; - case Error_ENOBUFS: - return ENOBUFS; - case Error_ENODEV: - return ENODEV; - case Error_ENOENT: - return ENOENT; - case Error_ENOEXEC: - return ENOEXEC; - case Error_ENOLCK: - return ENOLCK; - case Error_ENOLINK: - return ENOLINK; - case Error_ENOMEM: - return ENOMEM; - case Error_ENOMSG: - return ENOMSG; - case Error_ENOPROTOOPT: - return ENOPROTOOPT; - case Error_ENOSPC: - return ENOSPC; - case Error_ENOSYS: - return ENOSYS; - case Error_ENOTCONN: - return ENOTCONN; - case Error_ENOTDIR: - return ENOTDIR; - case Error_ENOTEMPTY: - return ENOTEMPTY; -#ifdef ENOTRECOVERABLE // not available in NetBSD - case Error_ENOTRECOVERABLE: - return ENOTRECOVERABLE; -#endif - case Error_ENOTSOCK: - return ENOTSOCK; - case Error_ENOTSUP: - return ENOTSUP; - case Error_ENOTTY: - return ENOTTY; - case Error_ENXIO: - return ENXIO; - case Error_EOVERFLOW: - return EOVERFLOW; -#ifdef EOWNERDEAD // not available in NetBSD - case Error_EOWNERDEAD: - return EOWNERDEAD; -#endif - case Error_EPERM: - return EPERM; - case Error_EPIPE: - return EPIPE; - case Error_EPROTO: - return EPROTO; - case Error_EPROTONOSUPPORT: - return EPROTONOSUPPORT; - case Error_EPROTOTYPE: - return EPROTOTYPE; - case Error_ERANGE: - return ERANGE; - case Error_EROFS: - return EROFS; - case Error_ESPIPE: - return ESPIPE; - case Error_ESRCH: - return ESRCH; - case Error_ESTALE: - return ESTALE; - case Error_ETIMEDOUT: - return ETIMEDOUT; - case Error_ETXTBSY: - return ETXTBSY; - case Error_EXDEV: - return EXDEV; - case Error_EPFNOSUPPORT: - return EPFNOSUPPORT; -#ifdef ESOCKTNOSUPPORT - case Error_ESOCKTNOSUPPORT: - return ESOCKTNOSUPPORT; -#endif - case Error_ESHUTDOWN: - return ESHUTDOWN; - case Error_EHOSTDOWN: - return EHOSTDOWN; - case Error_ENODATA: - return ENODATA; - case Error_EHOSTNOTFOUND: - return -(Error_EHOSTNOTFOUND); - case Error_ENONSTANDARD: - break; // fall through to assert - } - - // We should not use this function to round-trip platform -> pal - // -> platform. It's here only to synthesize a platform number - // from the fixed set above. Note that the assert is outside the - // switch rather than in a default case block because not - // having a default will trigger a warning (as error) if there's - // an enum value we haven't handled. Should that trigger, make - // note that there is probably a corresponding missing case in the - // other direction above, but the compiler can't warn in that case - // because the platform values are not part of an enum. - assert_err(false, "Unknown error code", (int) error); - return -1; + return ConvertErrorPalToPlatform(error); } -static int32_t SystemNative_ConvertErrorPalToGai(int32_t error) -{ - switch (error) - { - case -(Error_EHOSTNOTFOUND): - return EAI_NONAME; - } - // Fall-through for unknown codes. gai_strerror() will handle that. - - return error; -} - - - const char* SystemNative_StrErrorR(int32_t platformErrno, char* buffer, int32_t bufferSize) { - assert(buffer != NULL); - assert(bufferSize > 0); - - if (bufferSize < 0) - return NULL; - - if (platformErrno < 0) - { - // Not a system error - SafeStringCopy(buffer, (size_t)bufferSize, gai_strerror(SystemNative_ConvertErrorPalToGai(platformErrno))); - return buffer; - } - -// Note that we must use strerror_r because plain strerror is not -// thread-safe. -// -// However, there are two versions of strerror_r: -// - GNU: char* strerror_r(int, char*, size_t); -// - POSIX: int strerror_r(int, char*, size_t); -// -// The former may or may not use the supplied buffer, and returns -// the error message string. The latter stores the error message -// string into the supplied buffer and returns an error code. - -#if HAVE_GNU_STRERROR_R - const char* message = strerror_r(platformErrno, buffer, (uint32_t) bufferSize); - assert(message != NULL); - return message; -#else - int error = strerror_r(platformErrno, buffer, (uint32_t) bufferSize); - if (error == ERANGE) - { - // Buffer is too small to hold the entire message, but has - // still been filled to the extent possible and null-terminated. - return NULL; - } - - // The only other valid error codes are 0 for success or EINVAL for - // an unknown error, but in the latter case a reasonable string (e.g - // "Unknown error: 0x123") is returned. - assert_err(error == 0 || error == EINVAL, "invalid error", error); - return buffer; -#endif + return StrErrorR(platformErrno, buffer, bufferSize); } diff --git a/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj b/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj index abd86468910af..d29ea8f219520 100644 --- a/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj +++ b/src/libraries/System.IO.Ports/src/System.IO.Ports.csproj @@ -1,7 +1,7 @@ true - $(DefineConstants);NOSPAN + $(DefineConstants);NOSPAN;SERIAL_PORTS true annotations netstandard2.0-Windows_NT;netstandard2.0-Linux;netstandard2.0-OSX;netstandard2.0;net461-Windows_NT;netstandard2.0-FreeBSD;$(NetFrameworkCurrent)-Windows_NT From 8b24e646a7ee754213a94b757e55995326fdf722 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 14 May 2020 14:06:45 -0700 Subject: [PATCH 200/420] Optimize ToScalar() and GetElement() to use arm64 intrinsic (#36156) * ARM64 intrisic for ToScalar() and GetElement() * Fixed GetElement to just operate on constants * Fix bug in rationalize for Vector64 * fix NotSupported issue for GetElement and ToScalar * Reuse the baseType/retType in impSpecialIntrinsic and impBaseIntrinsic * Update comment * fix breaks * add comments * ran jit-format * Refactored to move common logic inside isSupportedBaseType * review comments * reuse simdSize * formatting * one missing formatting --- src/coreclr/src/jit/compiler.h | 10 ++- src/coreclr/src/jit/hwintrinsic.cpp | 67 ++++++++++++++++- src/coreclr/src/jit/hwintrinsicarm64.cpp | 52 +++----------- .../src/jit/hwintrinsiccodegenarm64.cpp | 23 ++++++ src/coreclr/src/jit/hwintrinsiclistarm64.h | 4 ++ src/coreclr/src/jit/hwintrinsicxarch.cpp | 71 +++++++------------ src/coreclr/src/jit/lowerarmarch.cpp | 2 + src/coreclr/src/jit/rationalize.cpp | 16 +++-- .../src/System/Runtime/Intrinsics/Vector64.cs | 2 + 9 files changed, 150 insertions(+), 97 deletions(-) diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index a8e6220db3d61..b76f905c2a990 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -3752,7 +3752,10 @@ class Compiler GenTree* impSpecialIntrinsic(NamedIntrinsic intrinsic, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig); + CORINFO_SIG_INFO* sig, + var_types baseType, + var_types retType, + unsigned simdSize); GenTree* getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass, bool expectAddr = false); GenTree* impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, var_types baseType); @@ -3762,7 +3765,10 @@ class Compiler GenTree* impBaseIntrinsic(NamedIntrinsic intrinsic, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig); + CORINFO_SIG_INFO* sig, + var_types baseType, + var_types retType, + unsigned simdSize); GenTree* impSSEIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); GenTree* impSSE2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); GenTree* impAvxOrAvx2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); diff --git a/src/coreclr/src/jit/hwintrinsic.cpp b/src/coreclr/src/jit/hwintrinsic.cpp index e0e835043dd39..d0b2c1b53f338 100644 --- a/src/coreclr/src/jit/hwintrinsic.cpp +++ b/src/coreclr/src/jit/hwintrinsic.cpp @@ -583,6 +583,40 @@ static bool impIsTableDrivenHWIntrinsic(NamedIntrinsic intrinsicId, HWIntrinsicC !HWIntrinsicInfo::HasSpecialImport(intrinsicId); } +//------------------------------------------------------------------------ +// isSupportedBaseType +// +// Arguments: +// intrinsicId - HW intrinsic id +// baseType - Base type of the intrinsic. +// +// Return Value: +// returns true if the baseType is supported for given intrinsic. +// +static bool isSupportedBaseType(NamedIntrinsic intrinsic, var_types baseType) +{ + // We don't actually check the intrinsic outside of the false case as we expect + // the exposed managed signatures are either generic and support all types + // or they are explicit and support the type indicated. + if (varTypeIsArithmetic(baseType)) + { + return true; + } + +#ifdef TARGET_XARCH + assert((intrinsic >= NI_Vector128_As && intrinsic <= NI_Vector128_AsUInt64) || + (intrinsic >= NI_Vector128_get_AllBitsSet && intrinsic <= NI_Vector128_ToVector256Unsafe) || + (intrinsic >= NI_Vector256_As && intrinsic <= NI_Vector256_AsUInt64) || + (intrinsic >= NI_Vector256_get_AllBitsSet && intrinsic <= NI_Vector256_ToScalar)); +#else + assert((intrinsic >= NI_Vector64_AsByte && intrinsic <= NI_Vector64_AsUInt32) || + (intrinsic >= NI_Vector64_get_AllBitsSet && intrinsic <= NI_Vector64_ToScalar) || + (intrinsic >= NI_Vector128_As && intrinsic <= NI_Vector128_AsUInt64) || + (intrinsic >= NI_Vector128_get_AllBitsSet && intrinsic <= NI_Vector128_ToScalar)); +#endif + return false; +} + //------------------------------------------------------------------------ // impHWIntrinsic: Import a hardware intrinsic as a GT_HWINTRINSIC node if possible // @@ -614,9 +648,38 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, baseType = getBaseTypeAndSizeOfSIMDType(sig->retTypeSigClass, &sizeBytes); retType = getSIMDTypeForSize(sizeBytes); assert(sizeBytes != 0); + + // We want to return early here for cases where retType was TYP_STRUCT as per method signature and + // rather than deferring the decision after getting the baseType of arg. + if (!isSupportedBaseType(intrinsic, baseType)) + { + return nullptr; + } + } + + baseType = getBaseTypeFromArgIfNeeded(intrinsic, clsHnd, sig, baseType); + + if (baseType == TYP_UNKNOWN) + { + if (category != HW_Category_Scalar) + { + unsigned int sizeBytes; + baseType = getBaseTypeAndSizeOfSIMDType(clsHnd, &sizeBytes); + assert((category == HW_Category_Special) || (sizeBytes != 0)); + } + else + { + baseType = retType; + } + } + + // Immediately return if the category is other than scalar/special and this is not a supported base type. + if ((category != HW_Category_Special) && (category != HW_Category_Scalar) && + !isSupportedBaseType(intrinsic, baseType)) + { + return nullptr; } - baseType = getBaseTypeFromArgIfNeeded(intrinsic, clsHnd, sig, baseType); unsigned simdSize = HWIntrinsicInfo::lookupSimdSize(this, intrinsic, sig); GenTree* immOp = nullptr; @@ -836,7 +899,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, return retNode; } - return impSpecialIntrinsic(intrinsic, clsHnd, method, sig); + return impSpecialIntrinsic(intrinsic, clsHnd, method, sig, baseType, retType, simdSize); } #endif // FEATURE_HW_INTRINSICS diff --git a/src/coreclr/src/jit/hwintrinsicarm64.cpp b/src/coreclr/src/jit/hwintrinsicarm64.cpp index 7127b69e850d1..a7d5c213f824f 100644 --- a/src/coreclr/src/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/src/jit/hwintrinsicarm64.cpp @@ -207,6 +207,8 @@ int HWIntrinsicInfo::lookupImmUpperBound(NamedIntrinsic intrinsic, int simdSize, case NI_AdvSimd_ExtractVector64: case NI_AdvSimd_Insert: case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128: + case NI_Vector64_GetElement: + case NI_Vector128_GetElement: immUpperBound = Compiler::getSIMDVectorLength(simdSize, baseType); break; @@ -260,7 +262,9 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT // intrinsic -- id of the intrinsic function. // clsHnd -- class handle containing the intrinsic function. // method -- method handle of the intrinsic function. -// sig -- signature of the intrinsic call +// sig -- signature of the intrinsic call. +// baseType -- generic argument of the intrinsic. +// retType -- return type of the intrinsic. // // Return Value: // The GT_HWINTRINSIC node, or nullptr if not a supported intrinsic @@ -268,52 +272,16 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig) + CORINFO_SIG_INFO* sig, + var_types baseType, + var_types retType, + unsigned simdSize) { HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsic); int numArgs = sig->numArgs; - var_types retType = JITtype2varType(sig->retType); - var_types baseType = TYP_UNKNOWN; - if ((retType == TYP_STRUCT) && featureSIMD) - { - unsigned int sizeBytes; - baseType = getBaseTypeAndSizeOfSIMDType(sig->retTypeSigClass, &sizeBytes); - retType = getSIMDTypeForSize(sizeBytes); - assert(sizeBytes != 0); - - if (!varTypeIsArithmetic(baseType)) - { - assert((intrinsic == NI_Vector64_AsByte) || (intrinsic == NI_Vector128_As) || - (intrinsic == NI_Vector64_get_Zero) || (intrinsic == NI_Vector64_get_AllBitsSet) || - (intrinsic == NI_Vector128_get_Zero) || (intrinsic == NI_Vector128_get_AllBitsSet)); - return nullptr; - } - } - - baseType = getBaseTypeFromArgIfNeeded(intrinsic, clsHnd, sig, baseType); - - if (baseType == TYP_UNKNOWN) - { - if (category != HW_Category_Scalar) - { - unsigned int sizeBytes; - baseType = getBaseTypeAndSizeOfSIMDType(clsHnd, &sizeBytes); - assert(sizeBytes != 0); - } - else - { - baseType = retType; - } - } - - if (!varTypeIsArithmetic(baseType)) - { - return nullptr; - } - - unsigned simdSize = HWIntrinsicInfo::lookupSimdSize(this, intrinsic, sig); assert(numArgs >= 0); + assert(varTypeIsArithmetic(baseType)); GenTree* retNode = nullptr; GenTree* op1 = nullptr; diff --git a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp index 7aca22290f00d..e2093a5b5f951 100644 --- a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp @@ -617,6 +617,29 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) } break; + case NI_Vector64_GetElement: + case NI_Vector128_GetElement: + case NI_Vector64_ToScalar: + case NI_Vector128_ToScalar: + { + ssize_t indexValue = 0; + if ((intrin.id == NI_Vector64_GetElement) || (intrin.id == NI_Vector128_GetElement)) + { + assert(intrin.op2->IsCnsIntOrI()); + indexValue = intrin.op2->AsIntCon()->gtIconVal; + } + + // no-op if vector is float/double, targetReg == op1Reg and fetching for 0th index. + if ((varTypeIsFloating(intrin.baseType) && (targetReg == op1Reg) && (indexValue == 0))) + { + break; + } + + GetEmitter()->emitIns_R_R_I(ins, emitTypeSize(intrin.baseType), targetReg, op1Reg, indexValue, + INS_OPTS_NONE); + } + break; + default: unreached(); } diff --git a/src/coreclr/src/jit/hwintrinsiclistarm64.h b/src/coreclr/src/jit/hwintrinsiclistarm64.h index 0ca6f8d918abc..80a5f487e2ff4 100644 --- a/src/coreclr/src/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/src/jit/hwintrinsiclistarm64.h @@ -28,6 +28,8 @@ HARDWARE_INTRINSIC(Vector64, CreateScalarUnsafe, HARDWARE_INTRINSIC(Vector64, get_AllBitsSet, 8, 0, {INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector64, get_Count, 8, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector64, get_Zero, 8, 0, {INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector64, GetElement, 8, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_NoJmpTableIMM|HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector64, ToScalar, 8, 1, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags @@ -50,6 +52,8 @@ HARDWARE_INTRINSIC(Vector128, CreateScalarUnsafe, 1 HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, 16, 0, {INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector128, get_Count, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, get_Zero, 16, 0, {INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector128, GetElement, 16, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_NoJmpTableIMM|HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector128, ToScalar, 16, 1, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags diff --git a/src/coreclr/src/jit/hwintrinsicxarch.cpp b/src/coreclr/src/jit/hwintrinsicxarch.cpp index 1ed4dd7716151..214ce21496f5a 100644 --- a/src/coreclr/src/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/src/jit/hwintrinsicxarch.cpp @@ -469,22 +469,26 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT // intrinsic -- id of the intrinsic function. // clsHnd -- class handle containing the intrinsic function. // method -- method handle of the intrinsic function. -// sig -- signature of the intrinsic call -// +// sig -- signature of the intrinsic call. +// baseType -- generic argument of the intrinsic. +// retType -- return type of the intrinsic. // Return Value: // the expanded intrinsic. // GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig) + CORINFO_SIG_INFO* sig, + var_types baseType, + var_types retType, + unsigned simdSize) { // other intrinsics need special importation switch (HWIntrinsicInfo::lookupIsa(intrinsic)) { case InstructionSet_Vector128: case InstructionSet_Vector256: - return impBaseIntrinsic(intrinsic, clsHnd, method, sig); + return impBaseIntrinsic(intrinsic, clsHnd, method, sig, baseType, retType, simdSize); case InstructionSet_SSE: return impSSEIntrinsic(intrinsic, method, sig); case InstructionSet_SSE2: @@ -509,15 +513,19 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, // Arguments: // intrinsic -- id of the intrinsic function. // method -- method handle of the intrinsic function. -// sig -- signature of the intrinsic call -// +// sig -- signature of the intrinsic call. +// baseType -- generic argument of the intrinsic. +// retType -- return type of the intrinsic. // Return Value: // the expanded intrinsic. // GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* sig) + CORINFO_SIG_INFO* sig, + var_types baseType, + var_types retType, + unsigned simdSize) { GenTree* retNode = nullptr; GenTree* op1 = nullptr; @@ -528,42 +536,6 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, return nullptr; } - unsigned simdSize = 0; - var_types baseType = TYP_UNKNOWN; - var_types retType = JITtype2varType(sig->retType); - - assert(!sig->hasThis()); - - if (HWIntrinsicInfo::BaseTypeFromFirstArg(intrinsic)) - { - baseType = getBaseTypeAndSizeOfSIMDType(info.compCompHnd->getArgClass(sig, sig->args), &simdSize); - - if (retType == TYP_STRUCT) - { - unsigned retSimdSize = 0; - var_types retBasetype = getBaseTypeAndSizeOfSIMDType(sig->retTypeClass, &retSimdSize); - if (!varTypeIsArithmetic(retBasetype)) - { - return nullptr; - } - retType = getSIMDTypeForSize(retSimdSize); - } - } - else if (retType == TYP_STRUCT) - { - baseType = getBaseTypeAndSizeOfSIMDType(sig->retTypeClass, &simdSize); - retType = getSIMDTypeForSize(simdSize); - } - else - { - baseType = getBaseTypeAndSizeOfSIMDType(clsHnd, &simdSize); - } - - if (!varTypeIsArithmetic(baseType)) - { - return nullptr; - } - switch (intrinsic) { case NI_Vector256_As: @@ -618,7 +590,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, if (getSIMDVectorRegisterByteLength() == YMM_REGSIZE_BYTES) { // Vector is TYP_SIMD32, so we should treat this as a call to Vector128.ToVector256 - return impBaseIntrinsic(NI_Vector128_ToVector256, clsHnd, method, sig); + return impBaseIntrinsic(NI_Vector128_ToVector256, clsHnd, method, sig, baseType, retType, simdSize); } assert(getSIMDVectorRegisterByteLength() == XMM_REGSIZE_BYTES); @@ -659,6 +631,11 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_AsVector128: { assert(sig->numArgs == 1); + assert(HWIntrinsicInfo::BaseTypeFromFirstArg(intrinsic)); + + var_types baseTypeOfIntrinsic = + getBaseTypeAndSizeOfSIMDType(info.compCompHnd->getArgClass(sig, sig->args), &simdSize); + assert(baseType == baseTypeOfIntrinsic); switch (getSIMDTypeForSize(simdSize)) { @@ -686,7 +663,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, case TYP_SIMD32: { // Vector is TYP_SIMD32, so we should treat this as a call to Vector256.GetLower - return impBaseIntrinsic(NI_Vector256_GetLower, clsHnd, method, sig); + return impBaseIntrinsic(NI_Vector256_GetLower, clsHnd, method, sig, baseType, retType, simdSize); } default: @@ -725,12 +702,12 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic, if (intrinsic == NI_Vector256_AsVector) { - return impBaseIntrinsic(NI_Vector256_GetLower, clsHnd, method, sig); + return impBaseIntrinsic(NI_Vector256_GetLower, clsHnd, method, sig, baseType, retType, simdSize); } else { assert(intrinsic == NI_Vector256_AsVector256); - return impBaseIntrinsic(NI_Vector128_ToVector256, clsHnd, method, sig); + return impBaseIntrinsic(NI_Vector128_ToVector256, clsHnd, method, sig, baseType, retType, simdSize); } } diff --git a/src/coreclr/src/jit/lowerarmarch.cpp b/src/coreclr/src/jit/lowerarmarch.cpp index d5272abb25c99..899531b896d21 100644 --- a/src/coreclr/src/jit/lowerarmarch.cpp +++ b/src/coreclr/src/jit/lowerarmarch.cpp @@ -1160,6 +1160,8 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AdvSimd_DuplicateSelectedScalarToVector128: case NI_AdvSimd_Extract: case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128: + case NI_Vector64_GetElement: + case NI_Vector128_GetElement: if (intrin.op2->IsCnsIntOrI()) { MakeSrcContained(node, intrin.op2); diff --git a/src/coreclr/src/jit/rationalize.cpp b/src/coreclr/src/jit/rationalize.cpp index 07bdd29f83411..d2f813463f369 100644 --- a/src/coreclr/src/jit/rationalize.cpp +++ b/src/coreclr/src/jit/rationalize.cpp @@ -785,10 +785,18 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, Compiler::Ge // type(s). if ((hwIntrinsicNode->gtType == TYP_I_IMPL) && (hwIntrinsicNode->gtSIMDSize == TARGET_POINTER_SIZE)) { - // This happens when it is consumed by a GT_RET_EXPR. - // It can only be a Vector2f or Vector2i. - assert(genTypeSize(hwIntrinsicNode->gtSIMDBaseType) == 4); - hwIntrinsicNode->gtType = TYP_SIMD8; +#ifdef TARGET_ARM64 + // Special case for GetElement/ToScalar because they take Vector64 and return T + // and T can be long or ulong. + if (!(hwIntrinsicNode->gtHWIntrinsicId == NI_Vector64_GetElement || + hwIntrinsicNode->gtHWIntrinsicId == NI_Vector64_ToScalar)) +#endif + { + // This happens when it is consumed by a GT_RET_EXPR. + // It can only be a Vector2f or Vector2i. + assert(genTypeSize(hwIntrinsicNode->gtSIMDBaseType) == 4); + hwIntrinsicNode->gtType = TYP_SIMD8; + } } break; } 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 f376ebf3bce52..873056c31dca9 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 @@ -885,6 +885,7 @@ public static unsafe Vector64 CreateScalarUnsafe(uint value) /// The value of the element at . /// The type of () is not supported. /// was less than zero or greater than the number of elements. + [Intrinsic] public static T GetElement(this Vector64 vector, int index) where T : struct { @@ -928,6 +929,7 @@ public static Vector64 WithElement(this Vector64 vector, int index, T v /// The vector to get the first element from. /// A scalar containing the value of the first element. /// The type of () is not supported. + [Intrinsic] public static T ToScalar(this Vector64 vector) where T : struct { From 9ee68d0921488e3a3323c79fbead9b8e7a1be361 Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Thu, 14 May 2020 14:49:33 -0700 Subject: [PATCH 201/420] Next round of Struct Improvements (#36146) - Allow accessing a SIMD12 as 16 bytes if it's the single field of a parent struct of 16 bytes. - On x64/ux don't copy an argument just because it is promoted; the copy would force it to memory anyway. - Use block init for a promoted struct that's been marked lvDoNotEnregister. - Allow field-by-field copy of structs with the same fields --- src/coreclr/src/jit/compiler.h | 20 ++++++++------- src/coreclr/src/jit/morph.cpp | 47 +++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index b76f905c2a990..5a2dfcfbfb598 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -3501,19 +3501,21 @@ class Compiler assert(varDsc->lvSize() == 16); #endif // defined(TARGET_64BIT) - // We make local variable SIMD12 types 16 bytes instead of just 12. lvSize() - // already does this calculation. However, we also need to prevent mapping types if the var is a - // dependently promoted struct field, which must remain its exact size within its parent struct. - // However, we don't know this until late, so we may have already pretended the field is bigger - // before that. - if ((varDsc->lvSize() == 16) && !lvaIsFieldOfDependentlyPromotedStruct(varDsc)) + // We make local variable SIMD12 types 16 bytes instead of just 12. + // lvSize() will return 16 bytes for SIMD12, even for fields. + // However, we can't do that mapping if the var is a dependently promoted struct field. + // Such a field must remain its exact size within its parent struct unless it is a single + // field *and* it is the only field in a struct of 16 bytes. + if (varDsc->lvSize() != 16) { - return true; + return false; } - else + if (lvaIsFieldOfDependentlyPromotedStruct(varDsc)) { - return false; + LclVarDsc* parentVarDsc = lvaGetDesc(varDsc->lvParentLcl); + return (parentVarDsc->lvFieldCnt == 1) && (parentVarDsc->lvSize() == 16); } + return true; } #endif // defined(FEATURE_SIMD) diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index fc64cf09877f9..379cf107b62f0 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -3665,31 +3665,21 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) #else // UNIX_AMD64_ABI // On Unix, structs are always passed by value. // We only need a copy if we have one of the following: - // - We have a lclVar that has been promoted and is passed in registers. // - The sizes don't match for a non-lclVar argument. // - We have a known struct type (e.g. SIMD) that requires multiple registers. - // TODO-Amd64-Unix-CQ: The first case could and should be handled without copies. // TODO-Amd64-Unix-Throughput: We don't need to keep the structDesc in the argEntry if it's not // actually passed in registers. if (argEntry->isPassedInRegisters()) { assert(argEntry->structDesc.passedInRegisters); - if (lclVar != nullptr) - { - if (lvaGetPromotionType(lclVar->AsLclVarCommon()->GetLclNum()) == - PROMOTION_TYPE_INDEPENDENT) - { - copyBlkClass = objClass; - } - } - else if (argObj->OperIs(GT_OBJ)) + if (argObj->OperIs(GT_OBJ)) { if (passingSize != structSize) { copyBlkClass = objClass; } } - else + else if (lclVar == nullptr) { // This should only be the case of a value directly producing a known struct type. assert(argObj->TypeGet() != TYP_STRUCT); @@ -9720,7 +9710,9 @@ GenTree* Compiler::fgMorphInitBlock(GenTree* tree) } #endif // LOCAL_ASSERTION_PROP - if (destLclVar->lvPromoted) + // If we have already determined that a promoted TYP_STRUCT lclVar will not be enregistered, + // we are better off doing a block init. + if (destLclVar->lvPromoted && (!destLclVar->lvDoNotEnregister || !destLclNode->TypeIs(TYP_STRUCT))) { GenTree* newTree = fgMorphPromoteLocalInitBlock(destLclNode->AsLclVar(), initVal, blockSize); @@ -10604,15 +10596,30 @@ GenTree* Compiler::fgMorphCopyBlock(GenTree* tree) // Are both dest and src promoted structs? if (destDoFldAsg && srcDoFldAsg) { - // Both structs should be of the same type, or each have a single field of the same type. + // Both structs should be of the same type, or have the same number of fields of the same type. // If not we will use a copy block. - if (lvaTable[destLclNum].lvVerTypeInfo.GetClassHandle() != - lvaTable[srcLclNum].lvVerTypeInfo.GetClassHandle()) + bool misMatchedTypes = false; + if (destLclVar->lvVerTypeInfo.GetClassHandle() != srcLclVar->lvVerTypeInfo.GetClassHandle()) { - unsigned destFieldNum = lvaTable[destLclNum].lvFieldLclStart; - unsigned srcFieldNum = lvaTable[srcLclNum].lvFieldLclStart; - if ((lvaTable[destLclNum].lvFieldCnt != 1) || (lvaTable[srcLclNum].lvFieldCnt != 1) || - (lvaTable[destFieldNum].lvType != lvaTable[srcFieldNum].lvType)) + if (destLclVar->lvFieldCnt != srcLclVar->lvFieldCnt) + { + misMatchedTypes = true; + } + else + { + for (int i = 0; i < destLclVar->lvFieldCnt; i++) + { + LclVarDsc* destFieldVarDsc = lvaGetDesc(destLclVar->lvFieldLclStart + i); + LclVarDsc* srcFieldVarDsc = lvaGetDesc(srcLclVar->lvFieldLclStart + i); + if ((destFieldVarDsc->lvType != srcFieldVarDsc->lvType) || + (destFieldVarDsc->lvFldOffset != srcFieldVarDsc->lvFldOffset)) + { + misMatchedTypes = true; + break; + } + } + } + if (misMatchedTypes) { requiresCopyBlock = true; // Mismatched types, leave as a CopyBlock JITDUMP(" with mismatched types"); From b9524694bc8f8b3676a6bcf25eb7586194693b38 Mon Sep 17 00:00:00 2001 From: Shimmy <2716316+weitzhandler@users.noreply.github.com> Date: Fri, 15 May 2020 00:53:25 +0300 Subject: [PATCH 202/420] Issue 36212: Remove space in parameter name (#36439) * Issue 36212: Remove space in parameter name * Update src/coreclr/src/vm/comutilnative.cpp Co-authored-by: Stephen Toub Co-authored-by: Stephen Toub --- src/coreclr/src/vm/comutilnative.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/vm/comutilnative.cpp b/src/coreclr/src/vm/comutilnative.cpp index 0205d70691396..a0649ccf348fa 100644 --- a/src/coreclr/src/vm/comutilnative.cpp +++ b/src/coreclr/src/vm/comutilnative.cpp @@ -917,7 +917,7 @@ FCIMPL1(int, GCInterface::GetGenerationWR, LPVOID handle) OBJECTREF temp; temp = ObjectFromHandle((OBJECTHANDLE) handle); if (temp == NULL) - COMPlusThrowArgumentNull(W("weak handle")); + COMPlusThrowArgumentNull(W("wo")); iRetVal = (INT32)GCHeapUtilities::GetGCHeap()->WhichGeneration(OBJECTREFToObject(temp)); From aea91ebf7bbf581b04fff82d385cd99796ce8b7c Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Thu, 14 May 2020 15:31:53 -0700 Subject: [PATCH 203/420] Remove unnessary guard against switched property names --- .../System.Text.Json/src/Resources/Strings.resx | 6 +++--- .../Collection/DictionaryDefaultConverter.cs | 2 +- .../Converters/Value/KeyValuePairConverter.cs | 7 ++----- .../Text/Json/ThrowHelper.Serialization.cs | 11 ++--------- .../CollectionTests.KeyValuePair.cs | 16 ---------------- 5 files changed, 8 insertions(+), 34 deletions(-) diff --git a/src/libraries/System.Text.Json/src/Resources/Strings.resx b/src/libraries/System.Text.Json/src/Resources/Strings.resx index 4ee750fe9d6bd..7296413876ee5 100644 --- a/src/libraries/System.Text.Json/src/Resources/Strings.resx +++ b/src/libraries/System.Text.Json/src/Resources/Strings.resx @@ -396,8 +396,8 @@ The converter '{0}' wrote too much or not enough. - - The dictionary key policy '{0}' cannot return a null key. + + The naming policy '{0}' cannot return null. The attribute '{0}' cannot exist more than once on '{1}'. @@ -524,4 +524,4 @@ The naming policy '{0}' returned an invalid value for a 'KeyValuePair' property name. The value cannot be 'null', cannot be a case-insensitive match for the literal 'Value' when converting the 'Key' property name, and cannot be a case-insensitive match for the literal 'Key' when converting the 'Value' property name. - + \ No newline at end of file diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs index a657398ca2d3f..4603b59c82f96 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs @@ -47,7 +47,7 @@ protected string GetKeyName(string key, ref WriteStack state, JsonSerializerOpti if (key == null) { - ThrowHelper.ThrowInvalidOperationException_SerializerDictionaryKeyNull(options.DictionaryKeyPolicy.GetType()); + ThrowHelper.ThrowInvalidOperationException_NamingPolicyReturnNull(options.DictionaryKeyPolicy); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs index 095613e1fc816..08e790738f62f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs @@ -38,12 +38,9 @@ internal override void Initialize(JsonSerializerOptions options) _keyName = namingPolicy.ConvertName(KeyNameCLR); _valueName = namingPolicy.ConvertName(ValueNameCLR); - if (_keyName == null || - _valueName == null || - string.Equals(_keyName, ValueNameCLR, StringComparison.OrdinalIgnoreCase) || - string.Equals(_valueName, KeyNameCLR, StringComparison.OrdinalIgnoreCase)) + if (_keyName == null || _valueName == null) { - ThrowHelper.ThrowInvalidOperationException_KeyValuePairPropertyNameInvalid(namingPolicy); + ThrowHelper.ThrowInvalidOperationException_NamingPolicyReturnNull(namingPolicy); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs index 4ef3ab641e420..0d7bd68400ee4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs @@ -163,16 +163,9 @@ public static void ThrowInvalidOperationException_SerializerPropertyNameNull(Typ [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowInvalidOperationException_SerializerDictionaryKeyNull(Type policyType) + public static void ThrowInvalidOperationException_NamingPolicyReturnNull(JsonNamingPolicy namingPolicy) { - throw new InvalidOperationException(SR.Format(SR.SerializerDictionaryKeyNull, policyType)); - } - - [DoesNotReturn] - [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowInvalidOperationException_KeyValuePairPropertyNameInvalid(JsonNamingPolicy namingPolicy) - { - throw new InvalidOperationException(SR.Format(SR.KeyValuePairPropertyNameInvalid, namingPolicy.GetType())); + throw new InvalidOperationException(SR.Format(SR.NamingPolicyReturnNull, namingPolicy)); } [DoesNotReturn] diff --git a/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.KeyValuePair.cs b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.KeyValuePair.cs index 08f679f62ab27..868167086cfa9 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.KeyValuePair.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CollectionTests/CollectionTests.KeyValuePair.cs @@ -389,8 +389,6 @@ private class TrailingAngleBracketPolicy : JsonNamingPolicy [Theory] [InlineData(typeof(KeyNameNullPolicy))] [InlineData(typeof(ValueNameNullPolicy))] - [InlineData(typeof(KeyNameMapsToValuePolicy))] - [InlineData(typeof(ValueNameMapsToKeyPolicy))] public static void InvalidPropertyNameFail(Type policyType) { var options = new JsonSerializerOptions @@ -400,11 +398,7 @@ public static void InvalidPropertyNameFail(Type policyType) InvalidOperationException ex = Assert.Throws(() => JsonSerializer.Deserialize>("", options)); string exAsStr = ex.ToString(); - Assert.Contains(policyType.ToString(), exAsStr); - Assert.Contains("'Key'", exAsStr); - Assert.Contains("'Value'", exAsStr); - Assert.Contains("'KeyValuePair'", exAsStr); Assert.Throws(() => JsonSerializer.Serialize(new KeyValuePair("", ""), options)); } @@ -419,16 +413,6 @@ private class ValueNameNullPolicy : JsonNamingPolicy public override string ConvertName(string name) => name == "Value" ? null : name; } - private class KeyNameMapsToValuePolicy : JsonNamingPolicy - { - public override string ConvertName(string name) => name == "Key" ? "Value" : name; - } - - private class ValueNameMapsToKeyPolicy : JsonNamingPolicy - { - public override string ConvertName(string name) => name == "Value" ? "k\u0045y" : name; // kEy - } - [Theory] [InlineData("")] [InlineData("1")] From 858642d15844126d9869d677a9b53864becd0a5f Mon Sep 17 00:00:00 2001 From: Simon Nattress Date: Thu, 14 May 2020 16:18:55 -0700 Subject: [PATCH 204/420] R2RTest - Partial composite images (#36471) Allow compiling composite R2R images which reference assemblies not in the composite. For example, this would allow compiling a set of application assemblies with references to ASP.NET / Framework. Currently R2RTest treats all references as unrooted inputs for the composite image. --- src/coreclr/src/tools/r2rtest/BuildOptions.cs | 1 + .../src/tools/r2rtest/CommandLineOptions.cs | 4 ++++ .../tools/r2rtest/Commands/CompileSerpCommand.cs | 16 +++++++++++++++- src/coreclr/src/tools/r2rtest/CpaotRunner.cs | 2 +- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/tools/r2rtest/BuildOptions.cs b/src/coreclr/src/tools/r2rtest/BuildOptions.cs index eec3f5bc711f3..152b6ae04352f 100644 --- a/src/coreclr/src/tools/r2rtest/BuildOptions.cs +++ b/src/coreclr/src/tools/r2rtest/BuildOptions.cs @@ -30,6 +30,7 @@ public class BuildOptions public bool Release { get; set; } public bool LargeBubble { get; set; } public bool Composite { get; set; } + public bool PartialComposite { get; set; } public int Crossgen2Parallelism { get; set; } public int CompilationTimeoutMinutes { get; set; } public int ExecutionTimeoutMinutes { get; set; } diff --git a/src/coreclr/src/tools/r2rtest/CommandLineOptions.cs b/src/coreclr/src/tools/r2rtest/CommandLineOptions.cs index 5f6d3d914d364..0deebb10d4619 100644 --- a/src/coreclr/src/tools/r2rtest/CommandLineOptions.cs +++ b/src/coreclr/src/tools/r2rtest/CommandLineOptions.cs @@ -158,6 +158,7 @@ public static CommandLineBuilder Build() CoreRootDirectory(), AspNetPath(), Composite(), + PartialComposite(), }, handler: CommandHandler.Create(CompileSerpCommand.CompileSerpAssemblies)); @@ -267,6 +268,9 @@ public static CommandLineBuilder Build() // Option AspNetPath() => new Option(new[] { "--asp-net-path", "-asp" }, "Path to SERP's ASP.NET Core folder", new Argument().ExistingOnly()); + + Option PartialComposite() => + new Option(new[] { "--partial-composite", "-pc" }, "Add references to framework and asp.net instead of unrooted inputs", new Argument()); } } } diff --git a/src/coreclr/src/tools/r2rtest/Commands/CompileSerpCommand.cs b/src/coreclr/src/tools/r2rtest/Commands/CompileSerpCommand.cs index af6b7ba8c918e..15893256577bc 100644 --- a/src/coreclr/src/tools/r2rtest/Commands/CompileSerpCommand.cs +++ b/src/coreclr/src/tools/r2rtest/Commands/CompileSerpCommand.cs @@ -110,12 +110,26 @@ public static int CompileSerpAssemblies(BuildOptions options) referenceAssemblies.Add(Path.Combine(options.CoreRootDirectory.FullName, "mscorlib.dll")); referenceAssemblies.Add(Path.Combine(options.CoreRootDirectory.FullName, "netstandard.dll")); + // + // binFiles is now all the assemblies that we want to compile (either individually or as composite) + // referenceAssemblies is all managed assemblies that are referenceable + // + + // Remove all bin files except serp.dll so they're just referenced (eventually we'll be able to compile all these in a single composite) + foreach (string item in new HashSet(File.ReadAllLines(whiteListFilePath))) + { + if (item == "Serp.dll") + continue; + + binFiles.Remove(Path.Combine(binDir, item)); + } + List fileCompilations = new List(); if (options.Composite) { string serpDll = Path.Combine(binDir, "Serp.dll"); var runner = new CpaotRunner(options, referenceAssemblies); - var compilationProcess = new ProcessInfo(new CompilationProcessConstructor(runner, Path.ChangeExtension(serpDll, ".ni.dll"), referenceAssemblies)); + var compilationProcess = new ProcessInfo(new CompilationProcessConstructor(runner, Path.ChangeExtension(serpDll, ".ni.dll"), binFiles)); fileCompilations.Add(compilationProcess); } else diff --git a/src/coreclr/src/tools/r2rtest/CpaotRunner.cs b/src/coreclr/src/tools/r2rtest/CpaotRunner.cs index f1f9090eec82e..128b0e20ed6ce 100644 --- a/src/coreclr/src/tools/r2rtest/CpaotRunner.cs +++ b/src/coreclr/src/tools/r2rtest/CpaotRunner.cs @@ -137,7 +137,7 @@ protected override IEnumerable BuildCommandLineArguments(IEnumerable Date: Thu, 14 May 2020 16:19:16 -0700 Subject: [PATCH 205/420] Add issue templates (#36431) * more * commented * yml * Add an issue template for API proposals * Update .github/ISSUE_TEMPLATE/api-proposal.md Co-authored-by: Stephen Toub * Update .github/ISSUE_TEMPLATE/api-proposal.md Co-authored-by: Stephen Toub * Update .github/ISSUE_TEMPLATE/api-proposal.md Co-authored-by: Stephen Toub * comment out template instructions * apply consistent naming * feedback * add blank * H2 and H3 Co-authored-by: Eirik Tsarpalis Co-authored-by: Stephen Toub --- .github/ISSUE_TEMPLATE/api_proposal.md | 52 +++++++++++++++++++++ .github/ISSUE_TEMPLATE/blank.md | 8 ++++ .github/ISSUE_TEMPLATE/bug_report.md | 41 ++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 20 ++++++++ .github/ISSUE_TEMPLATE/performance_issue.md | 50 ++++++++++++++++++++ 5 files changed, 171 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/api_proposal.md create mode 100644 .github/ISSUE_TEMPLATE/blank.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/performance_issue.md diff --git a/.github/ISSUE_TEMPLATE/api_proposal.md b/.github/ISSUE_TEMPLATE/api_proposal.md new file mode 100644 index 0000000000000..69dd06f60a307 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/api_proposal.md @@ -0,0 +1,52 @@ +--- +name: API Proposal +about: Propose a change to the public API surface. +title: '' +labels: api-suggestion +assignees: '' + +--- + +## Background and Motivation + + + +## Proposed API + + + +## Usage Examples + + + +## Alternative Designs + + + +## Risks + + diff --git a/.github/ISSUE_TEMPLATE/blank.md b/.github/ISSUE_TEMPLATE/blank.md new file mode 100644 index 0000000000000..0e3e133dcb9b8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/blank.md @@ -0,0 +1,8 @@ +--- +name: Blank +about: Something that doesn't fit the other categories +title: '' +labels: '' +assignees: '' + +--- diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000000..ddca1a08888f5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,41 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + + + +### Description + + + +### Configuration + + + +### Regression? + + + +### Other information + + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000000..4b38bcf921191 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,20 @@ +blank_issues_enabled: true +contact_links: + - name: Issue with ASP.NET Core + url: https://github.com/dotnet/aspnetcore/issues/new/choose + about: Please open issues with ASP.NET Core in their repo + - name: Issue with .NET Core SDK + url: https://github.com/dotnet/sdk/issues/new/choose + about: Please open issues with the .NET Core SDK in their repo + - name: Issue with Entity Framework + url: https://github.com/dotnet/efcore/issues/new/choose + about: Please open issues with Entity Framework in their repo + - name: Issue with Roslyn compiler + url: https://github.com/dotnet/roslyn/issues/new/choose + about: Please open issues with the Roslyn compiler in their repo + - name: Issue with Windows Forms + url: https://github.com/dotnet/winforms/issues/new/choose + about: Please open issues with Windows Forms in their repo + - name: Issue with WPF + url: https://github.com/dotnet/wpf/issues/new/choose + about: Please open issues with WPF in their repo diff --git a/.github/ISSUE_TEMPLATE/performance_issue.md b/.github/ISSUE_TEMPLATE/performance_issue.md new file mode 100644 index 0000000000000..6da186f0453df --- /dev/null +++ b/.github/ISSUE_TEMPLATE/performance_issue.md @@ -0,0 +1,50 @@ +--- +name: Performance issue +about: Report a performance problem or regression +title: '' +labels: 'tenet-performance' +assignees: '' + +--- + + + +### Description + + + +### Configuration + + + +### Regression? + + + +### Data + + + +### Analysis + + From 10c60fcdbe2d8173c62154ed80b5f71b564733a0 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 14 May 2020 16:27:35 -0700 Subject: [PATCH 206/420] Implement unwrapping a ComWrappers CCW when dumping a stowed exception. (#36360) --- src/coreclr/src/debug/daccess/CMakeLists.txt | 1 + src/coreclr/src/debug/daccess/dacimpl.h | 4 ++ src/coreclr/src/debug/daccess/enummem.cpp | 22 +++++- src/coreclr/src/debug/daccess/request.cpp | 72 ++++++++++++++++++++ src/coreclr/src/inc/daccess.h | 3 + src/coreclr/src/interop/comwrappers.cpp | 27 +++++--- src/coreclr/src/interop/inc/interoplibabi.h | 14 ++++ 7 files changed, 129 insertions(+), 14 deletions(-) create mode 100644 src/coreclr/src/interop/inc/interoplibabi.h diff --git a/src/coreclr/src/debug/daccess/CMakeLists.txt b/src/coreclr/src/debug/daccess/CMakeLists.txt index 6d18ad64fded8..b683d762885b4 100644 --- a/src/coreclr/src/debug/daccess/CMakeLists.txt +++ b/src/coreclr/src/debug/daccess/CMakeLists.txt @@ -5,6 +5,7 @@ include_directories(BEFORE ${VM_DIR}/${ARCH_SOURCES_DIR}) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CLR_DIR}/src/debug/ee) include_directories(${CLR_DIR}/src/gcdump) +include_directories(${CLR_DIR}/src/interop/inc) if(CLR_CMAKE_HOST_UNIX) include_directories(${GENERATED_INCLUDE_DIR}) diff --git a/src/coreclr/src/debug/daccess/dacimpl.h b/src/coreclr/src/debug/daccess/dacimpl.h index 958adb1fd9178..29183751fb53e 100644 --- a/src/coreclr/src/debug/daccess/dacimpl.h +++ b/src/coreclr/src/debug/daccess/dacimpl.h @@ -1456,6 +1456,10 @@ class ClrDataAccess PTR_IUnknown DACGetCOMIPFromCCW(PTR_ComCallWrapper pCCW, int vtableIndex); #endif +#ifdef FEATURE_COMWRAPPERS + HRESULT DACTryGetComWrappersObjectFromCCW(CLRDATA_ADDRESS ccwPtr, OBJECTREF* objRef); +#endif + static LONG s_procInit; public: diff --git a/src/coreclr/src/debug/daccess/enummem.cpp b/src/coreclr/src/debug/daccess/enummem.cpp index 6a3feec6cf9f5..5c5f402b99ad0 100644 --- a/src/coreclr/src/debug/daccess/enummem.cpp +++ b/src/coreclr/src/debug/daccess/enummem.cpp @@ -1298,7 +1298,7 @@ HRESULT ClrDataAccess::EnumMemDumpAllThreadsStack(CLRDataEnumMemoryFlags flags) } -#ifdef FEATURE_COMINTEROP +#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS) //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // WinRT stowed exception holds the (CCW)pointer to a managed exception object. @@ -1431,11 +1431,26 @@ HRESULT ClrDataAccess::DumpStowedExceptionObject(CLRDataEnumMemoryFlags flags, C if (ccwPtr == NULL) return S_OK; + OBJECTREF managedExceptionObject = NULL; + +#ifdef FEATURE_COMINTEROP // dump the managed exception object wrapped in CCW // memory of the CCW object itself is dumped later by DacInstanceManager::DumpAllInstances DacpCCWData ccwData; GetCCWData(ccwPtr, &ccwData); // this call collects some memory implicitly - DumpManagedExcepObject(flags, OBJECTREF(TO_TADDR(ccwData.managedObject))); + managedExceptionObject = OBJECTREF(CLRDATA_ADDRESS_TO_TADDR(ccwData.managedObject)); +#endif +#ifdef FEATURE_COMWRAPPERS + if (managedExceptionObject == NULL) + { + OBJECTREF wrappedObjAddress; + if (DACTryGetComWrappersObjectFromCCW(ccwPtr, &wrappedObjAddress) == S_OK) + { + managedExceptionObject = wrappedObjAddress; + } + } +#endif + DumpManagedExcepObject(flags, managedExceptionObject); // dump memory of the 2nd slot in the CCW's vtable // this is used in DACGetCCWFromAddress to identify if the passed in pointer is a valid CCW. @@ -1450,7 +1465,8 @@ HRESULT ClrDataAccess::DumpStowedExceptionObject(CLRDataEnumMemoryFlags flags, C CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED ( - ReportMem(vTableAddress + sizeof(PBYTE)* TEAR_OFF_SLOT, sizeof(TADDR)); + ReportMem(vTableAddress, sizeof(TADDR)); // Report the QI slot on the vtable for ComWrappers + ReportMem(vTableAddress + sizeof(PBYTE) * TEAR_OFF_SLOT, sizeof(TADDR)); // Report the AddRef slot on the vtable for built-in CCWs ); return S_OK; diff --git a/src/coreclr/src/debug/daccess/request.cpp b/src/coreclr/src/debug/daccess/request.cpp index 79880ff064e5e..8fc4896abdcd1 100644 --- a/src/coreclr/src/debug/daccess/request.cpp +++ b/src/coreclr/src/debug/daccess/request.cpp @@ -20,6 +20,8 @@ #include #endif // FEATURE_COMINTEROP +#include + #ifndef TARGET_UNIX // It is unfortunate having to include this header just to get the definition of GenericModeBlock #include @@ -4065,6 +4067,76 @@ PTR_IUnknown ClrDataAccess::DACGetCOMIPFromCCW(PTR_ComCallWrapper pCCW, int vtab } #endif +#ifdef FEATURE_COMWRAPPERS +HRESULT ClrDataAccess::DACTryGetComWrappersObjectFromCCW(CLRDATA_ADDRESS ccwPtr, OBJECTREF* objRef) +{ + if (ccwPtr == 0 || objRef == NULL) + return E_INVALIDARG; + + SOSDacEnter(); + + // Read CCWs QI address and compare it to the managed object wrapper's implementation. + ULONG32 bytesRead = 0; + TADDR ccw = CLRDATA_ADDRESS_TO_TADDR(ccwPtr); + TADDR vTableAddress = NULL; + IfFailGo(m_pTarget->ReadVirtual(ccw, (PBYTE)&vTableAddress, sizeof(TADDR), &bytesRead)); + if (bytesRead != sizeof(TADDR) + || vTableAddress == NULL) + { + hr = E_FAIL; + goto ErrExit; + } + + TADDR qiAddress = NULL; + IfFailGo(m_pTarget->ReadVirtual(vTableAddress, (PBYTE)&qiAddress, sizeof(TADDR), &bytesRead)); + if (bytesRead != sizeof(TADDR) + || qiAddress == NULL) + { + hr = E_FAIL; + goto ErrExit; + } + + +#ifdef TARGET_ARM + // clear the THUMB bit on qiAddress before comparing with known vtable entry + qiAddress &= ~THUMB_CODE; +#endif + + if (qiAddress != GetEEFuncEntryPoint(ManagedObjectWrapper_QueryInterface)) + { + hr = E_FAIL; + goto ErrExit; + } + + // Mask the "dispatch pointer" to get a double pointer to the ManagedObjectWrapper + TADDR managedObjectWrapperPtrPtr = ccw & InteropLib::ABI::DispatchThisPtrMask; + + // Return ManagedObjectWrapper as an OBJECTHANDLE. (The OBJECTHANDLE is guaranteed to live at offset 0). + TADDR managedObjectWrapperPtr; + IfFailGo(m_pTarget->ReadVirtual(managedObjectWrapperPtrPtr, (PBYTE)&managedObjectWrapperPtr, sizeof(TADDR), &bytesRead)); + if (bytesRead != sizeof(TADDR)) + { + hr = E_FAIL; + goto ErrExit; + } + + OBJECTHANDLE handle; + IfFailGo(m_pTarget->ReadVirtual(managedObjectWrapperPtr, (PBYTE)&handle, sizeof(OBJECTHANDLE), &bytesRead)); + if (bytesRead != sizeof(OBJECTHANDLE)) + { + hr = E_FAIL; + goto ErrExit; + } + + *objRef = ObjectFromHandle(handle); + + SOSDacLeave(); + + return S_OK; + +ErrExit: return hr; +} +#endif HRESULT ClrDataAccess::GetCCWData(CLRDATA_ADDRESS ccw, struct DacpCCWData *ccwData) { diff --git a/src/coreclr/src/inc/daccess.h b/src/coreclr/src/inc/daccess.h index 2c68abff92c18..f2b37c32db749 100644 --- a/src/coreclr/src/inc/daccess.h +++ b/src/coreclr/src/inc/daccess.h @@ -629,6 +629,9 @@ typedef struct _DacGlobals ULONG fn__Unknown_AddRefSpecial; ULONG fn__Unknown_AddRefInner; #endif +#ifdef FEATURE_COMWRAPPERS + ULONG fn__ManagedObjectWrapper_QueryInterface; +#endif // Vtable pointer values for all classes that must // be instanted using vtable pointers as the identity. diff --git a/src/coreclr/src/interop/comwrappers.cpp b/src/coreclr/src/interop/comwrappers.cpp index 60d80910a5078..3fb1b7941ed75 100644 --- a/src/coreclr/src/interop/comwrappers.cpp +++ b/src/coreclr/src/interop/comwrappers.cpp @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. #include "comwrappers.hpp" +#include #include #include // placement new @@ -47,8 +48,8 @@ namespace ABI }; ABI_ASSERT(sizeof(ComInterfaceDispatch) == sizeof(void*)); - const size_t DispatchAlignmentThisPtr = 16; // Should be a power of 2. - const intptr_t DispatchThisPtrMask = ~(DispatchAlignmentThisPtr - 1); + using InteropLib::ABI::DispatchAlignmentThisPtr; + using InteropLib::ABI::DispatchThisPtrMask; ABI_ASSERT(sizeof(void*) < DispatchAlignmentThisPtr); const intptr_t AlignmentThisPtrMaxPadding = DispatchAlignmentThisPtr - sizeof(void*); @@ -179,17 +180,20 @@ namespace ABI } } -namespace +// ManagedObjectWrapper_QueryInterface needs to be visible outside of this compilation unit +// to support the DAC. See code:ClrDataAccess::DACTryGetComWrappersObjectFromCCW for the +// usage in the DAC (look for the GetEEFuncEntryPoint call). +HRESULT STDMETHODCALLTYPE ManagedObjectWrapper_QueryInterface( + _In_ ABI::ComInterfaceDispatch* disp, + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject) { - HRESULT STDMETHODCALLTYPE ManagedObjectWrapper_QueryInterface( - _In_ ABI::ComInterfaceDispatch* disp, - /* [in] */ REFIID riid, - /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject) - { - ManagedObjectWrapper* wrapper = ABI::ToManagedObjectWrapper(disp); - return wrapper->QueryInterface(riid, ppvObject); - } + ManagedObjectWrapper* wrapper = ABI::ToManagedObjectWrapper(disp); + return wrapper->QueryInterface(riid, ppvObject); +} +namespace +{ ULONG STDMETHODCALLTYPE ManagedObjectWrapper_AddRef(_In_ ABI::ComInterfaceDispatch* disp) { ManagedObjectWrapper* wrapper = ABI::ToManagedObjectWrapper(disp); @@ -310,6 +314,7 @@ void ManagedObjectWrapper::GetIUnknownImpl( *fpRelease = ManagedObjectWrapper_IUnknownImpl.Release; } +// The logic here should match code:ClrDataAccess::DACTryGetComWrappersObjectFromCCW in daccess/request.cpp ManagedObjectWrapper* ManagedObjectWrapper::MapFromIUnknown(_In_ IUnknown* pUnk) { _ASSERTE(pUnk != nullptr); diff --git a/src/coreclr/src/interop/inc/interoplibabi.h b/src/coreclr/src/interop/inc/interoplibabi.h new file mode 100644 index 0000000000000..19a1e0c01e755 --- /dev/null +++ b/src/coreclr/src/interop/inc/interoplibabi.h @@ -0,0 +1,14 @@ +// 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. + +#include + +namespace InteropLib +{ + namespace ABI + { + const size_t DispatchAlignmentThisPtr = 16; // Should be a power of 2. + const intptr_t DispatchThisPtrMask = ~(DispatchAlignmentThisPtr - 1); + } +} From a1f86575ac262fc89b00399ad4fc3c8a73b90cb4 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Thu, 14 May 2020 16:51:48 -0700 Subject: [PATCH 207/420] Move mobile test runners to libs.pretest instead of P2P (#36473) --- eng/testing/tests.mobile.targets | 12 +++++++++++- eng/testing/tests.props | 13 +++++++++---- .../tests/AndroidTestRunner/AndroidTestRunner.cs | 2 ++ .../AndroidTestRunner/AndroidTestRunner.csproj | 6 ++---- .../tests/AppleTestRunner/AppleTestRunner.csproj | 6 ++---- src/libraries/Directory.Build.props | 3 --- src/libraries/pretest.proj | 3 +++ 7 files changed, 29 insertions(+), 16 deletions(-) diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index da84cdf37a6d0..586874ad362f6 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -3,7 +3,7 @@ $([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle')) $([MSBuild]::NormalizePath('$(BundleDir)', '$(RunScriptOutputName)')) - true + true @@ -104,6 +104,16 @@ + + + <_runnerFilesToPublish Include="$(AndroidTestRunnerDir)*" Condition="'$(TargetOS)' == 'Android'" /> + <_runnerFilesToPublish Include="$(AppleTestRunnerDir)*" Condition="'$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'tvOS'" /> + + + + + diff --git a/eng/testing/tests.props b/eng/testing/tests.props index 50ff37c891a4f..6a35aef60eba0 100644 --- a/eng/testing/tests.props +++ b/eng/testing/tests.props @@ -21,10 +21,15 @@ - $(NetCoreAppCurrent)-$(MonoConfiguration) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder', '$(MobileHelpersDirSuffix)')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', '$(MobileHelpersDirSuffix)')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'MonoAOTCompiler', '$(MobileHelpersDirSuffix)')) + $(NetCoreAppCurrent)-$(MonoConfiguration) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder', '$(MobileHelperTasksDirSuffix)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', '$(MobileHelperTasksDirSuffix)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'MonoAOTCompiler', '$(MobileHelperTasksDirSuffix)')) + + + $(NetCoreAppCurrent)-$(Configuration) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleTestRunner', '$(MobileRunnersDirSuffix)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidTestRunner', '$(MobileRunnersDirSuffix)')) $(PackageRID) true diff --git a/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs b/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs index 9f232f549ba92..cd02378f62542 100644 --- a/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs +++ b/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs @@ -92,7 +92,9 @@ protected override IEnumerable GetTestAssemblies() public string? Locale { get; } +#pragma warning disable CS8764 public override TextWriter? Logger => null; +#pragma warning restore CS8764 public override string TestsResultsFinalPath { diff --git a/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.csproj b/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.csproj index 24fde08ba8a65..6f73d8ec7cefb 100644 --- a/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.csproj +++ b/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.csproj @@ -2,11 +2,9 @@ Exe enable - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent) - - + diff --git a/src/libraries/Common/tests/AppleTestRunner/AppleTestRunner.csproj b/src/libraries/Common/tests/AppleTestRunner/AppleTestRunner.csproj index 078bf94a1172a..906eea315338d 100644 --- a/src/libraries/Common/tests/AppleTestRunner/AppleTestRunner.csproj +++ b/src/libraries/Common/tests/AppleTestRunner/AppleTestRunner.csproj @@ -2,11 +2,9 @@ Exe enable - $(NetCoreAppCurrent);$(NetFrameworkCurrent) + $(NetCoreAppCurrent) - - + diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index 67d25c68cd05b..c82088bcb6e98 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -323,9 +323,6 @@ - - - diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj index d073141959ef5..860998494f56e 100644 --- a/src/libraries/pretest.proj +++ b/src/libraries/pretest.proj @@ -16,6 +16,9 @@ + + + Date: Thu, 14 May 2020 20:39:08 -0400 Subject: [PATCH 208/420] Add options to ignore default values during serialization (#36322) * Add options to ignore default values during serialization * Address review feedback * Fix typo in test --- .../System.Text.Json/ref/System.Text.Json.cs | 7 +- .../src/Resources/Strings.resx | 6 + ...ctWithParameterizedConstructorConverter.cs | 2 +- .../Json/Serialization/JsonConverterOfT.cs | 3 + .../Json/Serialization/JsonIgnoreCondition.cs | 17 +- .../Json/Serialization/JsonPropertyInfo.cs | 22 ++- .../Json/Serialization/JsonPropertyInfoOfT.cs | 68 ++++---- .../JsonResumableConverterOfT.cs | 2 +- .../JsonSerializer.Read.HandlePropertyName.cs | 2 +- .../Serialization/JsonSerializerOptions.cs | 51 +++++- .../Serialization/JsonValueConverterOfT.cs | 2 + .../System.Text.Json/tests/JsonTestHelper.cs | 6 +- .../CustomConverterTests.HandleNull.cs | 42 ++++- .../tests/Serialization/ExtensionDataTests.cs | 4 +- .../tests/Serialization/OptionsTests.cs | 116 ++++++------- ...pertyVisibilityTests.NonPublicAccessors.cs | 2 +- .../Serialization/PropertyVisibilityTests.cs | 161 +++++++++++++----- 17 files changed, 359 insertions(+), 154 deletions(-) diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index 21b3c645040f4..4aa8377c12746 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -213,6 +213,7 @@ public sealed partial class JsonSerializerOptions public bool AllowTrailingCommas { get { throw null; } set { } } public System.Collections.Generic.IList Converters { get { throw null; } } public int DefaultBufferSize { get { throw null; } set { } } + public System.Text.Json.Serialization.JsonIgnoreCondition DefaultIgnoreCondition { get { throw null; } set { } } public System.Text.Json.JsonNamingPolicy? DictionaryKeyPolicy { get { throw null; } set { } } public System.Text.Encodings.Web.JavaScriptEncoder? Encoder { get { throw null; } set { } } public bool IgnoreNullValues { get { throw null; } set { } } @@ -465,9 +466,9 @@ namespace System.Text.Json.Serialization { public enum JsonIgnoreCondition { - Always = 0, - WhenNull = 1, - Never = 2, + Never = 0, + Always = 1, + WhenWritingDefault = 2, } public abstract partial class JsonAttribute : System.Attribute { diff --git a/src/libraries/System.Text.Json/src/Resources/Strings.resx b/src/libraries/System.Text.Json/src/Resources/Strings.resx index 3f54adaab7447..b34b706d92750 100644 --- a/src/libraries/System.Text.Json/src/Resources/Strings.resx +++ b/src/libraries/System.Text.Json/src/Resources/Strings.resx @@ -521,4 +521,10 @@ The collection type '{0}' is abstract, an interface, or is read only, and could not be instantiated and populated. + + 'IgnoreNullValues' and 'DefaultIgnoreCondition' cannot both be set to non-default values. + + + The value cannot be 'JsonIgnoreCondition.Always'. + \ No newline at end of file diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs index 7977458c42162..54e49b3d5dba2 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs @@ -99,7 +99,7 @@ internal sealed override bool OnTryRead(ref Utf8JsonReader reader, Type typeToCo if (dataExtKey == null) { - jsonPropertyInfo.SetValueAsObject(obj, propValue); + jsonPropertyInfo.SetExtensionDictionaryAsObject(obj, propValue); } else { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs index 058e7dc395bd8..bce4c1224ced7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -74,6 +75,8 @@ internal override sealed JsonParameterInfo CreateJsonParameterInfo() /// internal bool IsInternalConverter { get; set; } + internal readonly EqualityComparer _defaultComparer = EqualityComparer.Default; + // This non-generic API is sealed as it just forwards to the generic version. internal sealed override bool TryWriteAsObject(Utf8JsonWriter writer, object? value, JsonSerializerOptions options, ref WriteStack state) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonIgnoreCondition.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonIgnoreCondition.cs index 70a8bca3ad378..93239931addbb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonIgnoreCondition.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonIgnoreCondition.cs @@ -5,21 +5,24 @@ namespace System.Text.Json.Serialization { /// - /// Controls how the ignores properties on serialization and deserialization. + /// When specified on , + /// specifies that properties with default values are ignored during serialization. + /// When specified on , controls whether + /// a property is ignored during serialization and deserialization. /// public enum JsonIgnoreCondition { /// - /// Property will always be ignored. + /// Property is never ignored during serialization or deserialization. /// - Always = 0, + Never = 0, /// - /// Property will only be ignored if it is null. + /// Property is always ignored during serialization and deserialization. /// - WhenNull = 1, + Always = 1, /// - /// Property will always be serialized and deserialized, regardless of configuration. + /// If the value is the default, the property is ignored during serialization. /// - Never = 2 + WhenWritingDefault = 2, } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs index 81455209d2b11..4e345309e244c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs @@ -132,14 +132,23 @@ private void DetermineIgnoreCondition(JsonIgnoreCondition? ignoreCondition) if (ignoreCondition != JsonIgnoreCondition.Never) { - Debug.Assert(ignoreCondition == JsonIgnoreCondition.WhenNull); - IgnoreNullValues = true; + Debug.Assert(ignoreCondition == JsonIgnoreCondition.WhenWritingDefault); + IgnoreDefaultValuesOnWrite = true; } } - else +#pragma warning disable CS0618 // IgnoreNullValues is obsolete + else if (Options.IgnoreNullValues) + { + Debug.Assert(Options.DefaultIgnoreCondition == JsonIgnoreCondition.Never); + IgnoreDefaultValuesOnRead = true; + IgnoreDefaultValuesOnWrite = true; + } + else if (Options.DefaultIgnoreCondition == JsonIgnoreCondition.WhenWritingDefault) { - IgnoreNullValues = Options.IgnoreNullValues; + Debug.Assert(!Options.IgnoreNullValues); + IgnoreDefaultValuesOnWrite = true; } +#pragma warning restore CS0618 // IgnoreNullValues is obsolete } public static TAttribute? GetAttribute(PropertyInfo propertyInfo) where TAttribute : Attribute @@ -183,7 +192,8 @@ public virtual void GetPolicies(JsonIgnoreCondition? ignoreCondition) Options = options; } - public bool IgnoreNullValues { get; private set; } + public bool IgnoreDefaultValuesOnRead { get; private set; } + public bool IgnoreDefaultValuesOnWrite { get; private set; } public bool IsPropertyPolicy { get; protected set; } @@ -307,7 +317,7 @@ public JsonClassInfo RuntimeClassInfo public Type? RuntimePropertyType { get; private set; } = null; - public abstract void SetValueAsObject(object obj, object? value); + public abstract void SetExtensionDictionaryAsObject(object obj, object? extensionDict); public bool ShouldSerialize { get; private set; } public bool ShouldDeserialize { get; private set; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs index 357a247185a92..648158cd6d703 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Reflection; +using System.Runtime.CompilerServices; using System.Text.Json.Serialization; namespace System.Text.Json @@ -15,6 +16,8 @@ namespace System.Text.Json /// or a type's converter, if the current instance is a . internal sealed class JsonPropertyInfo : JsonPropertyInfo { + private static readonly T s_defaultValue = default!; + public Func? Get { get; private set; } public Action? Set { get; private set; } @@ -98,9 +101,13 @@ public override bool GetMemberAndWriteJson(object obj, ref WriteStack state, Utf bool success; T value = Get!(obj); + if (value == null) { - if (!IgnoreNullValues) + Debug.Assert(s_defaultValue == null && Converter.CanBeNull); + + success = true; + if (!IgnoreDefaultValuesOnWrite) { if (!Converter.HandleNull) { @@ -108,6 +115,9 @@ public override bool GetMemberAndWriteJson(object obj, ref WriteStack state, Utf } else { + // No object, collection, or re-entrancy converter handles null. + Debug.Assert(Converter.ClassType == ClassType.Value); + if (state.Current.PropertyState < StackFramePropertyState.Name) { state.Current.PropertyState = StackFramePropertyState.Name; @@ -122,7 +132,10 @@ public override bool GetMemberAndWriteJson(object obj, ref WriteStack state, Utf } } } - + } + else if (IgnoreDefaultValuesOnWrite && Converter._defaultComparer.Equals(s_defaultValue, value)) + { + Debug.Assert(s_defaultValue != null && !Converter.CanBeNull); success = true; } else @@ -159,45 +172,46 @@ public override bool GetMemberAndWriteJsonExtensionData(object obj, ref WriteSta public override bool ReadJsonAndSetMember(object obj, ref ReadStack state, ref Utf8JsonReader reader) { bool success; + bool isNullToken = reader.TokenType == JsonTokenType.Null; if (isNullToken && !Converter.HandleNull && !state.IsContinuation) { - if (!IgnoreNullValues) + if (!Converter.CanBeNull) { - if (!Converter.CanBeNull) - { - ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Converter.TypeToConvert); - } + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Converter.TypeToConvert); + } + + Debug.Assert(s_defaultValue == null); + if (!IgnoreDefaultValuesOnRead) + { T value = default; Set!(obj, value!); } success = true; } - else + else if (Converter.CanUseDirectReadOrWrite) { - // Get the value from the converter and set the property. - if (Converter.CanUseDirectReadOrWrite) + if (!(isNullToken && IgnoreDefaultValuesOnRead && Converter.CanBeNull)) { // Optimize for internal converters by avoiding the extra call to TryRead. T fastvalue = Converter.Read(ref reader, RuntimePropertyType!, Options); - if (!IgnoreNullValues || (!isNullToken && fastvalue != null)) - { - Set!(obj, fastvalue!); - } - - return true; + Set!(obj, fastvalue!); } - else + + success = true; + } + else + { + success = true; + + if (!(isNullToken && IgnoreDefaultValuesOnRead && Converter.CanBeNull)) { success = Converter.TryRead(ref reader, RuntimePropertyType!, Options, ref state, out T value); if (success) { - if (!IgnoreNullValues || (!isNullToken && value != null)) - { - Set!(obj, value!); - } + Set!(obj, value!); } } } @@ -225,7 +239,7 @@ public override bool ReadJsonAsObject(ref ReadStack state, ref Utf8JsonReader re if (Converter.CanUseDirectReadOrWrite) { value = Converter.Read(ref reader, RuntimePropertyType!, Options); - return true; + success = true; } else { @@ -237,15 +251,11 @@ public override bool ReadJsonAsObject(ref ReadStack state, ref Utf8JsonReader re return success; } - public override void SetValueAsObject(object obj, object? value) + public override void SetExtensionDictionaryAsObject(object obj, object? extensionDict) { Debug.Assert(HasSetter); - T typedValue = (T)value!; - - if (typedValue != null || !IgnoreNullValues) - { - Set!(obj, typedValue); - } + T typedValue = (T)extensionDict!; + Set!(obj, typedValue); } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs index 77d588af38153..9d25d2f38fceb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonResumableConverterOfT.cs @@ -41,6 +41,6 @@ public sealed override void Write(Utf8JsonWriter writer, T value, JsonSerializer TryWrite(writer, value, options, ref state); } - public override bool HandleNull => false; + public sealed override bool HandleNull => false; } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs index 6996f76561930..b7b4db728865a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs @@ -122,7 +122,7 @@ public static partial class JsonSerializer } extensionData = jsonPropertyInfo.RuntimeClassInfo.CreateObject(); - jsonPropertyInfo.SetValueAsObject(obj, extensionData); + jsonPropertyInfo.SetExtensionDictionaryAsObject(obj, extensionData); } // We don't add the value to the dictionary here because we need to support the read-ahead functionality for Streams. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs index dead794f239f8..27dc1fe336964 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs @@ -3,10 +3,10 @@ // See the LICENSE file in the project root for more information. using System.Collections.Concurrent; +using System.ComponentModel; using System.Diagnostics; using System.Text.Json.Serialization; using System.Text.Encodings.Web; -using System.Reflection; namespace System.Text.Json { @@ -29,6 +29,7 @@ public sealed partial class JsonSerializerOptions private JsonCommentHandling _readCommentHandling; private ReferenceHandling _referenceHandling = ReferenceHandling.Default; private JavaScriptEncoder? _encoder = null; + private JsonIgnoreCondition _defaultIgnoreCondition; private int _defaultBufferSize = BufferSizeDefault; private int _maxDepth; @@ -61,12 +62,13 @@ public JsonSerializerOptions(JsonSerializerOptions options) throw new ArgumentNullException(nameof(options)); } - _memberAccessorStrategy = options.MemberAccessorStrategy; + _memberAccessorStrategy = options._memberAccessorStrategy; _dictionaryKeyPolicy = options._dictionaryKeyPolicy; _jsonPropertyNamingPolicy = options._jsonPropertyNamingPolicy; _readCommentHandling = options._readCommentHandling; _referenceHandling = options._referenceHandling; _encoder = options._encoder; + _defaultIgnoreCondition = options._defaultIgnoreCondition; _defaultBufferSize = options._defaultBufferSize; _maxDepth = options._maxDepth; @@ -195,7 +197,10 @@ public int DefaultBufferSize /// /// /// Thrown if this property is set after serialization or deserialization has occurred. + /// or has been set to a non-default value. These properties cannot be used together. /// + [Obsolete("Use DefaultIgnoreCondition instead.", error: false)] + [EditorBrowsable(EditorBrowsableState.Never)] public bool IgnoreNullValues { get @@ -205,10 +210,52 @@ public bool IgnoreNullValues set { VerifyMutable(); + + if (value == true && _defaultIgnoreCondition != JsonIgnoreCondition.Never) + { + Debug.Assert(_defaultIgnoreCondition == JsonIgnoreCondition.WhenWritingDefault); + throw new InvalidOperationException(SR.DefaultIgnoreConditionAlreadySpecified); + } + _ignoreNullValues = value; } } + /// + /// Specifies a condition to determine when properties with default values are ignored during serialization or deserialization. + /// The default value is . + /// + /// + /// Thrown if this property is set to . + /// + /// + /// Thrown if this property is set after serialization or deserialization has occurred, + /// or has been set to . These properties cannot be used together. + /// + public JsonIgnoreCondition DefaultIgnoreCondition + { + get + { + return _defaultIgnoreCondition; + } + set + { + VerifyMutable(); + + if (value == JsonIgnoreCondition.Always) + { + throw new ArgumentException(SR.DefaultIgnoreConditionInvalid); + } + + if (value != JsonIgnoreCondition.Never && _ignoreNullValues) + { + throw new InvalidOperationException(SR.DefaultIgnoreConditionAlreadySpecified); + } + + _defaultIgnoreCondition = value; + } + } + /// /// Determines whether read-only properties are ignored during serialization. /// A property is read-only if it contains a public getter but not a public setter. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonValueConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonValueConverterOfT.cs index 94af2f7adf5d0..67fa8c46bfeee 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonValueConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonValueConverterOfT.cs @@ -12,6 +12,8 @@ internal abstract class JsonValueConverter : JsonConverter { internal sealed override ClassType ClassType => ClassType.NewValue; + public sealed override bool HandleNull => false; + [return: MaybeNull] public sealed override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { diff --git a/src/libraries/System.Text.Json/tests/JsonTestHelper.cs b/src/libraries/System.Text.Json/tests/JsonTestHelper.cs index 960e613502e5c..1f31adc4915ea 100644 --- a/src/libraries/System.Text.Json/tests/JsonTestHelper.cs +++ b/src/libraries/System.Text.Json/tests/JsonTestHelper.cs @@ -868,10 +868,14 @@ private static void AssertJsonEqual(JsonElement expected, JsonElement actual) Assert.Equal(expected.GetString(), actual.GetString()); break; case JsonValueKind.Number: + case JsonValueKind.True: + case JsonValueKind.False: + case JsonValueKind.Null: Assert.Equal(expected.GetRawText(), actual.GetRawText()); break; default: - throw new NotImplementedException(); + Debug.Fail($"Unexpected JsonValueKind: JsonValueKind.{valueKind}."); + break; } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs index 19b359f92badd..fd30dab747521 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests/CustomConverterTests.HandleNull.cs @@ -380,17 +380,18 @@ public static void ConverterNotCalled_IgnoreNullValues() var options = new JsonSerializerOptions(); options.Converters.Add(new UriNullConverter_NullOptIn()); - // Converter is not called. + // Converter is called - JsonIgnoreCondition.WhenWritingDefault does not apply to deserialization. ClassWithIgnoredUri obj = JsonSerializer.Deserialize(@"{""MyUri"":null}", options); - Assert.Equal(new Uri("https://microsoft.com"), obj.MyUri); + Assert.Equal(new Uri("https://default"), obj.MyUri); obj.MyUri = null; + // Converter is not called - value is ignored on serialization. Assert.Equal("{}", JsonSerializer.Serialize(obj, options)); } private class ClassWithIgnoredUri { - [JsonIgnore(Condition = JsonIgnoreCondition.WhenNull)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public Uri MyUri { get; set; } = new Uri("https://microsoft.com"); } @@ -506,5 +507,40 @@ public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOp public override bool HandleNull => true; } + + [Fact] + public static void SetterCalledWhenConverterReturnsNull() + { + var options = new JsonSerializerOptions + { + IgnoreNullValues = true, + Converters = { new UriToNullConverter() } + }; + + // Baseline - null values ignored, converter is not called. + string json = @"{""MyUri"":null}"; + + ClassWithInitializedUri obj = JsonSerializer.Deserialize(json, options); + Assert.Equal(new Uri("https://microsoft.com"), obj.MyUri); + + // Test - setter is called if payload is not null and converter returns null. + json = @"{""MyUri"":""https://default""}"; + obj = JsonSerializer.Deserialize(json, options); + Assert.Null(obj.MyUri); + } + + private class ClassWithInitializedUri + { + public Uri MyUri { get; set; } = new Uri("https://microsoft.com"); + } + + public class UriToNullConverter : JsonConverter + { + public override Uri Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => null; + + public override void Write(Utf8JsonWriter writer, Uri value, JsonSerializerOptions options) => throw new NotImplementedException(); + + public override bool HandleNull => true; + } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/ExtensionDataTests.cs b/src/libraries/System.Text.Json/tests/Serialization/ExtensionDataTests.cs index 1e0b46b7e1b7e..8c95c471e509e 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ExtensionDataTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ExtensionDataTests.cs @@ -56,7 +56,7 @@ void Verify() } [Fact] - public static void ExtensionPropertyIgnoredWhenNull() + public static void ExtensionPropertyIgnoredWhenWritingDefault() { string expected = @"{}"; string actual = JsonSerializer.Serialize(new ClassWithExtensionPropertyAsObject()); @@ -64,7 +64,7 @@ public static void ExtensionPropertyIgnoredWhenNull() } [Fact] - public static void MultipleExtensionPropertyIgnoredWhenNull() + public static void MultipleExtensionPropertyIgnoredWhenWritingDefault() { var obj = new ClassWithMultipleDictionaries(); string actual = JsonSerializer.Serialize(obj); diff --git a/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs b/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs index 5892a338e47f1..c4fe9c48bb757 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs @@ -451,35 +451,9 @@ private static void GenericConverterTestHelper(string converterName, object o } [Fact] - public static void CopyConstructorTest_OriginalMutable() + public static void CopyConstructor_OriginalLocked() { - JsonSerializerOptions options = CreateOptionsInstance(); - var newOptions = new JsonSerializerOptions(options); - VerifyOptionsEqual(options, newOptions); - - // No exception is thrown on mutating the new options instance because it is "unlocked". - newOptions.ReferenceHandling = ReferenceHandling.Preserve; - newOptions.Converters.Add(new JsonStringEnumConverter()); - newOptions.Converters.Add(new JsonStringEnumConverter()); - - // Changes to new options don't affect old options. - Assert.Equal(ReferenceHandling.Default, options.ReferenceHandling); - Assert.Equal(2, options.Converters.Count); - Assert.Equal(4, newOptions.Converters.Count); - - // Changes to old options don't affect new options. - options.DefaultBufferSize = 2; - options.Converters.Add(new ConverterForInt32()); - - Assert.Equal(20, newOptions.DefaultBufferSize); - Assert.Equal(3, options.Converters.Count); - Assert.Equal(4, newOptions.Converters.Count); - } - - [Fact] - public static void CopyConstructorTest_OriginalLocked() - { - JsonSerializerOptions options = CreateOptionsInstance(); + JsonSerializerOptions options = new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping }; // Perform serialization with options, after which it will be locked. JsonSerializer.Serialize("1", options); @@ -493,7 +467,7 @@ public static void CopyConstructorTest_OriginalLocked() } [Fact] - public static void CopyConstructorTest_MaxDepth() + public static void CopyConstructor_MaxDepth() { static void RunTest(int maxDepth, int effectiveMaxDepth) { @@ -524,15 +498,15 @@ static void RunTest(int maxDepth, int effectiveMaxDepth) } [Fact] - public static void CopyConstructorTest_CopiesAllPublicProperties() + public static void CopyConstructor_CopiesAllPublicProperties() { JsonSerializerOptions options = GetFullyPopulatedOptionsInstance(); var newOptions = new JsonSerializerOptions(options); - VerifyOptionsEqual_WithReflection(options, newOptions); + VerifyOptionsEqual(options, newOptions); } [Fact] - public static void CopyConstructorTest_NullInput() + public static void CopyConstructor_NullInput() { ArgumentNullException ex = Assert.Throws(() => new JsonSerializerOptions(null)); Assert.Contains("options", ex.ToString()); @@ -588,28 +562,6 @@ private static JsonSerializerOptions CreateOptionsInstance() return options; } - private static void VerifyOptionsEqual(JsonSerializerOptions options, JsonSerializerOptions newOptions) - { - Assert.Equal(options.AllowTrailingCommas, newOptions.AllowTrailingCommas); - Assert.Equal(options.DefaultBufferSize, newOptions.DefaultBufferSize); - Assert.Equal(options.IgnoreNullValues, newOptions.IgnoreNullValues); - Assert.Equal(options.IgnoreReadOnlyProperties, newOptions.IgnoreReadOnlyProperties); - Assert.Equal(options.MaxDepth, newOptions.MaxDepth); - Assert.Equal(options.PropertyNameCaseInsensitive, newOptions.PropertyNameCaseInsensitive); - Assert.Equal(options.ReadCommentHandling, newOptions.ReadCommentHandling); - Assert.Equal(options.WriteIndented, newOptions.WriteIndented); - - Assert.Same(options.DictionaryKeyPolicy, newOptions.DictionaryKeyPolicy); - Assert.Same(options.Encoder, newOptions.Encoder); - Assert.Same(options.PropertyNamingPolicy, newOptions.PropertyNamingPolicy); - - Assert.Equal(options.Converters.Count, newOptions.Converters.Count); - for (int i = 0; i < options.Converters.Count; i++) - { - Assert.Same(options.Converters[i], newOptions.Converters[i]); - } - } - private static JsonSerializerOptions GetFullyPopulatedOptionsInstance() { var options = new JsonSerializerOptions(); @@ -620,7 +572,11 @@ private static JsonSerializerOptions GetFullyPopulatedOptionsInstance() if (propertyType == typeof(bool)) { - property.SetValue(options, true); + // IgnoreNullValues and DefaultIgnoreCondition cannot be active at the same time. + if (property.Name != "IgnoreNullValues") + { + property.SetValue(options, true); + } } if (propertyType == typeof(int)) { @@ -647,6 +603,7 @@ private static JsonSerializerOptions GetFullyPopulatedOptionsInstance() else if (propertyType.IsValueType) { options.ReadCommentHandling = JsonCommentHandling.Disallow; + options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault; } else { @@ -659,7 +616,7 @@ private static JsonSerializerOptions GetFullyPopulatedOptionsInstance() return options; } - private static void VerifyOptionsEqual_WithReflection(JsonSerializerOptions options, JsonSerializerOptions newOptions) + private static void VerifyOptionsEqual(JsonSerializerOptions options, JsonSerializerOptions newOptions) { foreach (PropertyInfo property in typeof(JsonSerializerOptions).GetProperties()) { @@ -667,12 +624,10 @@ private static void VerifyOptionsEqual_WithReflection(JsonSerializerOptions opti if (propertyType == typeof(bool)) { - Assert.True((bool)property.GetValue(options)); Assert.Equal((bool)property.GetValue(options), (bool)property.GetValue(newOptions)); } else if (propertyType == typeof(int)) { - Assert.Equal(32, (int)property.GetValue(options)); Assert.Equal((int)property.GetValue(options), (int)property.GetValue(newOptions)); } else if (typeof(IEnumerable).IsAssignableFrom(propertyType)) @@ -692,6 +647,10 @@ private static void VerifyOptionsEqual_WithReflection(JsonSerializerOptions opti { Assert.Equal(options.ReadCommentHandling, newOptions.ReadCommentHandling); } + else if (property.Name == "DefaultIgnoreCondition") + { + Assert.Equal(options.DefaultIgnoreCondition, newOptions.DefaultIgnoreCondition); + } else { Assert.True(false, $"Public option was added to JsonSerializerOptions but not copied in the copy ctor: {property.Name}"); @@ -703,5 +662,46 @@ private static void VerifyOptionsEqual_WithReflection(JsonSerializerOptions opti } } } + + [Fact] + public static void CopyConstructor_IgnoreNullValuesCopied() + { + var options = new JsonSerializerOptions { IgnoreNullValues = true }; + var newOptions = new JsonSerializerOptions(options); + VerifyOptionsEqual(options, newOptions); + } + + [Fact] + public static void CannotSetBoth_IgnoreNullValues_And_DefaultIgnoreCondition() + { + // Set IgnoreNullValues first. + JsonSerializerOptions options = new JsonSerializerOptions { IgnoreNullValues = true }; + + InvalidOperationException ex = Assert.Throws( + () => options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault); + string exAsStr = ex.ToString(); + Assert.Contains("IgnoreNullValues", exAsStr); + Assert.Contains("DefaultIgnoreCondition", exAsStr); + + options.IgnoreNullValues = false; + // We can set the property now. + options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault; + + // Set DefaultIgnoreCondition first. + + options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault }; + Assert.Throws( + () => options.IgnoreNullValues = true); + + options.DefaultIgnoreCondition = JsonIgnoreCondition.Never; + // We can set the property now. + options.IgnoreNullValues = true; + } + + [Fact] + public static void CannotSet_DefaultIgnoreCondition_To_Always() + { + Assert.Throws(() => new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.Always }); + } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.NonPublicAccessors.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.NonPublicAccessors.cs index de7e206c5a953..4385cd6fae519 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.NonPublicAccessors.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.NonPublicAccessors.cs @@ -88,7 +88,7 @@ private class MyClass_WithNonPublicAccessors_WithPropertyAttributes_And_Property public int MyInt { get; private set; } [JsonInclude] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenNull)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public string MyString { get; internal set; } = "DefaultString"; [JsonInclude] diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs index 2cc311764cb8e..8cc9cf6e6bde7 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs @@ -987,8 +987,8 @@ public ClassWithProperty_IgnoreConditionAlways_Ctor(DateTime myDateTime, int myI } [Theory] - [MemberData(nameof(JsonIgnoreConditionWhenNull_ClassProperty_TestData))] - public static void JsonIgnoreConditionWhenNull_ClassProperty(Type type, JsonSerializerOptions options) + [MemberData(nameof(JsonIgnoreConditionWhenWritingDefault_ClassProperty_TestData))] + public static void JsonIgnoreConditionWhenWritingDefault_ClassProperty(Type type, JsonSerializerOptions options) { // Property shouldn't be ignored if it isn't null. string json = @"{""Int1"":1,""MyString"":""Random"",""Int2"":2}"; @@ -1008,7 +1008,17 @@ public static void JsonIgnoreConditionWhenNull_ClassProperty(Type type, JsonSeri obj = JsonSerializer.Deserialize(json, type, options); Assert.Equal(1, (int)type.GetProperty("Int1").GetValue(obj)); - Assert.Equal("DefaultString", (string)type.GetProperty("MyString").GetValue(obj)); + + if (options.IgnoreNullValues) + { + // Null values can be ignored on deserialization using IgnoreNullValues. + Assert.Equal("DefaultString", (string)type.GetProperty("MyString").GetValue(obj)); + } + else + { + Assert.Null((string)type.GetProperty("MyString").GetValue(obj)); + } + Assert.Equal(2, (int)type.GetProperty("Int2").GetValue(obj)); // Set property to be ignored to null. @@ -1020,22 +1030,22 @@ public static void JsonIgnoreConditionWhenNull_ClassProperty(Type type, JsonSeri Assert.DoesNotContain(@"""MyString"":", serialized); } - private class ClassWithClassProperty_IgnoreConditionWhenNull + private class ClassWithClassProperty_IgnoreConditionWhenWritingDefault { public int Int1 { get; set; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenNull)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public string MyString { get; set; } = "DefaultString"; public int Int2 { get; set; } } - private class ClassWithClassProperty_IgnoreConditionWhenNull_Ctor + private class ClassWithClassProperty_IgnoreConditionWhenWritingDefault_Ctor { public int Int1 { get; set; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenNull)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public string MyString { get; set; } = "DefaultString"; public int Int2 { get; set; } - public ClassWithClassProperty_IgnoreConditionWhenNull_Ctor(string myString) + public ClassWithClassProperty_IgnoreConditionWhenWritingDefault_Ctor(string myString) { if (myString != null) { @@ -1044,15 +1054,15 @@ public ClassWithClassProperty_IgnoreConditionWhenNull_Ctor(string myString) } } - private static IEnumerable JsonIgnoreConditionWhenNull_ClassProperty_TestData() + private static IEnumerable JsonIgnoreConditionWhenWritingDefault_ClassProperty_TestData() { - yield return new object[] { typeof(ClassWithClassProperty_IgnoreConditionWhenNull), new JsonSerializerOptions() }; - yield return new object[] { typeof(ClassWithClassProperty_IgnoreConditionWhenNull_Ctor), new JsonSerializerOptions { IgnoreNullValues = true } }; + yield return new object[] { typeof(ClassWithClassProperty_IgnoreConditionWhenWritingDefault), new JsonSerializerOptions() }; + yield return new object[] { typeof(ClassWithClassProperty_IgnoreConditionWhenWritingDefault_Ctor), new JsonSerializerOptions { IgnoreNullValues = true } }; } [Theory] - [MemberData(nameof(JsonIgnoreConditionWhenNull_StructProperty_TestData))] - public static void JsonIgnoreConditionWhenNull_StructProperty(Type type, JsonSerializerOptions options) + [MemberData(nameof(JsonIgnoreConditionWhenWritingDefault_StructProperty_TestData))] + public static void JsonIgnoreConditionWhenWritingDefault_StructProperty(Type type, JsonSerializerOptions options) { // Property shouldn't be ignored if it isn't null. string json = @"{""Int1"":1,""MyInt"":3,""Int2"":2}"; @@ -1072,23 +1082,23 @@ public static void JsonIgnoreConditionWhenNull_StructProperty(Type type, JsonSer Assert.Throws(() => JsonSerializer.Deserialize(json, type, options)); } - private class ClassWithStructProperty_IgnoreConditionWhenNull + private class ClassWithStructProperty_IgnoreConditionWhenWritingDefault { public int Int1 { get; set; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenNull)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public int MyInt { get; set; } public int Int2 { get; set; } } - private struct StructWithStructProperty_IgnoreConditionWhenNull_Ctor + private struct StructWithStructProperty_IgnoreConditionWhenWritingDefault_Ctor { public int Int1 { get; set; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenNull)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public int MyInt { get; } public int Int2 { get; set; } [JsonConstructor] - public StructWithStructProperty_IgnoreConditionWhenNull_Ctor(int myInt) + public StructWithStructProperty_IgnoreConditionWhenWritingDefault_Ctor(int myInt) { Int1 = 0; MyInt = myInt; @@ -1096,10 +1106,10 @@ public StructWithStructProperty_IgnoreConditionWhenNull_Ctor(int myInt) } } - private static IEnumerable JsonIgnoreConditionWhenNull_StructProperty_TestData() + private static IEnumerable JsonIgnoreConditionWhenWritingDefault_StructProperty_TestData() { - yield return new object[] { typeof(ClassWithStructProperty_IgnoreConditionWhenNull), new JsonSerializerOptions() }; - yield return new object[] { typeof(StructWithStructProperty_IgnoreConditionWhenNull_Ctor), new JsonSerializerOptions { IgnoreNullValues = true } }; + yield return new object[] { typeof(ClassWithStructProperty_IgnoreConditionWhenWritingDefault), new JsonSerializerOptions() }; + yield return new object[] { typeof(StructWithStructProperty_IgnoreConditionWhenWritingDefault_Ctor), new JsonSerializerOptions { IgnoreNullValues = true } }; } [Theory] @@ -1208,33 +1218,30 @@ public static void JsonIgnoreCondition_LastOneWins() } [Fact] - public static void ClassWithComplexObjectsUsingIgnoreWhenNullAttribute() + public static void ClassWithComplexObjectsUsingIgnoreWhenWritingDefaultAttribute() { string json = @"{""Class"":{""MyInt16"":18}, ""Dictionary"":null}"; - ClassUsingIgnoreWhenNullAttribute obj = JsonSerializer.Deserialize(json); + ClassUsingIgnoreWhenWritingDefaultAttribute obj = JsonSerializer.Deserialize(json); - // Class is deserialized because it is not null in json. + // Class is deserialized. Assert.NotNull(obj.Class); Assert.Equal(18, obj.Class.MyInt16); - // Dictionary is left alone because it is null in json. - Assert.NotNull(obj.Dictionary); - Assert.Equal(1, obj.Dictionary.Count); - Assert.Equal("Value", obj.Dictionary["Key"]); - + // Dictionary is deserialized as JsonIgnoreCondition.WhenWritingDefault only applies to deserialization. + Assert.Null(obj.Dictionary); - obj = new ClassUsingIgnoreWhenNullAttribute(); + obj = new ClassUsingIgnoreWhenWritingDefaultAttribute(); json = JsonSerializer.Serialize(obj); Assert.Equal(@"{""Dictionary"":{""Key"":""Value""}}", json); } - public class ClassUsingIgnoreWhenNullAttribute + public class ClassUsingIgnoreWhenWritingDefaultAttribute { - [JsonIgnore(Condition = JsonIgnoreCondition.WhenNull)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public SimpleTestClass Class { get; set; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenNull)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public Dictionary Dictionary { get; set; } = new Dictionary { ["Key"] = "Value" }; } @@ -1290,7 +1297,7 @@ public static void IgnoreConditionNever_WinsOver_IgnoreReadOnlyValues() } [Fact] - public static void IgnoreConditionWhenNull_WinsOver_IgnoreReadOnlyValues() + public static void IgnoreConditionWhenWritingDefault_WinsOver_IgnoreReadOnlyValues() { var options = new JsonSerializerOptions { IgnoreReadOnlyProperties = true }; @@ -1299,10 +1306,10 @@ public static void IgnoreConditionWhenNull_WinsOver_IgnoreReadOnlyValues() Assert.Equal("{}", json); // With condition to ignore when null - json = JsonSerializer.Serialize(new ClassWithReadOnlyString_IgnoreWhenNull("Hello"), options); + json = JsonSerializer.Serialize(new ClassWithReadOnlyString_IgnoreWhenWritingDefault("Hello"), options); Assert.Equal(@"{""MyString"":""Hello""}", json); - json = JsonSerializer.Serialize(new ClassWithReadOnlyString_IgnoreWhenNull(null), options); + json = JsonSerializer.Serialize(new ClassWithReadOnlyString_IgnoreWhenWritingDefault(null), options); Assert.Equal(@"{}", json); } @@ -1321,12 +1328,12 @@ private class ClassWithReadOnlyString_IgnoreNever public ClassWithReadOnlyString_IgnoreNever(string myString) => MyString = myString; } - private class ClassWithReadOnlyString_IgnoreWhenNull + private class ClassWithReadOnlyString_IgnoreWhenWritingDefault { - [JsonIgnore(Condition = JsonIgnoreCondition.WhenNull)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public string MyString { get; } - public ClassWithReadOnlyString_IgnoreWhenNull(string myString) => MyString = myString; + public ClassWithReadOnlyString_IgnoreWhenWritingDefault(string myString) => MyString = myString; } [Fact] @@ -1352,5 +1359,81 @@ private class ClassWithNonPublicProperties internal float GetMyFloat => MyFloat; internal double GetMyDouble => MyDouble; } + + [Fact] + public static void IgnoreCondition_WhenWritingDefault_Globally_Works() + { + // Baseline - default values written. + string expected = @"{""MyString"":null,""MyInt"":0,""MyPoint"":{""X"":0,""Y"":0}}"; + var obj = new ClassWithProps(); + JsonTestHelper.AssertJsonEqual(expected, JsonSerializer.Serialize(obj)); + + // Default values ignored when specified. + Assert.Equal("{}", JsonSerializer.Serialize(obj, new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault })); + } + + private class ClassWithProps + { + public string MyString { get; set; } + public int MyInt { get; set; } + public Point_2D_Struct MyPoint { get; set; } + } + + [Fact] + public static void IgnoreCondition_WhenWritingDefault_PerProperty_Works() + { + // Default values ignored when specified. + Assert.Equal(@"{""MyInt"":0}", JsonSerializer.Serialize(new ClassWithPropsAndIgnoreAttributes())); + } + + private class ClassWithPropsAndIgnoreAttributes + { + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string MyString { get; set; } + public int MyInt { get; set; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public Point_2D_Struct MyPoint { get; set; } + } + + [Fact] + public static void IgnoreCondition_WhenWritingDefault_DoesNotApplyToCollections() + { + var list = new List { false, true }; + + var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault }; + Assert.Equal("[false,true]", JsonSerializer.Serialize(list, options)); + } + + [Fact] + public static void IgnoreCondition_WhenWritingDefault_DoesNotApplyToDeserialization() + { + // Baseline - null values are ignored on deserialization when using IgnoreNullValues (for compat with initial support). + string json = @"{""MyString"":null,""MyInt"":0,""MyPoint"":{""X"":0,""Y"":0}}"; + + var options = new JsonSerializerOptions { IgnoreNullValues = true }; + ClassWithInitializedProps obj = JsonSerializer.Deserialize(json, options); + + Assert.Equal("Default", obj.MyString); + // Value types are not ignored. + Assert.Equal(0, obj.MyInt); + Assert.Equal(0, obj.MyPoint.X); + Assert.Equal(0, obj.MyPoint.X); + + // Test - default values (both null and default for value types) are not ignored when using + // JsonIgnoreCondition.WhenWritingDefault (as the option name implies) + options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault }; + obj = JsonSerializer.Deserialize(json, options); + Assert.Null(obj.MyString); + Assert.Equal(0, obj.MyInt); + Assert.Equal(0, obj.MyPoint.X); + Assert.Equal(0, obj.MyPoint.X); + } + + private class ClassWithInitializedProps + { + public string MyString { get; set; } = "Default"; + public int MyInt { get; set; } = -1; + public Point_2D_Struct MyPoint { get; set; } = new Point_2D_Struct(-1, -1); + } } } From adab8f20bb14677e5395e2c6a13c4ecda228adc8 Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Thu, 14 May 2020 18:02:11 -0700 Subject: [PATCH 209/420] Adding the support of reusing machine-wide credentials in the case where the machine is already domain-joined to the LDAP Server. (#36405) * Adding the support of reusing machine-wide credentials in the case where the machine is already domain-joined to the LDAP Server. Co-authored-by: Alexander Chermyanin * Addressing feedback and adding ldap4net to TPN Co-authored-by: Alexander Chermyanin --- THIRD-PARTY-NOTICES.TXT | 13 +++++ .../Common/src/Interop/Interop.Ldap.cs | 7 ++- .../Interop/Linux/OpenLdap/Interop.Ldap.cs | 58 ++++++++++++++++++- .../Protocols/Interop/LdapPal.Linux.cs | 55 ++++++++++++++++++ .../Protocols/ldap/LdapConnection.Linux.cs | 43 +++++++++++++- 5 files changed, 171 insertions(+), 5 deletions(-) diff --git a/THIRD-PARTY-NOTICES.TXT b/THIRD-PARTY-NOTICES.TXT index 33b2268a7f2fa..db9304008a31d 100644 --- a/THIRD-PARTY-NOTICES.TXT +++ b/THIRD-PARTY-NOTICES.TXT @@ -820,3 +820,16 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +License notice for ldap4net +--------------------------- + +The MIT License (MIT) + +Copyright (c) 2018 Alexander Chermyanin + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/libraries/Common/src/Interop/Interop.Ldap.cs b/src/libraries/Common/src/Interop/Interop.Ldap.cs index 121fae5580ed0..1c312dca820e0 100644 --- a/src/libraries/Common/src/Interop/Interop.Ldap.cs +++ b/src/libraries/Common/src/Interop/Interop.Ldap.cs @@ -9,6 +9,8 @@ internal static partial class Interop public const int SEC_WINNT_AUTH_IDENTITY_UNICODE = 0x2; public const int SEC_WINNT_AUTH_IDENTITY_VERSION = 0x200; public const string MICROSOFT_KERBEROS_NAME_W = "Kerberos"; + public const uint LDAP_SASL_QUIET = 2; + public const string KerberosDefaultMechanism = "GSSAPI"; } namespace System.DirectoryServices.Protocols @@ -94,7 +96,10 @@ internal enum LdapOption LDAP_OPT_SASL_METHOD = 0x97, LDAP_OPT_AREC_EXCLUSIVE = 0x98, // Not Supported in Linux LDAP_OPT_SECURITY_CONTEXT = 0x99, - LDAP_OPT_ROOTDSE_CACHE = 0x9a // Not Supported in Linux + LDAP_OPT_ROOTDSE_CACHE = 0x9a, // Not Supported in Linux + LDAP_OPT_X_SASL_REALM = 0x6101, + LDAP_OPT_X_SASL_AUTHCID = 0x6102, + LDAP_OPT_X_SASL_AUTHZID = 0x6103 } internal enum ResultAll diff --git a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs index 7925e24a7df96..02fea9754b9c7 100644 --- a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs +++ b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs @@ -6,6 +6,60 @@ using System.Runtime.InteropServices; using System.DirectoryServices.Protocols; +namespace System.DirectoryServices.Protocols +{ + /// + /// Structure that will get passed into the Sasl interactive callback in case + /// the authentication process emits challenges to validate information. + /// + [StructLayout(LayoutKind.Sequential)] + internal struct SaslDefaultCredentials + { + public string mech; + public string realm; + public string authcid; + public string passwd; + public string authzid; + } + + /// + /// Structure that will represent a Sasl Interactive challenge during a + /// Sasl interactive bind, which will contain the challenge and it is also + /// where we will have to resolve the result. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + internal class SaslInteractiveChallenge + { + public ulong saslChallengeType; + public string challenge; + public string prompt; + public string defresult; + public IntPtr result; + public uint len; + } + + internal enum SaslChallengeType + { + SASL_CB_LIST_END = 0, + SASL_CB_GETOPT = 1, + SASL_CB_LOG = 2, + SASL_CB_GETPATH = 3, + SASL_CB_VERIFYFILE = 4, + SASL_CB_GETCONFPATH = 5, + SASL_CB_USER = 0x4001, + SASL_CB_AUTHNAME = 0x4002, + SASL_CB_LANGUAGE = 0x4003, + SASL_CB_PASS = 0x4004, + SASL_CB_ECHOPROMPT = 0x4005, + SASL_CB_NOECHOPROMPT = 0x4006, + SASL_CB_CNONCE = 0x4007, + SASL_CB_GETREALM = 0x4008, + SASL_CB_PROXY_POLICY = 0x8001, + } +} + +internal delegate int LDAP_SASL_INTERACT_PROC(IntPtr ld, uint flags, IntPtr defaults, IntPtr interact); + internal static partial class Interop { [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_initialize", CharSet = CharSet.Ansi, SetLastError = true)] @@ -74,8 +128,8 @@ internal static partial class Interop [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_parse_reference", CharSet = CharSet.Ansi)] public static extern int ldap_parse_reference([In] ConnectionHandle ldapHandle, [In] IntPtr result, ref IntPtr referrals, IntPtr ServerControls, byte freeIt); - [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_sasl_bind_s", CharSet = CharSet.Ansi, SetLastError = true)] - public static extern int ldap_sasl_bind_s([In] ConnectionHandle ld, string dn, string mechanism, berval cred, IntPtr servercontrol, IntPtr clientcontrol, ref berval servercredp); + [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_sasl_interactive_bind_s", CharSet = CharSet.Ansi)] + internal static extern int ldap_sasl_interactive_bind([In] ConnectionHandle ld, string dn, string mechanism, IntPtr serverctrls, IntPtr clientctrls, uint flags, [MarshalAs(UnmanagedType.FunctionPtr)] LDAP_SASL_INTERACT_PROC proc, IntPtr defaults); [DllImport(Libraries.OpenLdap, EntryPoint = "ldap_simple_bind_s", CharSet = CharSet.Ansi, SetLastError = true)] public static extern int ldap_simple_bind([In] ConnectionHandle ld, string who, string passwd); diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Linux.cs index 09ae9c5e12272..9089e8902726c 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Linux.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Linux.cs @@ -110,5 +110,60 @@ internal static int ParseResultReferral(ConnectionHandle ldapHandle, IntPtr resu internal static string PtrToString(IntPtr requestName) => Marshal.PtrToStringAnsi(requestName); internal static IntPtr StringToPtr(string s) => Marshal.StringToHGlobalAnsi(s); + + /// + /// Function that will be sent to the Sasl interactive bind procedure which will resolve all Sasl challenges + /// that get passed in by using the defaults that we get passed in. + /// + /// The connection handle to the LDAP server. + /// Flags that control the interaction used to retrieve any necessary Sasl authentication parameters + /// Pointer to the defaults structure that was sent to sasl_interactive_bind + /// Pointer to the challenge we need to resolve + /// + internal static int SaslInteractionProcedure(IntPtr ldapHandle, uint flags, IntPtr defaultsPtr, IntPtr interactPtr) + { + if (ldapHandle == IntPtr.Zero) + { + return -9; // Parameter Error + } + // Convert pointers into managed structures. + IntPtr currentInteractPtr = interactPtr; + SaslInteractiveChallenge interactChallenge = Marshal.PtrToStructure(currentInteractPtr); + SaslDefaultCredentials defaults = Marshal.PtrToStructure(defaultsPtr); + + // loop through all of the challenges that were sent through the interactChallenge. + while (interactChallenge.saslChallengeType != (int)SaslChallengeType.SASL_CB_LIST_END) + { + // use defaults to fix the challenge type + switch (interactChallenge.saslChallengeType) + { + case (int)SaslChallengeType.SASL_CB_GETREALM: + interactChallenge.defresult = defaults.realm; + break; + case (int)SaslChallengeType.SASL_CB_AUTHNAME: + interactChallenge.defresult = defaults.authcid; + break; + case (int)SaslChallengeType.SASL_CB_PASS: + interactChallenge.defresult = defaults.passwd; + break; + case (int)SaslChallengeType.SASL_CB_USER: + interactChallenge.defresult = defaults.authzid; + break; + } + + if (!string.IsNullOrEmpty(interactChallenge.defresult)) + { + interactChallenge.result = Marshal.StringToHGlobalAnsi(interactChallenge.defresult); + interactChallenge.len = interactChallenge != null ? (uint)interactChallenge.defresult.Length : 0; + } + + // Move to next interact challenge + Marshal.StructureToPtr(interactChallenge, currentInteractPtr, false); + currentInteractPtr = IntPtr.Add(currentInteractPtr, Marshal.SizeOf()); + interactChallenge = Marshal.PtrToStructure(currentInteractPtr); + } + + return 0; + } } } diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Linux.cs index 405d4f9eb2a54..6383c1c0446a5 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Linux.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Linux.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Net; +using System.Runtime.InteropServices; namespace System.DirectoryServices.Protocols { @@ -24,9 +25,9 @@ private int InternalConnectToServer() private int InternalBind(NetworkCredential tempCredential, SEC_WINNT_AUTH_IDENTITY_EX cred, BindMethod method) { int error; - if (tempCredential == null && AuthType == AuthType.External) + if (tempCredential == null && (AuthType == AuthType.External || AuthType == AuthType.Kerberos)) { - error = Interop.ldap_simple_bind(_ldapHandle, null, null); + error = BindSasl(); } else { @@ -35,5 +36,43 @@ private int InternalBind(NetworkCredential tempCredential, SEC_WINNT_AUTH_IDENTI return error; } + + private int BindSasl() + { + SaslDefaultCredentials defaults = GetSaslDefaults(); + IntPtr ptrToDefaults = Marshal.AllocHGlobal(Marshal.SizeOf(defaults)); + Marshal.StructureToPtr(defaults, ptrToDefaults, false); + try + { + return Interop.ldap_sasl_interactive_bind(_ldapHandle, null, Interop.KerberosDefaultMechanism, IntPtr.Zero, IntPtr.Zero, Interop.LDAP_SASL_QUIET, LdapPal.SaslInteractionProcedure, ptrToDefaults); + } + finally + { + GC.KeepAlive(defaults); //Making sure we keep it in scope as we will still use ptrToDefaults + Marshal.FreeHGlobal(ptrToDefaults); + } + } + + private SaslDefaultCredentials GetSaslDefaults() + { + var defaults = new SaslDefaultCredentials { mech = Interop.KerberosDefaultMechanism }; + IntPtr outValue = IntPtr.Zero; + int error = Interop.ldap_get_option_ptr(_ldapHandle, LdapOption.LDAP_OPT_X_SASL_REALM, ref outValue); + if (error == 0 && outValue != IntPtr.Zero) + { + defaults.realm = Marshal.PtrToStringAnsi(outValue); + } + error = Interop.ldap_get_option_ptr(_ldapHandle, LdapOption.LDAP_OPT_X_SASL_AUTHCID, ref outValue); + if (error == 0 && outValue != IntPtr.Zero) + { + defaults.authcid = Marshal.PtrToStringAnsi(outValue); + } + error = Interop.ldap_get_option_ptr(_ldapHandle, LdapOption.LDAP_OPT_X_SASL_AUTHZID, ref outValue); + if (error == 0 && outValue != IntPtr.Zero) + { + defaults.authzid = Marshal.PtrToStringAnsi(outValue); + } + return defaults; + } } } From a5b5ec5da8027dbb8acecf0487d8cb250bbace4c Mon Sep 17 00:00:00 2001 From: Simon Nattress Date: Thu, 14 May 2020 18:39:37 -0700 Subject: [PATCH 210/420] Add dotnet cli to runtime test Helix jobs (#35426) * Currently managed tools such as crossgen2 and XUnit are run against the built runtime which is slow on Debug builds, and can obscure errors when the XUnit test harness fails due to an introduced runtime bug. * Add `xunit.console.runtimeconfig.dev.json` which allows `xunit.console` to use the repo-local dotnet.cmd on dev boxes and the same version installed on the path in Helix. * When running crossgen2 during test execution, support both local dev and Helix scenario when deciding which dotnet to run. On Helix, simply use `dotnet` which assumes a compatible dotnet runtime is in the path. Locally, tests are run with `runtest.cmd|sh` which sets `__TestDotNetCmd` to the repo-local dotnet script. This preserves the characteristic that no machine-wide 5.0 dotnet runtime must be installed for the runtime tests. * Update batch scripting to also use `dotnet.cmd|sh` when running Crossgen2 replacing corerun.exe. * crossgen2's `runtimes` folder is not getting copied to `CORE_ROOT` which causes the runtime host to abort the launch on the Unix CI VMs since crossgen.deps.json refers to files in that subfolder. Adjust the `CORE_ROOT` pruning in `Directory.Build.targets` to include subfolders for the two tools that need it. * Improve XUnit test boilerplate. Printing `Exception.Message` doesn't include stack trace. Use `ToString()` instead. * Import notargets sdk in `helixpublicwitharcade.proj`. It doesn't use the official sdk so `BundledNETCoreAppPackageVersion` wasn't set. Import the `Microsoft.Build.NoTargets` sdk so we can find the bundled runtime package version. --- eng/Versions.props | 2 +- src/coreclr/build-test.cmd | 18 ++++++++----- src/coreclr/build-test.sh | 6 ++--- src/coreclr/tests/helixpublishwitharcade.proj | 27 ++++++++++++++----- src/coreclr/tests/runtest.py | 3 +++ .../tests/src/CLRTest.CrossGen.targets | 14 ++++++++-- .../tests/src/Common/Directory.Build.targets | 17 +++++++++--- src/coreclr/tests/src/runtest.proj | 6 ++--- 8 files changed, 68 insertions(+), 25 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 3588f19c0d159..20e000651fb20 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -63,7 +63,7 @@ 5.0.0-beta.20261.9 5.0.0-beta.20261.9 5.0.0-beta.20261.9 - 2.5.1-beta.20261.9 + 2.5.1-beta.20264.3 5.0.0-beta.20261.9 5.0.0-beta.20261.9 5.0.0-beta.20261.9 diff --git a/src/coreclr/build-test.cmd b/src/coreclr/build-test.cmd index 9247e81cab9a9..01a41c0a91118 100644 --- a/src/coreclr/build-test.cmd +++ b/src/coreclr/build-test.cmd @@ -652,15 +652,17 @@ for %%F in ("%CORE_ROOT%\System.*.dll";"%CORE_ROOT%\Microsoft.*.dll";%CORE_ROOT% ))))) ) -echo Composite response line^: %__CompositeResponseFile% -type "%__CompositeResponseFile%" +if defined __CompositeBuildMode ( + echo Composite response line^: %__CompositeResponseFile% + type "%__CompositeResponseFile%" +) if defined __CompositeBuildMode ( - set __CompositeCommandLine="%CORE_ROOT%\corerun" + set __CompositeCommandLine="%__RepoRootDir%\dotnet.cmd" set __CompositeCommandLine=!__CompositeCommandLine! "%CORE_ROOT%\crossgen2\crossgen2.dll" set __CompositeCommandLine=!__CompositeCommandLine! "@%__CompositeResponseFile%" echo Building composite R2R framework^: !__CompositeCommandLine! - !__CompositeCommandLine! + call !__CompositeCommandLine! set __FailedToPrecompile=!ERRORLEVEL! copy /Y "!__CompositeOutputDir!\*.*" "!CORE_ROOT!\" ) @@ -684,7 +686,7 @@ if /i "%__BuildArch%" == "arm64" ( set __CrossgenExe="%__BinDir%\x64\crossgen.ex set __CrossgenExe=%__CrossgenExe% if defined __DoCrossgen2 ( - set __CrossgenExe="%CORE_ROOT%\corerun" "%__BinDir%\crossgen2\crossgen2.dll" + set __CrossgenExe="%__RepoRootDir%\dotnet.cmd" "%CORE_ROOT%\crossgen2\crossgen2.dll" ) REM Intentionally avoid using the .dll extension to prevent @@ -694,12 +696,14 @@ set __CrossgenCmd= if defined __DoCrossgen ( set __CrossgenCmd=!__CrossgenExe! /Platform_Assemblies_Paths "!CORE_ROOT!" /in !AssemblyPath! /out !__CrossgenOutputFile! + echo !__CrossgenCmd! + !__CrossgenCmd! ) else ( set __CrossgenCmd=!__CrossgenExe! -r:"!CORE_ROOT!\System.*.dll" -r:"!CORE_ROOT!\Microsoft.*.dll" -r:"!CORE_ROOT!\mscorlib.dll" -r:"!CORE_ROOT!\netstandard.dll" -O --inputbubble --out:!__CrossgenOutputFile! !AssemblyPath! + echo !__CrossgenCmd! + call !__CrossgenCmd! ) -echo %__CrossgenCmd% -%__CrossgenCmd% set /a __exitCode = !errorlevel! set /a "%~3+=1" diff --git a/src/coreclr/build-test.sh b/src/coreclr/build-test.sh index 46675133e1f0a..78d294bd83564 100755 --- a/src/coreclr/build-test.sh +++ b/src/coreclr/build-test.sh @@ -180,8 +180,8 @@ precompile_coreroot_fx() local totalPrecompiled=0 local failedToPrecompile=0 - local compositeCommandLine="$overlayDir/corerun" - compositeCommandLine+=" ${__BinDir}/crossgen2/crossgen2.dll" + local compositeCommandLine="${__DotNetCli}" + compositeCommandLine+=" $__BinDir/crossgen2/crossgen2.dll" compositeCommandLine+=" --composite" compositeCommandLine+=" -O" compositeCommandLine+=" --out:$outputDir/framework-r2r.dll" @@ -206,7 +206,7 @@ precompile_coreroot_fx() fi if [[ "$__DoCrossgen2" != 0 ]]; then - commandLine="$overlayDir/corerun $overlayDir/crossgen2/crossgen2.dll $crossgen2References -O --inputbubble --out $outputDir/$(basename $filename) $filename" + commandLine="${__DotNetCli} $overlayDir/crossgen2/crossgen2.dll $crossgen2References -O --inputbubble --out $outputDir/$(basename $filename) $filename" fi echo Precompiling "$filename" diff --git a/src/coreclr/tests/helixpublishwitharcade.proj b/src/coreclr/tests/helixpublishwitharcade.proj index c7aa3174852f9..6d46021c28e83 100644 --- a/src/coreclr/tests/helixpublishwitharcade.proj +++ b/src/coreclr/tests/helixpublishwitharcade.proj @@ -5,7 +5,7 @@ to send test jobs to helix. --> - + @@ -33,10 +33,14 @@ RunInUnloadableContext=$(_RunInUnloadableContext); TimeoutPerTestCollectionInMinutes=$(_TimeoutPerTestCollectionInMinutes); TimeoutPerTestInMinutes=$(_TimeoutPerTestInMinutes); - RuntimeMode=$(_RuntimeMode) + RuntimeMode=$(_RuntimeMode); + BundledNETCoreAppPackageVersion=$(BundledNETCoreAppPackageVersion) + + + @@ -59,12 +63,24 @@ + + + win-$(TargetArchitecture) + osx-$(TargetArchitecture) + linux-$(TargetArchitecture) + + $([MSBuild]::NormalizeDirectory($(TestWorkingDir))) $(BinDir)Tests\Core_Root\ $(BinDir)Payloads\ SetStressModes_$(Scenario).cmd SetStressModes_$(Scenario).sh + + true + runtime + $(BundledNETCoreAppPackageVersion) + $(HelixRuntimeRid) @@ -236,12 +252,10 @@ - %CORE_ROOT%\CoreRun.exe %CORE_ROOT%\xunit.console.dll - $CORE_ROOT/corerun $CORE_ROOT/xunit.console.dll @@ -263,12 +277,13 @@ %(PayloadDirectory) - $(CoreRun) $(XUnitRunnerDll) %(XUnitWrapperDlls) $(XUnitRunnerArgs) - $(CoreRun) $(XUnitRunnerDll) %(XUnitWrapperDlls) $(XUnitRunnerArgs) -trait TestGroup=%(TestGroup) + dotnet $(XUnitRunnerDll) %(XUnitWrapperDlls) $(XUnitRunnerArgs) + dotnet $(XUnitRunnerDll) %(XUnitWrapperDlls) $(XUnitRunnerArgs) -trait TestGroup=%(TestGroup) $([System.TimeSpan]::FromMinutes($(TimeoutPerTestCollectionInMinutes))) + diff --git a/src/coreclr/tests/runtest.py b/src/coreclr/tests/runtest.py index 68444d5d44089..e5ef2b0528ed1 100755 --- a/src/coreclr/tests/runtest.py +++ b/src/coreclr/tests/runtest.py @@ -934,6 +934,9 @@ def run_tests(args, print("Setting CORE_ROOT=%s" % args.core_root) os.environ["CORE_ROOT"] = args.core_root + # Set __TestDotNetCmd so tests which need to run dotnet can use the repo-local script on dev boxes + os.environ["__TestDotNetCmd"] = args.dotnetcli_script_path + # Set test env script path if it is set. if test_env_script_path is not None: print("Setting __TestEnv=%s" % test_env_script_path) diff --git a/src/coreclr/tests/src/CLRTest.CrossGen.targets b/src/coreclr/tests/src/CLRTest.CrossGen.targets index 00c9990b19d27..0dcc732202f75 100644 --- a/src/coreclr/tests/src/CLRTest.CrossGen.targets +++ b/src/coreclr/tests/src/CLRTest.CrossGen.targets @@ -83,7 +83,12 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then rm $__ResponseFile __Command=$_DebuggerFullPath - __Command+=" $CORE_ROOT/corerun" + # Tests run locally need __TestDotNetCmd (set by runtest.py) or a compatible 5.0 dotnet runtime in the path + if [ ! -z ${__TestDotNetCmd+x} ] %3B then + __Command+=" $__TestDotNetCmd" + else + __Command+=" dotnet" + fi __Command+=" $CORE_ROOT/crossgen2/crossgen2.dll" __Command+=" @$__ResponseFile" __Command+=" $ExtraCrossGen2Args" @@ -178,7 +183,12 @@ if defined RunCrossGen2 ( del /Q !__ResponseFile! set __Command=!_DebuggerFullPath! - set __Command=!__Command! "!CORE_ROOT!\CoreRun.exe" + REM Tests run locally need __TestDotNetCmd (set by runtest.py) or a compatible 5.0 dotnet runtime in the path + if defined __TestDotNetCmd ( + set __Command=!__Command! "!__TestDotNetCmd!" + ) else ( + set __Command=!__Command! "dotnet" + ) set __Command=!__Command! "!CORE_ROOT!\crossgen2\crossgen2.dll" set __Command=!__Command! @"!__ResponseFile!" set __Command=!__Command! !ExtraCrossGen2Args! diff --git a/src/coreclr/tests/src/Common/Directory.Build.targets b/src/coreclr/tests/src/Common/Directory.Build.targets index c4e3b79c5eddb..65ff6bd275946 100644 --- a/src/coreclr/tests/src/Common/Directory.Build.targets +++ b/src/coreclr/tests/src/Common/Directory.Build.targets @@ -58,26 +58,37 @@ - + + True + - + + True + + + Date: Thu, 14 May 2020 22:00:10 -0400 Subject: [PATCH 211/420] Fix DAC layout in checked builds (#35542) --- src/coreclr/src/inc/sstring.h | 2 ++ src/coreclr/src/inc/utilcode.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/coreclr/src/inc/sstring.h b/src/coreclr/src/inc/sstring.h index ec2eb0cf17525..8de0cd3d4277a 100644 --- a/src/coreclr/src/inc/sstring.h +++ b/src/coreclr/src/inc/sstring.h @@ -809,6 +809,7 @@ template class EMPTY_BASES_DECL InlineSString : public SString { private: + DAC_ALIGNAS(SString) BYTE m_inline[SBUFFER_PADDED_SIZE(MEMSIZE)]; public: @@ -991,6 +992,7 @@ template class EMPTY_BASES_DECL ScratchBuffer : public SString::AbstractScratchBuffer { private: + DAC_ALIGNAS(::SString::AbstractScratchBuffer) BYTE m_inline[MEMSIZE]; public: diff --git a/src/coreclr/src/inc/utilcode.h b/src/coreclr/src/inc/utilcode.h index 14b261b08ad07..15902ef99e976 100644 --- a/src/coreclr/src/inc/utilcode.h +++ b/src/coreclr/src/inc/utilcode.h @@ -2573,6 +2573,7 @@ template class CHashTableAndData : public CHashTable { public: + DAC_ALIGNAS(CHashTable) ULONG m_iFree; // Index into m_pcEntries[] of next available slot ULONG m_iEntries; // size of m_pcEntries[] From 85777ee6347c956cef6704fa4a18170d97541afb Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Fri, 15 May 2020 07:22:09 +0200 Subject: [PATCH 212/420] Improve Uri.Equals by removing unsafe code (#36444) * Improve Uri.Equals * Remove not useful and duplicated comments --- .../System.Private.Uri/src/System/Uri.cs | 109 ++++-------------- 1 file changed, 20 insertions(+), 89 deletions(-) diff --git a/src/libraries/System.Private.Uri/src/System/Uri.cs b/src/libraries/System.Private.Uri/src/System/Uri.cs index 0755daca458aa..a13566ee3415b 100644 --- a/src/libraries/System.Private.Uri/src/System/Uri.cs +++ b/src/libraries/System.Private.Uri/src/System/Uri.cs @@ -1553,38 +1553,34 @@ public override string ToString() return _info.String; } - // - // A static shortcut to Uri.Equals - // public static bool operator ==(Uri? uri1, Uri? uri2) { - if ((object?)uri1 == (object?)uri2) + if (ReferenceEquals(uri1, uri2)) { return true; } - if ((object?)uri1 == null || (object?)uri2 == null) + + if (uri1 is null || uri2 is null) { return false; } - return uri2.Equals(uri1); + + return uri1.Equals(uri2); } - // - // A static shortcut to !Uri.Equals - // public static bool operator !=(Uri? uri1, Uri? uri2) { - if ((object?)uri1 == (object?)uri2) + if (ReferenceEquals(uri1, uri2)) { return false; } - if ((object?)uri1 == null || (object?)uri2 == null) + if (uri1 is null || uri2 is null) { return true; } - return !uri2.Equals(uri1); + return !uri1.Equals(uri2); } // @@ -1593,7 +1589,7 @@ public override string ToString() // Overrides default function (in Object class) // // Assumes: - // is an object of class Uri + // is an object of class Uri or String // // Returns: // true if objects have the same value, else false @@ -1603,38 +1599,34 @@ public override string ToString() // public override bool Equals(object? comparand) { - if ((object?)comparand == null) + if (comparand is null) { return false; } - if ((object?)this == (object?)comparand) + if (ReferenceEquals(this, comparand)) { return true; } Uri? obj = comparand as Uri; - // // we allow comparisons of Uri and String objects only. If a string // is passed, convert to Uri. This is inefficient, but allows us to // canonicalize the comparand, making comparison possible - // - if ((object?)obj == null) + if (obj is null) { - string? s = comparand as string; - - if ((object?)s == null) + if (!(comparand is string s)) return false; + if (ReferenceEquals(s, OriginalString)) + return true; + if (!TryCreate(s, UriKind.RelativeOrAbsolute, out obj)) return false; } - // Since v1.0 two Uris are equal if everything but fragment and UserInfo does match - - // This check is for a case where we already fixed up the equal references - if ((object)_string == (object)obj._string) + if (ReferenceEquals(OriginalString, obj.OriginalString)) { return true; } @@ -1648,36 +1640,7 @@ public override bool Equals(object? comparand) if (NotAny(Flags.AllUriInfoSet) || obj.NotAny(Flags.AllUriInfoSet)) { // Try raw compare for _strings as the last chance to keep the working set small - if (!IsUncOrDosPath) - { - if (_string.Length == obj._string.Length) - { - unsafe - { - // Try case sensitive compare on _strings - fixed (char* selfPtr = _string) - { - fixed (char* otherPtr = obj._string) - { - // This will never go negative since _string is checked to be a valid URI - int i = (_string.Length - 1); - for (; i >= 0; --i) - { - if (*(selfPtr + i) != *(otherPtr + i)) - { - break; - } - } - if (i == -1) - { - return true; - } - } - } - } - } - } - else if (string.Equals(_string, obj._string, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(_string, obj._string, IsUncOrDosPath ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)) { return true; } @@ -1753,44 +1716,12 @@ public override bool Equals(object? comparand) MoreInfo selfInfo = _info.MoreInfo; MoreInfo otherInfo = obj._info.MoreInfo; + // Fragment AND UserInfo are ignored string selfUrl = selfInfo.RemoteUrl ??= GetParts(UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped); string otherUrl = otherInfo.RemoteUrl ??= obj.GetParts(UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped); - if (!IsUncOrDosPath) - { - if (selfUrl.Length != otherUrl.Length) - { - return false; - } - unsafe - { - // Try case sensitive compare on _strings - fixed (char* seltPtr = selfUrl) - { - fixed (char* otherPtr = otherUrl) - { - char* endSelf = seltPtr + selfUrl.Length; - char* endOther = otherPtr + selfUrl.Length; - while (endSelf != seltPtr) - { - if (*--endSelf != *--endOther) - { - return false; - } - } - return true; - } - } - } - } - // if IsUncOrDosPath is true then we ignore case in the path comparison - // Get Unescaped form as most safe for the comparison - // Fragment AND UserInfo are ignored - // - return (string.Compare(selfUrl, - otherUrl, - IsUncOrDosPath ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal) == 0); + return string.Equals(selfUrl, otherUrl, IsUncOrDosPath ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); } public Uri MakeRelativeUri(Uri uri) From f7585699066a1ef590b23d0dea926f3f0c1a5090 Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Fri, 15 May 2020 02:10:56 -0700 Subject: [PATCH 213/420] Refactor `HasMultiRegRetVal` and `impFixupCallStructReturn`. (#36465) * Fix target definitions. They were used in asserts only, no changes. * Fix failures after a recent HW changes. * Add a const getter for `ReturnTypeDesc` from a call. Used to make some new methods const as well. * Refactor `HasMultiRegRetVal` and `impFixupCallStructReturn`. Delete an unnecessary nested condition and make checks more straightforward. * Delete an extra `.` in some dumps. * Add an additional check that `ReturnTypeDesc` is initialized. * Remove old `const_cast` around `GetReturnTypeDesc`. * Replace non-const `GetReturnTypeDesc` with other methods. * Fix uninitialized `gtSpillFlags, gtOtherRegs, gtReturnTypeDesc` in `fgMorphIntoHelperCall`. --- src/coreclr/src/jit/codegenarmarch.cpp | 19 +++--- src/coreclr/src/jit/codegencommon.cpp | 2 +- src/coreclr/src/jit/codegenlinear.cpp | 28 ++++----- src/coreclr/src/jit/codegenxarch.cpp | 28 ++++----- src/coreclr/src/jit/decomposelongs.cpp | 8 +-- src/coreclr/src/jit/gentree.cpp | 83 +++++++++----------------- src/coreclr/src/jit/gentree.h | 68 ++++++++++++++------- src/coreclr/src/jit/importer.cpp | 82 ++++++++++++------------- src/coreclr/src/jit/lower.cpp | 5 ++ src/coreclr/src/jit/lsraarmarch.cpp | 6 +- src/coreclr/src/jit/lsrabuild.cpp | 14 ++--- src/coreclr/src/jit/lsraxarch.cpp | 10 ++-- src/coreclr/src/jit/morph.cpp | 41 +++++++------ src/coreclr/src/jit/regset.cpp | 6 +- src/coreclr/src/jit/target.h | 4 +- 15 files changed, 204 insertions(+), 200 deletions(-) diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index 6e55a28da2cf7..34ee4c3de5309 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -1394,8 +1394,8 @@ void CodeGen::genMultiRegCallStoreToLocal(GenTree* treeNode) genConsumeRegs(op1); - ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc(); - unsigned regCount = pRetTypeDesc->GetReturnRegCount(); + const ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc(); + const unsigned regCount = pRetTypeDesc->GetReturnRegCount(); if (treeNode->GetRegNum() != REG_NA) { @@ -2610,9 +2610,9 @@ void CodeGen::genCallInstruction(GenTreeCall* call) } // Determine return value size(s). - ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc(); - emitAttr retSize = EA_PTRSIZE; - emitAttr secondRetSize = EA_UNKNOWN; + const ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc(); + emitAttr retSize = EA_PTRSIZE; + emitAttr secondRetSize = EA_UNKNOWN; if (call->HasMultiRegRetVal()) { @@ -3880,12 +3880,9 @@ void CodeGen::genStructReturn(GenTree* treeNode) GenTree* actualOp1 = op1->gtSkipReloadOrCopy(); GenTreeCall* call = actualOp1->AsCall(); - ReturnTypeDesc* pRetTypeDesc; - unsigned regCount; - unsigned matchingCount = 0; - - pRetTypeDesc = call->GetReturnTypeDesc(); - regCount = pRetTypeDesc->GetReturnRegCount(); + const ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc(); + const unsigned regCount = pRetTypeDesc->GetReturnRegCount(); + unsigned matchingCount = 0; var_types regType[MAX_RET_REG_COUNT]; regNumber returnReg[MAX_RET_REG_COUNT]; diff --git a/src/coreclr/src/jit/codegencommon.cpp b/src/coreclr/src/jit/codegencommon.cpp index 452d4f47a6fc6..eeae703b43c47 100644 --- a/src/coreclr/src/jit/codegencommon.cpp +++ b/src/coreclr/src/jit/codegencommon.cpp @@ -11554,7 +11554,7 @@ void CodeGen::genReturn(GenTree* treeNode) { if (varTypeIsLong(compiler->info.compRetNativeType)) { - retTypeDesc.InitializeLongReturnType(compiler); + retTypeDesc.InitializeLongReturnType(); } else // we must have a struct return type { diff --git a/src/coreclr/src/jit/codegenlinear.cpp b/src/coreclr/src/jit/codegenlinear.cpp index a1e90ee040ed7..fe6199f1d1adb 100644 --- a/src/coreclr/src/jit/codegenlinear.cpp +++ b/src/coreclr/src/jit/codegenlinear.cpp @@ -1081,10 +1081,10 @@ void CodeGen::genUnspillRegIfNeeded(GenTree* tree) } else if (unspillTree->IsMultiRegCall()) { - GenTreeCall* call = unspillTree->AsCall(); - ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - unsigned regCount = retTypeDesc->GetReturnRegCount(); - GenTreeCopyOrReload* reloadTree = nullptr; + GenTreeCall* call = unspillTree->AsCall(); + const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); + const unsigned regCount = retTypeDesc->GetReturnRegCount(); + GenTreeCopyOrReload* reloadTree = nullptr; if (tree->OperGet() == GT_RELOAD) { reloadTree = tree->AsCopyOrReload(); @@ -1904,9 +1904,9 @@ void CodeGen::genProduceReg(GenTree* tree) // know which of its result regs needs to be spilled. if (tree->IsMultiRegCall()) { - GenTreeCall* call = tree->AsCall(); - ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - unsigned regCount = retTypeDesc->GetReturnRegCount(); + GenTreeCall* call = tree->AsCall(); + const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); + const unsigned regCount = retTypeDesc->GetReturnRegCount(); for (unsigned i = 0; i < regCount; ++i) { @@ -1987,9 +1987,9 @@ void CodeGen::genProduceReg(GenTree* tree) // Mark all the regs produced by call node. if (tree->IsMultiRegCall()) { - GenTreeCall* call = tree->AsCall(); - ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - unsigned regCount = retTypeDesc->GetReturnRegCount(); + const GenTreeCall* call = tree->AsCall(); + const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); + const unsigned regCount = retTypeDesc->GetReturnRegCount(); for (unsigned i = 0; i < regCount; ++i) { @@ -2006,10 +2006,10 @@ void CodeGen::genProduceReg(GenTree* tree) // A multi-reg GT_COPY node produces those regs to which // copy has taken place. - GenTreeCopyOrReload* copy = tree->AsCopyOrReload(); - GenTreeCall* call = copy->gtGetOp1()->AsCall(); - ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - unsigned regCount = retTypeDesc->GetReturnRegCount(); + const GenTreeCopyOrReload* copy = tree->AsCopyOrReload(); + const GenTreeCall* call = copy->gtGetOp1()->AsCall(); + const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); + const unsigned regCount = retTypeDesc->GetReturnRegCount(); for (unsigned i = 0; i < regCount; ++i) { diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index 3323b0566f7fa..10fa1681ff8de 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -137,14 +137,14 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg) ReturnTypeDesc retTypeDesc; if (varTypeIsLong(compiler->info.compRetNativeType)) { - retTypeDesc.InitializeLongReturnType(compiler); + retTypeDesc.InitializeLongReturnType(); } else // we must have a struct return type { retTypeDesc.InitializeStructReturnType(compiler, compiler->info.compMethodInfo->args.retTypeClass); } - unsigned regCount = retTypeDesc.GetReturnRegCount(); + const unsigned regCount = retTypeDesc.GetReturnRegCount(); // Only x86 and x64 Unix ABI allows multi-reg return and // number of result regs should be equal to MAX_RET_REG_COUNT. @@ -1179,7 +1179,7 @@ void CodeGen::genStructReturn(GenTree* treeNode) ReturnTypeDesc retTypeDesc; retTypeDesc.InitializeStructReturnType(compiler, varDsc->lvVerTypeInfo.GetClassHandle()); - unsigned regCount = retTypeDesc.GetReturnRegCount(); + const unsigned regCount = retTypeDesc.GetReturnRegCount(); assert(regCount == MAX_RET_REG_COUNT); if (varTypeIsEnregisterable(op1)) @@ -1243,10 +1243,10 @@ void CodeGen::genStructReturn(GenTree* treeNode) genConsumeRegs(op1); - GenTree* actualOp1 = op1->gtSkipReloadOrCopy(); - GenTreeCall* call = actualOp1->AsCall(); - ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - unsigned regCount = retTypeDesc->GetReturnRegCount(); + const GenTree* actualOp1 = op1->gtSkipReloadOrCopy(); + const GenTreeCall* call = actualOp1->AsCall(); + const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); + const unsigned regCount = retTypeDesc->GetReturnRegCount(); assert(regCount == MAX_RET_REG_COUNT); // Handle circular dependency between call allocated regs and ABI return regs. @@ -2043,7 +2043,7 @@ void CodeGen::genMultiRegCallStoreToLocal(GenTree* treeNode) genConsumeRegs(op1); - ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); + const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); assert(retTypeDesc->GetReturnRegCount() == MAX_RET_REG_COUNT); unsigned regCount = retTypeDesc->GetReturnRegCount(); @@ -2154,8 +2154,8 @@ void CodeGen::genMultiRegCallStoreToLocal(GenTree* treeNode) genConsumeRegs(op1); - ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - unsigned regCount = retTypeDesc->GetReturnRegCount(); + const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); + unsigned regCount = retTypeDesc->GetReturnRegCount(); assert(regCount == MAX_RET_REG_COUNT); // Stack store @@ -5490,9 +5490,9 @@ void CodeGen::genCallInstruction(GenTreeCall* call) } // Determine return value size(s). - ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - emitAttr retSize = EA_PTRSIZE; - emitAttr secondRetSize = EA_UNKNOWN; + const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); + emitAttr retSize = EA_PTRSIZE; + emitAttr secondRetSize = EA_UNKNOWN; if (call->HasMultiRegRetVal()) { @@ -5755,7 +5755,7 @@ void CodeGen::genCallInstruction(GenTreeCall* call) if (call->HasMultiRegRetVal()) { assert(retTypeDesc != nullptr); - unsigned regCount = retTypeDesc->GetReturnRegCount(); + const unsigned regCount = retTypeDesc->GetReturnRegCount(); // If regs allocated to call node are different from ABI return // regs in which the call has returned its result, move the result diff --git a/src/coreclr/src/jit/decomposelongs.cpp b/src/coreclr/src/jit/decomposelongs.cpp index 77112049271ea..855d60813ca02 100644 --- a/src/coreclr/src/jit/decomposelongs.cpp +++ b/src/coreclr/src/jit/decomposelongs.cpp @@ -1362,7 +1362,7 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use) GenTreeCall::Use* argList = m_compiler->gtNewCallArgs(loOp1, hiOp1, shiftByOp); - GenTree* call = m_compiler->gtNewHelperCallNode(helper, TYP_LONG, argList); + GenTreeCall* call = m_compiler->gtNewHelperCallNode(helper, TYP_LONG, argList); call->gtFlags |= shift->gtFlags & GTF_ALL_EFFECT; if (shift->IsUnusedValue()) @@ -1370,11 +1370,7 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use) call->SetUnusedValue(); } - GenTreeCall* callNode = call->AsCall(); - ReturnTypeDesc* retTypeDesc = callNode->GetReturnTypeDesc(); - retTypeDesc->InitializeLongReturnType(m_compiler); - - call = m_compiler->fgMorphArgs(callNode); + call = m_compiler->fgMorphArgs(call); Range().InsertAfter(shift, LIR::SeqTree(m_compiler, call)); Range().Remove(shift); diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index afeb708a2725b..f3208926e3bed 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -622,15 +622,12 @@ void GenTree::CopyReg(GenTree* from) // bool GenTree::gtHasReg() const { - bool hasReg; + bool hasReg = false; if (IsMultiRegCall()) { - // Have to cast away const-ness because GetReturnTypeDesc() is a non-const method - GenTree* tree = const_cast(this); - GenTreeCall* call = tree->AsCall(); - unsigned regCount = call->GetReturnTypeDesc()->GetReturnRegCount(); - hasReg = false; + const GenTreeCall* call = AsCall(); + const unsigned regCount = call->GetReturnTypeDesc()->GetReturnRegCount(); // A Multi-reg call node is said to have regs, if it has // reg assigned to each of its result registers. @@ -645,11 +642,9 @@ bool GenTree::gtHasReg() const } else if (IsCopyOrReloadOfMultiRegCall()) { - GenTree* tree = const_cast(this); - GenTreeCopyOrReload* copyOrReload = tree->AsCopyOrReload(); - GenTreeCall* call = copyOrReload->gtGetOp1()->AsCall(); - unsigned regCount = call->GetReturnTypeDesc()->GetReturnRegCount(); - hasReg = false; + const GenTreeCopyOrReload* copyOrReload = AsCopyOrReload(); + const GenTreeCall* call = copyOrReload->gtGetOp1()->AsCall(); + const unsigned regCount = call->GetReturnTypeDesc()->GetReturnRegCount(); // A Multi-reg copy or reload node is said to have regs, // if it has valid regs in any of the positions. @@ -693,9 +688,7 @@ int GenTree::GetRegisterDstCount() const } else if (IsMultiRegCall()) { - // temporarily cast away const-ness as AsCall() method is not declared const - GenTree* temp = const_cast(this); - return temp->AsCall()->GetReturnTypeDesc()->GetReturnRegCount(); + return AsCall()->GetReturnTypeDesc()->GetReturnRegCount(); } else if (IsCopyOrReload()) { @@ -750,9 +743,8 @@ regMaskTP GenTree::gtGetRegMask() const if (IsMultiRegCall()) { // temporarily cast away const-ness as AsCall() method is not declared const - resultMask = genRegMask(GetRegNum()); - GenTree* temp = const_cast(this); - resultMask |= temp->AsCall()->GetOtherRegMask(); + resultMask = genRegMask(GetRegNum()); + resultMask |= AsCall()->GetOtherRegMask(); } else if (IsCopyOrReloadOfMultiRegCall()) { @@ -760,10 +752,9 @@ regMaskTP GenTree::gtGetRegMask() const // positions that need to be copied or reloaded. Hence we need // to consider only those registers for computing reg mask. - GenTree* tree = const_cast(this); - GenTreeCopyOrReload* copyOrReload = tree->AsCopyOrReload(); - GenTreeCall* call = copyOrReload->gtGetOp1()->AsCall(); - unsigned regCount = call->GetReturnTypeDesc()->GetReturnRegCount(); + const GenTreeCopyOrReload* copyOrReload = AsCopyOrReload(); + const GenTreeCall* call = copyOrReload->gtGetOp1()->AsCall(); + const unsigned regCount = call->GetReturnTypeDesc()->GetReturnRegCount(); resultMask = RBM_NONE; for (unsigned i = 0; i < regCount; ++i) @@ -778,9 +769,8 @@ regMaskTP GenTree::gtGetRegMask() const #if FEATURE_ARG_SPLIT else if (OperIsPutArgSplit()) { - GenTree* tree = const_cast(this); - GenTreePutArgSplit* splitArg = tree->AsPutArgSplit(); - unsigned regCount = splitArg->gtNumRegs; + const GenTreePutArgSplit* splitArg = AsPutArgSplit(); + const unsigned regCount = splitArg->gtNumRegs; resultMask = RBM_NONE; for (unsigned i = 0; i < regCount; ++i) @@ -6182,21 +6172,14 @@ GenTreeCall* Compiler::gtNewCallNode( // Initialize spill flags of gtOtherRegs node->ClearOtherRegFlags(); -#if defined(TARGET_X86) || defined(TARGET_ARM) - // Initialize the multi-reg long return info if necessary +#if !defined(TARGET_64BIT) if (varTypeIsLong(node)) { - // The return type will remain as the incoming long type - node->gtReturnType = node->gtType; - + assert(node->gtReturnType == node->gtType); // Initialize Return type descriptor of call node - ReturnTypeDesc* retTypeDesc = node->GetReturnTypeDesc(); - retTypeDesc->InitializeLongReturnType(this); - - // must be a long returned in two registers - assert(retTypeDesc->GetReturnRegCount() == 2); + node->InitializeLongReturnType(); } -#endif // defined(TARGET_X86) || defined(TARGET_ARM) +#endif // !defined(TARGET_64BIT) return node; } @@ -10217,8 +10200,8 @@ void Compiler::gtDispRegVal(GenTree* tree) { // 0th reg is GettRegNum(), which is already printed above. // Print the remaining regs of a multi-reg call node. - GenTreeCall* call = tree->AsCall(); - unsigned regCount = call->GetReturnTypeDesc()->TryGetReturnRegCount(); + const GenTreeCall* call = tree->AsCall(); + const unsigned regCount = call->GetReturnTypeDesc()->TryGetReturnRegCount(); for (unsigned i = 1; i < regCount; ++i) { printf(",%s", compRegVarName(call->GetRegNumByIdx(i))); @@ -10226,9 +10209,9 @@ void Compiler::gtDispRegVal(GenTree* tree) } else if (tree->IsCopyOrReloadOfMultiRegCall()) { - GenTreeCopyOrReload* copyOrReload = tree->AsCopyOrReload(); - GenTreeCall* call = tree->gtGetOp1()->AsCall(); - unsigned regCount = call->GetReturnTypeDesc()->TryGetReturnRegCount(); + const GenTreeCopyOrReload* copyOrReload = tree->AsCopyOrReload(); + const GenTreeCall* call = tree->gtGetOp1()->AsCall(); + const unsigned regCount = call->GetReturnTypeDesc()->TryGetReturnRegCount(); for (unsigned i = 1; i < regCount; ++i) { printf(",%s", compRegVarName(copyOrReload->GetRegNumByIdx(i))); @@ -15315,9 +15298,7 @@ GenTree* Compiler::gtNewRefCOMfield(GenTree* objPtr, #if FEATURE_MULTIREG_RET if (varTypeIsStruct(call)) { - // Initialize Return type descriptor of call node. - ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - retTypeDesc->InitializeStructReturnType(this, structType); + call->InitializeStructReturnType(this, structType); } #endif // FEATURE_MULTIREG_RET @@ -16529,7 +16510,7 @@ bool GenTree::isContained() const else if (OperKind() & GTK_RELOP) { // We have to cast away const-ness since AsOp() method is non-const. - GenTree* childNode = const_cast(this)->AsOp()->gtOp1; + const GenTree* childNode = AsOp()->gtGetOp1(); assert((isMarkedContained == false) || childNode->IsSIMDEqualityOrInequality()); } @@ -18909,16 +18890,10 @@ void ReturnTypeDesc::InitializeStructReturnType(Compiler* comp, CORINFO_CLASS_HA // InitializeLongReturnType: // Initialize the Return Type Descriptor for a method that returns a TYP_LONG // -// Arguments -// comp - Compiler Instance -// -// Return Value -// None -// -void ReturnTypeDesc::InitializeLongReturnType(Compiler* comp) +void ReturnTypeDesc::InitializeLongReturnType() { + assert(!m_inited); #if defined(TARGET_X86) || defined(TARGET_ARM) - // Setups up a ReturnTypeDesc for returning a long using two registers // assert(MAX_RET_REG_COUNT >= 2); @@ -18950,7 +18925,7 @@ void ReturnTypeDesc::InitializeLongReturnType(Compiler* comp) // x86 and ARM return long in multiple registers. // ARM and ARM64 return HFA struct in multiple registers. // -regNumber ReturnTypeDesc::GetABIReturnReg(unsigned idx) +regNumber ReturnTypeDesc::GetABIReturnReg(unsigned idx) const { unsigned count = GetReturnRegCount(); assert(idx < count); @@ -19079,7 +19054,7 @@ regNumber ReturnTypeDesc::GetABIReturnReg(unsigned idx) // of return registers and wants to know the set of return registers. // // static -regMaskTP ReturnTypeDesc::GetABIReturnRegs() +regMaskTP ReturnTypeDesc::GetABIReturnRegs() const { regMaskTP resultMask = RBM_NONE; diff --git a/src/coreclr/src/jit/gentree.h b/src/coreclr/src/jit/gentree.h index efee04b7ee178..7b7b5af861d21 100644 --- a/src/coreclr/src/jit/gentree.h +++ b/src/coreclr/src/jit/gentree.h @@ -3601,8 +3601,8 @@ struct ReturnTypeDesc void InitializeStructReturnType(Compiler* comp, CORINFO_CLASS_HANDLE retClsHnd); // Initialize the Return Type Descriptor for a method that returns a TYP_LONG - // Only needed for X86 - void InitializeLongReturnType(Compiler* comp); + // Only needed for X86 and arm32. + void InitializeLongReturnType(); // Reset type descriptor to defaults void Reset() @@ -3681,6 +3681,7 @@ struct ReturnTypeDesc } else { + assert(m_inited); return ((m_regType[0] != TYP_UNKNOWN) && (m_regType[1] != TYP_UNKNOWN)); } } @@ -3696,7 +3697,7 @@ struct ReturnTypeDesc // var_type of the return register specified by its index. // asserts if the index does not have a valid register return type. - var_types GetReturnRegType(unsigned index) + var_types GetReturnRegType(unsigned index) const { var_types result = m_regType[index]; assert(result != TYP_UNKNOWN); @@ -3712,10 +3713,10 @@ struct ReturnTypeDesc } // Get ith ABI return register - regNumber GetABIReturnReg(unsigned idx); + regNumber GetABIReturnReg(unsigned idx) const; // Get reg mask of ABI return registers - regMaskTP GetABIReturnRegs(); + regMaskTP GetABIReturnRegs() const; }; class TailCallSiteInfo @@ -3919,7 +3920,6 @@ struct GenTreeCall final : public GenTree #if FEATURE_MULTIREG_RET // State required to support multi-reg returning call nodes. - // For now it is enabled only for x64 unix. // // TODO-AllArch: enable for all call nodes to unify single-reg and multi-reg returns. ReturnTypeDesc gtReturnTypeDesc; @@ -3941,12 +3941,8 @@ struct GenTreeCall final : public GenTree // Returns // Type descriptor of the value returned by call // - // Note: - // Right now implemented only for x64 unix and yet to be - // implemented for other multi-reg target arch (Arm64/Arm32/x86). - // // TODO-AllArch: enable for all call nodes to unify single-reg and multi-reg returns. - ReturnTypeDesc* GetReturnTypeDesc() + const ReturnTypeDesc* GetReturnTypeDesc() const { #if FEATURE_MULTIREG_RET return >ReturnTypeDesc; @@ -3955,6 +3951,27 @@ struct GenTreeCall final : public GenTree #endif } + void InitializeLongReturnType() + { +#if FEATURE_MULTIREG_RET + gtReturnTypeDesc.InitializeLongReturnType(); +#endif + } + + void InitializeStructReturnType(Compiler* comp, CORINFO_CLASS_HANDLE retClsHnd) + { +#if FEATURE_MULTIREG_RET + gtReturnTypeDesc.InitializeStructReturnType(comp, retClsHnd); +#endif + } + + void ResetReturnType() + { +#if FEATURE_MULTIREG_RET + gtReturnTypeDesc.Reset(); +#endif + } + //--------------------------------------------------------------------------- // GetRegNumByIdx: get ith return register allocated to this call node. // @@ -4221,18 +4238,29 @@ struct GenTreeCall final : public GenTree // bool HasMultiRegRetVal() const { -#if defined(TARGET_X86) - return varTypeIsLong(gtType); -#elif FEATURE_MULTIREG_RET && defined(TARGET_ARM) - return varTypeIsLong(gtType) || (varTypeIsStruct(gtType) && !HasRetBufArg()); +#ifdef FEATURE_MULTIREG_RET +#if defined(TARGET_X86) || defined(TARGET_ARM) + if (varTypeIsLong(gtType)) + { + return true; + } #elif defined(FEATURE_HFA) && defined(TARGET_ARM64) // SIMD types are returned in vector regs on ARM64. - return (gtType == TYP_STRUCT) && !HasRetBufArg(); -#elif FEATURE_MULTIREG_RET - return varTypeIsStruct(gtType) && !HasRetBufArg(); -#else + if (varTypeIsSIMD(gtType)) + { + return false; + } +#endif // FEATURE_HFA && TARGET_ARM64 + + if (!varTypeIsStruct(gtType) || HasRetBufArg()) + { + return false; + } + // Now it is a struct that is returned in registers. + return GetReturnTypeDesc()->IsMultiRegRetType(); +#else // !FEATURE_MULTIREG_RET return false; -#endif +#endif // !FEATURE_MULTIREG_RET } // Returns true if VM has flagged this method as CORINFO_FLG_PINVOKE. diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 014e42a1293d7..010cd3395cb14 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -8982,9 +8982,7 @@ GenTree* Compiler::impFixupCallStructReturn(GenTreeCall* call, CORINFO_CLASS_HAN call->gtRetClsHnd = retClsHnd; #if FEATURE_MULTIREG_RET - // Initialize Return type descriptor of call node - ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - retTypeDesc->InitializeStructReturnType(this, retClsHnd); + call->InitializeStructReturnType(this, retClsHnd); #endif // FEATURE_MULTIREG_RET #ifdef UNIX_AMD64_ABI @@ -8992,55 +8990,57 @@ GenTree* Compiler::impFixupCallStructReturn(GenTreeCall* call, CORINFO_CLASS_HAN // Not allowed for FEATURE_CORCLR which is the only SKU available for System V OSs. assert(!call->IsVarargs() && "varargs not allowed for System V OSs."); - // The return type will remain as the incoming struct type unless normalized to a - // single eightbyte return type below. - call->gtReturnType = call->gtType; - - unsigned retRegCount = retTypeDesc->GetReturnRegCount(); - if (retRegCount != 0) + const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); + const unsigned retRegCount = retTypeDesc->GetReturnRegCount(); + if (retRegCount == 0) + { + // struct not returned in registers i.e returned via hiddden retbuf arg. + call->gtCallMoreFlags |= GTF_CALL_M_RETBUFFARG; + } + else if (retRegCount == 1) { - if (retRegCount == 1) + if (!compDoOldStructRetyping()) { - // See if the struct size is smaller than the return - // type size... - if (retTypeDesc->IsEnclosingType()) + return call; + } + // See if the struct size is smaller than the return + // type size... + if (retTypeDesc->IsEnclosingType()) + { + // If we know for sure this call will remain a call, + // retype and return value via a suitable temp. + if ((!call->CanTailCall()) && (!call->IsInlineCandidate())) { - // If we know for sure this call will remain a call, - // retype and return value via a suitable temp. - if ((!call->CanTailCall()) && (!call->IsInlineCandidate())) - { - call->gtReturnType = retTypeDesc->GetReturnRegType(0); - return impAssignSmallStructTypeToVar(call, retClsHnd); - } + call->gtReturnType = retTypeDesc->GetReturnRegType(0); + return impAssignSmallStructTypeToVar(call, retClsHnd); } else { - // Return type is same size as struct, so we can - // simply retype the call. - call->gtReturnType = retTypeDesc->GetReturnRegType(0); + call->gtReturnType = call->gtType; } } else { - // must be a struct returned in two registers - assert(retRegCount == 2); - - if ((!call->CanTailCall()) && (!call->IsInlineCandidate())) - { - // Force a call returning multi-reg struct to be always of the IR form - // tmp = call - // - // No need to assign a multi-reg struct to a local var if: - // - It is a tail call or - // - The call is marked for in-lining later - return impAssignMultiRegTypeToVar(call, retClsHnd); - } + // Return type is same size as struct, so we can + // simply retype the call. + call->gtReturnType = retTypeDesc->GetReturnRegType(0); } } else { - // struct not returned in registers i.e returned via hiddden retbuf arg. - call->gtCallMoreFlags |= GTF_CALL_M_RETBUFFARG; + // must be a struct returned in two registers + assert(retRegCount == 2); + + if ((!call->CanTailCall()) && (!call->IsInlineCandidate())) + { + // Force a call returning multi-reg struct to be always of the IR form + // tmp = call + // + // No need to assign a multi-reg struct to a local var if: + // - It is a tail call or + // - The call is marked for in-lining later + return impAssignMultiRegTypeToVar(call, retClsHnd); + } } #else // not UNIX_AMD64_ABI @@ -9095,7 +9095,7 @@ GenTree* Compiler::impFixupCallStructReturn(GenTreeCall* call, CORINFO_CLASS_HAN } #if FEATURE_MULTIREG_RET - unsigned retRegCount = retTypeDesc->GetReturnRegCount(); + const unsigned retRegCount = call->GetReturnTypeDesc()->GetReturnRegCount(); assert(retRegCount != 0); if (retRegCount >= 2) @@ -16361,7 +16361,7 @@ void Compiler::impMarkLclDstNotPromotable(unsigned tmpNum, GenTree* src, CORINFO GenTree* Compiler::impAssignSmallStructTypeToVar(GenTree* op, CORINFO_CLASS_HANDLE hClass) { - unsigned tmpNum = lvaGrabTemp(true DEBUGARG("Return value temp for small struct return.")); + unsigned tmpNum = lvaGrabTemp(true DEBUGARG("Return value temp for small struct return")); impAssignTempGen(tmpNum, op, hClass, (unsigned)CHECK_SPILL_ALL); GenTree* ret = gtNewLclvNode(tmpNum, lvaTable[tmpNum].lvType); return ret; @@ -16381,7 +16381,7 @@ GenTree* Compiler::impAssignSmallStructTypeToVar(GenTree* op, CORINFO_CLASS_HAND GenTree* Compiler::impAssignMultiRegTypeToVar(GenTree* op, CORINFO_CLASS_HANDLE hClass) { - unsigned tmpNum = lvaGrabTemp(true DEBUGARG("Return value temp for multireg return.")); + unsigned tmpNum = lvaGrabTemp(true DEBUGARG("Return value temp for multireg return")); impAssignTempGen(tmpNum, op, hClass, (unsigned)CHECK_SPILL_ALL); GenTree* ret = gtNewLclvNode(tmpNum, lvaTable[tmpNum].lvType); diff --git a/src/coreclr/src/jit/lower.cpp b/src/coreclr/src/jit/lower.cpp index 16a0ee738e45e..b2b9a30322a4f 100644 --- a/src/coreclr/src/jit/lower.cpp +++ b/src/coreclr/src/jit/lower.cpp @@ -3063,7 +3063,12 @@ void Lowering::LowerRetStruct(GenTreeUnOp* ret) LowerRetStructLclVar(ret); break; +#ifdef FEATURE_SIMD case GT_SIMD: +#endif // FEATURE_SIMD +#ifdef FEATURE_HW_INTRINSICS + case GT_HWINTRINSIC: +#endif // FEATURE_HW_INTRINSICS case GT_LCL_FLD: { GenTreeUnOp* bitcast = new (comp, GT_BITCAST) GenTreeOp(GT_BITCAST, ret->TypeGet(), retVal, nullptr); diff --git a/src/coreclr/src/jit/lsraarmarch.cpp b/src/coreclr/src/jit/lsraarmarch.cpp index af7557807035a..8452ac68759d2 100644 --- a/src/coreclr/src/jit/lsraarmarch.cpp +++ b/src/coreclr/src/jit/lsraarmarch.cpp @@ -135,9 +135,9 @@ int LinearScan::BuildIndir(GenTreeIndir* indirTree) // int LinearScan::BuildCall(GenTreeCall* call) { - bool hasMultiRegRetVal = false; - ReturnTypeDesc* retTypeDesc = nullptr; - regMaskTP dstCandidates = RBM_NONE; + bool hasMultiRegRetVal = false; + const ReturnTypeDesc* retTypeDesc = nullptr; + regMaskTP dstCandidates = RBM_NONE; int srcCount = 0; int dstCount = 0; diff --git a/src/coreclr/src/jit/lsrabuild.cpp b/src/coreclr/src/jit/lsrabuild.cpp index 0e578987e9e49..44462d7a91ada 100644 --- a/src/coreclr/src/jit/lsrabuild.cpp +++ b/src/coreclr/src/jit/lsrabuild.cpp @@ -2699,7 +2699,7 @@ void LinearScan::BuildDefs(GenTree* tree, int dstCount, regMaskTP dstCandidates) { fixedReg = true; } - ReturnTypeDesc* retTypeDesc = nullptr; + const ReturnTypeDesc* retTypeDesc = nullptr; if (tree->IsMultiRegCall()) { retTypeDesc = tree->AsCall()->GetReturnTypeDesc(); @@ -3074,9 +3074,9 @@ int LinearScan::BuildStoreLoc(GenTreeLclVarCommon* storeLoc) assert(storeLoc->OperGet() == GT_STORE_LCL_VAR); // srcCount = number of registers in which the value is returned by call - GenTreeCall* call = op1->AsCall(); - ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - srcCount = retTypeDesc->GetReturnRegCount(); + const GenTreeCall* call = op1->AsCall(); + const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); + srcCount = retTypeDesc->GetReturnRegCount(); for (int i = 0; i < srcCount; ++i) { @@ -3284,9 +3284,9 @@ int LinearScan::BuildReturn(GenTree* tree) { noway_assert(op1->IsMultiRegCall()); - ReturnTypeDesc* retTypeDesc = op1->AsCall()->GetReturnTypeDesc(); - int srcCount = retTypeDesc->GetReturnRegCount(); - useCandidates = retTypeDesc->GetABIReturnRegs(); + const ReturnTypeDesc* retTypeDesc = op1->AsCall()->GetReturnTypeDesc(); + const int srcCount = retTypeDesc->GetReturnRegCount(); + useCandidates = retTypeDesc->GetABIReturnRegs(); for (int i = 0; i < srcCount; i++) { BuildUse(op1, useCandidates, i); diff --git a/src/coreclr/src/jit/lsraxarch.cpp b/src/coreclr/src/jit/lsraxarch.cpp index 348f971324843..772ab8c12c208 100644 --- a/src/coreclr/src/jit/lsraxarch.cpp +++ b/src/coreclr/src/jit/lsraxarch.cpp @@ -1033,11 +1033,11 @@ int LinearScan::BuildShiftRotate(GenTree* tree) // int LinearScan::BuildCall(GenTreeCall* call) { - bool hasMultiRegRetVal = false; - ReturnTypeDesc* retTypeDesc = nullptr; - int srcCount = 0; - int dstCount = 0; - regMaskTP dstCandidates = RBM_NONE; + bool hasMultiRegRetVal = false; + const ReturnTypeDesc* retTypeDesc = nullptr; + int srcCount = 0; + int dstCount = 0; + regMaskTP dstCandidates = RBM_NONE; assert(!call->isContained()); if (call->TypeGet() != TYP_VOID) diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 379cf107b62f0..c762cefbf24ca 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -63,38 +63,41 @@ GenTree* Compiler::fgMorphIntoHelperCall(GenTree* tree, int helper, GenTreeCall: // The helper call ought to be semantically equivalent to the original node, so preserve its VN. tree->ChangeOper(GT_CALL, GenTree::PRESERVE_VN); - tree->AsCall()->gtCallType = CT_HELPER; - tree->AsCall()->gtCallMethHnd = eeFindHelper(helper); - tree->AsCall()->gtCallThisArg = nullptr; - tree->AsCall()->gtCallArgs = args; - tree->AsCall()->gtCallLateArgs = nullptr; - tree->AsCall()->fgArgInfo = nullptr; - tree->AsCall()->gtRetClsHnd = nullptr; - tree->AsCall()->gtCallMoreFlags = 0; - tree->AsCall()->gtInlineCandidateInfo = nullptr; - tree->AsCall()->gtControlExpr = nullptr; + GenTreeCall* call = tree->AsCall(); + + call->gtCallType = CT_HELPER; + call->gtCallMethHnd = eeFindHelper(helper); + call->gtCallThisArg = nullptr; + call->gtCallArgs = args; + call->gtCallLateArgs = nullptr; + call->fgArgInfo = nullptr; + call->gtRetClsHnd = nullptr; + call->gtCallMoreFlags = 0; + call->gtInlineCandidateInfo = nullptr; + call->gtControlExpr = nullptr; #if DEBUG // Helper calls are never candidates. - tree->AsCall()->gtInlineObservation = InlineObservation::CALLSITE_IS_CALL_TO_HELPER; + call->gtInlineObservation = InlineObservation::CALLSITE_IS_CALL_TO_HELPER; #endif // DEBUG #ifdef FEATURE_READYTORUN_COMPILER - tree->AsCall()->gtEntryPoint.addr = nullptr; - tree->AsCall()->gtEntryPoint.accessType = IAT_VALUE; + call->gtEntryPoint.addr = nullptr; + call->gtEntryPoint.accessType = IAT_VALUE; #endif +#if FEATURE_MULTIREG_RET + call->ResetReturnType(); + call->ClearOtherRegs(); + call->ClearOtherRegFlags(); #ifndef TARGET_64BIT if (varTypeIsLong(tree)) { - GenTreeCall* callNode = tree->AsCall(); - ReturnTypeDesc* retTypeDesc = callNode->GetReturnTypeDesc(); - retTypeDesc->Reset(); - retTypeDesc->InitializeLongReturnType(this); - callNode->ClearOtherRegs(); + call->InitializeLongReturnType(); } #endif // !TARGET_64BIT +#endif // FEATURE_MULTIREG_RET if (tree->OperMayThrow(this)) { @@ -115,7 +118,7 @@ GenTree* Compiler::fgMorphIntoHelperCall(GenTree* tree, int helper, GenTreeCall: if (morphArgs) { - tree = fgMorphArgs(tree->AsCall()); + tree = fgMorphArgs(call); } return tree; diff --git a/src/coreclr/src/jit/regset.cpp b/src/coreclr/src/jit/regset.cpp index a550df415c030..92ef88f8c74b0 100644 --- a/src/coreclr/src/jit/regset.cpp +++ b/src/coreclr/src/jit/regset.cpp @@ -304,9 +304,9 @@ void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */) if (tree->IsMultiRegCall()) { - call = tree->AsCall(); - ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - treeType = retTypeDesc->GetReturnRegType(regIdx); + call = tree->AsCall(); + const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); + treeType = retTypeDesc->GetReturnRegType(regIdx); } #ifdef TARGET_ARM else if (tree->OperIsPutArgSplit()) diff --git a/src/coreclr/src/jit/target.h b/src/coreclr/src/jit/target.h index cbd6d46ceb267..6fd88968026c3 100644 --- a/src/coreclr/src/jit/target.h +++ b/src/coreclr/src/jit/target.h @@ -232,10 +232,10 @@ typedef unsigned char regNumberSmall; #define FEATURE_MULTIREG_ARGS 0 // Support for passing a single argument in more than one register #define FEATURE_MULTIREG_RET 1 // Support for returning a single value in more than one register #define MAX_PASS_SINGLEREG_BYTES 8 // Maximum size of a struct passed in a single register (double). - #define MAX_PASS_MULTIREG_BYTES 0 // No multireg arguments (note this seems wrong as MAX_ARG_REG_COUNT is 2) + #define MAX_PASS_MULTIREG_BYTES 0 // No multireg arguments #define MAX_RET_MULTIREG_BYTES 8 // Maximum size of a struct that could be returned in more than one register - #define MAX_ARG_REG_COUNT 2 // Maximum registers used to pass an argument. + #define MAX_ARG_REG_COUNT 1 // Maximum registers used to pass an argument. #define MAX_RET_REG_COUNT 2 // Maximum registers used to return a value. #define MAX_MULTIREG_COUNT 2 // Maxiumum number of registers defined by a single instruction (including calls). From c96b6a8c2702f573b1880f7e36779acf7224bfc1 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid Date: Fri, 15 May 2020 12:11:39 +0300 Subject: [PATCH 214/420] Implement get_own_executable_path for SunOS (#36514) --- .../corehost/cli/hostmisc/pal.unix.cpp | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/installer/corehost/cli/hostmisc/pal.unix.cpp b/src/installer/corehost/cli/hostmisc/pal.unix.cpp index 20612a16f6fcf..b09721677da7b 100644 --- a/src/installer/corehost/cli/hostmisc/pal.unix.cpp +++ b/src/installer/corehost/cli/hostmisc/pal.unix.cpp @@ -41,6 +41,16 @@ #define DT_LNK 10 #endif +#ifdef __linux__ +#define PAL_CWD_SIZE 0 +#elif defined(MAXPATHLEN) +#define PAL_CWD_SIZE MAXPATHLEN +#elif defined(PATH_MAX) +#define PAL_CWD_SIZE PATH_MAX +#else +#error "Don't know how to obtain max path on this platform" +#endif + pal::string_t pal::to_lower(const pal::string_t& in) { pal::string_t ret = in; @@ -118,7 +128,7 @@ void* pal::mmap_copy_on_write(const string_t& path, size_t* length) bool pal::getcwd(pal::string_t* recv) { recv->clear(); - pal::char_t* buf = ::getcwd(nullptr, 0); + pal::char_t* buf = ::getcwd(nullptr, PAL_CWD_SIZE); if (buf == nullptr) { if (errno == ENOENT) @@ -129,6 +139,7 @@ bool pal::getcwd(pal::string_t* recv) trace::error(_X("getcwd() failed: %s"), strerror(errno)); return false; } + recv->assign(buf); ::free(buf); return true; @@ -768,6 +779,28 @@ bool pal::get_own_executable_path(pal::string_t* recv) } return false; } +#elif defined(__sun) +bool pal::get_own_executable_path(pal::string_t* recv) +{ + const char *path; + if ((path = getexecname()) == NULL) + { + return false; + } + else if (*path != '/') + { + if (!getcwd(recv)) + { + return false; + } + + recv->append("/").append(path); + return true; + } + + recv->assign(path); + return true; +} #else bool pal::get_own_executable_path(pal::string_t* recv) { From 827a523bfc7fd6c3835e62f4fb5fdacafd0e0060 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Fri, 15 May 2020 14:48:11 +0300 Subject: [PATCH 215/420] [mono] Improve Android OpenSSL temp hack (#36463) --- eng/testing/tests.mobile.targets | 10 +++++----- src/libraries/Native/Unix/CMakeLists.txt | 2 +- .../CMakeLists.txt | 17 ++++++++++++++--- ...stem.Security.Cryptography.Algorithms.csproj | 4 ++-- src/mono/netcore/sample/Android/Program.csproj | 10 +++++----- 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 586874ad362f6..077b60c22b94f 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -13,7 +13,7 @@ arm64-v8a - armeabi + armeabi-v7a x86_64 x86 @@ -21,11 +21,11 @@ - - diff --git a/src/libraries/Native/Unix/CMakeLists.txt b/src/libraries/Native/Unix/CMakeLists.txt index 143c990257aee..6d6ca05dc3d94 100644 --- a/src/libraries/Native/Unix/CMakeLists.txt +++ b/src/libraries/Native/Unix/CMakeLists.txt @@ -215,7 +215,7 @@ elseif(CLR_CMAKE_TARGET_TVOS) elseif(CLR_CMAKE_TARGET_ANDROID AND NOT CROSS_ROOTFS) add_subdirectory(System.Globalization.Native) #add_subdirectory(System.Net.Security.Native) # TODO: reenable - if (NOT "$ENV{AndroidOpenSslHeaders}" STREQUAL "") + if (NOT "$ENV{ANDROID_OPENSSL_AAR}" STREQUAL "") add_subdirectory(System.Security.Cryptography.Native) endif() else() diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Security.Cryptography.Native/CMakeLists.txt index 743c501f12486..42f845d494d25 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native/CMakeLists.txt @@ -15,9 +15,20 @@ endif(CMAKE_STATIC_LIB_LINK) if(CLR_CMAKE_TARGET_ANDROID AND NOT CROSS_ROOTFS) # TEMP: consume OpenSSL dependencies from external sources via env. variables set(OPENSSL_FOUND 1) - set(OPENSSL_INCLUDE_DIR $ENV{AndroidOpenSslHeaders}) - set(OPENSSL_CRYPTO_LIBRARY $ENV{AndroidOpenSslCryptoLib}) - set(OPENSSL_SSL_LIBRARY $ENV{AndroidOpenSslLib}) + set(OPENSSL_INCLUDE_DIR $ENV{ANDROID_OPENSSL_AAR}/prefab/modules/ssl/include) + if(CLR_CMAKE_TARGET_ARCH_ARM64) + set(OPENSSL_CRYPTO_LIBRARY $ENV{ANDROID_OPENSSL_AAR}/prefab/modules/crypto/libs/android.arm64-v8a/libcrypto.so) + set(OPENSSL_SSL_LIBRARY $ENV{ANDROID_OPENSSL_AAR}/prefab/modules/ssl/libs/android.arm64-v8a/libssl.so) + elseif(CLR_CMAKE_TARGET_ARCH_ARM) + set(OPENSSL_CRYPTO_LIBRARY $ENV{ANDROID_OPENSSL_AAR}/prefab/modules/crypto/libs/android.armeabi-v7a/libcrypto.so) + set(OPENSSL_SSL_LIBRARY $ENV{ANDROID_OPENSSL_AAR}/prefab/modules/ssl/libs/android.armeabi-v7a/libssl.so) + elseif(CLR_CMAKE_TARGET_ARCH_I386) + set(OPENSSL_CRYPTO_LIBRARY $ENV{ANDROID_OPENSSL_AAR}/prefab/modules/crypto/libs/android.x86/libcrypto.so) + set(OPENSSL_SSL_LIBRARY $ENV{ANDROID_OPENSSL_AAR}/prefab/modules/ssl/libs/android.x86/libssl.so) + else() + set(OPENSSL_CRYPTO_LIBRARY $ENV{ANDROID_OPENSSL_AAR}/prefab/modules/crypto/libs/android.x86_64/libcrypto.so) + set(OPENSSL_SSL_LIBRARY $ENV{ANDROID_OPENSSL_AAR}/prefab/modules/ssl/libs/android.x86_64/libssl.so) + endif() else() find_package(OpenSSL) endif() diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj b/src/libraries/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj index 0a126fc83ceb2..da598436fea91 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj @@ -477,8 +477,8 @@ Link="Common\System\Security\Cryptography\RSAOpenSsl.cs" /> - - + + diff --git a/src/mono/netcore/sample/Android/Program.csproj b/src/mono/netcore/sample/Android/Program.csproj index 00831a0d344eb..00acd1e7cf41e 100644 --- a/src/mono/netcore/sample/Android/Program.csproj +++ b/src/mono/netcore/sample/Android/Program.csproj @@ -21,7 +21,7 @@ arm64-v8a - armeabi + armeabi-v7a x86_64 $(TargetArchitecture) @@ -38,11 +38,11 @@ - - Date: Fri, 15 May 2020 15:02:05 +0300 Subject: [PATCH 216/420] [docs] How to run tests on iOS and Android (#36297) --- .../testing/libraries/testing-android.md | 91 +++++++++++++++++++ .../testing/libraries/testing-apple.md | 32 +++++++ 2 files changed, 123 insertions(+) create mode 100644 docs/workflow/testing/libraries/testing-android.md create mode 100644 docs/workflow/testing/libraries/testing-apple.md diff --git a/docs/workflow/testing/libraries/testing-android.md b/docs/workflow/testing/libraries/testing-android.md new file mode 100644 index 0000000000000..4c32cd49279ff --- /dev/null +++ b/docs/workflow/testing/libraries/testing-android.md @@ -0,0 +1,91 @@ +# Testing Libraries on Android + +The following dependencies should be installed in order to be able to run tests: + +- Android NDK +- Android SDK +- OpenJDK +- OpenSSL + +OpenJDK can be installed on Linux (Ubuntu) using `apt-get`: +```bash +sudo apt-get install openjdk-8 unzip +``` + +Android SDK, NDK and OpenSSL can be automatically installed via the following script: +```bash +#!/usr/bin/env bash +set -e + +NDK_VER=r21b +SDK_VER=6200805_latest +SDK_API_LEVEL=29 +SDK_BUILD_TOOLS=29.0.3 +OPENSSL_VER=1.1.1g-alpha-1 + +if [[ "$OSTYPE" == "darwin"* ]]; then + HOST_OS=darwin + HOST_OS_SHORT=mac + BASHRC=~/.zprofile +else + HOST_OS=linux + HOST_OS_SHORT=linux + BASHRC=~/.bashrc +fi + +# download Android NDK +export ANDROID_NDK_ROOT=~/android-ndk-${NDK_VER} +curl https://dl.google.com/android/repository/android-ndk-${NDK_VER}-${HOST_OS}-x86_64.zip -L --output ~/andk.zip +unzip ~/andk.zip -o -d $(dirname ${ANDROID_NDK_ROOT}) && rm -rf ~/andk.zip + +# download Android SDK, accept licenses and download additional packages such as +# platform-tools, platforms and build-tools +export ANDROID_SDK_ROOT=~/android-sdk +curl https://dl.google.com/android/repository/commandlinetools-${HOST_OS_SHORT}-${SDK_VER}.zip -L --output ~/asdk.zip +unzip ~/asdk.zip -o -d ${ANDROID_SDK_ROOT} && rm -rf ~/asdk.zip +yes | ${ANDROID_SDK_ROOT}/tools/bin/./sdkmanager --sdk_root=${ANDROID_SDK_ROOT} --licenses +${ANDROID_SDK_ROOT}/tools/bin/./sdkmanager --sdk_root=${ANDROID_SDK_ROOT} "platform-tools" "platforms;android-${SDK_API_LEVEL}" "build-tools;${SDK_BUILD_TOOLS}" + +# We also need to download precompiled binaries and headers for OpenSSL from maven, this step is a temporary hack +# and will be removed once we figure out how to integrate OpenSSL properly as a dependency +export ANDROID_OPENSSL_AAR=~/openssl-android +curl https://maven.google.com/com/android/ndk/thirdparty/openssl/${OPENSSL_VER}/openssl-${OPENSSL_VER}.aar -L --output ~/openssl.zip +unzip ~/openssl.zip -o -d ${ANDROID_OPENSSL_AAR} && rm -rf ~/openssl.zip +printf "\n\nexport ANDROID_NDK_ROOT=${ANDROID_NDK_ROOT}\nexport ANDROID_SDK_ROOT=${ANDROID_SDK_ROOT}\nexport ANDROID_OPENSSL_AAR=${ANDROID_OPENSSL_AAR}\n" >> ${BASHRC} +``` +Make sure `ANDROID_NDK_ROOT`, `ANDROID_SDK_ROOT` and `ANDROID_OPENSSL_AAR` environment variables are accessible and point to correct locations. + +## Building Libs and Tests for Android + +Now we're ready to build everything for Android: +``` +./build.sh mono+libs -os Android -arch x64 +``` +and even run tests one by one for each library: +``` +./build.sh libs.tests -os Android -arch x64 -test +``` +Make sure an emulator is booted (see `AVD Manager`) or a device is plugged in and unlocked. +`AVD Manager` tool recommends to install `x86` images by default so if you follow that recommendation make sure `-arch x86` was used for the build script. + +### Running individual test suites +The following shows how to run tests for a specific library +``` +./dotnet.sh build /t:Test src/libraries/System.Numerics.Vectors/tests /p:TargetOS=Android /p:TargetArchitecture=x64 +``` + +### Test App Design +Android app is basically a [Java Instrumentation](https://github.com/dotnet/runtime/blob/master/src/mono/msbuild/AndroidAppBuilder/Templates/MonoRunner.java) and a simple Activity that inits the Mono Runtime via JNI. This Mono Runtime starts a simple xunit test +runner called XHarness.TestRunner (see https://github.com/dotnet/xharness) which runs tests for all `*.Tests.dll` libs in the bundle. There is also XHarness.CLI tool with ADB embedded to deploy `*.apk` to a target (device or emulator) and obtain logs once tests are completed. + +### Obtaining the logs +XHarness for Android doesn't talk much and only saves test results to a file. However, you can also subscribe to live logs via the following command: +``` +adb logcat -s "DOTNET" +``` +Or simply open `logcat` window in Android Studio or Visual Stuido. + +### Existing Limitations +- `-os Android` is not supported for Windows yet (`WSL` can be used instead) +- XHarness.CLI is not able to boot emulators yet (so you need to boot via `AVD Manager` or IDE) +- AOT and Interpreter modes are not supported yet \ No newline at end of file diff --git a/docs/workflow/testing/libraries/testing-apple.md b/docs/workflow/testing/libraries/testing-apple.md new file mode 100644 index 0000000000000..3f99570042065 --- /dev/null +++ b/docs/workflow/testing/libraries/testing-apple.md @@ -0,0 +1,32 @@ +# Testing Libraries on iOS and tvOS + +In order to build libraries and tests for iOS or tvOS you need recent version of XCode installed (e.g. 11.3 or higher). + +Build Libraries for iOS: +``` +./build.sh mono+libs -os iOS -arch x64 +``` +Run tests one by one for each test suite on a simulator: +``` +./build.sh libs.tests -os iOS -arch x64 -test +``` +In order to run the tests on a device you need to specify `DevTeamProvisioning` (see [developer.apple.com/account/#/membership](https://developer.apple.com/account/#/membership), scroll down to `Team ID`): +``` +./build.sh libs.tests -os iOS -arch x64 -test /p:DevTeamProvisioning=H1A2B3C4D5 +``` +[AppleAppBuilder](https://github.com/dotnet/runtime/blob/master/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.cs) generates temp Xcode projects you can manually open and resolve provisioning issues there using native UI and deploy to your devices. + +### Running individual test suites +- The following shows how to run tests for a specific library: +``` +./dotnet.sh build src/libraries/System.Numerics.Vectors/tests /t:Test /p:TargetOS=iOS /p:TargetArchitecture=x64 +``` + +### Test App Design +iOS/tvOS `*.app` (or `*.ipa`) is basically a simple [ObjC app](https://github.com/dotnet/runtime/blob/master/src/mono/msbuild/AppleAppBuilder/Templates/main-console.m) that inits the Mono Runtime. This Mono Runtime starts a simple xunit test +runner called XHarness.TestRunner (see https://github.com/dotnet/xharness) which runs tests for all `*.Tests.dll` libs in the bundle. There is also XHarness.CLI tool to deploy `*.app` and `*.ipa` to a target (device or simulator) and listens for logs via network sockets. + +### Existing Limitations +- Most of the test suites crash on devices due to #35674 +- Simulator uses JIT mode only at the moment (to be extended with FullAOT and Interpreter) +- Interpreter is not enabled yet. From e6ed360121d0156b2f3b3cd6754d7cd3ae3e682f Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Fri, 15 May 2020 06:00:19 -0700 Subject: [PATCH 217/420] Update XHarness for latest fixes (#36484) This includes a couple of fixes in xharness. --- .config/dotnet-tools.json | 2 +- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- .../Common/tests/AndroidTestRunner/AndroidTestRunner.cs | 2 -- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 73baf5d1e3a84..fa001915d85d3 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "1.0.0-prerelease.20264.2", + "version": "1.0.0-prerelease.20264.9", "commands": [ "xharness" ] diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 668b9bba02fb9..700894376a9d9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -174,9 +174,9 @@ https://github.com/mono/linker e9f0009b3bd7e42fdc7db6e416b9182828006309 - + https://github.com/dotnet/xharness - c6fd4f291bfc2a8dfb7d46577959e3a9ba0fa132 + bf6773e982acd8a8923b58de140843d9cebc9f69 diff --git a/eng/Versions.props b/eng/Versions.props index 20e000651fb20..512a4c8346da3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -113,7 +113,7 @@ 4.8.0 16.7.0-preview-20200429-01 - 1.0.0-prerelease.20264.1 + 1.0.0-prerelease.20264.9 2.4.1 1.2.1 2.0.5 diff --git a/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs b/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs index cd02378f62542..9f232f549ba92 100644 --- a/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs +++ b/src/libraries/Common/tests/AndroidTestRunner/AndroidTestRunner.cs @@ -92,9 +92,7 @@ protected override IEnumerable GetTestAssemblies() public string? Locale { get; } -#pragma warning disable CS8764 public override TextWriter? Logger => null; -#pragma warning restore CS8764 public override string TestsResultsFinalPath { From 09ca3c54699eeee31f95615dec1840f41e62a767 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Fri, 15 May 2020 14:51:05 +0100 Subject: [PATCH 218/420] order issue template files (#36524) --- .github/ISSUE_TEMPLATE/{bug_report.md => 01_bug_report.md} | 0 .github/ISSUE_TEMPLATE/{api_proposal.md => 02_api_proposal.md} | 0 .../{performance_issue.md => 03_performance_issue.md} | 0 .github/ISSUE_TEMPLATE/{blank.md => 04_blank.md} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{bug_report.md => 01_bug_report.md} (100%) rename .github/ISSUE_TEMPLATE/{api_proposal.md => 02_api_proposal.md} (100%) rename .github/ISSUE_TEMPLATE/{performance_issue.md => 03_performance_issue.md} (100%) rename .github/ISSUE_TEMPLATE/{blank.md => 04_blank.md} (100%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/01_bug_report.md similarity index 100% rename from .github/ISSUE_TEMPLATE/bug_report.md rename to .github/ISSUE_TEMPLATE/01_bug_report.md diff --git a/.github/ISSUE_TEMPLATE/api_proposal.md b/.github/ISSUE_TEMPLATE/02_api_proposal.md similarity index 100% rename from .github/ISSUE_TEMPLATE/api_proposal.md rename to .github/ISSUE_TEMPLATE/02_api_proposal.md diff --git a/.github/ISSUE_TEMPLATE/performance_issue.md b/.github/ISSUE_TEMPLATE/03_performance_issue.md similarity index 100% rename from .github/ISSUE_TEMPLATE/performance_issue.md rename to .github/ISSUE_TEMPLATE/03_performance_issue.md diff --git a/.github/ISSUE_TEMPLATE/blank.md b/.github/ISSUE_TEMPLATE/04_blank.md similarity index 100% rename from .github/ISSUE_TEMPLATE/blank.md rename to .github/ISSUE_TEMPLATE/04_blank.md From ab7597f99166512aa6b1c69872c17f2a914ddc69 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 15 May 2020 09:55:59 -0400 Subject: [PATCH 219/420] Update 02_api_proposal.md --- .github/ISSUE_TEMPLATE/02_api_proposal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/02_api_proposal.md b/.github/ISSUE_TEMPLATE/02_api_proposal.md index 69dd06f60a307..ad7a099166a6d 100644 --- a/.github/ISSUE_TEMPLATE/02_api_proposal.md +++ b/.github/ISSUE_TEMPLATE/02_api_proposal.md @@ -1,6 +1,6 @@ --- name: API Proposal -about: Propose a change to the public API surface. +about: Propose a change to the public API surface title: '' labels: api-suggestion assignees: '' From 923f723fe12fe856d132bb8e20690eb3835ee464 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 15 May 2020 09:56:50 -0400 Subject: [PATCH 220/420] Update 02_api_proposal.md --- .github/ISSUE_TEMPLATE/02_api_proposal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/02_api_proposal.md b/.github/ISSUE_TEMPLATE/02_api_proposal.md index ad7a099166a6d..4ba85d6256ab5 100644 --- a/.github/ISSUE_TEMPLATE/02_api_proposal.md +++ b/.github/ISSUE_TEMPLATE/02_api_proposal.md @@ -1,5 +1,5 @@ --- -name: API Proposal +name: API proposal about: Propose a change to the public API surface title: '' labels: api-suggestion From 7a60a8a7f54c920a9d82e26ae6f92a860459541f Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Fri, 15 May 2020 16:03:20 +0200 Subject: [PATCH 221/420] Consolidate NetCoreAppCurrent properties (#35953) --- eng/Configurations.props | 17 +++++++++++++---- eng/Versions.props | 4 ---- src/installer/Directory.Build.props | 6 ------ src/installer/corehost/build.proj | 2 +- src/installer/pkg/packaging/pack-managed.proj | 2 +- .../pkg/packaging/vs-insertion-packages.proj | 2 +- .../pkg/projects/Directory.Build.props | 8 ++++---- .../netcoreapp/pkg/Directory.Build.props | 6 +++--- .../netcoreapp/pkg/legacy/Directory.Build.props | 4 ++-- .../Microsoft.NETCore.App.Internal.pkgproj | 4 ++-- .../projects/netcoreapp/src/netcoreapp.depproj | 4 ++-- src/installer/publish/Directory.Build.props | 2 +- src/installer/signing/Directory.Build.props | 2 +- .../AppWithSubDirs/AppWithSubDirs.csproj | 2 +- .../TestProjects/AppWithWait/AppWithWait.csproj | 2 +- .../BundleProbeTester/BundleProbeTester.csproj | 2 +- .../TestProjects/ComLibrary/ComLibrary.csproj | 2 +- .../ComLibraryConflictingGuid.csproj | 2 +- .../ComLibraryMissingGuid.csproj | 2 +- .../ComponentWithNoDependencies.csproj | 2 +- .../HostApiInvokerApp/HostApiInvokerApp.csproj | 2 +- .../LightupClient/LightupClient.csproj | 2 +- .../TestProjects/LightupLib/LightupLib.csproj | 2 +- .../LocalizedApp/LocalizedApp.csproj | 2 +- .../TestProjects/PortableApp/PortableApp.csproj | 2 +- .../PortableAppWithException.csproj | 2 +- .../PortableAppWithLongPath.csproj | 2 +- .../PortableAppWithMissingRef.csproj | 2 +- .../SharedLibrary/ReferenceLibrary.csproj | 2 +- .../PortableTestApp/PortableTestApp.csproj | 2 +- .../ResourceLookup/ResourceLookup.csproj | 2 +- .../RuntimeProperties/RuntimeProperties.csproj | 2 +- .../SharedFxLookupPortableApp.csproj | 2 +- .../StandaloneApp/StandaloneApp.csproj | 2 +- .../StandaloneTestApp/StandaloneTestApp.csproj | 2 +- .../TestProjects/StartupHook/StartupHook.csproj | 2 +- .../StartupHookFake/StartupHookFake.csproj | 2 +- .../SharedLibrary/SharedLibrary.csproj | 2 +- .../StartupHookWithAssemblyResolver.csproj | 2 +- .../StartupHookWithDependency.csproj | 2 +- .../StartupHookWithInstanceMethod.csproj | 2 +- ...upHookWithMultipleIncorrectSignatures.csproj | 2 +- .../StartupHookWithNonPublicMethod.csproj | 2 +- .../StartupHookWithOverload.csproj | 2 +- .../StartupHookWithParameter.csproj | 2 +- .../StartupHookWithReturnType.csproj | 2 +- .../StartupHookWithoutInitializeMethod.csproj | 2 +- .../StartupHookWithoutStartupHookType.csproj | 2 +- .../TestWindowsOsShimsApp.csproj | 2 +- .../test/Assets/TestUtils/TestProjects.props | 2 +- .../test/Assets/TestUtils/TestProjects.targets | 8 -------- src/installer/test/Directory.Build.targets | 2 +- .../test/TestUtils/TestProjectFixture.cs | 6 +++--- src/libraries/pretest.proj | 9 ++++----- 54 files changed, 76 insertions(+), 86 deletions(-) diff --git a/eng/Configurations.props b/eng/Configurations.props index 06f1aac30eece..06ee77bbe8d17 100644 --- a/eng/Configurations.props +++ b/eng/Configurations.props @@ -17,11 +17,20 @@ - 5.0 - .NETCoreApp,Version=v$(NETCoreAppCurrentVersion) - net$(NETCoreAppCurrentVersion) - net472 + + 5.0 + .NETCoreApp + $(NetCoreAppCurrentIdentifier),Version=v$(NetCoreAppCurrentVersion) + net$(NetCoreAppCurrentVersion) + + $(NetCoreAppCurrent) Microsoft.NETCore.App + .NET $(NetCoreAppCurrentVersion) + + net472 diff --git a/eng/Versions.props b/eng/Versions.props index 512a4c8346da3..d7de2c44eee7d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -23,10 +23,6 @@ dotnet $(ContainerName) - - $(MajorVersion).$(MinorVersion) - $(MajorVersion).$(MinorVersion) - net$(NETCoreAppFrameworkVersion) true diff --git a/src/installer/corehost/build.proj b/src/installer/corehost/build.proj index 0d6d91ea43e08..79f4c0a5f0e7d 100644 --- a/src/installer/corehost/build.proj +++ b/src/installer/corehost/build.proj @@ -6,7 +6,7 @@ package's targets into the build. --> - $(NETCoreAppFramework) + $(NetCoreAppCurrent) diff --git a/src/installer/pkg/packaging/pack-managed.proj b/src/installer/pkg/packaging/pack-managed.proj index 5db5f08264bdc..acefdfff86d10 100644 --- a/src/installer/pkg/packaging/pack-managed.proj +++ b/src/installer/pkg/packaging/pack-managed.proj @@ -2,7 +2,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) diff --git a/src/installer/pkg/packaging/vs-insertion-packages.proj b/src/installer/pkg/packaging/vs-insertion-packages.proj index f36b24f9d1cac..fd69aea557f75 100644 --- a/src/installer/pkg/packaging/vs-insertion-packages.proj +++ b/src/installer/pkg/packaging/vs-insertion-packages.proj @@ -2,7 +2,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) diff --git a/src/installer/pkg/projects/Directory.Build.props b/src/installer/pkg/projects/Directory.Build.props index 40403c6fcd07f..9d6ae93d467c3 100644 --- a/src/installer/pkg/projects/Directory.Build.props +++ b/src/installer/pkg/projects/Directory.Build.props @@ -81,9 +81,9 @@ null-refs when this isn't set and an analyzer is in the packages --> unused - $(NETCoreAppFrameworkMoniker) - $(NETCoreAppFramework) - $(NETCoreAppFramework) + $(NetCoreAppCurrentTargetFrameworkMoniker) + $(NetCoreAppCurrent) + $(NetCoreAppCurrent) $(CrossGenRootPath)$(MSBuildProjectName)\ true true @@ -92,7 +92,7 @@ $(PackageTargetFramework) - $(NETCoreAppFramework) + $(NetCoreAppCurrent) diff --git a/src/installer/pkg/projects/netcoreapp/pkg/Directory.Build.props b/src/installer/pkg/projects/netcoreapp/pkg/Directory.Build.props index a34488f1be6c3..cad6d6838fc09 100644 --- a/src/installer/pkg/projects/netcoreapp/pkg/Directory.Build.props +++ b/src/installer/pkg/projects/netcoreapp/pkg/Directory.Build.props @@ -6,9 +6,9 @@ - $(NETCoreAppFrameworkBrandName) - $(NETCoreAppFrameworkIdentifier) - $(NETCoreAppFrameworkVersion) + $(NetCoreAppCurrentBrandName) + $(NetCoreAppCurrentIdentifier) + $(NetCoreAppCurrentVersion) $(SharedFrameworkName) diff --git a/src/installer/pkg/projects/netcoreapp/pkg/legacy/Directory.Build.props b/src/installer/pkg/projects/netcoreapp/pkg/legacy/Directory.Build.props index 96a120662af60..03473f6c66f5b 100644 --- a/src/installer/pkg/projects/netcoreapp/pkg/legacy/Directory.Build.props +++ b/src/installer/pkg/projects/netcoreapp/pkg/legacy/Directory.Build.props @@ -3,7 +3,7 @@ true - build/$(NETCoreAppFramework)/ + build/$(NetCoreAppCurrent)/ false @@ -17,7 +17,7 @@ + TargetFramework="$(NetCoreAppCurrent)" /> diff --git a/src/installer/pkg/projects/netcoreapp/pkg/legacy/Microsoft.NETCore.App.Internal.pkgproj b/src/installer/pkg/projects/netcoreapp/pkg/legacy/Microsoft.NETCore.App.Internal.pkgproj index bf4c13e02e050..a46f80401902f 100644 --- a/src/installer/pkg/projects/netcoreapp/pkg/legacy/Microsoft.NETCore.App.Internal.pkgproj +++ b/src/installer/pkg/projects/netcoreapp/pkg/legacy/Microsoft.NETCore.App.Internal.pkgproj @@ -20,8 +20,8 @@ - - + + diff --git a/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj b/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj index 4431cd576f29f..339c8a26e3065 100644 --- a/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj +++ b/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj @@ -99,12 +99,12 @@ - + - + diff --git a/src/installer/publish/Directory.Build.props b/src/installer/publish/Directory.Build.props index adae9ea9ed0af..de832e525302d 100644 --- a/src/installer/publish/Directory.Build.props +++ b/src/installer/publish/Directory.Build.props @@ -3,7 +3,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) diff --git a/src/installer/signing/Directory.Build.props b/src/installer/signing/Directory.Build.props index 8fcaf35bd68f9..7c45d0300be12 100644 --- a/src/installer/signing/Directory.Build.props +++ b/src/installer/signing/Directory.Build.props @@ -3,7 +3,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) true diff --git a/src/installer/test/Assets/TestProjects/AppWithSubDirs/AppWithSubDirs.csproj b/src/installer/test/Assets/TestProjects/AppWithSubDirs/AppWithSubDirs.csproj index d00c71f748e6a..92aed3cea064c 100644 --- a/src/installer/test/Assets/TestProjects/AppWithSubDirs/AppWithSubDirs.csproj +++ b/src/installer/test/Assets/TestProjects/AppWithSubDirs/AppWithSubDirs.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(TestTargetRid) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/AppWithWait/AppWithWait.csproj b/src/installer/test/Assets/TestProjects/AppWithWait/AppWithWait.csproj index 748e7abb2bd90..fd506fea04cc0 100644 --- a/src/installer/test/Assets/TestProjects/AppWithWait/AppWithWait.csproj +++ b/src/installer/test/Assets/TestProjects/AppWithWait/AppWithWait.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(TestTargetRid) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/BundleProbeTester/BundleProbeTester.csproj b/src/installer/test/Assets/TestProjects/BundleProbeTester/BundleProbeTester.csproj index d563f340bf216..d23f7ab1bd114 100644 --- a/src/installer/test/Assets/TestProjects/BundleProbeTester/BundleProbeTester.csproj +++ b/src/installer/test/Assets/TestProjects/BundleProbeTester/BundleProbeTester.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(TestTargetRid) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/ComLibrary/ComLibrary.csproj b/src/installer/test/Assets/TestProjects/ComLibrary/ComLibrary.csproj index 07612ef9143b4..637cbf46c656d 100644 --- a/src/installer/test/Assets/TestProjects/ComLibrary/ComLibrary.csproj +++ b/src/installer/test/Assets/TestProjects/ComLibrary/ComLibrary.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/ComLibraryConflictingGuid/ComLibraryConflictingGuid.csproj b/src/installer/test/Assets/TestProjects/ComLibraryConflictingGuid/ComLibraryConflictingGuid.csproj index 07612ef9143b4..637cbf46c656d 100644 --- a/src/installer/test/Assets/TestProjects/ComLibraryConflictingGuid/ComLibraryConflictingGuid.csproj +++ b/src/installer/test/Assets/TestProjects/ComLibraryConflictingGuid/ComLibraryConflictingGuid.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/ComLibraryMissingGuid/ComLibraryMissingGuid.csproj b/src/installer/test/Assets/TestProjects/ComLibraryMissingGuid/ComLibraryMissingGuid.csproj index 07612ef9143b4..637cbf46c656d 100644 --- a/src/installer/test/Assets/TestProjects/ComLibraryMissingGuid/ComLibraryMissingGuid.csproj +++ b/src/installer/test/Assets/TestProjects/ComLibraryMissingGuid/ComLibraryMissingGuid.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/ComponentWithNoDependencies/ComponentWithNoDependencies.csproj b/src/installer/test/Assets/TestProjects/ComponentWithNoDependencies/ComponentWithNoDependencies.csproj index 9ca49040cf1d9..27861faa61056 100644 --- a/src/installer/test/Assets/TestProjects/ComponentWithNoDependencies/ComponentWithNoDependencies.csproj +++ b/src/installer/test/Assets/TestProjects/ComponentWithNoDependencies/ComponentWithNoDependencies.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) true diff --git a/src/installer/test/Assets/TestProjects/HostApiInvokerApp/HostApiInvokerApp.csproj b/src/installer/test/Assets/TestProjects/HostApiInvokerApp/HostApiInvokerApp.csproj index 1f7b037304bae..570b3efa794ed 100644 --- a/src/installer/test/Assets/TestProjects/HostApiInvokerApp/HostApiInvokerApp.csproj +++ b/src/installer/test/Assets/TestProjects/HostApiInvokerApp/HostApiInvokerApp.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(MNAVersion) WINDOWS;$(DefineConstants) diff --git a/src/installer/test/Assets/TestProjects/LightupClient/LightupClient.csproj b/src/installer/test/Assets/TestProjects/LightupClient/LightupClient.csproj index 01dead620aa25..f413febe3ff59 100644 --- a/src/installer/test/Assets/TestProjects/LightupClient/LightupClient.csproj +++ b/src/installer/test/Assets/TestProjects/LightupClient/LightupClient.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/LightupLib/LightupLib.csproj b/src/installer/test/Assets/TestProjects/LightupLib/LightupLib.csproj index a6203fb4db502..e7fb1c6a06540 100644 --- a/src/installer/test/Assets/TestProjects/LightupLib/LightupLib.csproj +++ b/src/installer/test/Assets/TestProjects/LightupLib/LightupLib.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Library $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/LocalizedApp/LocalizedApp.csproj b/src/installer/test/Assets/TestProjects/LocalizedApp/LocalizedApp.csproj index eab506148b873..dd7e2b67f9d89 100644 --- a/src/installer/test/Assets/TestProjects/LocalizedApp/LocalizedApp.csproj +++ b/src/installer/test/Assets/TestProjects/LocalizedApp/LocalizedApp.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(TestTargetRid) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/PortableApp/PortableApp.csproj b/src/installer/test/Assets/TestProjects/PortableApp/PortableApp.csproj index f4c6cb42db33c..0a72b6bc1fcd7 100644 --- a/src/installer/test/Assets/TestProjects/PortableApp/PortableApp.csproj +++ b/src/installer/test/Assets/TestProjects/PortableApp/PortableApp.csproj @@ -3,7 +3,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/PortableAppWithException/PortableAppWithException.csproj b/src/installer/test/Assets/TestProjects/PortableAppWithException/PortableAppWithException.csproj index 01dead620aa25..f413febe3ff59 100644 --- a/src/installer/test/Assets/TestProjects/PortableAppWithException/PortableAppWithException.csproj +++ b/src/installer/test/Assets/TestProjects/PortableAppWithException/PortableAppWithException.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/PortableAppWithLongPath/PortableAppWithLongPath.csproj b/src/installer/test/Assets/TestProjects/PortableAppWithLongPath/PortableAppWithLongPath.csproj index 01dead620aa25..f413febe3ff59 100644 --- a/src/installer/test/Assets/TestProjects/PortableAppWithLongPath/PortableAppWithLongPath.csproj +++ b/src/installer/test/Assets/TestProjects/PortableAppWithLongPath/PortableAppWithLongPath.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/PortableAppWithMissingRef/PortableAppWithMissingRef.csproj b/src/installer/test/Assets/TestProjects/PortableAppWithMissingRef/PortableAppWithMissingRef.csproj index dc7dc9d7f5b55..17d3f0556923d 100644 --- a/src/installer/test/Assets/TestProjects/PortableAppWithMissingRef/PortableAppWithMissingRef.csproj +++ b/src/installer/test/Assets/TestProjects/PortableAppWithMissingRef/PortableAppWithMissingRef.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(MNAVersion) false diff --git a/src/installer/test/Assets/TestProjects/PortableAppWithMissingRef/SharedLibrary/ReferenceLibrary.csproj b/src/installer/test/Assets/TestProjects/PortableAppWithMissingRef/SharedLibrary/ReferenceLibrary.csproj index 427e95cc1ac3a..715eb5425edb0 100644 --- a/src/installer/test/Assets/TestProjects/PortableAppWithMissingRef/SharedLibrary/ReferenceLibrary.csproj +++ b/src/installer/test/Assets/TestProjects/PortableAppWithMissingRef/SharedLibrary/ReferenceLibrary.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Library $(MNAVersion) SharedLibrary diff --git a/src/installer/test/Assets/TestProjects/PortableTestApp/PortableTestApp.csproj b/src/installer/test/Assets/TestProjects/PortableTestApp/PortableTestApp.csproj index 59707bcaccb06..26b183bbec085 100644 --- a/src/installer/test/Assets/TestProjects/PortableTestApp/PortableTestApp.csproj +++ b/src/installer/test/Assets/TestProjects/PortableTestApp/PortableTestApp.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) true $(PackageTargetFallback);dotnet5.4;portable-net451+win8 $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/ResourceLookup/ResourceLookup.csproj b/src/installer/test/Assets/TestProjects/ResourceLookup/ResourceLookup.csproj index 0f3bd67c8b599..50e675ffb951f 100644 --- a/src/installer/test/Assets/TestProjects/ResourceLookup/ResourceLookup.csproj +++ b/src/installer/test/Assets/TestProjects/ResourceLookup/ResourceLookup.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/RuntimeProperties/RuntimeProperties.csproj b/src/installer/test/Assets/TestProjects/RuntimeProperties/RuntimeProperties.csproj index 01dead620aa25..f413febe3ff59 100644 --- a/src/installer/test/Assets/TestProjects/RuntimeProperties/RuntimeProperties.csproj +++ b/src/installer/test/Assets/TestProjects/RuntimeProperties/RuntimeProperties.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/SharedFxLookupPortableApp/SharedFxLookupPortableApp.csproj b/src/installer/test/Assets/TestProjects/SharedFxLookupPortableApp/SharedFxLookupPortableApp.csproj index b75d06cf66130..e1f97d2216d9a 100644 --- a/src/installer/test/Assets/TestProjects/SharedFxLookupPortableApp/SharedFxLookupPortableApp.csproj +++ b/src/installer/test/Assets/TestProjects/SharedFxLookupPortableApp/SharedFxLookupPortableApp.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/StandaloneApp/StandaloneApp.csproj b/src/installer/test/Assets/TestProjects/StandaloneApp/StandaloneApp.csproj index 5d5fdfaf636ca..0846750fb7c91 100644 --- a/src/installer/test/Assets/TestProjects/StandaloneApp/StandaloneApp.csproj +++ b/src/installer/test/Assets/TestProjects/StandaloneApp/StandaloneApp.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe $(TestTargetRid) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/StandaloneTestApp/StandaloneTestApp.csproj b/src/installer/test/Assets/TestProjects/StandaloneTestApp/StandaloneTestApp.csproj index 2c18ac635b713..42bc4348e5d5b 100644 --- a/src/installer/test/Assets/TestProjects/StandaloneTestApp/StandaloneTestApp.csproj +++ b/src/installer/test/Assets/TestProjects/StandaloneTestApp/StandaloneTestApp.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Exe true $(PackageTargetFallback);dotnet5.4;portable-net451+win8 diff --git a/src/installer/test/Assets/TestProjects/StartupHook/StartupHook.csproj b/src/installer/test/Assets/TestProjects/StartupHook/StartupHook.csproj index 07612ef9143b4..637cbf46c656d 100644 --- a/src/installer/test/Assets/TestProjects/StartupHook/StartupHook.csproj +++ b/src/installer/test/Assets/TestProjects/StartupHook/StartupHook.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/StartupHookFake/StartupHookFake.csproj b/src/installer/test/Assets/TestProjects/StartupHookFake/StartupHookFake.csproj index 30c7a27baa05c..f55862545f6a5 100644 --- a/src/installer/test/Assets/TestProjects/StartupHookFake/StartupHookFake.csproj +++ b/src/installer/test/Assets/TestProjects/StartupHookFake/StartupHookFake.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/StartupHookWithAssemblyResolver/SharedLibrary/SharedLibrary.csproj b/src/installer/test/Assets/TestProjects/StartupHookWithAssemblyResolver/SharedLibrary/SharedLibrary.csproj index 2affa7647bebe..6c0a57b1b0b8a 100644 --- a/src/installer/test/Assets/TestProjects/StartupHookWithAssemblyResolver/SharedLibrary/SharedLibrary.csproj +++ b/src/installer/test/Assets/TestProjects/StartupHookWithAssemblyResolver/SharedLibrary/SharedLibrary.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) Library $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/StartupHookWithAssemblyResolver/StartupHookWithAssemblyResolver.csproj b/src/installer/test/Assets/TestProjects/StartupHookWithAssemblyResolver/StartupHookWithAssemblyResolver.csproj index 3fe787852504b..e15ced0349c71 100644 --- a/src/installer/test/Assets/TestProjects/StartupHookWithAssemblyResolver/StartupHookWithAssemblyResolver.csproj +++ b/src/installer/test/Assets/TestProjects/StartupHookWithAssemblyResolver/StartupHookWithAssemblyResolver.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) false diff --git a/src/installer/test/Assets/TestProjects/StartupHookWithDependency/StartupHookWithDependency.csproj b/src/installer/test/Assets/TestProjects/StartupHookWithDependency/StartupHookWithDependency.csproj index 8726c60e29aa5..cc51ff2471c3e 100644 --- a/src/installer/test/Assets/TestProjects/StartupHookWithDependency/StartupHookWithDependency.csproj +++ b/src/installer/test/Assets/TestProjects/StartupHookWithDependency/StartupHookWithDependency.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/StartupHookWithInstanceMethod/StartupHookWithInstanceMethod.csproj b/src/installer/test/Assets/TestProjects/StartupHookWithInstanceMethod/StartupHookWithInstanceMethod.csproj index 07612ef9143b4..637cbf46c656d 100644 --- a/src/installer/test/Assets/TestProjects/StartupHookWithInstanceMethod/StartupHookWithInstanceMethod.csproj +++ b/src/installer/test/Assets/TestProjects/StartupHookWithInstanceMethod/StartupHookWithInstanceMethod.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/StartupHookWithMultipleIncorrectSignatures/StartupHookWithMultipleIncorrectSignatures.csproj b/src/installer/test/Assets/TestProjects/StartupHookWithMultipleIncorrectSignatures/StartupHookWithMultipleIncorrectSignatures.csproj index 07612ef9143b4..637cbf46c656d 100644 --- a/src/installer/test/Assets/TestProjects/StartupHookWithMultipleIncorrectSignatures/StartupHookWithMultipleIncorrectSignatures.csproj +++ b/src/installer/test/Assets/TestProjects/StartupHookWithMultipleIncorrectSignatures/StartupHookWithMultipleIncorrectSignatures.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/StartupHookWithNonPublicMethod/StartupHookWithNonPublicMethod.csproj b/src/installer/test/Assets/TestProjects/StartupHookWithNonPublicMethod/StartupHookWithNonPublicMethod.csproj index 07612ef9143b4..637cbf46c656d 100644 --- a/src/installer/test/Assets/TestProjects/StartupHookWithNonPublicMethod/StartupHookWithNonPublicMethod.csproj +++ b/src/installer/test/Assets/TestProjects/StartupHookWithNonPublicMethod/StartupHookWithNonPublicMethod.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/StartupHookWithOverload/StartupHookWithOverload.csproj b/src/installer/test/Assets/TestProjects/StartupHookWithOverload/StartupHookWithOverload.csproj index 07612ef9143b4..637cbf46c656d 100644 --- a/src/installer/test/Assets/TestProjects/StartupHookWithOverload/StartupHookWithOverload.csproj +++ b/src/installer/test/Assets/TestProjects/StartupHookWithOverload/StartupHookWithOverload.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/StartupHookWithParameter/StartupHookWithParameter.csproj b/src/installer/test/Assets/TestProjects/StartupHookWithParameter/StartupHookWithParameter.csproj index 07612ef9143b4..637cbf46c656d 100644 --- a/src/installer/test/Assets/TestProjects/StartupHookWithParameter/StartupHookWithParameter.csproj +++ b/src/installer/test/Assets/TestProjects/StartupHookWithParameter/StartupHookWithParameter.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/StartupHookWithReturnType/StartupHookWithReturnType.csproj b/src/installer/test/Assets/TestProjects/StartupHookWithReturnType/StartupHookWithReturnType.csproj index 07612ef9143b4..637cbf46c656d 100644 --- a/src/installer/test/Assets/TestProjects/StartupHookWithReturnType/StartupHookWithReturnType.csproj +++ b/src/installer/test/Assets/TestProjects/StartupHookWithReturnType/StartupHookWithReturnType.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/StartupHookWithoutInitializeMethod/StartupHookWithoutInitializeMethod.csproj b/src/installer/test/Assets/TestProjects/StartupHookWithoutInitializeMethod/StartupHookWithoutInitializeMethod.csproj index 07612ef9143b4..637cbf46c656d 100644 --- a/src/installer/test/Assets/TestProjects/StartupHookWithoutInitializeMethod/StartupHookWithoutInitializeMethod.csproj +++ b/src/installer/test/Assets/TestProjects/StartupHookWithoutInitializeMethod/StartupHookWithoutInitializeMethod.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/StartupHookWithoutStartupHookType/StartupHookWithoutStartupHookType.csproj b/src/installer/test/Assets/TestProjects/StartupHookWithoutStartupHookType/StartupHookWithoutStartupHookType.csproj index 07612ef9143b4..637cbf46c656d 100644 --- a/src/installer/test/Assets/TestProjects/StartupHookWithoutStartupHookType/StartupHookWithoutStartupHookType.csproj +++ b/src/installer/test/Assets/TestProjects/StartupHookWithoutStartupHookType/StartupHookWithoutStartupHookType.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(MNAVersion) diff --git a/src/installer/test/Assets/TestProjects/TestWindowsOsShimsApp/TestWindowsOsShimsApp.csproj b/src/installer/test/Assets/TestProjects/TestWindowsOsShimsApp/TestWindowsOsShimsApp.csproj index 0ca22a9e2952e..adda104a389e2 100644 --- a/src/installer/test/Assets/TestProjects/TestWindowsOsShimsApp/TestWindowsOsShimsApp.csproj +++ b/src/installer/test/Assets/TestProjects/TestWindowsOsShimsApp/TestWindowsOsShimsApp.csproj @@ -1,7 +1,7 @@ - $(NETCoreAppFramework) + $(NetCoreAppCurrent) $(TestTargetRid) Exe $(MNAVersion) diff --git a/src/installer/test/Assets/TestUtils/TestProjects.props b/src/installer/test/Assets/TestUtils/TestProjects.props index 97993c19cf977..46ff750035765 100644 --- a/src/installer/test/Assets/TestUtils/TestProjects.props +++ b/src/installer/test/Assets/TestUtils/TestProjects.props @@ -6,7 +6,7 @@ in a different manner than using the $(RepositoryEngineeringDir) variable. --> - + diff --git a/src/installer/test/Assets/TestUtils/TestProjects.targets b/src/installer/test/Assets/TestUtils/TestProjects.targets index 1ee0e9450058d..32180ba2f700d 100644 --- a/src/installer/test/Assets/TestUtils/TestProjects.targets +++ b/src/installer/test/Assets/TestUtils/TestProjects.targets @@ -4,12 +4,4 @@ provides basic info needed for restore and build with the vanilla SDK. --> - - - $(MajorVersion).$(MinorVersion) - - diff --git a/src/installer/test/Directory.Build.targets b/src/installer/test/Directory.Build.targets index 82a7c6d4e6010..7d93a09399835 100644 --- a/src/installer/test/Directory.Build.targets +++ b/src/installer/test/Directory.Build.targets @@ -81,7 +81,7 @@ - + diff --git a/src/installer/test/TestUtils/TestProjectFixture.cs b/src/installer/test/TestUtils/TestProjectFixture.cs index b1a67453d716d..5ab37de8f80ff 100644 --- a/src/installer/test/TestUtils/TestProjectFixture.cs +++ b/src/installer/test/TestUtils/TestProjectFixture.cs @@ -233,7 +233,7 @@ private void ValidateRequiredDirectories(RepoDirectoriesProvider repoDirectories } storeArgs.Add($"/p:MNAVersion={RepoDirProvider.MicrosoftNETCoreAppVersion}"); - storeArgs.Add($"/p:NETCoreAppFramework={Framework}"); + storeArgs.Add($"/p:NetCoreAppCurrent={Framework}"); // Ensure the project's OutputType isn't 'Exe', since that causes issues with 'dotnet store' storeArgs.Add("/p:OutputType=Library"); @@ -286,7 +286,7 @@ private void ValidateRequiredDirectories(RepoDirectoriesProvider repoDirectories { publishArgs.Add("--framework"); publishArgs.Add(framework); - publishArgs.Add($"/p:NETCoreAppFramework={framework}"); + publishArgs.Add($"/p:NetCoreAppCurrent={framework}"); } if (selfContained != null) @@ -333,7 +333,7 @@ public TestProjectFixture RestoreProject(string[] fallbackSources, string extraM restoreArgs.Add("--disable-parallel"); restoreArgs.Add($"/p:MNAVersion={RepoDirProvider.MicrosoftNETCoreAppVersion}"); - restoreArgs.Add($"/p:NETCoreAppFramework={Framework}"); + restoreArgs.Add($"/p:NetCoreAppCurrent={Framework}"); if (extraMSBuildProperties != null) { diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj index 860998494f56e..94141031b8b85 100644 --- a/src/libraries/pretest.proj +++ b/src/libraries/pretest.proj @@ -3,7 +3,6 @@ BuildAllProjects=true - $(TargetFrameworkIdentifier) @@ -86,7 +85,7 @@ <_runtimePackLibFiles Include="$(RuntimePackLibDir)*.*"> - $(RuntimePackTargetFrameworkPath)/lib/$(NETCoreAppFramework) + $(RuntimePackTargetFrameworkPath)/lib/$(NetCoreAppCurrent) true <_runtimePackNativeFiles Include="$(RuntimePackNativeDir)*.*"> @@ -94,9 +93,9 @@ true - - - + + + From c2449c6acb76ca9b86eca0cb91af66ec2c6961e7 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Fri, 15 May 2020 15:29:56 +0100 Subject: [PATCH 222/420] Rename 'Blank' issue template to 'Blank issue' (#36533) * Update and rename 04_blank.md to 04_blank_issue.md * Use consistent casing --- .github/ISSUE_TEMPLATE/{04_blank.md => 04_blank_issue.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/ISSUE_TEMPLATE/{04_blank.md => 04_blank_issue.md} (84%) diff --git a/.github/ISSUE_TEMPLATE/04_blank.md b/.github/ISSUE_TEMPLATE/04_blank_issue.md similarity index 84% rename from .github/ISSUE_TEMPLATE/04_blank.md rename to .github/ISSUE_TEMPLATE/04_blank_issue.md index 0e3e133dcb9b8..d1429bfd4c1d9 100644 --- a/.github/ISSUE_TEMPLATE/04_blank.md +++ b/.github/ISSUE_TEMPLATE/04_blank_issue.md @@ -1,5 +1,5 @@ --- -name: Blank +name: Blank issue about: Something that doesn't fit the other categories title: '' labels: '' From c34055097b7845b0ccc9f1bfdcf4be27744f9882 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Fri, 15 May 2020 16:45:36 +0200 Subject: [PATCH 223/420] Ignore .github folder changes in CI (#36530) --- eng/pipelines/coreclr/ci.yml | 1 + eng/pipelines/coreclr/perf.yml | 1 + eng/pipelines/global-build.yml | 1 + eng/pipelines/runtime-official.yml | 1 + eng/pipelines/runtime.yml | 2 ++ 5 files changed, 6 insertions(+) diff --git a/eng/pipelines/coreclr/ci.yml b/eng/pipelines/coreclr/ci.yml index 4982ffd0018bd..ec43000725840 100644 --- a/eng/pipelines/coreclr/ci.yml +++ b/eng/pipelines/coreclr/ci.yml @@ -8,6 +8,7 @@ trigger: - '*' - src/libraries/System.Private.CoreLib/* exclude: + - .github/* - docs/* - CODE-OF-CONDUCT.md - CONTRIBUTING.md diff --git a/eng/pipelines/coreclr/perf.yml b/eng/pipelines/coreclr/perf.yml index 952fab6827849..d2ed639d434bd 100644 --- a/eng/pipelines/coreclr/perf.yml +++ b/eng/pipelines/coreclr/perf.yml @@ -8,6 +8,7 @@ trigger: - '*' - src/libraries/System.Private.CoreLib/* exclude: + - .github/* - docs/* - CODE-OF-CONDUCT.md - CONTRIBUTING.md diff --git a/eng/pipelines/global-build.yml b/eng/pipelines/global-build.yml index 8006c888ee00c..0c75cd5020622 100644 --- a/eng/pipelines/global-build.yml +++ b/eng/pipelines/global-build.yml @@ -15,6 +15,7 @@ pr: - docs/manpages/* - eng/pipelines/global-build.yml exclude: + - .github/* - docs/* - eng/pipelines/coreclr/*.* - eng/pipelines/libraries/*.* diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index 107f8e34da0bd..cb8388d654679 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -9,6 +9,7 @@ trigger: - '*' - docs/manpages/* exclude: + - .github/* - docs/* - CODE-OF-CONDUCT.md - CONTRIBUTING.md diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index d63762c70c50e..0a9e05f94a6cb 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -15,6 +15,7 @@ trigger: - docs/manpages/* exclude: - eng/Version.Details.xml + - .github/* - docs/* - CODE-OF-CONDUCT.md - CONTRIBUTING.md @@ -36,6 +37,7 @@ pr: - docs/manpages/* exclude: - eng/Version.Details.xml + - .github/* - docs/* - CODE-OF-CONDUCT.md - CONTRIBUTING.md From d3e3fe5d331050360126caf65ee462f2584492c8 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 15 May 2020 10:48:15 -0400 Subject: [PATCH 224/420] Clean up text in config.yml issue template (#36529) --- .github/ISSUE_TEMPLATE/config.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 4b38bcf921191..54d8c5740bad6 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,19 +2,19 @@ blank_issues_enabled: true contact_links: - name: Issue with ASP.NET Core url: https://github.com/dotnet/aspnetcore/issues/new/choose - about: Please open issues with ASP.NET Core in their repo - - name: Issue with .NET Core SDK + about: Please open issues relating to ASP.NET Core in dotnet/aspnetcore. + - name: Issue with .NET SDK url: https://github.com/dotnet/sdk/issues/new/choose - about: Please open issues with the .NET Core SDK in their repo + about: Please open issues relating to the .NET SDK in dotnet/sdk. - name: Issue with Entity Framework url: https://github.com/dotnet/efcore/issues/new/choose - about: Please open issues with Entity Framework in their repo + about: Please open issues relating to Entity Framework in dotnet/efcore. - name: Issue with Roslyn compiler url: https://github.com/dotnet/roslyn/issues/new/choose - about: Please open issues with the Roslyn compiler in their repo + about: Please open issues relating to the Roslyn .NET compiler in dotnet/roslyn. - name: Issue with Windows Forms url: https://github.com/dotnet/winforms/issues/new/choose - about: Please open issues with Windows Forms in their repo + about: Please open issues relating to Windows Forms in dotnet/winforms. - name: Issue with WPF url: https://github.com/dotnet/wpf/issues/new/choose - about: Please open issues with WPF in their repo + about: Please open issues relating to WPF in dotnet/wpf. From 592a1e61af160f383859f1a46c63649cc71a8274 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 15 May 2020 08:48:59 -0700 Subject: [PATCH 225/420] Convert Extract(0) to ToScalar() (#36474) * Convert Extract(0) to ToScalar() * Update the shim --- .../src/System/Numerics/BitOperations.cs | 4 ++-- .../src/System/Runtime/Intrinsics/Intrinsics.Shims.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs index fe457200e960d..0847f377e0c98 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs @@ -254,7 +254,7 @@ public static int PopCount(uint value) // Hence use Vector64.Create(ulong) to create Vector64 and operate on that. Vector64 input = Vector64.Create((ulong)value); Vector64 aggregated = AdvSimd.Arm64.AddAcross(AdvSimd.PopCount(input.AsByte())); - return AdvSimd.Extract(aggregated, 0); + return aggregated.ToScalar(); } return SoftwareFallback(value); @@ -293,7 +293,7 @@ public static int PopCount(ulong value) // PopCount works on vector so convert input value to vector first. Vector64 input = Vector64.Create(value); Vector64 aggregated = AdvSimd.Arm64.AddAcross(AdvSimd.PopCount(input.AsByte())); - return AdvSimd.Extract(aggregated, 0); + return aggregated.ToScalar(); } #if TARGET_32BIT diff --git a/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs b/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs index e1654081c7766..38e129a08022c 100644 --- a/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs +++ b/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs @@ -25,6 +25,7 @@ internal static class Vector128 public static Vector128 AsUInt32(this Vector128 vector) where T : struct => throw new PlatformNotSupportedException(); public static Vector128 AsUInt64(this Vector128 vector) where T : struct => throw new PlatformNotSupportedException(); public static T GetElement(this Vector128 vector, int index) where T : struct => throw new PlatformNotSupportedException(); + public static T ToScalar(this Vector64 vector) where T : struct => throw new PlatformNotSupportedException(); } internal readonly struct Vector128 where T : struct @@ -147,7 +148,6 @@ public new abstract class Arm64 : ArmBase.Arm64 { public static Vector64 AddAcross(Vector64 value) => throw new PlatformNotSupportedException(); } - public static byte Extract(Vector64 vector, byte index) => throw new PlatformNotSupportedException(); public static Vector64 PopCount(Vector64 value) => throw new PlatformNotSupportedException(); } } From b6ef0a54ad0dbe016ec63850e3a70bfacb9bde09 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Fri, 15 May 2020 13:36:11 -0400 Subject: [PATCH 226/420] Move mobile AppBuilder & AOTCompiler projects into tools-local (#36478) Moving the projects will make sure their artifacts are always available to the different CI legs. --- Build.proj | 41 ++-------------- Directory.Build.props | 10 ++++ eng/testing/tests.mobile.targets | 14 +++--- eng/testing/tests.props | 5 -- src/mono/Directory.Build.props | 10 ++-- src/mono/mono.proj | 20 +------- src/mono/netcore/sample/Android/Makefile | 5 +- .../netcore/sample/Android/Program.csproj | 3 +- src/mono/netcore/sample/iOS/Makefile | 7 +-- src/mono/netcore/sample/iOS/Program.csproj | 8 ++-- .../AndroidAppBuilder/AndroidAppBuilder.cs | 0 .../AndroidAppBuilder.csproj | 2 + .../AndroidAppBuilder/ApkBuilder.cs | 0 .../Templates/AndroidManifest.xml | 0 .../Templates/CMakeLists-android.txt | 0 .../Templates/MainActivity.java | 0 .../Templates/MonoRunner.java | 0 .../Templates/runtime-android.c | 0 .../mobile.tasks}/AndroidAppBuilder/Utils.cs | 0 .../AotCompilerTask/MonoAOTCompiler.cs | 0 .../AotCompilerTask/MonoAOTCompiler.csproj | 7 +++ .../AotCompilerTask/MonoAOTCompiler.props | 0 .../mobile.tasks}/AotCompilerTask/Utils.cs | 0 .../AppleAppBuilder/AppleAppBuilder.cs | 0 .../AppleAppBuilder/AppleAppBuilder.csproj | 2 + .../Templates/CMakeLists.txt.template | 0 .../Templates/Info.plist.template | 0 .../AppleAppBuilder/Templates/main-console.m | 0 .../AppleAppBuilder/Templates/main-simple.m | 0 .../AppleAppBuilder/Templates/runtime.h | 0 .../AppleAppBuilder/Templates/runtime.m | 0 .../mobile.tasks}/AppleAppBuilder/Utils.cs | 0 .../mobile.tasks}/AppleAppBuilder/Xcode.cs | 0 tools-local/tasks/tasks.proj | 48 +++++++++++++++++++ 34 files changed, 97 insertions(+), 85 deletions(-) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AndroidAppBuilder/AndroidAppBuilder.cs (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AndroidAppBuilder/AndroidAppBuilder.csproj (90%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AndroidAppBuilder/ApkBuilder.cs (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AndroidAppBuilder/Templates/AndroidManifest.xml (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AndroidAppBuilder/Templates/CMakeLists-android.txt (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AndroidAppBuilder/Templates/MainActivity.java (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AndroidAppBuilder/Templates/MonoRunner.java (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AndroidAppBuilder/Templates/runtime-android.c (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AndroidAppBuilder/Utils.cs (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AotCompilerTask/MonoAOTCompiler.cs (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AotCompilerTask/MonoAOTCompiler.csproj (76%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AotCompilerTask/MonoAOTCompiler.props (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AotCompilerTask/Utils.cs (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AppleAppBuilder/AppleAppBuilder.cs (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AppleAppBuilder/AppleAppBuilder.csproj (90%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AppleAppBuilder/Templates/CMakeLists.txt.template (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AppleAppBuilder/Templates/Info.plist.template (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AppleAppBuilder/Templates/main-console.m (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AppleAppBuilder/Templates/main-simple.m (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AppleAppBuilder/Templates/runtime.h (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AppleAppBuilder/Templates/runtime.m (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AppleAppBuilder/Utils.cs (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/AppleAppBuilder/Xcode.cs (100%) create mode 100644 tools-local/tasks/tasks.proj diff --git a/Build.proj b/Build.proj index ef12cca9de1cc..dc4a15ab5f413 100644 --- a/Build.proj +++ b/Build.proj @@ -27,43 +27,10 @@ - - - - - - - - - - - - - - - - $(RepoTasksDir) - $(ArtifactsObjDir)runtime.tasks\Debug\build-semaphore.txt - - - - - + + $([MSBuild]::NormalizeDirectory('$(LibrariesProjectRoot)', 'System.Private.CoreLib', 'src')) + + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder', 'Debug', '$(NetCoreAppCurrent)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', 'Debug', '$(NetCoreAppCurrent)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'MonoAOTCompiler', 'Debug', '$(NetCoreAppCurrent)')) + + $([MSBuild]::NormalizePath('$(AppleAppBuilderDir)', 'AppleAppBuilder.dll')) + $([MSBuild]::NormalizePath('$(AndroidAppBuilderDir)', 'AndroidAppBuilder.dll')) + $([MSBuild]::NormalizePath('$(MonoAOTCompilerDir)', 'MonoAOTCompiler.dll')) + + - + @@ -48,12 +49,13 @@ - + + AssemblyFile="$(MonoAOTCompilerTasksAssemblyPath)" /> - + diff --git a/eng/testing/tests.props b/eng/testing/tests.props index 6a35aef60eba0..9b7bc1d270ee7 100644 --- a/eng/testing/tests.props +++ b/eng/testing/tests.props @@ -21,11 +21,6 @@ - $(NetCoreAppCurrent)-$(MonoConfiguration) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder', '$(MobileHelperTasksDirSuffix)')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', '$(MobileHelperTasksDirSuffix)')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'MonoAOTCompiler', '$(MobileHelperTasksDirSuffix)')) - $(NetCoreAppCurrent)-$(Configuration) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleTestRunner', '$(MobileRunnersDirSuffix)')) diff --git a/src/mono/Directory.Build.props b/src/mono/Directory.Build.props index aa7e500eb75a6..a17c7ae918729 100644 --- a/src/mono/Directory.Build.props +++ b/src/mono/Directory.Build.props @@ -104,10 +104,10 @@ - $([MSBuild]::NormalizeDirectory('$(MonoProjectRoot)', 'msbuild', 'AppleAppBuilder')) - $([MSBuild]::NormalizeDirectory('$(MonoProjectRoot)', 'msbuild', 'AppleTestRunner')) - $([MSBuild]::NormalizeDirectory('$(MonoProjectRoot)', 'msbuild', 'AndroidAppBuilder')) - $([MSBuild]::NormalizeDirectory('$(MonoProjectRoot)', 'msbuild', 'AndroidTestRunner')) - $([MSBuild]::NormalizeDirectory('$(MonoProjectRoot)', 'msbuild', 'AotCompilerTask')) + $([MSBuild]::NormalizeDirectory('$(RepoTasksDir)', 'mobile.tasks', 'AppleAppBuilder')) + $([MSBuild]::NormalizeDirectory('$(LibrariesProjectRoot)', 'Common', tests, 'AppleTestRunner')) + $([MSBuild]::NormalizeDirectory('$(RepoTasksDir)', 'mobile.tasks', 'AndroidAppBuilder')) + $([MSBuild]::NormalizeDirectory('$(LibrariesProjectRoot)', 'Common', tests, 'AndroidTestRunner')) + $([MSBuild]::NormalizeDirectory('$(RepoTasksDir)', 'mobile.tasks', 'AotCompilerTask')) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 76f5dba28afce..83ddd98916415 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -885,18 +885,6 @@ - - - - - - - - - - - - - + <_MonoRuntimeFilePath Condition="'$(TargetsWindows)' == 'true' and '$(Platform)' == 'x64'">$(MonoObjDir)x64\Bin\$(Configuration)\mono-2.0-sgen.dll <_MonoRuntimeFilePath Condition="'$(TargetsWindows)' == 'true' and '$(Platform)' == 'x86'">$(MonoObjDir)Win32\Bin\$(Configuration)\mono-2.0-sgen.dll diff --git a/src/mono/netcore/sample/Android/Makefile b/src/mono/netcore/sample/Android/Makefile index b069bb1fb27e9..898c8cf1bea57 100644 --- a/src/mono/netcore/sample/Android/Makefile +++ b/src/mono/netcore/sample/Android/Makefile @@ -5,7 +5,7 @@ DOTNET := ../../../../.././dotnet.sh #export ANDROID_NDK_ROOT=/path/to/android/ndk #export ANDROID_SDK_ROOT=/path/to/android/sdk -all: runtimepack bundle +all: bundle bundle: clean $(DOTNET) build -c $(MONO_CONFIG) Program.csproj @@ -14,8 +14,5 @@ bundle: clean deploy-launch: bundle $(DOTNET) msbuild /t:ReinstallAndLaunch -runtimepack: - ../../../../.././build.sh -c $(MONO_CONFIG) -os Android -arch $(MONO_ARCH) -subset Mono+Libs /p:DisableCrossgen=true - clean: rm -rf bin diff --git a/src/mono/netcore/sample/Android/Program.csproj b/src/mono/netcore/sample/Android/Program.csproj index 00acd1e7cf41e..600ac6dd74727 100644 --- a/src/mono/netcore/sample/Android/Program.csproj +++ b/src/mono/netcore/sample/Android/Program.csproj @@ -7,7 +7,8 @@ x64 $(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-Android-$(Configuration)-$(TargetArchitecture)\runtimes\android-$(TargetArchitecture) $(MSBuildThisFileDirectory)\bin\bundle - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', '$(NetCoreAppCurrent)-$(Configuration)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', 'Debug', '$(NetCoreAppCurrent)')) + diff --git a/src/mono/netcore/sample/iOS/Makefile b/src/mono/netcore/sample/iOS/Makefile index 40a59f0c07e8d..240d55da76a1b 100644 --- a/src/mono/netcore/sample/iOS/Makefile +++ b/src/mono/netcore/sample/iOS/Makefile @@ -1,11 +1,11 @@ MONO_CONFIG=Debug -MONO_ARCH=arm64 +MONO_ARCH=x64 DOTNET := ../../../../.././dotnet.sh USE_LLVM=True # usage example: # 'make all MONO_ARCH=x64 MONO_CONFIG=Release' to build the app for simulator -all: runtimepack bundle +all: bundle program: $(DOTNET) build -c $(MONO_CONFIG) Program.csproj @@ -17,8 +17,5 @@ bundle: clean program deploy-sim: $(DOTNET) msbuild /t:IosDeployToSimulator /p:Configuration=$(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH) -runtimepack: - ../../../../.././build.sh -c $(MONO_CONFIG) -os iOS -arch $(MONO_ARCH) -subset Mono+Libs /p:DisableCrossgen=true - clean: rm -rf bin diff --git a/src/mono/netcore/sample/iOS/Program.csproj b/src/mono/netcore/sample/iOS/Program.csproj index 473832246ae0b..6105c1f58fbb4 100644 --- a/src/mono/netcore/sample/iOS/Program.csproj +++ b/src/mono/netcore/sample/iOS/Program.csproj @@ -9,9 +9,11 @@ $(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-iOS-$(Configuration)-$(TargetArchitecture)\runtimes\ios-$(TargetArchitecture) $(ArtifactsDir)bin\mono\iOS.$(TargetArchitecture).$(Configuration) $(MSBuildThisFileDirectory)\bin\bundle - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder', '$(NetCoreAppCurrent)-$(Configuration)')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'MonoAOTCompiler', '$(NetCoreAppCurrent)-$(Configuration)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder', 'Debug', '$(NetCoreAppCurrent)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'MonoAOTCompiler', 'Debug', '$(NetCoreAppCurrent)')) true + true + false @@ -84,7 +86,7 @@ BuildAppBundle="True" DevTeamProvisioning="$(DevTeamProvisioning)" OutputDirectory="$(BundleDir)" - Optimized="True" + Optimized="$(Optimized)" AppDir="$(BundleDir)"> diff --git a/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.cs similarity index 100% rename from src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.cs rename to tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.cs diff --git a/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.csproj b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.csproj similarity index 90% rename from src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.csproj rename to tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.csproj index 987d10d54c5f1..179ca9aa2af4a 100644 --- a/src/mono/msbuild/AndroidAppBuilder/AndroidAppBuilder.csproj +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.csproj @@ -1,8 +1,10 @@ + $(NetCoreAppCurrent) Library true false + enable diff --git a/src/mono/msbuild/AndroidAppBuilder/ApkBuilder.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs similarity index 100% rename from src/mono/msbuild/AndroidAppBuilder/ApkBuilder.cs rename to tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs diff --git a/src/mono/msbuild/AndroidAppBuilder/Templates/AndroidManifest.xml b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/AndroidManifest.xml similarity index 100% rename from src/mono/msbuild/AndroidAppBuilder/Templates/AndroidManifest.xml rename to tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/AndroidManifest.xml diff --git a/src/mono/msbuild/AndroidAppBuilder/Templates/CMakeLists-android.txt b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/CMakeLists-android.txt similarity index 100% rename from src/mono/msbuild/AndroidAppBuilder/Templates/CMakeLists-android.txt rename to tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/CMakeLists-android.txt diff --git a/src/mono/msbuild/AndroidAppBuilder/Templates/MainActivity.java b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/MainActivity.java similarity index 100% rename from src/mono/msbuild/AndroidAppBuilder/Templates/MainActivity.java rename to tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/MainActivity.java diff --git a/src/mono/msbuild/AndroidAppBuilder/Templates/MonoRunner.java b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/MonoRunner.java similarity index 100% rename from src/mono/msbuild/AndroidAppBuilder/Templates/MonoRunner.java rename to tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/MonoRunner.java diff --git a/src/mono/msbuild/AndroidAppBuilder/Templates/runtime-android.c b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/runtime-android.c similarity index 100% rename from src/mono/msbuild/AndroidAppBuilder/Templates/runtime-android.c rename to tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/runtime-android.c diff --git a/src/mono/msbuild/AndroidAppBuilder/Utils.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Utils.cs similarity index 100% rename from src/mono/msbuild/AndroidAppBuilder/Utils.cs rename to tools-local/tasks/mobile.tasks/AndroidAppBuilder/Utils.cs diff --git a/src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.cs b/tools-local/tasks/mobile.tasks/AotCompilerTask/MonoAOTCompiler.cs similarity index 100% rename from src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.cs rename to tools-local/tasks/mobile.tasks/AotCompilerTask/MonoAOTCompiler.cs diff --git a/src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.csproj b/tools-local/tasks/mobile.tasks/AotCompilerTask/MonoAOTCompiler.csproj similarity index 76% rename from src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.csproj rename to tools-local/tasks/mobile.tasks/AotCompilerTask/MonoAOTCompiler.csproj index f5766a3fdcfb7..b487236cc3627 100644 --- a/src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.csproj +++ b/tools-local/tasks/mobile.tasks/AotCompilerTask/MonoAOTCompiler.csproj @@ -1,8 +1,10 @@ + $(NetCoreAppCurrent) Library true false + enable @@ -14,4 +16,9 @@ + + + PreserveNewest + + diff --git a/src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.props b/tools-local/tasks/mobile.tasks/AotCompilerTask/MonoAOTCompiler.props similarity index 100% rename from src/mono/msbuild/AotCompilerTask/MonoAOTCompiler.props rename to tools-local/tasks/mobile.tasks/AotCompilerTask/MonoAOTCompiler.props diff --git a/src/mono/msbuild/AotCompilerTask/Utils.cs b/tools-local/tasks/mobile.tasks/AotCompilerTask/Utils.cs similarity index 100% rename from src/mono/msbuild/AotCompilerTask/Utils.cs rename to tools-local/tasks/mobile.tasks/AotCompilerTask/Utils.cs diff --git a/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.cs b/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs similarity index 100% rename from src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.cs rename to tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs diff --git a/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj b/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.csproj similarity index 90% rename from src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj rename to tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.csproj index 859da678a7d27..255150988f9c7 100644 --- a/src/mono/msbuild/AppleAppBuilder/AppleAppBuilder.csproj +++ b/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.csproj @@ -1,8 +1,10 @@ + $(NetCoreAppCurrent) Library true false + enable diff --git a/src/mono/msbuild/AppleAppBuilder/Templates/CMakeLists.txt.template b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/CMakeLists.txt.template similarity index 100% rename from src/mono/msbuild/AppleAppBuilder/Templates/CMakeLists.txt.template rename to tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/CMakeLists.txt.template diff --git a/src/mono/msbuild/AppleAppBuilder/Templates/Info.plist.template b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/Info.plist.template similarity index 100% rename from src/mono/msbuild/AppleAppBuilder/Templates/Info.plist.template rename to tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/Info.plist.template diff --git a/src/mono/msbuild/AppleAppBuilder/Templates/main-console.m b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/main-console.m similarity index 100% rename from src/mono/msbuild/AppleAppBuilder/Templates/main-console.m rename to tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/main-console.m diff --git a/src/mono/msbuild/AppleAppBuilder/Templates/main-simple.m b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/main-simple.m similarity index 100% rename from src/mono/msbuild/AppleAppBuilder/Templates/main-simple.m rename to tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/main-simple.m diff --git a/src/mono/msbuild/AppleAppBuilder/Templates/runtime.h b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/runtime.h similarity index 100% rename from src/mono/msbuild/AppleAppBuilder/Templates/runtime.h rename to tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/runtime.h diff --git a/src/mono/msbuild/AppleAppBuilder/Templates/runtime.m b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/runtime.m similarity index 100% rename from src/mono/msbuild/AppleAppBuilder/Templates/runtime.m rename to tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/runtime.m diff --git a/src/mono/msbuild/AppleAppBuilder/Utils.cs b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Utils.cs similarity index 100% rename from src/mono/msbuild/AppleAppBuilder/Utils.cs rename to tools-local/tasks/mobile.tasks/AppleAppBuilder/Utils.cs diff --git a/src/mono/msbuild/AppleAppBuilder/Xcode.cs b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs similarity index 100% rename from src/mono/msbuild/AppleAppBuilder/Xcode.cs rename to tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs diff --git a/tools-local/tasks/tasks.proj b/tools-local/tasks/tasks.proj new file mode 100644 index 0000000000000..5fc0d0abf5de0 --- /dev/null +++ b/tools-local/tasks/tasks.proj @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + $([MSBuild]::NormalizePath('$(ArtifactsObjDir)', '$(MSBuildProjectName)', 'Debug', 'build-semaphore.txt')) + + + + + + + \ No newline at end of file From 4b4e87a77399f43fd0022fa89676616e98edfaca Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 15 May 2020 15:06:34 -0400 Subject: [PATCH 227/420] Add comment to NetworkStream's ctor about socket.Blocking check (#36539) --- .../src/System/Net/Sockets/NetworkStream.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs index 78f87814575a6..772ad52790e9f 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs @@ -51,6 +51,10 @@ public NetworkStream(Socket socket, FileAccess access, bool ownsSocket) } if (!socket.Blocking) { + // Stream.Read*/Write* are incompatible with the semantics of non-blocking sockets, and + // allowing non-blocking sockets could result in non-deterministic failures from those + // operations. A developer that requires using NetworkStream with a non-blocking socket can + // temporarily flip Socket.Blocking as a workaround. throw new IOException(SR.net_sockets_blocking); } if (!socket.Connected) From 9933a66898f9eea068d0ced1aead52b5e1eb56cc Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 15 May 2020 19:12:55 +0000 Subject: [PATCH 228/420] [master] Update dependencies from mono/linker Microsoft/vstest dotnet/xharness (#36525) * Update dependencies from https://github.com/mono/linker build 20200515.1 Microsoft.NET.ILLink.Tasks From Version 5.0.0-preview.3.20264.1 -> To Version 5.0.0-preview.3.20265.1 * Update dependencies from https://github.com/microsoft/vstest build 20200515-01 Microsoft.NET.Test.Sdk From Version 16.7.0-preview-20200429-01 -> To Version 16.7.0-preview-20200515-01 * Update dependencies from https://github.com/dotnet/xharness build 20200515.1 Microsoft.DotNet.XHarness.Tests.Runners From Version 1.0.0-prerelease.20264.9 -> To Version 1.0.0-prerelease.20265.1 Co-authored-by: dotnet-maestro[bot] Co-authored-by: Viktor Hofer --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 700894376a9d9..54a3d03935e2a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -82,9 +82,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization d0bb63d2ec7060714e63ee4082fac48f2e57f3e2 - + https://github.com/microsoft/vstest - df61f73a1f4608df5ee0957350fbd3e81f924c6b + cffe1860c1e821db78bf18ba0b829c73ae1e3944 https://github.com/dotnet/runtime-assets @@ -170,13 +170,13 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - e9f0009b3bd7e42fdc7db6e416b9182828006309 + d94ab76abdc1cb87349ed9fe4c2f0ed34cab5b1e - + https://github.com/dotnet/xharness - bf6773e982acd8a8923b58de140843d9cebc9f69 + 7c4562725b1c313e617393017f4903bde02d53e5 diff --git a/eng/Versions.props b/eng/Versions.props index d7de2c44eee7d..8eb5078211a2c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -108,8 +108,8 @@ 4.8.0 - 16.7.0-preview-20200429-01 - 1.0.0-prerelease.20264.9 + 16.7.0-preview-20200515-01 + 1.0.0-prerelease.20265.1 2.4.1 1.2.1 2.0.5 @@ -118,7 +118,7 @@ 3.1.0-preview-20200129.1 - 5.0.0-preview.3.20264.1 + 5.0.0-preview.3.20265.1 9.0.1-alpha.1.20262.1 9.0.1-alpha.1.20262.1 From 363ac3692ca08a9f8066723bc18c585ef461212a Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Fri, 15 May 2020 12:26:51 -0700 Subject: [PATCH 229/420] Disable MemoryCacheTest.Trim in arm64 and enable Runtime.Caching tests on Unix (#36494) --- .../tests/System.Runtime.Caching.Tests.csproj | 2 +- .../tests/System.Runtime.Caching/MemoryCacheTest.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching.Tests.csproj b/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching.Tests.csproj index d666431543e62..8259713ac2060 100644 --- a/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching.Tests.csproj +++ b/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent) + $(NetCoreAppCurrent);$(NetFrameworkCurrent) diff --git a/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching/MemoryCacheTest.cs b/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching/MemoryCacheTest.cs index 71254a10928ff..b114698730101 100644 --- a/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching/MemoryCacheTest.cs +++ b/src/libraries/System.Runtime.Caching/tests/System.Runtime.Caching/MemoryCacheTest.cs @@ -969,7 +969,8 @@ public void ChangeMonitors() } // Due to internal implementation details Trim has very few easily verifiable scenarios - [Fact] + // ActiveIssue: https://github.com/dotnet/runtime/issues/36488 + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArm64Process))] public void Trim() { var config = new NameValueCollection(); From b764cae5f815fc4328eb59f570872d3285b3f82f Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 15 May 2020 12:31:27 -0700 Subject: [PATCH 230/420] Enable basic generation of ngen pdb from composite image (#36311) * Enable basic generation of ngen pdb from composite image - Port non-line number handling portion of ngen pdb from crossgen to r2rdump - This pdb generation logic may be used for both composite and non-composite R2R images - Only pdb generation is supported. Perfmap generation for unix is not supported - pdb generation is only supported on Windows x86 and amd64 platforms. Diasymreader is not supported on other systems - Pdb generation does not generation symbols with the same names as crossgen. Instead it uses the name generator from r2rdump. For current needs this should be sufficient - Update composite file format so that pdb generation process will work. Major difference is that a CorHeader is always produced for composite images now. This CorHeader is not used by the runtime, but is required for DiaSymReader to generate an ngen pdb. --- docs/design/coreclr/botr/readytorun-format.md | 5 +- eng/DiaSymReaderNative.targets | 35 ++ .../CodeGen/ReadyToRunObjectWriter.cs | 9 +- .../ReadyToRun/CopiedCorHeaderNode.cs | 167 +++++--- .../ReadyToRun/DebugDirectoryEntryNode.cs | 19 +- .../ReadyToRun/DebugDirectoryNode.cs | 39 +- .../ReadyToRunCodegenNodeFactory.cs | 12 +- .../Compiler/ReadyToRunCodegenCompilation.cs | 2 +- .../ReadyToRunCodegenCompilationBuilder.cs | 12 +- .../ILCompiler.ReadyToRun.csproj | 2 +- .../ReadyToRunReader.cs | 16 +- .../src/tools/crossgen2/crossgen2/Program.cs | 1 + .../src/tools/r2rdump/CommandLineOptions.cs | 2 + .../src/tools/r2rdump/ISymNGenWriter.cs | 85 ++++ src/coreclr/src/tools/r2rdump/PdbWriter.cs | 394 ++++++++++++++++++ src/coreclr/src/tools/r2rdump/R2RDump.cs | 35 +- src/coreclr/src/tools/r2rdump/R2RDump.csproj | 2 + 17 files changed, 744 insertions(+), 93 deletions(-) create mode 100644 eng/DiaSymReaderNative.targets create mode 100644 src/coreclr/src/tools/r2rdump/ISymNGenWriter.cs create mode 100644 src/coreclr/src/tools/r2rdump/PdbWriter.cs diff --git a/docs/design/coreclr/botr/readytorun-format.md b/docs/design/coreclr/botr/readytorun-format.md index 51fcd1cab56b4..8db3423dbadfe 100644 --- a/docs/design/coreclr/botr/readytorun-format.md +++ b/docs/design/coreclr/botr/readytorun-format.md @@ -28,8 +28,9 @@ in the COFF header represent a full copy of the input IL and MSIL metadata it wa **Composite R2R files** currently conform to Windows PE executable file format as the native envelope. Moving forward we plan to gradually add support for platform-native -executable formats (ELF on Linux, MachO on OSX) as the native envelopes. As a natural corollary -there is no global CLI / COR header in the file. The ReadyToRun header structure is pointed to +executable formats (ELF on Linux, MachO on OSX) as the native envelopes. There is a +global CLI / COR header in the file, but it only exists to facilitate pdb generation, and does +not participate in any usages by the CoreCLR runtime. The ReadyToRun header structure is pointed to by the well-known export symbol `RTR_HEADER` and has the `READYTORUN_FLAG_COMPOSITE` flag set. Input MSIL metadata and IL streams can be either embedded in the composite R2R file or left diff --git a/eng/DiaSymReaderNative.targets b/eng/DiaSymReaderNative.targets new file mode 100644 index 0000000000000..5836a781dfa8f --- /dev/null +++ b/eng/DiaSymReaderNative.targets @@ -0,0 +1,35 @@ + + + + + + AnyCPU + + + + + + PreserveNewest + false + false + + + PreserveNewest + false + false + + + + + \ No newline at end of file diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs index c38cc8b6fa989..8238d9418f9ce 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs @@ -150,8 +150,6 @@ public void EmitPortableExecutable() if (node is NativeDebugDirectoryEntryNode nddeNode) { // There should be only one NativeDebugDirectoryEntry. - // This assert will need to be revisited when we implement the composite R2R format, where we'll need to figure - // out how native symbols will be emitted, and verify that the DiaSymReader library is able to consume them. Debug.Assert(nativeDebugDirectoryEntryNode == null); nativeDebugDirectoryEntryNode = nddeNode; } @@ -176,11 +174,8 @@ public void EmitPortableExecutable() EmitObjectData(r2rPeBuilder, nodeContents, nodeIndex, name, node.Section, _mapFileBuilder); } - if (!_nodeFactory.CompilationModuleGroup.IsCompositeBuildMode || _componentModule != null) - { - r2rPeBuilder.SetCorHeader(_nodeFactory.CopiedCorHeaderNode, _nodeFactory.CopiedCorHeaderNode.Size); - r2rPeBuilder.SetDebugDirectory(_nodeFactory.DebugDirectoryNode, _nodeFactory.DebugDirectoryNode.Size); - } + r2rPeBuilder.SetCorHeader(_nodeFactory.CopiedCorHeaderNode, _nodeFactory.CopiedCorHeaderNode.Size); + r2rPeBuilder.SetDebugDirectory(_nodeFactory.DebugDirectoryNode, _nodeFactory.DebugDirectoryNode.Size); if (_nodeFactory.Win32ResourcesNode != null) { diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedCorHeaderNode.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedCorHeaderNode.cs index 5e7a96afa4c71..87772fa7079f7 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedCorHeaderNode.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedCorHeaderNode.cs @@ -51,7 +51,10 @@ private static DirectoryEntry ReadDirectoryEntry(ref BlobReader reader) public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { sb.Append(nameMangler.CompilationUnitPrefix); - sb.Append($"__CorHeader_{_module.Assembly.GetName().Name}"); + if (_module != null) + sb.Append($"__CorHeader_{_module.Assembly.GetName().Name}"); + else + sb.Append("__CompositeCorHeader_"); } protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler); @@ -62,75 +65,116 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) builder.RequireInitialPointerAlignment(); builder.AddSymbol(this); - BlobReader reader = _module.PEReader.GetEntireImage().GetReader(); - reader.Offset = _module.PEReader.PEHeaders.CorHeaderStartOffset; - - // Header Size - int headerSize = reader.ReadInt32(); - builder.EmitInt(headerSize); - - // Runtime major, minor version - builder.EmitUShort(reader.ReadUInt16()); - builder.EmitUShort(reader.ReadUInt16()); + if (_module != null) + { + BlobReader reader = _module.PEReader.GetEntireImage().GetReader(); + reader.Offset = _module.PEReader.PEHeaders.CorHeaderStartOffset; + + // Header Size + int headerSize = reader.ReadInt32(); + builder.EmitInt(headerSize); + + // Runtime major, minor version + builder.EmitUShort(reader.ReadUInt16()); + builder.EmitUShort(reader.ReadUInt16()); + + // Metadata Directory + ReadDirectoryEntry(ref reader); + var metadataBlob = factory.CopiedMetadataBlob(_module); + builder.EmitReloc(metadataBlob, RelocType.IMAGE_REL_BASED_ADDR32NB); + builder.EmitInt(metadataBlob.Size); + + // Flags + builder.EmitUInt((uint)(((CorFlags)reader.ReadUInt32() & ~CorFlags.ILOnly) | CorFlags.ILLibrary)); + + // Entrypoint + builder.EmitInt(reader.ReadInt32()); + + // Resources Directory + if (ReadDirectoryEntry(ref reader).Size > 0) + { + var managedResources = factory.CopiedManagedResources(_module); + builder.EmitReloc(managedResources, RelocType.IMAGE_REL_BASED_ADDR32NB); + builder.EmitInt(managedResources.Size); + } + else + { + WriteEmptyDirectoryEntry(ref builder); + } + + // Strong Name Signature Directory + if (ReadDirectoryEntry(ref reader).Size > 0) + { + var strongNameSignature = factory.CopiedStrongNameSignature(_module); + builder.EmitReloc(strongNameSignature, RelocType.IMAGE_REL_BASED_ADDR32NB); + builder.EmitInt(strongNameSignature.Size); + } + else + { + WriteEmptyDirectoryEntry(ref builder); + } + + // Code Manager Table Directory + ReadDirectoryEntry(ref reader); + WriteEmptyDirectoryEntry(ref builder); - // Metadata Directory - ReadDirectoryEntry(ref reader); - var metadataBlob = factory.CopiedMetadataBlob(_module); - builder.EmitReloc(metadataBlob, RelocType.IMAGE_REL_BASED_ADDR32NB); - builder.EmitInt(metadataBlob.Size); + // VTable Fixups Directory + ReadDirectoryEntry(ref reader); + WriteEmptyDirectoryEntry(ref builder); - // Flags - builder.EmitUInt((uint)(((CorFlags)reader.ReadUInt32() & ~CorFlags.ILOnly) | CorFlags.ILLibrary)); + // Export Address Table Jumps Directory + ReadDirectoryEntry(ref reader); + WriteEmptyDirectoryEntry(ref builder); - // Entrypoint - builder.EmitInt(reader.ReadInt32()); + // Managed Native (ReadyToRun) Header Directory + ReadDirectoryEntry(ref reader); + builder.EmitReloc(factory.Header, RelocType.IMAGE_REL_BASED_ADDR32NB); + builder.EmitReloc(factory.Header, RelocType.IMAGE_REL_SYMBOL_SIZE); - // Resources Directory - if (ReadDirectoryEntry(ref reader).Size > 0) - { - var managedResources = factory.CopiedManagedResources(_module); - builder.EmitReloc(managedResources, RelocType.IMAGE_REL_BASED_ADDR32NB); - builder.EmitInt(managedResources.Size); + // Did we fully read the header? + Debug.Assert(reader.Offset - headerSize == _module.PEReader.PEHeaders.CorHeaderStartOffset); + Debug.Assert(builder.CountBytes == headerSize); + Debug.Assert(headerSize == Size); } else { - WriteEmptyDirectoryEntry(ref builder); - } + // Generating CORHeader for composite image + // Header Size + builder.EmitInt(Size); - // Strong Name Signature Directory - if (ReadDirectoryEntry(ref reader).Size > 0) - { - var strongNameSignature = factory.CopiedStrongNameSignature(_module); - builder.EmitReloc(strongNameSignature, RelocType.IMAGE_REL_BASED_ADDR32NB); - builder.EmitInt(strongNameSignature.Size); - } - else - { + // Runtime major, minor version + builder.EmitUShort(0); + builder.EmitUShort(0); + + // Metadata Directory + builder.EmitReloc(factory.ManifestMetadataTable, RelocType.IMAGE_REL_BASED_ADDR32NB); + builder.EmitReloc(factory.ManifestMetadataTable, RelocType.IMAGE_REL_SYMBOL_SIZE); + + // Flags + builder.EmitUInt(0); + + // Entrypoint + builder.EmitInt(0); + + // Resources Directory WriteEmptyDirectoryEntry(ref builder); - } - - // Code Manager Table Directory - ReadDirectoryEntry(ref reader); - WriteEmptyDirectoryEntry(ref builder); + // Strong Name Signature Directory + WriteEmptyDirectoryEntry(ref builder); - // VTable Fixups Directory - ReadDirectoryEntry(ref reader); - WriteEmptyDirectoryEntry(ref builder); + // Code Manager Table Directory + WriteEmptyDirectoryEntry(ref builder); - // Export Address Table Jumps Directory - ReadDirectoryEntry(ref reader); - WriteEmptyDirectoryEntry(ref builder); + // VTable Fixups Directory + WriteEmptyDirectoryEntry(ref builder); - // Managed Native (ReadyToRun) Header Directory - ReadDirectoryEntry(ref reader); - builder.EmitReloc(factory.Header, RelocType.IMAGE_REL_BASED_ADDR32NB); - builder.EmitReloc(factory.Header, RelocType.IMAGE_REL_SYMBOL_SIZE); + // Export Address Table Jumps Directory + WriteEmptyDirectoryEntry(ref builder); - // Did we fully read the header? - Debug.Assert(reader.Offset - headerSize == _module.PEReader.PEHeaders.CorHeaderStartOffset); - Debug.Assert(builder.CountBytes == headerSize); - Debug.Assert(headerSize == Size); + // Managed Native (ReadyToRun) Header Directory + builder.EmitReloc(factory.Header, RelocType.IMAGE_REL_BASED_ADDR32NB); + builder.EmitReloc(factory.Header, RelocType.IMAGE_REL_SYMBOL_SIZE); + } return builder.ToObjectData(); } @@ -143,6 +187,17 @@ private void WriteEmptyDirectoryEntry(ref ObjectDataBuilder builder) public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) { + if (_module == null) + { + if (((CopiedCorHeaderNode)other)._module == null) + return 0; + return -1; + } + else if (((CopiedCorHeaderNode)other)._module == null) + { + return 1; + } + return _module.CompareTo(((CopiedCorHeaderNode)other)._module); } } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryEntryNode.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryEntryNode.cs index e88b2805d7369..6a691d831c199 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryEntryNode.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryEntryNode.cs @@ -56,14 +56,18 @@ public class NativeDebugDirectoryEntryNode : DebugDirectoryEntryNode public unsafe int Size => RSDSSize; - public NativeDebugDirectoryEntryNode(EcmaModule sourceModule) - : base(sourceModule) - { } + public NativeDebugDirectoryEntryNode(string pdbName) + : base(null) + { + _pdbName = pdbName; + } + + private string _pdbName; public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { sb.Append(nameMangler.CompilationUnitPrefix); - sb.Append($"__NativeRvaBlob_{_module.Assembly.GetName().Name}"); + sb.Append($"__NativeDebugDirectory_{_pdbName.Replace('.','_')}"); } public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) @@ -99,7 +103,7 @@ public byte[] GenerateRSDSEntryData(byte[] md5Hash) // Age writer.Write(1); - string pdbFileName = _module.Assembly.GetName().Name + ".ni.pdb"; + string pdbFileName = _pdbName; byte[] pdbFileNameBytes = Encoding.UTF8.GetBytes(pdbFileName); writer.Write(pdbFileNameBytes); @@ -107,6 +111,11 @@ public byte[] GenerateRSDSEntryData(byte[] md5Hash) return rsdsEntry.ToArray(); } } + + public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) + { + return _pdbName.CompareTo(((NativeDebugDirectoryEntryNode)other)._pdbName); + } } public class CopiedDebugDirectoryEntryNode : DebugDirectoryEntryNode diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryNode.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryNode.cs index 52e49afe79828..5c1bd729b64cc 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryNode.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryNode.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Immutable; using System.Diagnostics; +using System.IO; using System.Reflection.PortableExecutable; using Internal.Text; using Internal.TypeSystem.Ecma; @@ -25,10 +26,17 @@ public class DebugDirectoryNode : ObjectNode, ISymbolDefinitionNode sizeof(int); // PointerToRawData private EcmaModule _module; + private NativeDebugDirectoryEntryNode _nativeEntry; - public DebugDirectoryNode(EcmaModule sourceModule) + public DebugDirectoryNode(EcmaModule sourceModule, string outputFileName) { _module = sourceModule; + string pdbNameRoot = Path.GetFileNameWithoutExtension(outputFileName); + if (sourceModule != null) + { + pdbNameRoot = sourceModule.Assembly.GetName().Name; + } + _nativeEntry = new NativeDebugDirectoryEntryNode(pdbNameRoot + ".ni.pdb"); } public override ObjectNodeSection Section => ObjectNodeSection.TextSection; @@ -48,13 +56,22 @@ public DebugDirectoryNode(EcmaModule sourceModule) public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { sb.Append(nameMangler.CompilationUnitPrefix); - sb.Append($"__DebugDirectory_{_module.Assembly.GetName().Name}"); + string directoryName; + if (_module != null) + directoryName = _module.Assembly.GetName().Name; + else + directoryName = "Composite"; + + sb.Append($"__DebugDirectory_{directoryName}"); } protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler); int GetNumDebugDirectoryEntriesInModule() { + if (_module == null) + return 0; + ImmutableArray entries = _module.PEReader.ReadDebugDirectory(); return entries == null ? 0 : entries.Length; } @@ -65,12 +82,15 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) builder.RequireInitialPointerAlignment(); builder.AddSymbol(this); - ImmutableArray entries = _module.PEReader.ReadDebugDirectory(); + ImmutableArray entries = default(ImmutableArray); + if (_module != null) + entries = _module.PEReader.ReadDebugDirectory(); + int numEntries = GetNumDebugDirectoryEntriesInModule(); // First, write the native debug directory entry { - var entry = (NativeDebugDirectoryEntryNode)factory.DebugDirectoryEntry(_module, -1); + var entry = _nativeEntry; builder.EmitUInt(0 /* Characteristics */); if (numEntries > 0) @@ -121,6 +141,17 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) { + if (_module == null) + { + if (((DebugDirectoryNode)other)._module == null) + return 0; + return -1; + } + else if (((DebugDirectoryNode)other)._module == null) + { + return 1; + } + return _module.CompareTo(((DebugDirectoryNode)other)._module); } } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs index 267b946973e75..eeb590bce993b 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs @@ -133,11 +133,13 @@ public ModuleAndIntValueKey(int integer, EcmaModule module) Module = module; } - public bool Equals(ModuleAndIntValueKey other) => IntValue == other.IntValue && Module.Equals(other.Module); + public bool Equals(ModuleAndIntValueKey other) => IntValue == other.IntValue && ((Module == null && other.Module == null) || Module.Equals(other.Module)); public override bool Equals(object obj) => obj is ModuleAndIntValueKey && Equals((ModuleAndIntValueKey)obj); public override int GetHashCode() { int hashCode = IntValue * 0x5498341 + 0x832424; + if (Module == null) + return hashCode; return hashCode * 23 + Module.GetHashCode(); } } @@ -255,9 +257,6 @@ private void CreateNodeCaches() _debugDirectoryEntries = new NodeCache(key => { - if (key.IntValue < 0) - return new NativeDebugDirectoryEntryNode(key.Module); - else return new CopiedDebugDirectoryEntryNode(key.Module, key.IntValue); }); @@ -657,10 +656,7 @@ public void AttachToDependencyGraph(DependencyAnalyzerBase graph) graph.AddRoot(PrecodeImports, "Precode helper imports are always generated"); graph.AddRoot(StringImports, "String imports are always generated"); graph.AddRoot(Header, "ReadyToRunHeader is always generated"); - if (!CompilationModuleGroup.IsCompositeBuildMode) - { - graph.AddRoot(CopiedCorHeaderNode, "MSIL COR header is always generated for single-file R2R files"); - } + graph.AddRoot(CopiedCorHeaderNode, "MSIL COR header is always generated for R2R files"); graph.AddRoot(DebugDirectoryNode, "Debug Directory will always contain at least one entry"); if (Win32ResourcesNode != null) diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs index 3b3f323ff3a5f..bd08ba25809db 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs @@ -302,7 +302,7 @@ private void RewriteComponentFile(string inputFile, string outputFile, string ow EcmaModule inputModule = NodeFactory.TypeSystemContext.GetModuleFromPath(inputFile); CopiedCorHeaderNode copiedCorHeader = new CopiedCorHeaderNode(inputModule); - DebugDirectoryNode debugDirectory = new DebugDirectoryNode(inputModule); + DebugDirectoryNode debugDirectory = new DebugDirectoryNode(inputModule, outputFile); NodeFactory componentFactory = new NodeFactory( _nodeFactory.TypeSystemContext, _nodeFactory.CompilationModuleGroup, diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs index a889d469051b0..a5e388083be3b 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs @@ -28,6 +28,7 @@ public sealed class ReadyToRunCodegenCompilationBuilder : CompilationBuilder private InstructionSetSupport _instructionSetSupport; private string _jitPath; + private string _outputFile; // These need to provide reasonable defaults so that the user can optionally skip // calling the Use/Configure methods and still get something reasonable back. @@ -115,13 +116,20 @@ public ReadyToRunCodegenCompilationBuilder UseInstructionSetSupport(InstructionS return this; } + public ReadyToRunCodegenCompilationBuilder GenerateOutputFile(string outputFile) + { + _outputFile = outputFile; + return this; + } + public override ICompilation ToCompilation() { // TODO: only copy COR headers for single-assembly build and for composite build with embedded MSIL IEnumerable inputModules = _compilationGroup.CompilationModuleSet; - CopiedCorHeaderNode corHeaderNode = (_compilationGroup.IsCompositeBuildMode ? null : new CopiedCorHeaderNode(inputModules.First())); + EcmaModule singleModule = _compilationGroup.IsCompositeBuildMode ? null : inputModules.First(); + CopiedCorHeaderNode corHeaderNode = new CopiedCorHeaderNode(singleModule); // TODO: proper support for multiple input files - DebugDirectoryNode debugDirectoryNode = new DebugDirectoryNode(inputModules.First()); + DebugDirectoryNode debugDirectoryNode = new DebugDirectoryNode(singleModule, _outputFile); // Produce a ResourceData where the IBC PROFILE_DATA entry has been filtered out // TODO: proper support for multiple input files diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj index 798f7074b69ae..5183fbfc0f6c9 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj @@ -1,4 +1,4 @@ - + Library ILCompiler.ReadyToRun diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index 729a492215755..3537d6429374a 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -411,14 +411,20 @@ private unsafe void Initialize(MetadataReader metadata) { if ((PEReader.PEHeaders.CorHeader.Flags & CorFlags.ILLibrary) == 0) { - throw new BadImageFormatException("The file is not a ReadyToRun image"); + if (!TryLocateNativeReadyToRunHeader()) + throw new BadImageFormatException("The file is not a ReadyToRun image"); + + Debug.Assert(Composite); } + else + { + _assemblyCache.Add(metadata); - _assemblyCache.Add(metadata); + DirectoryEntry r2rHeaderDirectory = PEReader.PEHeaders.CorHeader.ManagedNativeHeaderDirectory; + _readyToRunHeaderRVA = r2rHeaderDirectory.RelativeVirtualAddress; + Debug.Assert(!Composite); + } - DirectoryEntry r2rHeaderDirectory = PEReader.PEHeaders.CorHeader.ManagedNativeHeaderDirectory; - _readyToRunHeaderRVA = r2rHeaderDirectory.RelativeVirtualAddress; - Debug.Assert(!Composite); } else if (!TryLocateNativeReadyToRunHeader()) { diff --git a/src/coreclr/src/tools/crossgen2/crossgen2/Program.cs b/src/coreclr/src/tools/crossgen2/crossgen2/Program.cs index 72843451e10e2..3b52671fc6641 100644 --- a/src/coreclr/src/tools/crossgen2/crossgen2/Program.cs +++ b/src/coreclr/src/tools/crossgen2/crossgen2/Program.cs @@ -476,6 +476,7 @@ private int Run() .UseParallelism(_commandLineOptions.Parallelism) .UseJitPath(_commandLineOptions.JitPath) .UseInstructionSetSupport(instructionSetSupport) + .GenerateOutputFile(_commandLineOptions.OutputFilePath.FullName) .UseILProvider(ilProvider) .UseBackendOptions(_commandLineOptions.CodegenOptions) .UseLogger(logger) diff --git a/src/coreclr/src/tools/r2rdump/CommandLineOptions.cs b/src/coreclr/src/tools/r2rdump/CommandLineOptions.cs index 5ddfd1dbeb6b3..7647e829ad071 100644 --- a/src/coreclr/src/tools/r2rdump/CommandLineOptions.cs +++ b/src/coreclr/src/tools/r2rdump/CommandLineOptions.cs @@ -36,6 +36,8 @@ public static RootCommand RootCommand() command.AddOption(new Option(new[] { "--referencePath", "--rp" }, "Search paths for reference assemblies", new Argument())); command.AddOption(new Option(new[] { "--inlineSignatureBinary", "--isb" }, "Embed binary signature into its textual representation", new Argument())); command.AddOption(new Option(new[] { "--signatureBinary", "--sb" }, "Append signature binary to its textual representation", new Argument())); + command.AddOption(new Option(new[] { "--create-pdb" }, "Create PDB", new Argument())); + command.AddOption(new Option(new[] { "--pdb-path" }, "PDB output path for --createpdb", new Argument())); return command; } } diff --git a/src/coreclr/src/tools/r2rdump/ISymNGenWriter.cs b/src/coreclr/src/tools/r2rdump/ISymNGenWriter.cs new file mode 100644 index 0000000000000..8a4eb8074fb6f --- /dev/null +++ b/src/coreclr/src/tools/r2rdump/ISymNGenWriter.cs @@ -0,0 +1,85 @@ +// 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. + +#pragma warning disable 436 // SuppressUnmanagedCodeSecurityAttribute defined in source and mscorlib + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Microsoft.DiaSymReader +{ + [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("D682FD12-43dE-411C-811B-BE8404CEA126"), SuppressUnmanagedCodeSecurity] + internal interface ISymNGenWriter + { + // Add a new public symbol to the NGEN PDB. + void AddSymbol([MarshalAs(UnmanagedType.BStr)] string pSymbol, + ushort iSection, + ulong rva); + + // Adds a new section to the NGEN PDB. + void AddSection(ushort iSection, + OMF flags, + int offset, + int cb); + } + + [Flags] + internal enum OMF : ushort + { + Const_Read = 0x0001, + Const_Write = 0x0002, + Const_Exec = 0x0004, + Const_F32Bit = 0x0008, + Const_ReservedBits1 = 0x00f0, + Const_FSel = 0x0100, + Const_FAbs = 0x0200, + Const_ReservedBits2 = 0x0C00, + Const_FGroup = 0x1000, + Const_ReservedBits3 = 0xE000, + + + StandardText = (Const_FSel|Const_F32Bit|Const_Exec|Const_Read), // 0x10D + SentinelType = (Const_FAbs|Const_F32Bit) // 0x208 + } + + + [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("B029E51B-4C55-4fe2-B993-9F7BC1F10DB4"), SuppressUnmanagedCodeSecurity] + internal interface ISymNGenWriter2 : ISymNGenWriter + { + // Add a new public symbol to the NGEN PDB. + new void AddSymbol([MarshalAs(UnmanagedType.BStr)] string pSymbol, + ushort iSection, + ulong rva); + + // Adds a new section to the NGEN PDB. + new void AddSection(ushort iSection, + OMF flags, + int offset, + int cb); + + void OpenModW([MarshalAs(UnmanagedType.LPWStr)] string wszModule, + [MarshalAs(UnmanagedType.LPWStr)] string wszObjFile, + out UIntPtr ppmod); + + void CloseMod(UIntPtr pmod); + + void ModAddSymbols(UIntPtr pmod, [MarshalAs(UnmanagedType.LPArray)] byte[] pbSym, int cb); + + void ModAddSecContribEx( + UIntPtr pmod, + ushort isect, + int off, + int cb, + uint dwCharacteristics, + uint dwDataCrc, + uint dwRelocCrc); + + void QueryPDBNameExW( + [MarshalAs(UnmanagedType.LPWStr)] StringBuilder pdb, + IntPtr cchMax); + } +} diff --git a/src/coreclr/src/tools/r2rdump/PdbWriter.cs b/src/coreclr/src/tools/r2rdump/PdbWriter.cs new file mode 100644 index 0000000000000..bbf6c5f1f1cbe --- /dev/null +++ b/src/coreclr/src/tools/r2rdump/PdbWriter.cs @@ -0,0 +1,394 @@ +// 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. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection.PortableExecutable; +using System.Runtime.InteropServices; +using System.Text; + +using Microsoft.DiaSymReader; + +namespace ILCompiler.PdbWriter +{ + // NGEN always generates PDBs with public symbols lists (so tools can map IP ranges to + // methods). This bitmask indicates what extra info should be added to the PDB + [Flags] + public enum PDBExtraData + { + None = 0, + // Add string table subsection, files checksum subsection, and lines subsection to + // allow tools to map IP ranges to source lines. + kPDBLines = 0x00000001, + }; + + struct MethodInfo + { + public string AssemblyName; + public uint MethodToken; + public uint HotRVA; + public string Name; + public uint ColdRVA; + } + + interface IModuleData + { + IEnumerable Methods { get; } + } + + public enum SymChecksumType : byte + { + None = 0, // indicates no checksum is available + MD5, + SHA1, + SHA_256, + }; + + class SymDocument : IEquatable + { + public string Name; + public SymChecksumType ChecksumType; + public byte[] Checksum; + + + public override int GetHashCode() + { + return Name.GetHashCode(); + } + + public override bool Equals(object other) + { + if (other is SymDocument documentOther) + { + return Equals(documentOther); + } + + return false; + } + + public bool Equals(SymDocument other) + { + if (Name != other.Name) + return false; + if (ChecksumType != other.ChecksumType) + return false; + if (Checksum.Length != other.Checksum.Length) + return false; + for (int i = 0; i < Checksum.Length; i++) + { + if (Checksum[i] != other.Checksum[i]) + return false; + } + + return true; + } + } + + class PdbWriter + { + string _pdbPath; + PDBExtraData _pdbExtraData; + + string _pdbFilePath; + string _tempSourceDllName; + + List _symDocuments = new List(); + Dictionary _stringTableToOffsetMapping; + Dictionary _documentToChecksumOffsetMapping; + + UIntPtr _pdbMod; + ISymNGenWriter2 _ngenWriter; + + private const string DiaSymReaderModuleName32 = "Microsoft.DiaSymReader.Native.x86.dll"; + private const string DiaSymReaderModuleName64 = "Microsoft.DiaSymReader.Native.amd64.dll"; + + private const string CreateNGenPdbWriterFactoryName = "CreateNGenPdbWriter"; + + [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.SafeDirectories)] + [DllImport(DiaSymReaderModuleName32, EntryPoint = CreateNGenPdbWriterFactoryName, PreserveSig = false)] + private extern static void CreateNGenPdbWriter32([MarshalAs(UnmanagedType.LPWStr)] string ngenImagePath, [MarshalAs(UnmanagedType.LPWStr)] string pdbPath, [MarshalAs(UnmanagedType.IUnknown)] out object ngenPdbWriter); + + [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.SafeDirectories)] + [DllImport(DiaSymReaderModuleName64, EntryPoint = CreateNGenPdbWriterFactoryName, PreserveSig = false)] + private extern static void CreateNGenPdbWriter64([MarshalAs(UnmanagedType.LPWStr)] string ngenImagePath, [MarshalAs(UnmanagedType.LPWStr)] string pdbPath, [MarshalAs(UnmanagedType.IUnknown)] out object ngenPdbWriter); + + private static ISymNGenWriter2 CreateNGenWriter(string ngenImagePath, string pdbPath) + { + object instance; + + if (IntPtr.Size == 4) + { + CreateNGenPdbWriter32(ngenImagePath, pdbPath, out instance); + } + else + { + CreateNGenPdbWriter64(ngenImagePath, pdbPath, out instance); + } + return (ISymNGenWriter2)instance; + } + + public PdbWriter(string pdbPath, PDBExtraData pdbExtraData) + { + SymDocument unknownDocument = new SymDocument(); + unknownDocument.Name = "unknown"; + unknownDocument.ChecksumType = SymChecksumType.None; + unknownDocument.Checksum = Array.Empty(); + + _symDocuments.Add(unknownDocument); + _pdbPath = pdbPath; + _pdbExtraData = pdbExtraData; + } + + public void WritePDBData(string dllPath, IEnumerable methods) + { + bool failed = true; + try + { + try + { + try + { + WritePDBDataHelper(dllPath, methods); + } + finally + { + if ((_ngenWriter != null) && (_pdbMod != UIntPtr.Zero)) + { + _ngenWriter.CloseMod(_pdbMod); + } + } + } + finally + { + if (_ngenWriter != null) + { + Marshal.FinalReleaseComObject(_ngenWriter); + } + } + + failed = false; + } + finally + { + if (_tempSourceDllName != null) + { + try + { + File.Delete(_tempSourceDllName); + } + catch {} + } + + if (failed && (_pdbFilePath != null)) + { + try + { + // If anything fails, do not create a partial pdb file + File.Delete(_pdbFilePath); + } + catch {} + } + } + } + + private void WritePDBDataHelper(string dllPath, IEnumerable methods) + { + // This will try to open the managed PDB if lines info was requested. This is a + // likely failure point, so intentionally do this before creating the NGEN PDB file + // on disk. + bool isILPDBProvided = false; + if (_pdbExtraData.HasFlag(PDBExtraData.kPDBLines)) + { + // line mapping not ported from crossgen yet. + throw new NotImplementedException(); + } + + string originalDllPath = dllPath; + + // Currently DiaSymReader does not work properly generating NGEN PDBS unless + // the DLL whose PDB is being generated ends in .ni.*. Unfortunately, readyToRun + // images do not follow this convention and end up producing bad PDBS. To fix + // this (without changing diasymreader.dll which ships indepdendently of .NET Core) + // we copy the file to somethign with this convention before generating the PDB + // and delete it when we are done. + if (!dllPath.EndsWith(".ni.dll", StringComparison.OrdinalIgnoreCase) && !dllPath.EndsWith(".ni.exe", StringComparison.OrdinalIgnoreCase)) + { + _tempSourceDllName = Path.Combine(Path.GetDirectoryName(dllPath), Path.GetFileNameWithoutExtension(dllPath) + ".ni" + Path.GetExtension(dllPath)); + File.Copy(dllPath, _tempSourceDllName); + dllPath = _tempSourceDllName; + } + + _ngenWriter = CreateNGenWriter(dllPath, _pdbPath + "\\"); + + { + // PDB file is now created. Get its path and initialize _pdbFilePath so the PDB file + // can be deleted if we don't make it successfully to the end + StringBuilder pdbFilePathBuilder = new StringBuilder(); + pdbFilePathBuilder.Capacity = 1024; + _ngenWriter.QueryPDBNameExW(pdbFilePathBuilder, new IntPtr(pdbFilePathBuilder.Capacity)); + _pdbFilePath = pdbFilePathBuilder.ToString(); + } + + _ngenWriter.OpenModW(originalDllPath, Path.GetFileName(originalDllPath), out _pdbMod); + + WriteStringTable(); + WriteFileChecksums(); + + ushort? iCodeSection = null; + uint rvaOfTextSection = 0; + using (var peReader = new PEReader(new FileStream(dllPath, FileMode.Open), PEStreamOptions.Default)) + { + var sections = peReader.PEHeaders.SectionHeaders; + + for (int i = 0; i < sections.Length; i++) + { + ushort pdbSectionNumber = checked((ushort)(i+1)); + + _ngenWriter.AddSection(pdbSectionNumber, OMF.StandardText, 0, sections[i].SizeOfRawData); + if (sections[i].Name == ".text") + { + iCodeSection = pdbSectionNumber; + rvaOfTextSection = (uint)sections[i].VirtualAddress; + } + _ngenWriter.ModAddSecContribEx(_pdbMod, pdbSectionNumber, 0, sections[i].SizeOfRawData, (uint)sections[i].SectionCharacteristics, 0, 0); + } + } + + // To support lines info, we need a "dummy" section, indexed as 0, for use as a + // sentinel when MSPDB sets up its section contribution table + _ngenWriter.AddSection(0, // Dummy section 0 + OMF.SentinelType, + 0, + unchecked((int)0xFFFFFFFF)); + + foreach (var method in methods) + { + WriteMethodPDBData(iCodeSection.Value, method, Path.GetFileNameWithoutExtension(originalDllPath), rvaOfTextSection, isILPDBProvided); + } + } + + void WriteMethodPDBData(ushort iCodeSection, MethodInfo method, string assemblyName, uint textSectionOffset, bool isILPDBProvided) + { + string nameSuffix = $"{method.Name}$#{(assemblyName != method.AssemblyName ? method.AssemblyName : String.Empty)}#{method.MethodToken.ToString("X")}"; + + _ngenWriter.AddSymbol(nameSuffix, iCodeSection, method.HotRVA - textSectionOffset); + if (method.ColdRVA != 0) + { + _ngenWriter.AddSymbol($"[COLD] {nameSuffix}", iCodeSection, method.ColdRVA); + } + + if (isILPDBProvided) + { + // line mapping not ported from crossgen yet. + throw new NotImplementedException(); + } + } + + private const int CV_SIGNATURE_C13 = 4; + private enum DEBUG_S_SUBSECTION_TYPE { + DEBUG_S_IGNORE = unchecked((int)0x80000000), // if this bit is set in a subsection type then ignore the subsection contents + + DEBUG_S_SYMBOLS = 0xf1, + DEBUG_S_LINES, + DEBUG_S_STRINGTABLE, + DEBUG_S_FILECHKSMS, + DEBUG_S_FRAMEDATA, + DEBUG_S_INLINEELINES, + DEBUG_S_CROSSSCOPEIMPORTS, + DEBUG_S_CROSSSCOPEEXPORTS, + + DEBUG_S_IL_LINES, + DEBUG_S_FUNC_MDTOKEN_MAP, + DEBUG_S_TYPE_MDTOKEN_MAP, + DEBUG_S_MERGED_ASSEMBLYINPUT, + + DEBUG_S_COFF_SYMBOL_RVA, + } + + private void WriteStringTable() + { + _stringTableToOffsetMapping = new Dictionary(); + + MemoryStream stringTableStream = new MemoryStream(); + BinaryWriter writer = new BinaryWriter(stringTableStream, Encoding.UTF8); + writer.Write(CV_SIGNATURE_C13); + writer.Write((uint)DEBUG_S_SUBSECTION_TYPE.DEBUG_S_STRINGTABLE); + long sizeOfStringTablePosition = writer.BaseStream.Position; + writer.Write((uint)0); // Size of actual string table. To be filled in later + long startOfStringTableOffset = writer.BaseStream.Position; + foreach (var document in _symDocuments) + { + string str = document.Name; + if (_stringTableToOffsetMapping.ContainsKey(str)) + continue; + + long offset = writer.BaseStream.Position; + _stringTableToOffsetMapping.Add(str, checked((int)(offset - startOfStringTableOffset))); + writer.Write(str.AsSpan()); + writer.Write((byte)0); // Null terminate all strings + } + + // Update string table size + long stringTableSize = writer.BaseStream.Position - startOfStringTableOffset; + writer.BaseStream.Position = sizeOfStringTablePosition; + writer.Write(checked((uint)stringTableSize)); + writer.Flush(); + + // Write string table into pdb file + byte[] stringTableArray = stringTableStream.ToArray(); + _ngenWriter.ModAddSymbols(_pdbMod, stringTableArray, stringTableArray.Length); + } + + private void WriteFileChecksums() + { + _documentToChecksumOffsetMapping = new Dictionary(); + + MemoryStream checksumStream = new MemoryStream(); + BinaryWriter writer = new BinaryWriter(checksumStream, Encoding.UTF8); + writer.Write(CV_SIGNATURE_C13); + writer.Write((uint)DEBUG_S_SUBSECTION_TYPE.DEBUG_S_FILECHKSMS); + + long sizeOfChecksumTablePosition = writer.BaseStream.Position; + writer.Write((uint)0); // Size of actual checksum table. To be filled in later + long startOfChecksumTableOffset = writer.BaseStream.Position; + foreach (var document in _symDocuments) + { + long offset = writer.BaseStream.Position; + _documentToChecksumOffsetMapping.Add(document, checked((int)(offset - startOfChecksumTableOffset))); + + SymChecksumType checksumType = document.ChecksumType; + byte[] checksum = document.Checksum; + + if (document.Checksum.Length > 255) + { + // Should never happen, but just in case checksum data is invalid, just put + // no checksum into the NGEN PDB + checksumType = SymChecksumType.None; + checksum = Array.Empty(); + } + writer.Write(_stringTableToOffsetMapping[document.Name]); + writer.Write((byte)checksum.Length); + writer.Write((byte)checksumType); + writer.Write(checksum); + + // Must align to the next 4-byte boundary + while ((writer.BaseStream.Position % 4) != 0) + { + writer.Write((byte)0); + } + } + + // Update checksum table size + long checksumTableSize = writer.BaseStream.Position - startOfChecksumTableOffset; + writer.BaseStream.Position = sizeOfChecksumTablePosition; + writer.Write(checked((uint)checksumTableSize)); + writer.Flush(); + + // Write string table into pdb file + byte[] checksumTableArray = checksumStream.ToArray(); + _ngenWriter.ModAddSymbols(_pdbMod, checksumTableArray, checksumTableArray.Length); + } + } +} diff --git a/src/coreclr/src/tools/r2rdump/R2RDump.cs b/src/coreclr/src/tools/r2rdump/R2RDump.cs index 5e4360db44228..e718bc955ccd4 100644 --- a/src/coreclr/src/tools/r2rdump/R2RDump.cs +++ b/src/coreclr/src/tools/r2rdump/R2RDump.cs @@ -15,6 +15,7 @@ using System.Text; using System.Threading.Tasks; using ILCompiler.Reflection.ReadyToRun; +using ILCompiler.PdbWriter; using Internal.Runtime; @@ -46,6 +47,9 @@ public class DumpOptions : IAssemblyResolver public bool DiffHideSameDisasm { get; set; } public bool IgnoreSensitive { get; set; } + public bool CreatePDB { get; set; } + public string PdbPath { get; set; } + public FileInfo[] Reference { get; set; } public DirectoryInfo[] ReferencePath { get; set; } @@ -337,8 +341,9 @@ private void QueryRuntimeFunction(ReadyToRunReader r2r, IEnumerable quer public void Dump(ReadyToRunReader r2r) { _dumper.Begin(); + bool standardDump = !(_options.EntryPoints || _options.CreatePDB); - if (_options.Header || !_options.EntryPoints) + if (_options.Header && standardDump) { _dumper.WriteDivider("R2R Header"); _dumper.DumpHeader(true); @@ -377,7 +382,18 @@ public void Dump(ReadyToRunReader r2r) _dumper.DumpEntryPoints(); } - if (!_options.Header && !_options.EntryPoints) + if (_options.CreatePDB) + { + string pdbPath = _options.PdbPath; + if (String.IsNullOrEmpty(pdbPath)) + { + pdbPath = Path.GetDirectoryName(r2r.Filename); + } + var pdbWriter = new PdbWriter(pdbPath, PDBExtraData.None); + pdbWriter.WritePDBData(r2r.Filename, ProducePdbWriterMethods(r2r)); + } + + if (!_options.Header && standardDump) { _dumper.DumpAllMethods(); } @@ -386,6 +402,21 @@ public void Dump(ReadyToRunReader r2r) _dumper.End(); } + IEnumerable ProducePdbWriterMethods(ReadyToRunReader r2r) + { + foreach (var method in _dumper.NormalizedMethods()) + { + MethodInfo mi = new MethodInfo(); + mi.Name = method.SignatureString; + mi.HotRVA = (uint)method.RuntimeFunctions[0].StartAddress; + mi.MethodToken = (uint)MetadataTokens.GetToken(method.MetadataReader, method.MethodHandle); + mi.AssemblyName = method.MetadataReader.GetString(method.MetadataReader.GetAssemblyDefinition().Name); + mi.ColdRVA = 0; + + yield return mi; + } + } + /// /// Returns true if the name, signature or id of method matches query /// diff --git a/src/coreclr/src/tools/r2rdump/R2RDump.csproj b/src/coreclr/src/tools/r2rdump/R2RDump.csproj index f54756878189d..c2c1433f6c227 100644 --- a/src/coreclr/src/tools/r2rdump/R2RDump.csproj +++ b/src/coreclr/src/tools/r2rdump/R2RDump.csproj @@ -15,6 +15,8 @@ AnyCPU;x64 + + 1.0.1-prerelease-00005 From ca0fd167d540d12d50fd1fbfd09eb1825d54a0f7 Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Fri, 15 May 2020 13:04:26 -0700 Subject: [PATCH 231/420] Next round of multireg preliminary changes (#36155) This is a zero-diff set of mostly refactoring changes in preparation for supporting multireg locals: - Move `genRegCopy()` and `genStructReturn()` to codegencommon.cpp, making a new method for `genSIMDSplitReturn` which is target-specific. - Factor out a new `genUnspillLocal` method from `genUnspillRegIfNeeded()`. - Similarly factor out `genSpillLocal()` - Rename `genMultiRegCallStoreToLocal()` and more generally support multireg local stores. - Fix a bug in the order and shift amount for last-use bits on `GenTreeLclVar` - Some additional cleanup and preparatory changes --- src/coreclr/src/jit/codegen.h | 10 +- src/coreclr/src/jit/codegenarm.cpp | 4 +- src/coreclr/src/jit/codegenarm64.cpp | 4 +- src/coreclr/src/jit/codegenarmarch.cpp | 457 +++-------------------- src/coreclr/src/jit/codegencommon.cpp | 276 ++++++++++++++ src/coreclr/src/jit/codegenlinear.cpp | 233 ++++++------ src/coreclr/src/jit/codegenxarch.cpp | 469 ++++-------------------- src/coreclr/src/jit/gentree.h | 72 +++- src/coreclr/src/jit/lclvars.cpp | 15 +- src/coreclr/src/jit/lsra.cpp | 51 ++- src/coreclr/src/jit/lsra.h | 8 +- src/coreclr/src/jit/morph.cpp | 2 - src/coreclr/src/jit/rationalize.cpp | 2 +- src/coreclr/src/jit/regset.cpp | 42 ++- src/coreclr/src/jit/ssabuilder.cpp | 4 + src/coreclr/src/jit/treelifeupdater.cpp | 64 ++-- 16 files changed, 734 insertions(+), 979 deletions(-) diff --git a/src/coreclr/src/jit/codegen.h b/src/coreclr/src/jit/codegen.h index 93227bc7f6c1f..4262e561fe780 100644 --- a/src/coreclr/src/jit/codegen.h +++ b/src/coreclr/src/jit/codegen.h @@ -1113,6 +1113,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // Do liveness update for register produced by the current node in codegen after // code has been emitted for it. void genProduceReg(GenTree* tree); + void genSpillLocal(unsigned varNum, var_types type, GenTreeLclVar* lclNode, regNumber regNum); + void genUnspillLocal( + unsigned varNum, var_types type, GenTreeLclVar* lclNode, regNumber regNum, bool reSpill, bool isLastUse); void genUnspillRegIfNeeded(GenTree* tree); regNumber genConsumeReg(GenTree* tree); void genCopyRegIfNeeded(GenTree* tree, regNumber needReg); @@ -1275,10 +1278,13 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void genEHFinallyOrFilterRet(BasicBlock* block); #endif // !FEATURE_EH_FUNCLETS - void genMultiRegCallStoreToLocal(GenTree* treeNode); + void genMultiRegStoreToLocal(GenTree* treeNode); - // Deals with codegen for muti-register struct returns. + // Codegen for multi-register struct returns. bool isStructReturn(GenTree* treeNode); +#ifdef FEATURE_SIMD + void genSIMDSplitReturn(GenTree* src, ReturnTypeDesc* retTypeDesc); +#endif void genStructReturn(GenTree* treeNode); #if defined(TARGET_X86) || defined(TARGET_ARM) diff --git a/src/coreclr/src/jit/codegenarm.cpp b/src/coreclr/src/jit/codegenarm.cpp index 7a3c5fac26f5e..6ddb1ff166356 100644 --- a/src/coreclr/src/jit/codegenarm.cpp +++ b/src/coreclr/src/jit/codegenarm.cpp @@ -961,7 +961,7 @@ void CodeGen::genCodeForLclVar(GenTreeLclVar* tree) // If this is a register candidate that has been spilled, genConsumeReg() will // reload it at the point of use. Otherwise, if it's not in a register, we load it here. - if (!isRegCandidate && !(tree->gtFlags & GTF_SPILLED)) + if (!isRegCandidate && !tree->IsMultiReg() && !(tree->gtFlags & GTF_SPILLED)) { const LclVarDsc* varDsc = compiler->lvaGetDesc(tree); var_types type = varDsc->GetRegisterType(tree); @@ -1050,7 +1050,7 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree) // case is handled separately. if (data->gtSkipReloadOrCopy()->IsMultiRegCall()) { - genMultiRegCallStoreToLocal(tree); + genMultiRegStoreToLocal(tree); } else { diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index c3f7c07bbfcf8..f6b6ee3a3ff7b 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -1839,7 +1839,7 @@ void CodeGen::genCodeForLclVar(GenTreeLclVar* tree) // If this is a register candidate that has been spilled, genConsumeReg() will // reload it at the point of use. Otherwise, if it's not in a register, we load it here. - if (!isRegCandidate && !(tree->gtFlags & GTF_SPILLED)) + if (!isRegCandidate && !tree->IsMultiReg() && !(tree->gtFlags & GTF_SPILLED)) { // targetType must be a normal scalar type and not a TYP_STRUCT assert(targetType != TYP_STRUCT); @@ -1929,7 +1929,7 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree) // case is handled separately. if (data->gtSkipReloadOrCopy()->IsMultiRegCall()) { - genMultiRegCallStoreToLocal(tree); + genMultiRegStoreToLocal(tree); } else { diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index 34ee4c3de5309..a5e2bd4152657 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -1355,7 +1355,7 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) #endif // FEATURE_ARG_SPLIT //---------------------------------------------------------------------------------- -// genMultiRegCallStoreToLocal: store multi-reg return value of a call node to a local +// genMultiRegStoreToLocal: store multi-reg return value of a call node to a local // // Arguments: // treeNode - Gentree of GT_STORE_LCL_VAR @@ -1364,42 +1364,35 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) // None // // Assumption: -// The child of store is a multi-reg call node. -// genProduceReg() on treeNode is made by caller of this routine. +// The child of store is a multi-reg node. // -void CodeGen::genMultiRegCallStoreToLocal(GenTree* treeNode) +void CodeGen::genMultiRegStoreToLocal(GenTree* treeNode) { assert(treeNode->OperGet() == GT_STORE_LCL_VAR); - -#if defined(TARGET_ARM) - // Longs are returned in two return registers on Arm32. - // Structs are returned in four registers on ARM32 and HFAs. - assert(varTypeIsLong(treeNode) || varTypeIsStruct(treeNode)); -#elif defined(TARGET_ARM64) - // Structs of size >=9 and <=16 are returned in two return registers on ARM64 and HFAs. - assert(varTypeIsStruct(treeNode)); -#endif // TARGET* + assert(varTypeIsStruct(treeNode) || varTypeIsMultiReg(treeNode)); + GenTree* op1 = treeNode->gtGetOp1(); + GenTree* actualOp1 = op1->gtSkipReloadOrCopy(); + assert(op1->IsMultiRegNode()); + unsigned regCount = op1->GetMultiRegCount(); // Assumption: current implementation requires that a multi-reg // var in 'var = call' is flagged as lvIsMultiRegRet to prevent it from // being promoted. unsigned lclNum = treeNode->AsLclVarCommon()->GetLclNum(); - LclVarDsc* varDsc = &(compiler->lvaTable[lclNum]); - noway_assert(varDsc->lvIsMultiRegRet); - - GenTree* op1 = treeNode->gtGetOp1(); - GenTree* actualOp1 = op1->gtSkipReloadOrCopy(); - GenTreeCall* call = actualOp1->AsCall(); - assert(call->HasMultiRegRetVal()); + LclVarDsc* varDsc = compiler->lvaGetDesc(lclNum); + if (op1->OperIs(GT_CALL)) + { + assert(regCount <= MAX_RET_REG_COUNT); + noway_assert(varDsc->lvIsMultiRegRet); + } genConsumeRegs(op1); - const ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc(); - const unsigned regCount = pRetTypeDesc->GetReturnRegCount(); + int offset = 0; - if (treeNode->GetRegNum() != REG_NA) + // Check for the case of an enregistered SIMD type that's returned in multiple registers. + if (varDsc->lvIsRegCandidate() && treeNode->GetRegNum() != REG_NA) { - // Right now the only enregistrable multi-reg return types supported are SIMD types. assert(varTypeIsSIMD(treeNode)); assert(regCount != 0); @@ -1409,8 +1402,8 @@ void CodeGen::genMultiRegCallStoreToLocal(GenTree* treeNode) // Insert pieces in reverse order for (int i = regCount - 1; i >= 0; --i) { - var_types type = pRetTypeDesc->GetReturnRegType(i); - regNumber reg = call->GetRegNumByIdx(i); + var_types type = op1->GetRegTypeByIndex(i); + regNumber reg = op1->GetRegByIndex(i); if (op1->IsCopyOrReload()) { // GT_COPY/GT_RELOAD will have valid reg for those positions @@ -1449,12 +1442,10 @@ void CodeGen::genMultiRegCallStoreToLocal(GenTree* treeNode) } else { - // Stack store - int offset = 0; for (unsigned i = 0; i < regCount; ++i) { - var_types type = pRetTypeDesc->GetReturnRegType(i); - regNumber reg = call->GetRegNumByIdx(i); + var_types type = op1->GetRegTypeByIndex(i); + regNumber reg = op1->GetRegByIndex(i); if (op1->IsCopyOrReload()) { // GT_COPY/GT_RELOAD will have valid reg for those positions @@ -1471,7 +1462,7 @@ void CodeGen::genMultiRegCallStoreToLocal(GenTree* treeNode) offset += genTypeSize(type); } - // Updating variable liveness after instruction was emitted + // Update variable liveness. genUpdateLife(treeNode); varDsc->SetRegNum(REG_STK); } @@ -2333,132 +2324,6 @@ void CodeGen::genCodeForInitBlkHelper(GenTreeBlk* initBlkNode) genEmitHelperCall(CORINFO_HELP_MEMSET, 0, EA_UNKNOWN); } -//------------------------------------------------------------------------ -// genRegCopy: Produce code for a GT_COPY node. -// -// Arguments: -// tree - the GT_COPY node -// -// Notes: -// This will copy the register(s) produced by this node's source, to -// the register(s) allocated to this GT_COPY node. -// It has some special handling for these cases: -// - when the source and target registers are in different register files -// (note that this is *not* a conversion). -// - when the source is a lclVar whose home location is being moved to a new -// register (rather than just being copied for temporary use). -// -void CodeGen::genRegCopy(GenTree* treeNode) -{ - assert(treeNode->OperGet() == GT_COPY); - GenTree* op1 = treeNode->AsOp()->gtOp1; - - regNumber sourceReg = genConsumeReg(op1); - - if (op1->IsMultiRegNode()) - { - noway_assert(!op1->IsCopyOrReload()); - unsigned regCount = op1->GetMultiRegCount(); - for (unsigned i = 0; i < regCount; i++) - { - regNumber srcReg = op1->GetRegByIndex(i); - regNumber tgtReg = treeNode->AsCopyOrReload()->GetRegNumByIdx(i); - var_types regType = op1->GetRegTypeByIndex(i); - inst_RV_RV(ins_Copy(regType), tgtReg, srcReg, regType); - } - } - else - { - var_types targetType = treeNode->TypeGet(); - regNumber targetReg = treeNode->GetRegNum(); - assert(targetReg != REG_NA); - assert(targetType != TYP_STRUCT); - - // Check whether this node and the node from which we're copying the value have the same - // register type. - // This can happen if (currently iff) we have a SIMD vector type that fits in an integer - // register, in which case it is passed as an argument, or returned from a call, - // in an integer register and must be copied if it's in a floating point register. - - bool srcFltReg = (varTypeIsFloating(op1) || varTypeIsSIMD(op1)); - bool tgtFltReg = (varTypeIsFloating(treeNode) || varTypeIsSIMD(treeNode)); - if (srcFltReg != tgtFltReg) - { -#ifdef TARGET_ARM64 - inst_RV_RV(INS_fmov, targetReg, sourceReg, targetType); -#else // !TARGET_ARM64 - if (varTypeIsFloating(treeNode)) - { - // GT_COPY from 'int' to 'float' currently can't happen. Maybe if ARM SIMD is implemented - // it will happen, according to the comment above? - NYI_ARM("genRegCopy from 'int' to 'float'"); - } - else - { - assert(varTypeIsFloating(op1)); - - if (op1->TypeGet() == TYP_FLOAT) - { - inst_RV_RV(INS_vmov_f2i, targetReg, genConsumeReg(op1), targetType); - } - else - { - regNumber otherReg = (regNumber)treeNode->AsCopyOrReload()->gtOtherRegs[0]; - assert(otherReg != REG_NA); - inst_RV_RV_RV(INS_vmov_d2i, targetReg, otherReg, genConsumeReg(op1), EA_8BYTE); - } - } -#endif // !TARGET_ARM64 - } - else - { - inst_RV_RV(ins_Copy(targetType), targetReg, sourceReg, targetType); - } - } - - if (op1->IsLocal()) - { - // The lclVar will never be a def. - // If it is a last use, the lclVar will be killed by genConsumeReg(), as usual, and genProduceReg will - // appropriately set the gcInfo for the copied value. - // If not, there are two cases we need to handle: - // - If this is a TEMPORARY copy (indicated by the GTF_VAR_DEATH flag) the variable - // will remain live in its original register. - // genProduceReg() will appropriately set the gcInfo for the copied value, - // and genConsumeReg will reset it. - // - Otherwise, we need to update register info for the lclVar. - - GenTreeLclVarCommon* lcl = op1->AsLclVarCommon(); - assert((lcl->gtFlags & GTF_VAR_DEF) == 0); - - if ((lcl->gtFlags & GTF_VAR_DEATH) == 0 && (treeNode->gtFlags & GTF_VAR_DEATH) == 0) - { - LclVarDsc* varDsc = &compiler->lvaTable[lcl->GetLclNum()]; - - // If we didn't just spill it (in genConsumeReg, above), then update the register info - if (varDsc->GetRegNum() != REG_STK) - { - // The old location is dying - genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(op1)); - - gcInfo.gcMarkRegSetNpt(genRegMask(op1->GetRegNum())); - - genUpdateVarReg(varDsc, treeNode); - -#ifdef USING_VARIABLE_LIVE_RANGE - // Report the home change for this variable - varLiveKeeper->siUpdateVariableLiveRange(varDsc, lcl->GetLclNum()) -#endif // USING_VARIABLE_LIVE_RANGE - - // The new location is going live - genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(treeNode)); - } - } - } - - genProduceReg(treeNode); -} - //------------------------------------------------------------------------ // genCallInstruction: Produce code for a GT_CALL node // @@ -3759,261 +3624,49 @@ void CodeGen::genLeaInstruction(GenTreeAddrMode* lea) genProduceReg(lea); } +#ifdef FEATURE_SIMD //------------------------------------------------------------------------ -// isStructReturn: Returns whether the 'treeNode' is returning a struct. -// -// Arguments: -// treeNode - The tree node to evaluate whether is a struct return. -// -// Return Value: -// Returns true if the 'treeNode" is a GT_RETURN node of type struct. -// Otherwise returns false. -// -bool CodeGen::isStructReturn(GenTree* treeNode) -{ - // This method could be called for 'treeNode' of GT_RET_FILT or GT_RETURN. - // For the GT_RET_FILT, the return is always - // a bool or a void, for the end of a finally block. - noway_assert(treeNode->OperGet() == GT_RETURN || treeNode->OperGet() == GT_RETFILT); - var_types returnType = treeNode->TypeGet(); - -#ifdef TARGET_ARM64 - return varTypeIsStruct(returnType) && (compiler->info.compRetNativeType == TYP_STRUCT); -#else - return varTypeIsStruct(returnType); -#endif -} - -//------------------------------------------------------------------------ -// genStructReturn: Generates code for returning a struct. +// genSIMDSplitReturn: Generates code for returning a fixed-size SIMD type that lives +// in a single register, but is returned in multiple registers. // // Arguments: -// treeNode - The GT_RETURN tree node. -// -// Return Value: -// None +// src - The source of the return +// retTypeDesc - The return type descriptor. // -// Assumption: -// op1 of GT_RETURN node is either GT_LCL_VAR or multi-reg GT_CALL -void CodeGen::genStructReturn(GenTree* treeNode) +void CodeGen::genSIMDSplitReturn(GenTree* src, ReturnTypeDesc* retTypeDesc) { - assert(treeNode->OperGet() == GT_RETURN); - assert(isStructReturn(treeNode)); - GenTree* op1 = treeNode->gtGetOp1(); - - if (op1->OperGet() == GT_LCL_VAR) - { - GenTreeLclVarCommon* lclVar = op1->AsLclVarCommon(); - LclVarDsc* varDsc = &(compiler->lvaTable[lclVar->GetLclNum()]); - var_types lclType = genActualType(varDsc->TypeGet()); - - assert(varTypeIsStruct(lclType)); - assert(varDsc->lvIsMultiRegRet); - - ReturnTypeDesc retTypeDesc; - unsigned regCount; - - retTypeDesc.InitializeStructReturnType(compiler, varDsc->lvVerTypeInfo.GetClassHandle()); - regCount = retTypeDesc.GetReturnRegCount(); - - assert(regCount >= 2); - - assert(varTypeIsSIMD(lclType) || op1->isContained()); - - if (op1->isContained()) - { - // Copy var on stack into ABI return registers - // TODO: It could be optimized by reducing two float loading to one double - int offset = 0; - for (unsigned i = 0; i < regCount; ++i) - { - var_types type = retTypeDesc.GetReturnRegType(i); - regNumber reg = retTypeDesc.GetABIReturnReg(i); - GetEmitter()->emitIns_R_S(ins_Load(type), emitTypeSize(type), reg, lclVar->GetLclNum(), offset); - offset += genTypeSize(type); - } + assert(varTypeIsSIMD(src)); + assert(src->isUsedFromReg()); + regNumber srcReg = src->GetRegNum(); + + // Treat src register as a homogenous vector with element size equal to the reg size + // Insert pieces in order + unsigned regCount = retTypeDesc->GetReturnRegCount(); + for (unsigned i = 0; i < regCount; ++i) + { + var_types type = retTypeDesc->GetReturnRegType(i); + regNumber reg = retTypeDesc->GetABIReturnReg(i); + if (varTypeIsFloating(type)) + { + // If the register piece is to be passed in a floating point register + // Use a vector mov element instruction + // reg is not a vector, so it is in the first element reg[0] + // mov reg[0], src[i] + // This effectively moves from `src[i]` to `reg[0]`, upper bits of reg remain unchanged + // For the case where src == reg, since we are only writing reg[0], as long as we iterate + // so that src[0] is consumed before writing reg[0], we do not need a temporary. + GetEmitter()->emitIns_R_R_I_I(INS_mov, emitTypeSize(type), reg, srcReg, 0, i); } else { - // Handle SIMD genStructReturn case - NYI_ARM("SIMD genStructReturn"); - -#ifdef TARGET_ARM64 - genConsumeRegs(op1); - regNumber src = op1->GetRegNum(); - - // Treat src register as a homogenous vector with element size equal to the reg size - // Insert pieces in order - for (unsigned i = 0; i < regCount; ++i) - { - var_types type = retTypeDesc.GetReturnRegType(i); - regNumber reg = retTypeDesc.GetABIReturnReg(i); - if (varTypeIsFloating(type)) - { - // If the register piece is to be passed in a floating point register - // Use a vector mov element instruction - // reg is not a vector, so it is in the first element reg[0] - // mov reg[0], src[i] - // This effectively moves from `src[i]` to `reg[0]`, upper bits of reg remain unchanged - // For the case where src == reg, since we are only writing reg[0], as long as we iterate - // so that src[0] is consumed before writing reg[0], we do not need a temporary. - GetEmitter()->emitIns_R_R_I_I(INS_mov, emitTypeSize(type), reg, src, 0, i); - } - else - { - // If the register piece is to be passed in an integer register - // Use a vector mov to general purpose register instruction - // mov reg, src[i] - // This effectively moves from `src[i]` to `reg` - GetEmitter()->emitIns_R_R_I(INS_mov, emitTypeSize(type), reg, src, i); - } - } -#endif // TARGET_ARM64 + // If the register piece is to be passed in an integer register + // Use a vector mov to general purpose register instruction + // mov reg, src[i] + // This effectively moves from `src[i]` to `reg` + GetEmitter()->emitIns_R_R_I(INS_mov, emitTypeSize(type), reg, srcReg, i); } } - else // op1 must be multi-reg GT_CALL - { - assert(op1->IsMultiRegCall() || op1->IsCopyOrReloadOfMultiRegCall()); - - genConsumeRegs(op1); - - GenTree* actualOp1 = op1->gtSkipReloadOrCopy(); - GenTreeCall* call = actualOp1->AsCall(); - - const ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc(); - const unsigned regCount = pRetTypeDesc->GetReturnRegCount(); - unsigned matchingCount = 0; - - var_types regType[MAX_RET_REG_COUNT]; - regNumber returnReg[MAX_RET_REG_COUNT]; - regNumber allocatedReg[MAX_RET_REG_COUNT]; - regMaskTP srcRegsMask = 0; - regMaskTP dstRegsMask = 0; - bool needToShuffleRegs = false; // Set to true if we have to move any registers - - for (unsigned i = 0; i < regCount; ++i) - { - regType[i] = pRetTypeDesc->GetReturnRegType(i); - returnReg[i] = pRetTypeDesc->GetABIReturnReg(i); - - regNumber reloadReg = REG_NA; - if (op1->IsCopyOrReload()) - { - // GT_COPY/GT_RELOAD will have valid reg for those positions - // that need to be copied or reloaded. - reloadReg = op1->AsCopyOrReload()->GetRegNumByIdx(i); - } - - if (reloadReg != REG_NA) - { - allocatedReg[i] = reloadReg; - } - else - { - allocatedReg[i] = call->GetRegNumByIdx(i); - } - - if (returnReg[i] == allocatedReg[i]) - { - matchingCount++; - } - else // We need to move this value - { - // We want to move the value from allocatedReg[i] into returnReg[i] - // so record these two registers in the src and dst masks - // - srcRegsMask |= genRegMask(allocatedReg[i]); - dstRegsMask |= genRegMask(returnReg[i]); - - needToShuffleRegs = true; - } - } - - if (needToShuffleRegs) - { - assert(matchingCount < regCount); - - unsigned remainingRegCount = regCount - matchingCount; - regMaskTP extraRegMask = treeNode->gtRsvdRegs; - - while (remainingRegCount > 0) - { - // set 'available' to the 'dst' registers that are not currently holding 'src' registers - // - regMaskTP availableMask = dstRegsMask & ~srcRegsMask; - - regMaskTP dstMask; - regNumber srcReg; - regNumber dstReg; - var_types curType = TYP_UNKNOWN; - regNumber freeUpReg = REG_NA; - - if (availableMask == 0) - { - // Circular register dependencies - // So just free up the lowest register in dstRegsMask by moving it to the 'extra' register - - assert(dstRegsMask == srcRegsMask); // this has to be true for us to reach here - assert(extraRegMask != 0); // we require an 'extra' register - assert((extraRegMask & ~dstRegsMask) != 0); // it can't be part of dstRegsMask - - availableMask = extraRegMask & ~dstRegsMask; - - regMaskTP srcMask = genFindLowestBit(srcRegsMask); - freeUpReg = genRegNumFromMask(srcMask); - } - - dstMask = genFindLowestBit(availableMask); - dstReg = genRegNumFromMask(dstMask); - srcReg = REG_NA; - - if (freeUpReg != REG_NA) - { - // We will free up the srcReg by moving it to dstReg which is an extra register - // - srcReg = freeUpReg; - - // Find the 'srcReg' and set 'curType', change allocatedReg[] to dstReg - // and add the new register mask bit to srcRegsMask - // - for (unsigned i = 0; i < regCount; ++i) - { - if (allocatedReg[i] == srcReg) - { - curType = regType[i]; - allocatedReg[i] = dstReg; - srcRegsMask |= genRegMask(dstReg); - } - } - } - else // The normal case - { - // Find the 'srcReg' and set 'curType' - // - for (unsigned i = 0; i < regCount; ++i) - { - if (returnReg[i] == dstReg) - { - srcReg = allocatedReg[i]; - curType = regType[i]; - } - } - // After we perform this move we will have one less registers to setup - remainingRegCount--; - } - assert(curType != TYP_UNKNOWN); - - inst_RV_RV(ins_Copy(curType), dstReg, srcReg, curType); - - // Clear the appropriate bits in srcRegsMask and dstRegsMask - srcRegsMask &= ~genRegMask(srcReg); - dstRegsMask &= ~genRegMask(dstReg); - - } // while (remainingRegCount > 0) - - } // (needToShuffleRegs) - - } // op1 must be multi-reg GT_CALL } +#endif // FEATURE_SIMD #endif // TARGET_ARMARCH diff --git a/src/coreclr/src/jit/codegencommon.cpp b/src/coreclr/src/jit/codegencommon.cpp index eeae703b43c47..a3c47a2ba2225 100644 --- a/src/coreclr/src/jit/codegencommon.cpp +++ b/src/coreclr/src/jit/codegencommon.cpp @@ -11627,6 +11627,282 @@ void CodeGen::genReturn(GenTree* treeNode) #endif // defined(DEBUG) && defined(TARGET_XARCH) } +//------------------------------------------------------------------------ +// isStructReturn: Returns whether the 'treeNode' is returning a struct. +// +// Arguments: +// treeNode - The tree node to evaluate whether is a struct return. +// +// Return Value: +// Returns true if the 'treeNode" is a GT_RETURN node of type struct. +// Otherwise returns false. +// +bool CodeGen::isStructReturn(GenTree* treeNode) +{ + // This method could be called for 'treeNode' of GT_RET_FILT or GT_RETURN. + // For the GT_RET_FILT, the return is always a bool or a void, for the end of a finally block. + noway_assert(treeNode->OperGet() == GT_RETURN || treeNode->OperGet() == GT_RETFILT); + if (treeNode->OperGet() != GT_RETURN) + { + return false; + } + +#if defined(TARGET_AMD64) && !defined(UNIX_AMD64_ABI) + assert(!varTypeIsStruct(treeNode)); + return false; +#elif defined(TARGET_ARM64) + return varTypeIsStruct(treeNode) && (compiler->info.compRetNativeType == TYP_STRUCT); +#else + return varTypeIsStruct(treeNode); +#endif +} + +//------------------------------------------------------------------------ +// genStructReturn: Generates code for returning a struct. +// +// Arguments: +// treeNode - The GT_RETURN tree node. +// +// Return Value: +// None +// +// Assumption: +// op1 of GT_RETURN node is either GT_LCL_VAR or multi-reg GT_CALL +// +void CodeGen::genStructReturn(GenTree* treeNode) +{ + assert(treeNode->OperGet() == GT_RETURN); + GenTree* op1 = treeNode->gtGetOp1(); + genConsumeRegs(op1); + GenTree* actualOp1 = op1; + if (op1->IsCopyOrReload()) + { + actualOp1 = op1->gtGetOp1(); + } + + ReturnTypeDesc retTypeDesc; + LclVarDsc* varDsc = nullptr; + if (actualOp1->OperIs(GT_LCL_VAR)) + { + varDsc = compiler->lvaGetDesc(actualOp1->AsLclVar()->GetLclNum()); + retTypeDesc.InitializeStructReturnType(compiler, varDsc->lvVerTypeInfo.GetClassHandle()); + } + else + { + assert(actualOp1->OperIs(GT_CALL)); + retTypeDesc = *(actualOp1->AsCall()->GetReturnTypeDesc()); + } + unsigned regCount = retTypeDesc.GetReturnRegCount(); + assert(regCount <= MAX_RET_REG_COUNT); + +#if FEATURE_MULTIREG_RET + if (actualOp1->OperIs(GT_LCL_VAR) && (varTypeIsEnregisterable(op1))) + { + // Right now the only enregisterable structs supported are SIMD vector types. + assert(varTypeIsSIMD(op1)); +#ifdef FEATURE_SIMD + genSIMDSplitReturn(op1, &retTypeDesc); +#endif // FEATURE_SIMD + } + else if (actualOp1->OperIs(GT_LCL_VAR)) + { + GenTreeLclVar* lclNode = actualOp1->AsLclVar(); + LclVarDsc* varDsc = compiler->lvaGetDesc(lclNode->GetLclNum()); + assert(varDsc->lvIsMultiRegRet); + int offset = 0; + for (unsigned i = 0; i < regCount; ++i) + { + var_types type = retTypeDesc.GetReturnRegType(i); + regNumber toReg = retTypeDesc.GetABIReturnReg(i); + GetEmitter()->emitIns_R_S(ins_Load(type), emitTypeSize(type), toReg, lclNode->GetLclNum(), offset); + offset += genTypeSize(type); + } + } + else + { + assert(actualOp1->IsMultiRegCall()); + for (unsigned i = 0; i < regCount; ++i) + { + var_types type = retTypeDesc.GetReturnRegType(i); + regNumber toReg = retTypeDesc.GetABIReturnReg(i); + regNumber fromReg = op1->GetRegByIndex(i); + if (fromReg == REG_NA) + { + assert(op1->IsCopyOrReload()); + fromReg = actualOp1->GetRegByIndex(i); + } + if (fromReg != toReg) + { + inst_RV_RV(ins_Copy(type), toReg, fromReg, type); + } + } + } +#else // !FEATURE_MULTIREG_RET + unreached(); +#endif +} + +//------------------------------------------------------------------------ +// genRegCopy: Produce code for a GT_COPY node. +// +// Arguments: +// tree - the GT_COPY node +// +// Notes: +// This will copy the register(s) produced by this nodes source, to +// the register(s) allocated to this GT_COPY node. +// It has some special handling for these casess: +// - when the source and target registers are in different register files +// (note that this is *not* a conversion). +// - when the source is a lclVar whose home location is being moved to a new +// register (rather than just being copied for temporary use). +// +void CodeGen::genRegCopy(GenTree* treeNode) +{ + assert(treeNode->OperGet() == GT_COPY); + GenTree* op1 = treeNode->AsOp()->gtOp1; + + if (op1->IsMultiRegNode()) + { + // Register allocation assumes that any reload and copy are done in operand order. + // That is, we can have: + // (reg0, reg1) = COPY(V0,V1) where V0 is in reg1 and V1 is in memory + // The register allocation model assumes: + // First, V0 is moved to reg0 (v1 can't be in reg0 because it is still live, which would be a conflict). + // Then, V1 is moved to reg1 + // However, if we call genConsumeRegs on op1, it will do the reload of V1 before we do the copy of V0. + // So we need to handle that case first. + // + // There should never be any circular dependencies, and we will check that here. + + GenTreeCopyOrReload* copyNode = treeNode->AsCopyOrReload(); + unsigned regCount = copyNode->GetRegCount(); + // GenTreeCopyOrReload only reports the number of registers that are valid. + assert(regCount <= 2); + + // First set the source registers as busy if they haven't been spilled. + // (Note that this is just for verification that we don't have circular dependencies.) + regMaskTP busyRegs = RBM_NONE; + for (unsigned i = 0; i < regCount; ++i) + { + if ((op1->GetRegSpillFlagByIdx(i) & GTF_SPILLED) == 0) + { + busyRegs |= genRegMask(op1->GetRegByIndex(i)); + } + } + // First do any copies - we'll do the reloads after all the copies are complete. + for (unsigned i = 0; i < regCount; ++i) + { + regNumber sourceReg = op1->GetRegByIndex(i); + regNumber targetReg = copyNode->GetRegNumByIdx(i); + regMaskTP targetRegMask = genRegMask(targetReg); + // GenTreeCopyOrReload only reports the number of registers that are valid. + if (targetReg != REG_NA) + { + // We shouldn't specify a no-op move. + assert(sourceReg != targetReg); + assert((busyRegs & targetRegMask) == 0); + // Clear sourceReg from the busyRegs, and add targetReg. + busyRegs &= ~genRegMask(sourceReg); + busyRegs |= genRegMask(targetReg); + var_types type; + if (op1->IsMultiRegLclVar()) + { + type = op1->AsLclVar()->GetFieldTypeByIndex(compiler, i); + } + else + { + type = op1->GetRegTypeByIndex(i); + } + inst_RV_RV(ins_Copy(type), targetReg, sourceReg, type); + } + } + // Now we can consume op1, which will perform any necessary reloads. + genConsumeReg(op1); + } + else + { + var_types targetType = treeNode->TypeGet(); + regNumber targetReg = treeNode->GetRegNum(); + assert(targetReg != REG_NA); + assert(targetType != TYP_STRUCT); + + // Check whether this node and the node from which we're copying the value have + // different register types. This can happen if (currently iff) we have a SIMD + // vector type that fits in an integer register, in which case it is passed as + // an argument, or returned from a call, in an integer register and must be + // copied if it's in an xmm register. + + bool srcFltReg = (varTypeIsFloating(op1) || varTypeIsSIMD(op1)); + bool tgtFltReg = (varTypeIsFloating(treeNode) || varTypeIsSIMD(treeNode)); + if (srcFltReg != tgtFltReg) + { + instruction ins; + regNumber fpReg; + regNumber intReg; + if (tgtFltReg) + { + ins = ins_CopyIntToFloat(op1->TypeGet(), treeNode->TypeGet()); + fpReg = targetReg; + intReg = op1->GetRegNum(); + } + else + { + ins = ins_CopyFloatToInt(op1->TypeGet(), treeNode->TypeGet()); + intReg = targetReg; + fpReg = op1->GetRegNum(); + } + inst_RV_RV(ins, fpReg, intReg, targetType); + } + else + { + inst_RV_RV(ins_Copy(targetType), targetReg, genConsumeReg(op1), targetType); + } + + if (op1->IsLocal()) + { + // The lclVar will never be a def. + // If it is a last use, the lclVar will be killed by genConsumeReg(), as usual, and genProduceReg will + // appropriately set the gcInfo for the copied value. + // If not, there are two cases we need to handle: + // - If this is a TEMPORARY copy (indicated by the GTF_VAR_DEATH flag) the variable + // will remain live in its original register. + // genProduceReg() will appropriately set the gcInfo for the copied value, + // and genConsumeReg will reset it. + // - Otherwise, we need to update register info for the lclVar. + + GenTreeLclVarCommon* lcl = op1->AsLclVarCommon(); + assert((lcl->gtFlags & GTF_VAR_DEF) == 0); + + if ((lcl->gtFlags & GTF_VAR_DEATH) == 0 && (treeNode->gtFlags & GTF_VAR_DEATH) == 0) + { + LclVarDsc* varDsc = compiler->lvaGetDesc(lcl); + + // If we didn't just spill it (in genConsumeReg, above), then update the register info + if (varDsc->GetRegNum() != REG_STK) + { + // The old location is dying + genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(op1)); + + gcInfo.gcMarkRegSetNpt(genRegMask(op1->GetRegNum())); + + genUpdateVarReg(varDsc, treeNode); + +#ifdef USING_VARIABLE_LIVE_RANGE + // Report the home change for this variable + varLiveKeeper->siUpdateVariableLiveRange(varDsc, lcl->GetLclNum()); +#endif // USING_VARIABLE_LIVE_RANGE + + // The new location is going live + genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(treeNode)); + } + } + } + } + + genProduceReg(treeNode); +} + #if defined(DEBUG) && defined(TARGET_XARCH) //------------------------------------------------------------------------ diff --git a/src/coreclr/src/jit/codegenlinear.cpp b/src/coreclr/src/jit/codegenlinear.cpp index fe6199f1d1adb..b9ed297495f64 100644 --- a/src/coreclr/src/jit/codegenlinear.cpp +++ b/src/coreclr/src/jit/codegenlinear.cpp @@ -938,6 +938,86 @@ GenTree* sameRegAsDst(GenTree* tree, GenTree*& other /*out*/) } } +//------------------------------------------------------------------------ +// genUnspillLocal: Reload a register candidate local into a register. +// +// Arguments: +// varNum - The variable number of the local to be reloaded (unspilled). +// It may be a local field. +// type - The type of the local. +// lclNode - The node being unspilled. Note that for a multi-reg local, +// the gtLclNum will be that of the parent struct. +// regNum - The register that 'varNum' should be loaded to. +// reSpill - True if it will be immediately spilled after use. +// isLastUse - True if this is a last use of 'varNum'. +// +// Notes: +// The caller must have determined that this local needs to be unspilled. +void CodeGen::genUnspillLocal( + unsigned varNum, var_types type, GenTreeLclVar* lclNode, regNumber regNum, bool reSpill, bool isLastUse) +{ + LclVarDsc* varDsc = compiler->lvaGetDesc(varNum); + inst_set_SV_var(lclNode); + instruction ins = ins_Load(type, compiler->isSIMDTypeLocalAligned(varNum)); + GetEmitter()->emitIns_R_S(ins, emitTypeSize(type), regNum, varNum, 0); + + // TODO-Review: We would like to call: + // genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(tree)); + // instead of the following code, but this ends up hitting this assert: + // assert((regSet.GetMaskVars() & regMask) == 0); + // due to issues with LSRA resolution moves. + // So, just force it for now. This probably indicates a condition that creates a GC hole! + // + // Extra note: I think we really want to call something like gcInfo.gcUpdateForRegVarMove, + // because the variable is not really going live or dead, but that method is somewhat poorly + // factored because it, in turn, updates rsMaskVars which is part of RegSet not GCInfo. + // TODO-Cleanup: This code exists in other CodeGen*.cpp files, and should be moved to CodeGenCommon.cpp. + + // Don't update the variable's location if we are just re-spilling it again. + + if (!reSpill) + { + varDsc->SetRegNum(regNum); + +#ifdef USING_VARIABLE_LIVE_RANGE + // We want "VariableLiveRange" inclusive on the beginning and exclusive on the ending. + // For that we shouldn't report an update of the variable location if is becoming dead + // on the same native offset. + if (!isLastUse) + { + // Report the home change for this variable + varLiveKeeper->siUpdateVariableLiveRange(varDsc, varNum); + } +#endif // USING_VARIABLE_LIVE_RANGE + + if (!varDsc->lvLiveInOutOfHndlr) + { +#ifdef DEBUG + if (VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex)) + { + JITDUMP("\t\t\t\t\t\t\tRemoving V%02u from gcVarPtrSetCur\n", varNum); + } +#endif // DEBUG + VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex); + } + +#ifdef DEBUG + if (compiler->verbose) + { + printf("\t\t\t\t\t\t\tV%02u in reg ", varNum); + varDsc->PrintVarReg(); + printf(" is becoming live "); + compiler->printTreeID(lclNode); + printf("\n"); + } +#endif // DEBUG + + regSet.AddMaskVars(genGetRegMask(varDsc)); + } + + gcInfo.gcMarkRegPtrVal(regNum, type); +} + //------------------------------------------------------------------------ // genUnspillRegIfNeeded: Reload the value into a register, if needed // @@ -968,8 +1048,9 @@ void CodeGen::genUnspillRegIfNeeded(GenTree* tree) // Reset spilled flag, since we are going to load a local variable from its home location. unspillTree->gtFlags &= ~GTF_SPILLED; - GenTreeLclVarCommon* lcl = unspillTree->AsLclVarCommon(); - LclVarDsc* varDsc = &compiler->lvaTable[lcl->GetLclNum()]; + GenTreeLclVar* lcl = unspillTree->AsLclVar(); + LclVarDsc* varDsc = compiler->lvaGetDesc(lcl->GetLclNum()); + var_types spillType = unspillTree->TypeGet(); // TODO-Cleanup: The following code could probably be further merged and cleaned up. #ifdef TARGET_XARCH @@ -985,99 +1066,26 @@ void CodeGen::genUnspillRegIfNeeded(GenTree* tree) // In the normalizeOnLoad case ins_Load will return an appropriate sign- or zero- // extending load. - var_types treeType = unspillTree->TypeGet(); - if (treeType != genActualType(varDsc->lvType) && !varTypeIsGC(treeType) && !varDsc->lvNormalizeOnLoad()) + if (spillType != genActualType(varDsc->lvType) && !varTypeIsGC(spillType) && !varDsc->lvNormalizeOnLoad()) { assert(!varTypeIsGC(varDsc)); - var_types spillType = genActualType(varDsc->lvType); - unspillTree->gtType = spillType; - inst_RV_TT(ins_Load(spillType, compiler->isSIMDTypeLocalAligned(lcl->GetLclNum())), dstReg, - unspillTree); - unspillTree->gtType = treeType; - } - else - { - inst_RV_TT(ins_Load(treeType, compiler->isSIMDTypeLocalAligned(lcl->GetLclNum())), dstReg, unspillTree); + spillType = genActualType(varDsc->lvType); } #elif defined(TARGET_ARM64) var_types targetType = unspillTree->gtType; - if (targetType != genActualType(varDsc->lvType) && !varTypeIsGC(targetType) && !varDsc->lvNormalizeOnLoad()) + if (spillType != genActualType(varDsc->lvType) && !varTypeIsGC(spillType) && !varDsc->lvNormalizeOnLoad()) { assert(!varTypeIsGC(varDsc)); - targetType = genActualType(varDsc->lvType); + spillType = genActualType(varDsc->lvType); } - instruction ins = ins_Load(targetType, compiler->isSIMDTypeLocalAligned(lcl->GetLclNum())); - emitAttr attr = emitActualTypeSize(targetType); - emitter* emit = GetEmitter(); - - // Load local variable from its home location. - inst_RV_TT(ins, dstReg, unspillTree, 0, attr); #elif defined(TARGET_ARM) - var_types targetType = unspillTree->gtType; - instruction ins = ins_Load(targetType, compiler->isSIMDTypeLocalAligned(lcl->GetLclNum())); - emitAttr attr = emitTypeSize(targetType); - - // Load local variable from its home location. - inst_RV_TT(ins, dstReg, unspillTree, 0, attr); +// No normalizing for ARM #else NYI("Unspilling not implemented for this target architecture."); #endif - - // TODO-Review: We would like to call: - // genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(tree)); - // instead of the following code, but this ends up hitting this assert: - // assert((regSet.GetMaskVars() & regMask) == 0); - // due to issues with LSRA resolution moves. - // So, just force it for now. This probably indicates a condition that creates a GC hole! - // - // Extra note: I think we really want to call something like gcInfo.gcUpdateForRegVarMove, - // because the variable is not really going live or dead, but that method is somewhat poorly - // factored because it, in turn, updates rsMaskVars which is part of RegSet not GCInfo. - // TODO-Cleanup: This code exists in other CodeGen*.cpp files, and should be moved to CodeGenCommon.cpp. - - // Don't update the variable's location if we are just re-spilling it again. - - if ((unspillTree->gtFlags & GTF_SPILL) == 0) - { - genUpdateVarReg(varDsc, tree); - -#ifdef USING_VARIABLE_LIVE_RANGE - // We want "VariableLiveRange" inclusive on the beginbing and exclusive on the ending. - // For that we shouldn't report an update of the variable location if is becoming dead - // on the same native offset. - if ((unspillTree->gtFlags & GTF_VAR_DEATH) == 0) - { - // Report the home change for this variable - varLiveKeeper->siUpdateVariableLiveRange(varDsc, lcl->GetLclNum()); - } -#endif // USING_VARIABLE_LIVE_RANGE - - if (!varDsc->lvLiveInOutOfHndlr) - { -#ifdef DEBUG - if (VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex)) - { - JITDUMP("\t\t\t\t\t\t\tRemoving V%02u from gcVarPtrSetCur\n", lcl->GetLclNum()); - } -#endif // DEBUG - VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex); - } - -#ifdef DEBUG - if (compiler->verbose) - { - printf("\t\t\t\t\t\t\tV%02u in reg ", lcl->GetLclNum()); - varDsc->PrintVarReg(); - printf(" is becoming live "); - compiler->printTreeID(unspillTree); - printf("\n"); - } -#endif // DEBUG - - regSet.AddMaskVars(genGetRegMask(varDsc)); - } - - gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet()); + bool reSpill = ((unspillTree->gtFlags & GTF_SPILL) != 0); + bool isLastUse = lcl->IsLastUse(0); + genUnspillLocal(lcl->GetLclNum(), spillType, lcl, dstReg, reSpill, isLastUse); } else if (unspillTree->IsMultiRegCall()) { @@ -1849,6 +1857,41 @@ void CodeGen::genConsumeBlockOp(GenTreeBlk* blkNode, regNumber dstReg, regNumber genSetBlockSize(blkNode, sizeReg); } +//------------------------------------------------------------------------- +// genSpillLocal: Generate the actual spill of a local var. +// +// Arguments: +// varNum - The variable number of the local to be spilled. +// It may be a local field. +// type - The type of the local. +// lclNode - The node being spilled. Note that for a multi-reg local, +// the gtLclNum will be that of the parent struct. +// regNum - The register that 'varNum' is currently in. +// +// Return Value: +// None. +// +void CodeGen::genSpillLocal(unsigned varNum, var_types type, GenTreeLclVar* lclNode, regNumber regNum) +{ + LclVarDsc* varDsc = compiler->lvaGetDesc(varNum); + assert(!varDsc->lvNormalizeOnStore() || (type == genActualType(varDsc->TypeGet()))); + + // We have a register candidate local that is marked with GTF_SPILL. + // This flag generally means that we need to spill this local. + // The exception is the case of a use of an EH var use that is being "spilled" + // to the stack, indicated by GTF_SPILL (note that all EH lclVar defs are always + // spilled, i.e. write-thru). + // An EH var use is always valid on the stack (so we don't need to actually spill it), + // but the GTF_SPILL flag records the fact that the register value is going dead. + if (((lclNode->gtFlags & GTF_VAR_DEF) != 0) || !varDsc->lvLiveInOutOfHndlr) + { + // Store local variable to its home location. + // Ensure that lclVar stores are typed correctly. + GetEmitter()->emitIns_S_R(ins_Store(type, compiler->isSIMDTypeLocalAligned(varNum)), emitTypeSize(type), regNum, + varNum, 0); + } +} + //------------------------------------------------------------------------- // genProduceReg: do liveness update for register produced by the current // node in codegen after code has been emitted for it. @@ -1877,24 +1920,8 @@ void CodeGen::genProduceReg(GenTree* tree) if (genIsRegCandidateLocal(tree)) { - unsigned varNum = tree->AsLclVarCommon()->GetLclNum(); - LclVarDsc* varDsc = compiler->lvaGetDesc(varNum); - assert(!varDsc->lvNormalizeOnStore() || (tree->TypeGet() == genActualType(varDsc->TypeGet()))); - - // If we reach here, we have a register candidate local that is marked with GTF_SPILL. - // This flag generally means that we need to spill this local. - // The exception is the case of a use of an EH var use that is being "spilled" - // to the stack, indicated by GTF_SPILL (note that all EH lclVar defs are always - // spilled, i.e. write-thru). - // An EH var use is always valid on the stack (so we don't need to actually spill it), - // but the GTF_SPILL flag records the fact that the register value is going dead. - if (((tree->gtFlags & GTF_VAR_DEF) != 0) || !varDsc->lvLiveInOutOfHndlr) - { - // Store local variable to its home location. - // Ensure that lclVar stores are typed correctly. - inst_TT_RV(ins_Store(tree->gtType, compiler->isSIMDTypeLocalAligned(varNum)), - emitTypeSize(tree->TypeGet()), tree, tree->GetRegNum()); - } + unsigned varNum = tree->AsLclVarCommon()->GetLclNum(); + genSpillLocal(varNum, tree->TypeGet(), tree->AsLclVar(), tree->GetRegNum()); } else { @@ -1983,8 +2010,8 @@ void CodeGen::genProduceReg(GenTree* tree) // the register as live, with a GC pointer, if the variable is dead. if (!genIsRegCandidateLocal(tree) || ((tree->gtFlags & GTF_VAR_DEATH) == 0)) { - // Multi-reg call node will produce more than one register result. - // Mark all the regs produced by call node. + // Multi-reg nodes will produce more than one register result. + // Mark all the regs produced by the node. if (tree->IsMultiRegCall()) { const GenTreeCall* call = tree->AsCall(); diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index 10fa1681ff8de..e6bb678d93a26 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -1124,214 +1124,55 @@ void CodeGen::genCodeForMul(GenTreeOp* treeNode) genProduceReg(treeNode); } +#ifdef FEATURE_SIMD //------------------------------------------------------------------------ -// isStructReturn: Returns whether the 'treeNode' is returning a struct. +// genSIMDSplitReturn: Generates code for returning a fixed-size SIMD type that lives +// in a single register, but is returned in multiple registers. // // Arguments: -// treeNode - The tree node to evaluate whether is a struct return. -// -// Return Value: -// For AMD64 *nix: returns true if the 'treeNode" is a GT_RETURN node, of type struct. -// Otherwise returns false. -// For other platforms always returns false. +// src - The source of the return +// retTypeDesc - The return type descriptor. // -bool CodeGen::isStructReturn(GenTree* treeNode) +void CodeGen::genSIMDSplitReturn(GenTree* src, ReturnTypeDesc* retTypeDesc) { - // This method could be called for 'treeNode' of GT_RET_FILT or GT_RETURN. - // For the GT_RET_FILT, the return is always - // a bool or a void, for the end of a finally block. - noway_assert(treeNode->OperGet() == GT_RETURN || treeNode->OperGet() == GT_RETFILT); - if (treeNode->OperGet() != GT_RETURN) - { - return false; - } + assert(varTypeIsSIMD(src)); + assert(src->isUsedFromReg()); -#ifdef UNIX_AMD64_ABI - return varTypeIsStruct(treeNode); -#else // !UNIX_AMD64_ABI - assert(!varTypeIsStruct(treeNode)); - return false; -#endif // UNIX_AMD64_ABI -} + // This is a case of operand is in a single reg and needs to be + // returned in multiple ABI return registers. + regNumber opReg = src->GetRegNum(); + regNumber reg0 = retTypeDesc->GetABIReturnReg(0); + regNumber reg1 = retTypeDesc->GetABIReturnReg(1); -//------------------------------------------------------------------------ -// genStructReturn: Generates code for returning a struct. -// -// Arguments: -// treeNode - The GT_RETURN tree node. -// -// Return Value: -// None -// -// Assumption: -// op1 of GT_RETURN node is either GT_LCL_VAR or multi-reg GT_CALL -void CodeGen::genStructReturn(GenTree* treeNode) -{ - assert(treeNode->OperGet() == GT_RETURN); - GenTree* op1 = treeNode->gtGetOp1(); - -#ifdef UNIX_AMD64_ABI - if (op1->OperGet() == GT_LCL_VAR) + if (opReg != reg0 && opReg != reg1) { - GenTreeLclVarCommon* lclVar = op1->AsLclVarCommon(); - LclVarDsc* varDsc = &(compiler->lvaTable[lclVar->GetLclNum()]); - assert(varDsc->lvIsMultiRegRet); - - ReturnTypeDesc retTypeDesc; - retTypeDesc.InitializeStructReturnType(compiler, varDsc->lvVerTypeInfo.GetClassHandle()); - const unsigned regCount = retTypeDesc.GetReturnRegCount(); - assert(regCount == MAX_RET_REG_COUNT); - - if (varTypeIsEnregisterable(op1)) - { - // Right now the only enregisterable structs supported are SIMD vector types. - assert(varTypeIsSIMD(op1)); - assert(op1->isUsedFromReg()); - - // This is a case of operand is in a single reg and needs to be - // returned in multiple ABI return registers. - regNumber opReg = genConsumeReg(op1); - regNumber reg0 = retTypeDesc.GetABIReturnReg(0); - regNumber reg1 = retTypeDesc.GetABIReturnReg(1); - - if (opReg != reg0 && opReg != reg1) - { - // Operand reg is different from return regs. - // Copy opReg to reg0 and let it to be handled by one of the - // two cases below. - inst_RV_RV(ins_Copy(TYP_DOUBLE), reg0, opReg, TYP_DOUBLE); - opReg = reg0; - } - - if (opReg == reg0) - { - assert(opReg != reg1); - - // reg0 - already has required 8-byte in bit position [63:0]. - // reg1 = opReg. - // swap upper and lower 8-bytes of reg1 so that desired 8-byte is in bit position [63:0]. - inst_RV_RV(ins_Copy(TYP_DOUBLE), reg1, opReg, TYP_DOUBLE); - } - else - { - assert(opReg == reg1); + // Operand reg is different from return regs. + // Copy opReg to reg0 and let it to be handled by one of the + // two cases below. + inst_RV_RV(ins_Copy(TYP_DOUBLE), reg0, opReg, TYP_DOUBLE); + opReg = reg0; + } - // reg0 = opReg. - // swap upper and lower 8-bytes of reg1 so that desired 8-byte is in bit position [63:0]. - inst_RV_RV(ins_Copy(TYP_DOUBLE), reg0, opReg, TYP_DOUBLE); - } - inst_RV_RV_IV(INS_shufpd, EA_16BYTE, reg1, reg1, 0x01); - } - else - { - assert(op1->isUsedFromMemory()); + if (opReg == reg0) + { + assert(opReg != reg1); - // Copy var on stack into ABI return registers - int offset = 0; - for (unsigned i = 0; i < regCount; ++i) - { - var_types type = retTypeDesc.GetReturnRegType(i); - regNumber reg = retTypeDesc.GetABIReturnReg(i); - GetEmitter()->emitIns_R_S(ins_Load(type), emitTypeSize(type), reg, lclVar->GetLclNum(), offset); - offset += genTypeSize(type); - } - } + // reg0 - already has required 8-byte in bit position [63:0]. + // reg1 = opReg. + // swap upper and lower 8-bytes of reg1 so that desired 8-byte is in bit position [63:0]. + inst_RV_RV(ins_Copy(TYP_DOUBLE), reg1, opReg, TYP_DOUBLE); } else { - assert(op1->IsMultiRegCall() || op1->IsCopyOrReloadOfMultiRegCall()); + assert(opReg == reg1); - genConsumeRegs(op1); - - const GenTree* actualOp1 = op1->gtSkipReloadOrCopy(); - const GenTreeCall* call = actualOp1->AsCall(); - const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - const unsigned regCount = retTypeDesc->GetReturnRegCount(); - assert(regCount == MAX_RET_REG_COUNT); - - // Handle circular dependency between call allocated regs and ABI return regs. - // - // It is possible under LSRA stress that originally allocated regs of call node, - // say rax and rdx, are spilled and reloaded to rdx and rax respectively. But - // GT_RETURN needs to move values as follows: rdx->rax, rax->rdx. Similar kind - // kind of circular dependency could arise between xmm0 and xmm1 return regs. - // Codegen is expected to handle such circular dependency. - // - var_types regType0 = retTypeDesc->GetReturnRegType(0); - regNumber returnReg0 = retTypeDesc->GetABIReturnReg(0); - regNumber allocatedReg0 = call->GetRegNumByIdx(0); - - var_types regType1 = retTypeDesc->GetReturnRegType(1); - regNumber returnReg1 = retTypeDesc->GetABIReturnReg(1); - regNumber allocatedReg1 = call->GetRegNumByIdx(1); - - if (op1->IsCopyOrReload()) - { - // GT_COPY/GT_RELOAD will have valid reg for those positions - // that need to be copied or reloaded. - regNumber reloadReg = op1->AsCopyOrReload()->GetRegNumByIdx(0); - if (reloadReg != REG_NA) - { - allocatedReg0 = reloadReg; - } - - reloadReg = op1->AsCopyOrReload()->GetRegNumByIdx(1); - if (reloadReg != REG_NA) - { - allocatedReg1 = reloadReg; - } - } - - if (allocatedReg0 == returnReg1 && allocatedReg1 == returnReg0) - { - // Circular dependency - swap allocatedReg0 and allocatedReg1 - if (varTypeIsFloating(regType0)) - { - assert(varTypeIsFloating(regType1)); - - // The fastest way to swap two XMM regs is using PXOR - inst_RV_RV(INS_pxor, allocatedReg0, allocatedReg1, TYP_DOUBLE); - inst_RV_RV(INS_pxor, allocatedReg1, allocatedReg0, TYP_DOUBLE); - inst_RV_RV(INS_pxor, allocatedReg0, allocatedReg1, TYP_DOUBLE); - } - else - { - assert(varTypeIsIntegral(regType0)); - assert(varTypeIsIntegral(regType1)); - inst_RV_RV(INS_xchg, allocatedReg1, allocatedReg0, TYP_I_IMPL); - } - } - else if (allocatedReg1 == returnReg0) - { - // Change the order of moves to correctly handle dependency. - if (allocatedReg1 != returnReg1) - { - inst_RV_RV(ins_Copy(regType1), returnReg1, allocatedReg1, regType1); - } - - if (allocatedReg0 != returnReg0) - { - inst_RV_RV(ins_Copy(regType0), returnReg0, allocatedReg0, regType0); - } - } - else - { - // No circular dependency case. - if (allocatedReg0 != returnReg0) - { - inst_RV_RV(ins_Copy(regType0), returnReg0, allocatedReg0, regType0); - } - - if (allocatedReg1 != returnReg1) - { - inst_RV_RV(ins_Copy(regType1), returnReg1, allocatedReg1, regType1); - } - } + // reg0 = opReg. + // swap upper and lower 8-bytes of reg1 so that desired 8-byte is in bit position [63:0]. + inst_RV_RV(ins_Copy(TYP_DOUBLE), reg0, opReg, TYP_DOUBLE); } -#else - unreached(); -#endif + inst_RV_RV_IV(INS_shufpd, EA_16BYTE, reg1, reg1, 0x01); } +#endif // FEATURE_SIMD #if defined(TARGET_X86) @@ -2009,7 +1850,7 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) } //---------------------------------------------------------------------------------- -// genMultiRegCallStoreToLocal: store multi-reg return value of a call node to a local +// genMultiRegStoreToLocal: store multi-reg return value of a call node to a local // // Arguments: // treeNode - Gentree of GT_STORE_LCL_VAR @@ -2017,45 +1858,52 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) // Return Value: // None // -// Assumption: -// The child of store is a multi-reg call node. -// genProduceReg() on treeNode is made by caller of this routine. +// Assumptions: +// The child of store is a multi-reg node. // -void CodeGen::genMultiRegCallStoreToLocal(GenTree* treeNode) +void CodeGen::genMultiRegStoreToLocal(GenTree* treeNode) { assert(treeNode->OperGet() == GT_STORE_LCL_VAR); + assert(varTypeIsStruct(treeNode) || varTypeIsMultiReg(treeNode)); + GenTree* op1 = treeNode->gtGetOp1(); + GenTree* actualOp1 = op1->gtSkipReloadOrCopy(); + assert(op1->IsMultiRegNode()); + unsigned regCount = op1->GetMultiRegCount(); -#ifdef UNIX_AMD64_ABI - // Structs of size >=9 and <=16 are returned in two return registers on x64 Unix. - assert(varTypeIsStruct(treeNode)); - - // Assumption: current x64 Unix implementation requires that a multi-reg struct + // Assumption: The current implementation requires that a multi-reg // var in 'var = call' is flagged as lvIsMultiRegRet to prevent it from // being struct promoted. - unsigned lclNum = treeNode->AsLclVarCommon()->GetLclNum(); - LclVarDsc* varDsc = &(compiler->lvaTable[lclNum]); - noway_assert(varDsc->lvIsMultiRegRet); - GenTree* op1 = treeNode->gtGetOp1(); - GenTree* actualOp1 = op1->gtSkipReloadOrCopy(); - GenTreeCall* call = actualOp1->AsCall(); - assert(call->HasMultiRegRetVal()); + unsigned lclNum = treeNode->AsLclVarCommon()->GetLclNum(); + LclVarDsc* varDsc = compiler->lvaGetDesc(lclNum); + if (op1->OperIs(GT_CALL)) + { + assert(regCount == MAX_RET_REG_COUNT); + noway_assert(varDsc->lvIsMultiRegRet); + } genConsumeRegs(op1); - const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - assert(retTypeDesc->GetReturnRegCount() == MAX_RET_REG_COUNT); - unsigned regCount = retTypeDesc->GetReturnRegCount(); +#ifdef UNIX_AMD64_ABI + // Structs of size >=9 and <=16 are returned in two return registers on x64 Unix. - if (treeNode->GetRegNum() != REG_NA) + // Handle the case of a SIMD type returned in 2 registers. + if (varTypeIsSIMD(treeNode) && (treeNode->GetRegNum() != REG_NA)) { // Right now the only enregistrable structs supported are SIMD types. - assert(varTypeIsSIMD(treeNode)); + // They are only returned in 1 or 2 registers - the 1 register case is + // handled as a regular STORE_LCL_VAR. + // This case is always a call (AsCall() will assert if it is not). + GenTreeCall* call = actualOp1->AsCall(); + const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); + assert(retTypeDesc->GetReturnRegCount() == MAX_RET_REG_COUNT); + + assert(regCount == 2); assert(varTypeIsFloating(retTypeDesc->GetReturnRegType(0))); assert(varTypeIsFloating(retTypeDesc->GetReturnRegType(1))); - // This is a case of two 8-bytes that comprise the operand is in - // two different xmm registers and needs to assembled into a single + // This is a case where the two 8-bytes that comprise the operand are in + // two different xmm registers and need to be assembled into a single // xmm register. regNumber targetReg = treeNode->GetRegNum(); regNumber reg0 = call->GetRegNumByIdx(0); @@ -2111,13 +1959,17 @@ void CodeGen::genMultiRegCallStoreToLocal(GenTree* treeNode) } } else +#endif // UNIX_AMD64_ABI { - // Stack store + // This may be: + // - a call returning multiple registers + // - a HW intrinsic producing two registers to be stored into a TYP_STRUCT + // int offset = 0; for (unsigned i = 0; i < regCount; ++i) { - var_types type = retTypeDesc->GetReturnRegType(i); - regNumber reg = call->GetRegNumByIdx(i); + var_types type = op1->GetRegTypeByIndex(i); + regNumber reg = op1->GetRegByIndex(i); if (op1->IsCopyOrReload()) { // GT_COPY/GT_RELOAD will have valid reg for those positions @@ -2133,57 +1985,10 @@ void CodeGen::genMultiRegCallStoreToLocal(GenTree* treeNode) GetEmitter()->emitIns_S_R(ins_Store(type), emitTypeSize(type), reg, lclNum, offset); offset += genTypeSize(type); } - + // Update variable liveness. + genUpdateLife(treeNode); varDsc->SetRegNum(REG_STK); } -#elif defined(TARGET_X86) - // Longs are returned in two return registers on x86. - assert(varTypeIsLong(treeNode)); - - // Assumption: current x86 implementation requires that a multi-reg long - // var in 'var = call' is flagged as lvIsMultiRegRet to prevent it from - // being promoted. - unsigned lclNum = treeNode->AsLclVarCommon()->GetLclNum(); - LclVarDsc* varDsc = &(compiler->lvaTable[lclNum]); - noway_assert(varDsc->lvIsMultiRegRet); - - GenTree* op1 = treeNode->gtGetOp1(); - GenTree* actualOp1 = op1->gtSkipReloadOrCopy(); - GenTreeCall* call = actualOp1->AsCall(); - assert(call->HasMultiRegRetVal()); - - genConsumeRegs(op1); - - const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - unsigned regCount = retTypeDesc->GetReturnRegCount(); - assert(regCount == MAX_RET_REG_COUNT); - - // Stack store - int offset = 0; - for (unsigned i = 0; i < regCount; ++i) - { - var_types type = retTypeDesc->GetReturnRegType(i); - regNumber reg = call->GetRegNumByIdx(i); - if (op1->IsCopyOrReload()) - { - // GT_COPY/GT_RELOAD will have valid reg for those positions - // that need to be copied or reloaded. - regNumber reloadReg = op1->AsCopyOrReload()->GetRegNumByIdx(i); - if (reloadReg != REG_NA) - { - reg = reloadReg; - } - } - - assert(reg != REG_NA); - GetEmitter()->emitIns_S_R(ins_Store(type), emitTypeSize(type), reg, lclNum, offset); - offset += genTypeSize(type); - } - - varDsc->SetRegNum(REG_STK); -#else // !UNIX_AMD64_ABI && !TARGET_X86 - assert(!"Unreached"); -#endif // !UNIX_AMD64_ABI && !TARGET_X86 } //------------------------------------------------------------------------ @@ -4636,9 +4441,9 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree) // var = call, where call returns a multi-reg return value // case is handled separately. - if (op1->gtSkipReloadOrCopy()->IsMultiRegCall()) + if (op1->gtSkipReloadOrCopy()->IsMultiRegNode()) { - genMultiRegCallStoreToLocal(tree); + genMultiRegStoreToLocal(tree); } else { @@ -4874,130 +4679,6 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree) genProduceReg(tree); } -//------------------------------------------------------------------------ -// genRegCopy: Produce code for a GT_COPY node. -// -// Arguments: -// tree - the GT_COPY node -// -// Notes: -// This will copy the register(s) produced by this nodes source, to -// the register(s) allocated to this GT_COPY node. -// It has some special handling for these casess: -// - when the source and target registers are in different register files -// (note that this is *not* a conversion). -// - when the source is a lclVar whose home location is being moved to a new -// register (rather than just being copied for temporary use). -// -void CodeGen::genRegCopy(GenTree* treeNode) -{ - assert(treeNode->OperGet() == GT_COPY); - GenTree* op1 = treeNode->AsOp()->gtOp1; - - if (op1->IsMultiRegNode()) - { - genConsumeReg(op1); - - GenTreeCopyOrReload* copyTree = treeNode->AsCopyOrReload(); - unsigned regCount = treeNode->GetMultiRegCount(); - - for (unsigned i = 0; i < regCount; ++i) - { - var_types type = op1->GetRegTypeByIndex(i); - regNumber fromReg = op1->GetRegByIndex(i); - regNumber toReg = copyTree->GetRegNumByIdx(i); - - // A Multi-reg GT_COPY node will have a valid reg only for those positions for which a corresponding - // result reg of the multi-reg node needs to be copied. - if (toReg != REG_NA) - { - assert(toReg != fromReg); - inst_RV_RV(ins_Copy(type), toReg, fromReg, type); - } - } - } - else - { - var_types targetType = treeNode->TypeGet(); - regNumber targetReg = treeNode->GetRegNum(); - assert(targetReg != REG_NA); - - // Check whether this node and the node from which we're copying the value have - // different register types. This can happen if (currently iff) we have a SIMD - // vector type that fits in an integer register, in which case it is passed as - // an argument, or returned from a call, in an integer register and must be - // copied if it's in an xmm register. - - bool srcFltReg = (varTypeIsFloating(op1) || varTypeIsSIMD(op1)); - bool tgtFltReg = (varTypeIsFloating(treeNode) || varTypeIsSIMD(treeNode)); - if (srcFltReg != tgtFltReg) - { - instruction ins; - regNumber fpReg; - regNumber intReg; - if (tgtFltReg) - { - ins = ins_CopyIntToFloat(op1->TypeGet(), treeNode->TypeGet()); - fpReg = targetReg; - intReg = op1->GetRegNum(); - } - else - { - ins = ins_CopyFloatToInt(op1->TypeGet(), treeNode->TypeGet()); - intReg = targetReg; - fpReg = op1->GetRegNum(); - } - inst_RV_RV(ins, fpReg, intReg, targetType); - } - else - { - inst_RV_RV(ins_Copy(targetType), targetReg, genConsumeReg(op1), targetType); - } - - if (op1->IsLocal()) - { - // The lclVar will never be a def. - // If it is a last use, the lclVar will be killed by genConsumeReg(), as usual, and genProduceReg will - // appropriately set the gcInfo for the copied value. - // If not, there are two cases we need to handle: - // - If this is a TEMPORARY copy (indicated by the GTF_VAR_DEATH flag) the variable - // will remain live in its original register. - // genProduceReg() will appropriately set the gcInfo for the copied value, - // and genConsumeReg will reset it. - // - Otherwise, we need to update register info for the lclVar. - - GenTreeLclVarCommon* lcl = op1->AsLclVarCommon(); - assert((lcl->gtFlags & GTF_VAR_DEF) == 0); - - if ((lcl->gtFlags & GTF_VAR_DEATH) == 0 && (treeNode->gtFlags & GTF_VAR_DEATH) == 0) - { - LclVarDsc* varDsc = &compiler->lvaTable[lcl->GetLclNum()]; - - // If we didn't just spill it (in genConsumeReg, above), then update the register info - if (varDsc->GetRegNum() != REG_STK) - { - // The old location is dying - genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(op1)); - - gcInfo.gcMarkRegSetNpt(genRegMask(op1->GetRegNum())); - - genUpdateVarReg(varDsc, treeNode); - -#ifdef USING_VARIABLE_LIVE_RANGE - // Report the home change for this variable - varLiveKeeper->siUpdateVariableLiveRange(varDsc, lcl->GetLclNum()); -#endif // USING_VARIABLE_LIVE_RANGE - - // The new location is going live - genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(treeNode)); - } - } - } - } - - genProduceReg(treeNode); -} - //------------------------------------------------------------------------ // genCodeForStoreInd: Produce code for a GT_STOREIND node. // diff --git a/src/coreclr/src/jit/gentree.h b/src/coreclr/src/jit/gentree.h index 7b7b5af861d21..62abda039dbe6 100644 --- a/src/coreclr/src/jit/gentree.h +++ b/src/coreclr/src/jit/gentree.h @@ -775,14 +775,14 @@ struct GenTree // Note that a node marked GTF_VAR_MULTIREG can only be a pure definition of all the fields, or a pure use of all the fields, // so we don't need the equivalent of GTF_VAR_USEASG. -#define GTF_VAR_MULTIREG_DEATH0 0x20000000 // GT_LCL_VAR -- The last-use bit for a lclVar (the first register if it is multireg). +#define GTF_VAR_MULTIREG_DEATH0 0x04000000 // GT_LCL_VAR -- The last-use bit for a lclVar (the first register if it is multireg). #define GTF_VAR_DEATH GTF_VAR_MULTIREG_DEATH0 -#define GTF_VAR_MULTIREG_DEATH1 0x10000000 // GT_LCL_VAR -- The last-use bit for the second register of a multireg lclVar. -#define GTF_VAR_MULTIREG_DEATH2 0x08000000 // GT_LCL_VAR -- The last-use bit for the third register of a multireg lclVar. -#define GTF_VAR_MULTIREG_DEATH3 0x04000000 // GT_LCL_VAR -- The last-use bit for the fourth register of a multireg lclVar. +#define GTF_VAR_MULTIREG_DEATH1 0x08000000 // GT_LCL_VAR -- The last-use bit for the second register of a multireg lclVar. +#define GTF_VAR_MULTIREG_DEATH2 0x10000000 // GT_LCL_VAR -- The last-use bit for the third register of a multireg lclVar. +#define GTF_VAR_MULTIREG_DEATH3 0x20000000 // GT_LCL_VAR -- The last-use bit for the fourth register of a multireg lclVar. #define GTF_VAR_DEATH_MASK (GTF_VAR_MULTIREG_DEATH0|GTF_VAR_MULTIREG_DEATH1 | GTF_VAR_MULTIREG_DEATH2 | GTF_VAR_MULTIREG_DEATH3) - // This is the amount we have to shift, plus the regIndex, to get the last use bit we want. -#define MULTIREG_LAST_USE_SHIFT 17 +// This is the amount we have to shift, plus the regIndex, to get the last use bit we want. +#define MULTIREG_LAST_USE_SHIFT 26 #define GTF_VAR_MULTIREG 0x02000000 // This is a struct or (on 32-bit platforms) long variable that is used or defined // to/from a multireg source or destination (e.g. a call arg or return, or an op // that returns its result in multiple registers such as a long multiply). @@ -1733,6 +1733,9 @@ struct GenTree // Returns the type of the regIndex'th register defined by a multi-reg node. var_types GetRegTypeByIndex(int regIndex); + // Returns the GTF flag equivalent for the regIndex'th register of a multi-reg node. + unsigned int GetRegSpillFlagByIdx(int regIndex) const; + // Returns true if it is a GT_COPY or GT_RELOAD node inline bool IsCopyOrReload() const; @@ -3233,6 +3236,7 @@ struct GenTreeLclVar : public GenTreeLclVarCommon unsigned int GetLastUseBit(int regIndex) { assert(regIndex < 4); + static_assert_no_msg((1 << MULTIREG_LAST_USE_SHIFT) == GTF_VAR_MULTIREG_DEATH0); return (1 << (MULTIREG_LAST_USE_SHIFT + regIndex)); } @@ -3251,6 +3255,7 @@ struct GenTreeLclVar : public GenTreeLclVarCommon void SetMultiReg() { gtFlags |= GTF_VAR_MULTIREG; + ClearOtherRegFlags(); } regNumber GetRegNumByIdx(int regIndex) @@ -7303,6 +7308,61 @@ inline var_types GenTree::GetRegTypeByIndex(int regIndex) return TYP_UNDEF; } +//----------------------------------------------------------------------------------- +// GetRegSpillFlagByIdx: Get a specific register's spill flags, based on regIndex, +// for this multi-reg node. +// +// Arguments: +// regIndex - which register's spill flags to return +// +// Return Value: +// The spill flags (GTF_SPILL GTF_SPILLED) for this register. +// +// Notes: +// This must be a multireg node and 'regIndex' must be a valid index for this node. +// This method returns the GTF "equivalent" flags based on the packed flags on the multireg node. +// +inline unsigned int GenTree::GetRegSpillFlagByIdx(int regIndex) const +{ +#if FEATURE_MULTIREG_RET + if (IsMultiRegCall()) + { + return AsCall()->AsCall()->GetRegSpillFlagByIdx(regIndex); + } + +#if FEATURE_ARG_SPLIT + if (OperIsPutArgSplit()) + { + return AsPutArgSplit()->GetRegSpillFlagByIdx(regIndex); + } +#endif +#if !defined(TARGET_64BIT) + if (OperIsMultiRegOp()) + { + return AsMultiRegOp()->GetRegSpillFlagByIdx(regIndex); + } +#endif + +#endif // FEATURE_MULTIREG_RET + +#if defined(TARGET_XARCH) && defined(FEATURE_HW_INTRINSICS) + if (OperIs(GT_HWINTRINSIC)) + { + // At this time, the only multi-reg HW intrinsics all return the type of their + // arguments. If this changes, we will need a way to record or determine this. + assert(TypeGet() == TYP_STRUCT); + return gtGetOp1()->TypeGet(); + } +#endif + if (OperIs(GT_LCL_VAR, GT_STORE_LCL_VAR)) + { + return AsLclVar()->GetRegSpillFlagByIdx(regIndex); + } + + assert(!"Invalid node type for GetRegSpillFlagByIdx"); + return TYP_UNDEF; +} + //------------------------------------------------------------------------- // IsCopyOrReload: whether this is a GT_COPY or GT_RELOAD node. // diff --git a/src/coreclr/src/jit/lclvars.cpp b/src/coreclr/src/jit/lclvars.cpp index ab3280b9c296b..608b4410cd942 100644 --- a/src/coreclr/src/jit/lclvars.cpp +++ b/src/coreclr/src/jit/lclvars.cpp @@ -1971,10 +1971,12 @@ bool Compiler::StructPromotionHelper::ShouldPromoteStructVar(unsigned lclNum) // void Compiler::StructPromotionHelper::SortStructFields() { - assert(!structPromotionInfo.fieldsSorted); - qsort(structPromotionInfo.fields, structPromotionInfo.fieldCnt, sizeof(*structPromotionInfo.fields), - lvaFieldOffsetCmp); - structPromotionInfo.fieldsSorted = true; + if (!structPromotionInfo.fieldsSorted) + { + qsort(structPromotionInfo.fields, structPromotionInfo.fieldCnt, sizeof(*structPromotionInfo.fields), + lvaFieldOffsetCmp); + structPromotionInfo.fieldsSorted = true; + } } //-------------------------------------------------------------------------------------------- @@ -2158,10 +2160,7 @@ void Compiler::StructPromotionHelper::PromoteStructVar(unsigned lclNum) } #endif - if (!structPromotionInfo.fieldsSorted) - { - SortStructFields(); - } + SortStructFields(); for (unsigned index = 0; index < structPromotionInfo.fieldCnt; ++index) { diff --git a/src/coreclr/src/jit/lsra.cpp b/src/coreclr/src/jit/lsra.cpp index 8c9783cedad80..5101e57389295 100644 --- a/src/coreclr/src/jit/lsra.cpp +++ b/src/coreclr/src/jit/lsra.cpp @@ -1791,6 +1791,8 @@ void LinearScan::identifyCandidates() VarSetOps::AddElemD(compiler, fpMaybeCandidateVars, varDsc->lvVarIndex); } } + JITDUMP(" "); + DBEXEC(VERBOSE, newInt->dump()); } else { @@ -6282,6 +6284,26 @@ void LinearScan::updatePreviousInterval(RegRecord* reg, Interval* interval, Regi #endif } +//----------------------------------------------------------------------------- +// writeLocalReg: Write the register assignment for a GT_LCL_VAR node. +// +// Arguments: +// lclNode - The GT_LCL_VAR node +// varNum - The variable number for the register +// reg - The assigned register +// +// Return Value: +// None +// +void LinearScan::writeLocalReg(GenTreeLclVar* lclNode, unsigned varNum, regNumber reg) +{ + // We don't yet support multireg locals. + assert((lclNode->GetLclNum() == varNum) && !lclNode->IsMultiReg()); + assert(lclNode->GetLclNum() == varNum); + lclNode->SetRegNum(reg); +} + +//----------------------------------------------------------------------------- // LinearScan::resolveLocalRef // Description: // Update the graph for a local reference. @@ -6318,7 +6340,7 @@ void LinearScan::updatePreviousInterval(RegRecord* reg, Interval* interval, Regi // NICE: Consider tracking whether an Interval is always in the same location (register/stack) // in which case it will require no resolution. // -void LinearScan::resolveLocalRef(BasicBlock* block, GenTree* treeNode, RefPosition* currentRefPosition) +void LinearScan::resolveLocalRef(BasicBlock* block, GenTreeLclVar* treeNode, RefPosition* currentRefPosition) { assert((block == nullptr) == (treeNode == nullptr)); assert(enregisterLocalVars); @@ -6339,11 +6361,11 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTree* treeNode, RefPositi { if (currentRefPosition->lastUse) { - treeNode->gtFlags |= GTF_VAR_DEATH; + treeNode->SetLastUse(currentRefPosition->getMultiRegIdx()); } else { - treeNode->gtFlags &= ~GTF_VAR_DEATH; + treeNode->ClearLastUse(currentRefPosition->getMultiRegIdx()); } if ((currentRefPosition->registerAssignment != RBM_NONE) && (interval->physReg == REG_NA) && @@ -6354,7 +6376,7 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTree* treeNode, RefPositi // during resolution. In this case we're better off making it contained. assert(inVarToRegMaps[curBBNum][varDsc->lvVarIndex] == REG_STK); currentRefPosition->registerAssignment = RBM_NONE; - treeNode->SetRegNum(REG_NA); + writeLocalReg(treeNode->AsLclVar(), interval->varNum, REG_NA); } } @@ -6445,9 +6467,11 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTree* treeNode, RefPositi // // Note that varDsc->GetRegNum() is already to REG_STK above. interval->physReg = REG_NA; - treeNode->SetRegNum(REG_NA); + writeLocalReg(treeNode->AsLclVar(), interval->varNum, REG_NA); treeNode->gtFlags &= ~GTF_SPILLED; treeNode->SetContained(); + // We don't support RegOptional for multi-reg localvars. + assert(!treeNode->IsMultiReg()); } else { @@ -6470,7 +6494,7 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTree* treeNode, RefPositi interval->physReg = REG_NA; if (treeNode != nullptr) { - treeNode->SetRegNum(REG_NA); + writeLocalReg(treeNode->AsLclVar(), interval->varNum, REG_NA); } } else // Not reload and Not pure-def that's spillAfter @@ -6489,7 +6513,7 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTree* treeNode, RefPositi // But for copyReg, the homeReg remains unchanged. assert(treeNode != nullptr); - treeNode->SetRegNum(interval->physReg); + writeLocalReg(treeNode->AsLclVar(), interval->varNum, interval->physReg); if (currentRefPosition->copyReg) { @@ -7345,9 +7369,9 @@ void LinearScan::resolveRegisters() { writeRegisters(currentRefPosition, treeNode); - if (treeNode->IsLocal() && currentRefPosition->getInterval()->isLocalVar) + if (treeNode->OperIs(GT_LCL_VAR, GT_STORE_LCL_VAR) && currentRefPosition->getInterval()->isLocalVar) { - resolveLocalRef(block, treeNode, currentRefPosition); + resolveLocalRef(block, treeNode->AsLclVar(), currentRefPosition); } // Mark spill locations on temps @@ -7370,7 +7394,7 @@ void LinearScan::resolveRegisters() treeNode->ResetReuseRegVal(); } - // In case of multi-reg call node, also set spill flag on the + // In case of multi-reg node, also set spill flag on the // register specified by multi-reg index of current RefPosition. // Note that the spill flag on treeNode indicates that one or // more its allocated registers are in that state. @@ -9305,7 +9329,7 @@ void Interval::dump() } if (isStructField) { - printf(" (struct)"); + printf(" (field)"); } if (isPromotedStruct) { @@ -9495,7 +9519,7 @@ void LinearScan::lsraGetOperandString(GenTree* tree, void LinearScan::lsraDispNode(GenTree* tree, LsraTupleDumpMode mode, bool hasDest) { Compiler* compiler = JitTls::GetCompiler(); - const unsigned operandStringLength = 16; + const unsigned operandStringLength = 6 * MAX_MULTIREG_COUNT + 1; char operandString[operandStringLength]; const char* emptyDestOperand = " "; char spillChar = ' '; @@ -9635,7 +9659,7 @@ void LinearScan::TupleStyleDump(LsraTupleDumpMode mode) { BasicBlock* block; LsraLocation currentLoc = 1; // 0 is the entry - const unsigned operandStringLength = 16; + const unsigned operandStringLength = 6 * MAX_MULTIREG_COUNT + 1; char operandString[operandStringLength]; // currentRefPosition is not used for LSRA_DUMP_PRE @@ -10799,6 +10823,7 @@ void LinearScan::verifyFinalAllocation() regRecord->assignedInterval = interval; if (VERBOSE) { + dumpEmptyRefPosition(); printf("Move %-4s ", getRegName(regRecord->regNum)); } } diff --git a/src/coreclr/src/jit/lsra.h b/src/coreclr/src/jit/lsra.h index bc077aad9f77b..7c4056241daca 100644 --- a/src/coreclr/src/jit/lsra.h +++ b/src/coreclr/src/jit/lsra.h @@ -965,8 +965,8 @@ class LinearScan : public LinearScanInterface #ifdef DEBUG void checkLastUses(BasicBlock* block); - static int ComputeOperandDstCount(GenTree* operand); - static int ComputeAvailableSrcCount(GenTree* node); + int ComputeOperandDstCount(GenTree* operand); + int ComputeAvailableSrcCount(GenTree* node); #endif // DEBUG void setFrameType(); @@ -1090,7 +1090,8 @@ class LinearScan : public LinearScanInterface RefPosition* buildInternalFloatRegisterDefForNode(GenTree* tree, regMaskTP internalCands = RBM_NONE); void buildInternalRegisterUses(); - void resolveLocalRef(BasicBlock* block, GenTree* treeNode, RefPosition* currentRefPosition); + void writeLocalReg(GenTreeLclVar* lclNode, unsigned varNum, regNumber reg); + void resolveLocalRef(BasicBlock* block, GenTreeLclVar* treeNode, RefPosition* currentRefPosition); void insertMove(BasicBlock* block, GenTree* insertionPoint, unsigned lclNum, regNumber inReg, regNumber outReg); @@ -1575,6 +1576,7 @@ class LinearScan : public LinearScanInterface int BuildBlockStore(GenTreeBlk* blkNode); int BuildModDiv(GenTree* tree); int BuildIntrinsic(GenTree* tree); + void BuildStoreLocDef(GenTreeLclVarCommon* storeLoc, LclVarDsc* varDsc, RefPosition* singleUseRef, int index); int BuildStoreLoc(GenTreeLclVarCommon* tree); int BuildIndir(GenTreeIndir* indirTree); int BuildGCWriteBarrier(GenTree* tree); diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index c762cefbf24ca..6b76648e0c074 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -1950,8 +1950,6 @@ GenTree* Compiler::fgMakeTmpArgNode(fgArgTabEntry* curArgTabEntry) assert(varTypeIsStruct(type)); if (lvaIsMultiregStruct(varDsc, curArgTabEntry->IsVararg())) { - // ToDo-ARM64: Consider using: arg->ChangeOper(GT_LCL_FLD); - // as that is how UNIX_AMD64_ABI works. // We will create a GT_OBJ for the argument below. // This will be passed by value in two registers. assert(addrNode != nullptr); diff --git a/src/coreclr/src/jit/rationalize.cpp b/src/coreclr/src/jit/rationalize.cpp index d2f813463f369..b8f8595b43e06 100644 --- a/src/coreclr/src/jit/rationalize.cpp +++ b/src/coreclr/src/jit/rationalize.cpp @@ -295,7 +295,7 @@ static void RewriteAssignmentIntoStoreLclCore(GenTreeOp* assignment, store->AsLclFld()->SetFieldSeq(var->AsLclFld()->GetFieldSeq()); } - copyFlags(store, var, GTF_LIVENESS_MASK); + copyFlags(store, var, (GTF_LIVENESS_MASK | GTF_VAR_MULTIREG)); store->gtFlags &= ~GTF_REVERSE_OPS; store->gtType = var->TypeGet(); diff --git a/src/coreclr/src/jit/regset.cpp b/src/coreclr/src/jit/regset.cpp index 92ef88f8c74b0..0ebde49eadfb2 100644 --- a/src/coreclr/src/jit/regset.cpp +++ b/src/coreclr/src/jit/regset.cpp @@ -285,18 +285,17 @@ RegSet::SpillDsc* RegSet::rsGetSpillInfo(GenTree* tree, regNumber reg, SpillDsc* // Return Value: // None. // -// Assumption: -// RyuJIT backend specific: in case of multi-reg call nodes, GTF_SPILL -// flag associated with the reg that is being spilled is cleared. The -// caller of this method is expected to clear GTF_SPILL flag on call -// node after all of its registers marked for spilling are spilled. +// Notes: +// For multi-reg nodes, only the spill flag associated with this reg is cleared. +// The spill flag on the node should be cleared by the caller of this method. // void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */) { assert(tree != nullptr); - GenTreeCall* call = nullptr; - var_types treeType; + GenTreeCall* call = nullptr; + GenTreeLclVar* lcl = nullptr; + var_types treeType; #if defined(TARGET_ARM) GenTreePutArgSplit* splitArg = nullptr; GenTreeMultiRegOp* multiReg = nullptr; @@ -320,6 +319,12 @@ void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */) treeType = multiReg->GetRegType(regIdx); } #endif // TARGET_ARM + else if (tree->IsMultiRegLclVar()) + { + GenTreeLclVar* lcl = tree->AsLclVar(); + LclVarDsc* varDsc = m_rsCompiler->lvaGetDesc(lcl->GetLclNum()); + treeType = varDsc->TypeGet(); + } else { treeType = tree->TypeGet(); @@ -345,9 +350,8 @@ void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */) // vars should be handled elsewhere, and to prevent // spilling twice clear GTF_SPILL flag on tree node. // - // In case of multi-reg call nodes only the spill flag - // associated with the reg is cleared. Spill flag on - // call node should be cleared by the caller of this method. + // In case of multi-reg nodes, only the spill flag associated with this reg is cleared. + // The spill flag on the node should be cleared by the caller of this method. assert((tree->gtFlags & GTF_SPILL) != 0); unsigned regFlags = 0; @@ -371,6 +375,12 @@ void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */) regFlags &= ~GTF_SPILL; } #endif // TARGET_ARM + else if (lcl != nullptr) + { + regFlags = lcl->GetRegSpillFlagByIdx(regIdx); + assert((regFlags & GTF_SPILL) != 0); + regFlags &= ~GTF_SPILL; + } else { assert(!varTypeIsMultiReg(tree)); @@ -446,6 +456,11 @@ void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */) multiReg->SetRegSpillFlagByIdx(regFlags, regIdx); } #endif // TARGET_ARM + else if (lcl != nullptr) + { + regFlags |= GTF_SPILLED; + lcl->SetRegSpillFlagByIdx(regFlags, regIdx); + } } #if defined(TARGET_X86) @@ -565,6 +580,13 @@ TempDsc* RegSet::rsUnspillInPlace(GenTree* tree, regNumber oldReg, unsigned regI multiReg->SetRegSpillFlagByIdx(flags, regIdx); } #endif // TARGET_ARM + else if (tree->IsMultiRegLclVar()) + { + GenTreeLclVar* lcl = tree->AsLclVar(); + unsigned flags = lcl->GetRegSpillFlagByIdx(regIdx); + flags &= ~GTF_SPILLED; + lcl->SetRegSpillFlagByIdx(flags, regIdx); + } else { tree->gtFlags &= ~GTF_SPILLED; diff --git a/src/coreclr/src/jit/ssabuilder.cpp b/src/coreclr/src/jit/ssabuilder.cpp index 53cffb67c9e34..8730a277c6fd6 100644 --- a/src/coreclr/src/jit/ssabuilder.cpp +++ b/src/coreclr/src/jit/ssabuilder.cpp @@ -1650,6 +1650,10 @@ bool SsaBuilder::IncludeInSsa(unsigned lclNum) // return false; } + else if (varDsc->lvIsStructField && m_pCompiler->lvaGetDesc(varDsc->lvParentLcl)->lvIsMultiRegRet) + { + return false; + } // otherwise this variable is included in SSA return true; } diff --git a/src/coreclr/src/jit/treelifeupdater.cpp b/src/coreclr/src/jit/treelifeupdater.cpp index b903c903b7ee4..d1a574c071fe8 100644 --- a/src/coreclr/src/jit/treelifeupdater.cpp +++ b/src/coreclr/src/jit/treelifeupdater.cpp @@ -74,9 +74,27 @@ void TreeLifeUpdater::UpdateLifeVar(GenTree* tree) } // if it's a partial definition then variable "x" must have had a previous, original, site to be born. - bool isBorn = ((lclVarTree->gtFlags & GTF_VAR_DEF) != 0 && (lclVarTree->gtFlags & GTF_VAR_USEASG) == 0); - bool isDying = ((lclVarTree->gtFlags & GTF_VAR_DEATH) != 0); - bool spill = ((lclVarTree->gtFlags & GTF_SPILL) != 0); + bool isBorn; + bool isDying; + bool spill; + bool isMultiRegLocal = lclVarTree->IsMultiRegLclVar(); + if (isMultiRegLocal) + { + assert((tree->gtFlags & GTF_VAR_USEASG) == 0); + isBorn = ((tree->gtFlags & GTF_VAR_DEF) != 0); + // Note that for multireg locals we can have definitions for which some of those are last uses. + // We don't want to add those to the varDeltaSet because otherwise they will be added as newly + // live. + isDying = !isBorn && tree->AsLclVar()->HasLastUse(); + // GTF_SPILL will be set if any registers need to be spilled. + spill = ((tree->gtFlags & GTF_SPILL) != 0); + } + else + { + isBorn = ((lclVarTree->gtFlags & GTF_VAR_DEF) != 0 && (lclVarTree->gtFlags & GTF_VAR_USEASG) == 0); + isDying = ((lclVarTree->gtFlags & GTF_VAR_DEATH) != 0); + spill = ((lclVarTree->gtFlags & GTF_SPILL) != 0); + } // Since all tracked vars are register candidates, but not all are in registers at all times, // we maintain two separate sets of variables - the total set of variables that are either @@ -108,6 +126,10 @@ void TreeLifeUpdater::UpdateLifeVar(GenTree* tree) } } } + else if (ForCodeGen && lclVarTree->IsMultiRegLclVar()) + { + assert(!"MultiRegLclVars not yet supported"); + } else if (varDsc->lvPromoted) { // If hasDeadTrackedFieldVars is true, then, for a LDOBJ(ADDR()), @@ -126,15 +148,17 @@ void TreeLifeUpdater::UpdateLifeVar(GenTree* tree) } } - for (unsigned i = varDsc->lvFieldLclStart; i < varDsc->lvFieldLclStart + varDsc->lvFieldCnt; ++i) + unsigned firstFieldVarNum = varDsc->lvFieldLclStart; + for (unsigned i = 0; i < varDsc->lvFieldCnt; ++i) { - LclVarDsc* fldVarDsc = &(compiler->lvaTable[i]); + LclVarDsc* fldVarDsc = compiler->lvaGetDesc(firstFieldVarNum + i); noway_assert(fldVarDsc->lvIsStructField); if (fldVarDsc->lvTracked) { unsigned fldVarIndex = fldVarDsc->lvVarIndex; - bool isInReg = fldVarDsc->lvIsInReg(); - bool isInMemory = !isInReg || fldVarDsc->lvLiveInOutOfHndlr; + // We should never see enregistered fields in a struct local unless + // IsMultiRegLclVar() returns true, in which case we've handled this above. + assert(!fldVarDsc->lvIsInReg()); noway_assert(fldVarIndex < compiler->lvaTrackedCount); if (!hasDeadTrackedFieldVars) { @@ -143,34 +167,12 @@ void TreeLifeUpdater::UpdateLifeVar(GenTree* tree) { // We repeat this call here and below to avoid the VarSetOps::IsMember // test in this, the common case, where we have no deadTrackedFieldVars. - if (isInReg) - { - if (isBorn) - { - compiler->codeGen->genUpdateVarReg(fldVarDsc, tree); - } - compiler->codeGen->genUpdateRegLife(fldVarDsc, isBorn, isDying DEBUGARG(tree)); - } - if (isInMemory) - { - VarSetOps::AddElemD(compiler, stackVarDeltaSet, fldVarIndex); - } + VarSetOps::AddElemD(compiler, stackVarDeltaSet, fldVarIndex); } } else if (ForCodeGen && VarSetOps::IsMember(compiler, varDeltaSet, fldVarIndex)) { - if (isInReg) - { - if (isBorn) - { - compiler->codeGen->genUpdateVarReg(fldVarDsc, tree); - } - compiler->codeGen->genUpdateRegLife(fldVarDsc, isBorn, isDying DEBUGARG(tree)); - } - if (isInMemory) - { - VarSetOps::AddElemD(compiler, stackVarDeltaSet, fldVarIndex); - } + VarSetOps::AddElemD(compiler, stackVarDeltaSet, fldVarIndex); } } } From ee0aadc3dad5c8d64ce67c6f7ddeb07326aeb8ec Mon Sep 17 00:00:00 2001 From: buyaa-n Date: Fri, 15 May 2020 13:55:30 -0700 Subject: [PATCH 232/420] Fix argument exception warnings on runtime (#35717) * Fix argument exception warnings on runtime * Apply feedback * Addressing feedback and test fix * Fix test failures * Fix tests for NetFx run * Fix suppressed warning for socket.SendAsyn(e) and fix corresponding tests * Applied feedback --- .editorconfig | 1 + eng/CodeAnalysis.ruleset | 2 +- .../Runtime/InteropServices/ComActivator.cs | 8 ++--- .../src/System/ArgIterator.cs | 2 ++ .../System.Private.CoreLib/src/System/GC.cs | 2 +- .../Runtime/InteropServices/ComWrappers.cs | 6 ++-- .../src/System/RuntimeType.CoreCLR.cs | 10 +++---- .../System/Threading/ThreadPool.CoreCLR.cs | 2 +- .../src/System/Buffers/ArrayBufferWriter.cs | 4 +-- .../src/System/Threading/Tasks/TaskToApm.cs | 4 +-- .../TestUtilities/System/AssertExtensions.cs | 5 ++-- .../src/ChainedConfigurationProvider.cs | 2 +- .../src/Resources/Strings.resx | 3 ++ .../src/Dependency.cs | 4 +-- .../src/Library.cs | 6 ++-- .../src/ResourceAssembly.cs | 6 ++-- .../src/RuntimeAssembly.cs | 6 ++-- .../src/RuntimeFallbacks.cs | 4 +-- .../src/RuntimeFile.cs | 2 +- .../src/TargetInfo.cs | 4 +-- .../src/Resources/Strings.resx | 21 ++++++------- .../Design/DesignerOptionService.cs | 2 +- .../MemberRelationshipService.cs | 4 +-- .../Design/DesignerOptionServiceTests.cs | 2 +- .../MemberRelationshipServiceTests.cs | 4 +-- .../Diagnostics/PerformanceData/CounterSet.cs | 4 +-- .../AccountManagement/Principal.cs | 4 +-- .../AccountManagement/PrincipalSearcher.cs | 2 +- .../tests/ComputerPrincipalTest.cs | 2 +- .../ActiveDirectorySchedule.cs | 2 +- .../ActiveDirectorySchemaClassCollection.cs | 8 ++--- ...ActiveDirectorySchemaPropertyCollection.cs | 8 ++--- .../ActiveDirectorySiteCollection.cs | 2 +- .../ActiveDirectorySiteLink.cs | 2 +- .../ActiveDirectorySiteLinkCollection.cs | 2 +- .../ActiveDirectorySubnetCollection.cs | 4 +-- .../DirectoryServerCollection.cs | 4 +-- .../Drawing/Drawing2D/LinearGradientBrush.cs | 4 +-- .../Drawing/Drawing2D/PathGradientBrush.cs | 16 ++++------ .../src/System/Drawing/Font.Windows.cs | 2 +- .../src/System/Drawing/Font.cs | 2 +- .../src/System/Drawing/Icon.Windows.cs | 3 +- .../Drawing/Text/PrivateFontCollection.cs | 6 ++-- .../Drawing2D/LinearGradientBrushTests.cs | 6 ++-- .../tests/Drawing2D/PathGradientBrushTests.cs | 14 ++++----- .../System.Drawing.Common/tests/IconTests.cs | 2 +- .../tests/Text/PrivateFontCollectionTests.cs | 2 +- .../src/Resources/Strings.resx | 8 +++-- .../System/Management/ManagementDateTime.cs | 2 +- .../src/System/Management/ManagementQuery.cs | 28 ++++++++--------- .../src/System/Net/HttpListenerResponse.cs | 2 +- .../HttpListenerResponseTests.Headers.cs | 2 +- .../SystemIPGlobalProperties.cs | 2 +- .../src/System/Net/CookieContainer.cs | 6 ++-- .../tests/UnitTests/CookieContainerTest.cs | 8 ++--- .../src/Resources/Strings.resx | 12 +++++--- .../src/System/Net/Sockets/Socket.cs | 20 ++++++------- .../ArgumentValidationTests.cs | 30 +++++++++---------- .../tests/FunctionalTests/SendTo.cs | 2 +- .../src/System/Net/WebHeaderCollection.cs | 2 +- .../src/System/DateTime.cs | 4 +-- .../src/System/Globalization/CultureInfo.cs | 2 ++ .../src/System/IO/BinaryWriter.cs | 2 +- .../src/System/IO/UnmanagedMemoryStream.cs | 2 +- .../src/System/Text/StringBuilder.cs | 2 ++ .../src/System/Threading/Thread.cs | 2 +- .../src/System/Type.Enum.cs | 4 +-- .../System.Private.CoreLib/src/System/Type.cs | 2 +- .../src/Resources/Strings.resx | 3 ++ .../System.Private.Uri/src/System/Uri.cs | 4 +-- .../tests/ExtendedFunctionalTests/UriTests.cs | 2 +- .../src/System/Xml/NameTable.cs | 2 +- .../tests/RuntimeReflectionExtensionTests.cs | 2 +- .../InteropServices/ComAwareEventInfoTests.cs | 2 +- .../tests/System/DateTimeOffsetTests.cs | 4 +-- .../tests/System/DateTimeTests.cs | 4 +-- .../System.Runtime/tests/System/GCTests.cs | 2 +- .../tests/System/Type/TypeTests.Get.cs | 2 +- .../AccessControl/CommonObjectSecurity.cs | 2 +- .../System/Security/Cryptography/DSA.Xml.cs | 2 ++ .../Security/Cryptography/PemEncoding.cs | 4 +-- .../src/Resources/Strings.resx | 13 ++++---- .../Cryptography/Pkcs/Pkcs12Builder.cs | 4 +-- .../Cryptography/Pkcs/Pkcs9AttributeObject.cs | 6 ++-- .../Security/Cryptography/Pkcs/SignedCms.cs | 2 +- .../Security/Cryptography/Pkcs/SignerInfo.cs | 4 +-- .../tests/Pkcs9AttributeTests.cs | 6 ++-- .../tests/SignedCms/SignerInfoTests.cs | 1 + .../src/Resources/Strings.resx | 16 ++++++---- .../X509Certificates/X509Extension.cs | 2 +- .../src/System/Security/Principal/SID.cs | 2 ++ .../Security/Principal/WindowsIdentity.cs | 5 +--- .../System/Transactions/TransactionScope.cs | 4 +-- .../src/System/Drawing/FontConverter.cs | 2 +- .../System/Drawing/FontConverterTests.cs | 2 +- .../src/System/GC.Mono.cs | 2 +- .../Reflection/Emit/TypeBuilder.Mono.cs | 10 +++---- .../CompilerServices/RuntimeHelpers.Mono.cs | 6 ++-- .../src/System/RuntimeType.Mono.cs | 10 +++---- 99 files changed, 257 insertions(+), 236 deletions(-) diff --git a/.editorconfig b/.editorconfig index bb9c61f6623de..28e3eaba64e83 100644 --- a/.editorconfig +++ b/.editorconfig @@ -155,6 +155,7 @@ csharp_space_between_square_brackets = false # Analyzers dotnet_code_quality.ca1802.api_surface = private, internal +dotnet_code_quality.CA2208.api_surface = public # C++ Files [*.{cpp,h,in}] diff --git a/eng/CodeAnalysis.ruleset b/eng/CodeAnalysis.ruleset index bc11bd3b6d58a..66a6af943a1ef 100644 --- a/eng/CodeAnalysis.ruleset +++ b/eng/CodeAnalysis.ruleset @@ -106,7 +106,7 @@ - + diff --git a/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs b/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs index 2b6c9b7ebad22..ffecc9b0d493b 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs @@ -124,7 +124,7 @@ public static object GetClassFactoryForType(ComActivationContext cxt) if (!Path.IsPathRooted(cxt.AssemblyPath)) { - throw new ArgumentException(); + throw new ArgumentException(null, nameof(cxt)); } Type classType = FindClassType(cxt.ClassId, cxt.AssemblyPath, cxt.AssemblyName, cxt.TypeName); @@ -156,7 +156,7 @@ public static void ClassRegistrationScenarioForType(ComActivationContext cxt, bo if (!Path.IsPathRooted(cxt.AssemblyPath)) { - throw new ArgumentException(); + throw new ArgumentException(null, nameof(cxt)); } Type classType = FindClassType(cxt.ClassId, cxt.AssemblyPath, cxt.AssemblyName, cxt.TypeName); @@ -288,7 +288,7 @@ public static unsafe int RegisterClassForTypeInternal(ComActivationContextIntern if (cxtInt.InterfaceId != Guid.Empty || cxtInt.ClassFactoryDest != IntPtr.Zero) { - throw new ArgumentException(); + throw new ArgumentException(null, nameof(pCxtInt)); } try @@ -328,7 +328,7 @@ public static unsafe int UnregisterClassForTypeInternal(ComActivationContextInte if (cxtInt.InterfaceId != Guid.Empty || cxtInt.ClassFactoryDest != IntPtr.Zero) { - throw new ArgumentException(); + throw new ArgumentException(null, nameof(pCxtInt)); } try diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/ArgIterator.cs b/src/coreclr/src/System.Private.CoreLib/src/System/ArgIterator.cs index d32d53ae753b6..8c7039e557b45 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/ArgIterator.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/ArgIterator.cs @@ -85,7 +85,9 @@ public TypedReference GetNextArg(RuntimeTypeHandle rth) // malicious caller to increment the pointer to an arbitrary // location in memory and read the contents. if (ArgPtr == IntPtr.Zero) +#pragma warning disable CA2208 // Instantiate argument exceptions correctly, the argument not applicable throw new ArgumentNullException(); +#pragma warning restore CA2208 TypedReference result = default; // reference to TypedReference is banned, so have to pass result as pointer diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs index fc8a9650f63b7..e3e1b54373fa5 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs @@ -135,7 +135,7 @@ public static void AddMemoryPressure(long bytesAllocated) if ((4 == IntPtr.Size) && (bytesAllocated > int.MaxValue)) { - throw new ArgumentOutOfRangeException("pressure", + throw new ArgumentOutOfRangeException(nameof(bytesAllocated), SR.ArgumentOutOfRange_MustBeNonNegInt32); } diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs index 8c377012666b5..6bdd48d7290a9 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs @@ -136,7 +136,7 @@ public IntPtr GetOrCreateComInterfaceForObject(object instance, CreateComInterfa { IntPtr ptr; if (!TryGetOrCreateComInterfaceForObjectInternal(this, instance, flags, out ptr)) - throw new ArgumentException(); + throw new ArgumentException(null, nameof(instance)); return ptr; } @@ -215,7 +215,7 @@ public object GetOrCreateObjectForComInstance(IntPtr externalComObject, CreateOb { object? obj; if (!TryGetOrCreateObjectForComInstanceInternal(this, externalComObject, flags, null, out obj)) - throw new ArgumentNullException(); + throw new ArgumentNullException(nameof(externalComObject)); return obj!; } @@ -271,7 +271,7 @@ public object GetOrRegisterObjectForComInstance(IntPtr externalComObject, Create object? obj; if (!TryGetOrCreateObjectForComInstanceInternal(this, externalComObject, flags, wrapper, out obj)) - throw new ArgumentNullException(); + throw new ArgumentNullException(nameof(externalComObject)); return obj!; } diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index bfbdbea7de41d..38511276255be 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -2755,7 +2755,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType) protected override PropertyInfo? GetPropertyImpl( string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { - if (name == null) throw new ArgumentNullException(); + if (name == null) throw new ArgumentNullException(nameof(name)); ListBuilder candidates = GetPropertyCandidates(name, bindingAttr, types, false); @@ -2791,7 +2791,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType) public override EventInfo? GetEvent(string name, BindingFlags bindingAttr) { - if (name is null) throw new ArgumentNullException(); + if (name is null) throw new ArgumentNullException(nameof(name)); FilterHelper(bindingAttr, ref name, out _, out MemberListType listType); @@ -2854,7 +2854,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType) public override Type? GetInterface(string fullname, bool ignoreCase) { - if (fullname is null) throw new ArgumentNullException(); + if (fullname is null) throw new ArgumentNullException(nameof(fullname)); BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.NonPublic; @@ -2888,7 +2888,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType) public override Type? GetNestedType(string fullname, BindingFlags bindingAttr) { - if (fullname is null) throw new ArgumentNullException(); + if (fullname is null) throw new ArgumentNullException(nameof(fullname)); bindingAttr &= ~BindingFlags.Static; string name, ns; @@ -2916,7 +2916,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType) public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { - if (name is null) throw new ArgumentNullException(); + if (name is null) throw new ArgumentNullException(nameof(name)); ListBuilder methods = default; ListBuilder constructors = default; diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs index c2d72e3915cae..9752c3cbde366 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs @@ -260,7 +260,7 @@ public static void GetAvailableThreads(out int workerThreads, out int completion get; } - private static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException + private static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, object? state, diff --git a/src/libraries/Common/src/System/Buffers/ArrayBufferWriter.cs b/src/libraries/Common/src/System/Buffers/ArrayBufferWriter.cs index 71b23e1f7cd3f..a7b047119d5d5 100644 --- a/src/libraries/Common/src/System/Buffers/ArrayBufferWriter.cs +++ b/src/libraries/Common/src/System/Buffers/ArrayBufferWriter.cs @@ -42,7 +42,7 @@ public ArrayBufferWriter() public ArrayBufferWriter(int initialCapacity) { if (initialCapacity <= 0) - throw new ArgumentException(nameof(initialCapacity)); + throw new ArgumentException(null, nameof(initialCapacity)); _buffer = new T[initialCapacity]; _index = 0; @@ -101,7 +101,7 @@ public void Clear() public void Advance(int count) { if (count < 0) - throw new ArgumentException(nameof(count)); + throw new ArgumentException(null, nameof(count)); if (_index > _buffer.Length - count) ThrowInvalidOperationException_AdvancedTooFar(_buffer.Length); diff --git a/src/libraries/Common/src/System/Threading/Tasks/TaskToApm.cs b/src/libraries/Common/src/System/Threading/Tasks/TaskToApm.cs index ecd9f27ecb8dd..96b41501f3407 100644 --- a/src/libraries/Common/src/System/Threading/Tasks/TaskToApm.cs +++ b/src/libraries/Common/src/System/Threading/Tasks/TaskToApm.cs @@ -43,7 +43,7 @@ public static void End(IAsyncResult asyncResult) return; } - throw new ArgumentNullException(); + throw new ArgumentNullException(nameof(asyncResult)); } /// Processes an IAsyncResult returned by Begin. @@ -55,7 +55,7 @@ public static TResult End(IAsyncResult asyncResult) return task.GetAwaiter().GetResult(); } - throw new ArgumentNullException(); + throw new ArgumentNullException(nameof(asyncResult)); } /// Provides a simple IAsyncResult that wraps a Task. diff --git a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs index d1688c9c860b0..45f0d59333667 100644 --- a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs +++ b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs @@ -27,7 +27,7 @@ public static void ThrowsContains(Action action, string expectedMessageConten Assert.Contains(expectedMessageContent, Assert.Throws(action).Message); } - public static void Throws(string netCoreParamName, string netFxParamName, Action action) + public static T Throws(string netCoreParamName, string netFxParamName, Action action) where T : ArgumentException { T exception = Assert.Throws(action); @@ -35,7 +35,7 @@ public static void Throws(string netCoreParamName, string netFxParamName, Act if (netFxParamName == null && IsNetFramework) { // Param name varies between .NET Framework versions -- skip checking it - return; + return exception; } string expectedParamName = @@ -43,6 +43,7 @@ public static void Throws(string netCoreParamName, string netFxParamName, Act netFxParamName : netCoreParamName; Assert.Equal(expectedParamName, exception.ParamName); + return exception; } public static void Throws(string netCoreParamName, string netFxParamName, Func testCode) diff --git a/src/libraries/Microsoft.Extensions.Configuration/src/ChainedConfigurationProvider.cs b/src/libraries/Microsoft.Extensions.Configuration/src/ChainedConfigurationProvider.cs index ffc3a406b9f8f..56802e813c795 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/src/ChainedConfigurationProvider.cs +++ b/src/libraries/Microsoft.Extensions.Configuration/src/ChainedConfigurationProvider.cs @@ -29,7 +29,7 @@ public ChainedConfigurationProvider(ChainedConfigurationSource source) } if (source.Configuration == null) { - throw new ArgumentNullException(nameof(source.Configuration)); + throw new ArgumentException(SR.Format(SR.InvalidNullArgument, "source.Configuration"), nameof(source)); } _config = source.Configuration; diff --git a/src/libraries/Microsoft.Extensions.Configuration/src/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Configuration/src/Resources/Strings.resx index 52fb2be3e50a1..1c4c38af9b51b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration/src/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Configuration/src/Resources/Strings.resx @@ -120,4 +120,7 @@ A configuration source is not registered. Please register one before setting a value. + + Null is not a valid value for '{0}'. + \ No newline at end of file diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/Dependency.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/Dependency.cs index e60989f77a5c8..6c26416a9359e 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/Dependency.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/Dependency.cs @@ -13,11 +13,11 @@ public Dependency(string name, string version) { if (string.IsNullOrEmpty(name)) { - throw new ArgumentException(nameof(name)); + throw new ArgumentException(null, nameof(name)); } if (string.IsNullOrEmpty(version)) { - throw new ArgumentException(nameof(version)); + throw new ArgumentException(null, nameof(version)); } Name = name; Version = version; diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/Library.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/Library.cs index cef2b76d2c9c9..eb64ac5fc95da 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/Library.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/Library.cs @@ -43,15 +43,15 @@ public class Library { if (string.IsNullOrEmpty(type)) { - throw new ArgumentException(nameof(type)); + throw new ArgumentException(null, nameof(type)); } if (string.IsNullOrEmpty(name)) { - throw new ArgumentException(nameof(name)); + throw new ArgumentException(null, nameof(name)); } if (string.IsNullOrEmpty(version)) { - throw new ArgumentException(nameof(version)); + throw new ArgumentException(null, nameof(version)); } if (dependencies == null) { diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/ResourceAssembly.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/ResourceAssembly.cs index 998789b51001e..4e754367b7791 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/ResourceAssembly.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/ResourceAssembly.cs @@ -12,11 +12,11 @@ public ResourceAssembly(string path, string locale) { if (string.IsNullOrEmpty(path)) { - throw new ArgumentException(nameof(path)); + throw new ArgumentException(null, nameof(path)); } if (string.IsNullOrEmpty(locale)) { - throw new ArgumentException(nameof(locale)); + throw new ArgumentException(null, nameof(locale)); } Locale = locale; Path = path; @@ -27,4 +27,4 @@ public ResourceAssembly(string path, string locale) public string Path { get; set; } } -} \ No newline at end of file +} diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeAssembly.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeAssembly.cs index c4e07fe7deb4b..edf908e9766c6 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeAssembly.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeAssembly.cs @@ -16,11 +16,11 @@ public RuntimeAssembly(string assemblyName, string path) { if (string.IsNullOrEmpty(assemblyName)) { - throw new ArgumentException(nameof(assemblyName)); + throw new ArgumentException(null, nameof(assemblyName)); } if (string.IsNullOrEmpty(path)) { - throw new ArgumentException(nameof(path)); + throw new ArgumentException(null, nameof(path)); } _assemblyName = assemblyName; Path = path; @@ -45,4 +45,4 @@ public static RuntimeAssembly Create(string path) return new RuntimeAssembly(assemblyName, path); } } -} \ No newline at end of file +} diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeFallbacks.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeFallbacks.cs index 32b3635c92f66..9ce186d557b6c 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeFallbacks.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeFallbacks.cs @@ -18,7 +18,7 @@ public RuntimeFallbacks(string runtime, IEnumerable fallbacks) { if (string.IsNullOrEmpty(runtime)) { - throw new ArgumentException(nameof(runtime)); + throw new ArgumentException(null, nameof(runtime)); } if (fallbacks == null) { @@ -28,4 +28,4 @@ public RuntimeFallbacks(string runtime, IEnumerable fallbacks) Fallbacks = fallbacks.ToArray(); } } -} \ No newline at end of file +} diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeFile.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeFile.cs index 542a5b65a51aa..5777a34dfa2c4 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeFile.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/RuntimeFile.cs @@ -12,7 +12,7 @@ public RuntimeFile(string path, string assemblyVersion, string fileVersion) { if (string.IsNullOrEmpty(path)) { - throw new ArgumentException(nameof(path)); + throw new ArgumentException(null, nameof(path)); } Path = path; diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/TargetInfo.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/TargetInfo.cs index 0b2f53607b863..485ff58d3eb23 100644 --- a/src/libraries/Microsoft.Extensions.DependencyModel/src/TargetInfo.cs +++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/TargetInfo.cs @@ -14,7 +14,7 @@ public class TargetInfo { if (string.IsNullOrEmpty(framework)) { - throw new ArgumentException(nameof(framework)); + throw new ArgumentException(null, nameof(framework)); } Framework = framework; @@ -32,4 +32,4 @@ public class TargetInfo public bool IsPortable { get; } } -} \ No newline at end of file +} diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/Resources/Strings.resx b/src/libraries/System.ComponentModel.TypeConverter/src/Resources/Strings.resx index 84fd677ad6763..7de9810d591ed 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/Resources/Strings.resx +++ b/src/libraries/System.ComponentModel.TypeConverter/src/Resources/Strings.resx @@ -1,4 +1,5 @@ - + + @@ -76,16 +77,16 @@ The value '{0}' is not a valid value for the enum '{1}'. - Invalid event handler for the {0} event. + Invalid event handler for the {0} event. - Invalid type for the {0} event. + Invalid type for the {0} event. Invalid type for the {0} property - Accessor methods for the {0} event are missing. + Accessor methods for the {0} event are missing. Accessor methods for the {0} property are missing. @@ -170,7 +171,7 @@ The {0} culture cannot be converted to a CultureInfo object on this computer. - + The service instance must derive from or implement {0}. @@ -178,7 +179,7 @@ The service {0} already exists in the service container. - Value of '{1}' is not valid for '{0}'. + Value of '{0}' cannot be empty. Null is not a valid value for {0}. @@ -242,11 +243,11 @@ The checkout was canceled by the user. - - + + (none) - + Relationships between {0}.{1} and {2}.{3} are not supported. - + \ No newline at end of file diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerOptionService.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerOptionService.cs index ae870960bbf87..3227d9c8170df 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerOptionService.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerOptionService.cs @@ -47,7 +47,7 @@ protected DesignerOptionCollection CreateOptionCollection(DesignerOptionCollecti if (name.Length == 0) { - throw new ArgumentException(SR.Format(SR.InvalidArgumentValue, name.Length.ToString(), "0"), "name.Length"); + throw new ArgumentException(SR.Format(SR.InvalidArgumentValue, "name.Length"), nameof(name)); } return new DesignerOptionCollection(this, parent, name, value); diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/Serialization/MemberRelationshipService.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/Serialization/MemberRelationshipService.cs index c5bceb6e9d450..81889b0ca6327 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/Serialization/MemberRelationshipService.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/Serialization/MemberRelationshipService.cs @@ -44,7 +44,7 @@ public abstract class MemberRelationshipService // and not the other as the main constructor performs argument validation. if (source.Owner == null) { - throw new ArgumentNullException(nameof(MemberRelationship.Owner)); + throw new ArgumentException(SR.Format(SR.InvalidNullArgument, "source.Owner"), nameof(source)); } Debug.Assert(source.Member != null); @@ -57,7 +57,7 @@ public abstract class MemberRelationshipService // and not the other as the main constructor performs argument validation. if (source.Owner == null) { - throw new ArgumentNullException(nameof(MemberRelationship.Owner)); + throw new ArgumentException(SR.Format(SR.InvalidNullArgument, "source.Owner"), nameof(source)); } Debug.Assert(source.Member != null); diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerOptionServiceTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerOptionServiceTests.cs index 37aaf19073788..78778d048a330 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerOptionServiceTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/DesignerOptionServiceTests.cs @@ -53,7 +53,7 @@ public void CreateOptionCollection_NullName_ThrowsArgumentNullException() public void CreateOptionCollection_EmptyName_ThrowsArgumentException() { var service = new TestDesignerOptionService(); - AssertExtensions.Throws("name.Length", () => service.DoCreateOptionCollection(service.Options, string.Empty, "value")); + AssertExtensions.Throws("name", () => service.DoCreateOptionCollection(service.Options, string.Empty, "value")); } [Fact] diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/MemberRelationshipServiceTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/MemberRelationshipServiceTests.cs index 9f85a1eeff671..5bc0242ca9ed5 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/MemberRelationshipServiceTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/Design/Serialization/MemberRelationshipServiceTests.cs @@ -56,8 +56,8 @@ public void Indexer_NullSourceOwner_ThrowsArgumentNullException() Assert.Throws("sourceOwner", () => service[null, member]); Assert.Throws("sourceOwner", () => service[null, member] = new MemberRelationship()); - Assert.Throws("Owner", () => service[new MemberRelationship()]); - Assert.Throws("Owner", () => service[new MemberRelationship()] = new MemberRelationship()); + Assert.Throws("source", () => service[new MemberRelationship()]); + Assert.Throws("source", () => service[new MemberRelationship()] = new MemberRelationship()); } [Fact] diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceData/CounterSet.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceData/CounterSet.cs index 13ac7471b6968..3a62324c07461 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceData/CounterSet.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceData/CounterSet.cs @@ -195,7 +195,7 @@ public CounterSetInstance CreateCounterSetInstance(string instanceName) { if (_provider == null) { - throw new ArgumentException(SR.Format(SR.Perflib_Argument_ProviderNotFound, _providerGuid), "ProviderGuid"); + throw new InvalidOperationException(SR.Format(SR.Perflib_InvalidOperation_NoActiveProvider, _providerGuid)); } if (_provider._hProvider.IsInvalid) { @@ -256,7 +256,7 @@ public CounterSetInstance CreateCounterSetInstance(string instanceName) { throw Status switch { - (uint)Interop.Errors.ERROR_ALREADY_EXISTS => new ArgumentException(SR.Format(SR.Perflib_Argument_CounterSetAlreadyRegister, _counterSet), "CounterSetGuid"), + (uint)Interop.Errors.ERROR_ALREADY_EXISTS => new InvalidOperationException(SR.Format(SR.Perflib_Argument_CounterSetAlreadyRegister, _counterSet)), _ => new Win32Exception((int)Status), }; diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/Principal.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/Principal.cs index 040de0d0c932c..8c2bcb0871291 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/Principal.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/Principal.cs @@ -124,7 +124,7 @@ public string SamAccountName set { if (null == value || 0 == value.Length) - throw new ArgumentNullException(PropertyNames.PrincipalSamAccountName); + throw new ArgumentNullException(nameof(value)); if (!GetStoreCtxToUse().IsValidProperty(this, PropertyNames.PrincipalSamAccountName)) throw new InvalidOperationException(SR.InvalidPropertyForStore); @@ -244,7 +244,7 @@ public string Name set { if (null == value || 0 == value.Length) - throw new ArgumentNullException(PropertyNames.PrincipalName); + throw new ArgumentNullException(nameof(value)); if (!GetStoreCtxToUse().IsValidProperty(this, PropertyNames.PrincipalName)) throw new InvalidOperationException(SR.InvalidPropertyForStore); diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/PrincipalSearcher.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/PrincipalSearcher.cs index 62b8e52e5239d..68d1811c0a0eb 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/PrincipalSearcher.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/PrincipalSearcher.cs @@ -23,7 +23,7 @@ public PrincipalSearcher() public PrincipalSearcher(Principal queryFilter) { if (null == queryFilter) - throw new ArgumentException(nameof(queryFilter)); + throw new ArgumentException(null, nameof(queryFilter)); _ctx = queryFilter.Context; this.QueryFilter = queryFilter; // use property to enforce "no persisted principals" check diff --git a/src/libraries/System.DirectoryServices.AccountManagement/tests/ComputerPrincipalTest.cs b/src/libraries/System.DirectoryServices.AccountManagement/tests/ComputerPrincipalTest.cs index e17eaf3f60aac..9d83710d15168 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/tests/ComputerPrincipalTest.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/tests/ComputerPrincipalTest.cs @@ -35,7 +35,7 @@ public void Ctor_NullSamAccountName_ThrowsArgumentException() public void Ctor_EmptySamAccountName_ThrowsArgumentNullException() { var context = new PrincipalContext(ContextType.Machine); - AssertExtensions.Throws("Principal.SamAccountName", null, () => new ComputerPrincipal(context, string.Empty, "password", enabled: true)); + AssertExtensions.Throws("value", null, () => new ComputerPrincipal(context, string.Empty, "password", enabled: true)); } [Fact] diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySchedule.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySchedule.cs index e4eee6a47e26d..2ae4757c6f3b9 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySchedule.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySchedule.cs @@ -59,7 +59,7 @@ public ActiveDirectorySchedule() public ActiveDirectorySchedule(ActiveDirectorySchedule schedule) : this() { if (schedule == null) - throw new ArgumentNullException(); + throw new ArgumentNullException(nameof(schedule)); bool[] tmpSchedule = schedule._scheduleArray; for (int i = 0; i < 672; i++) diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySchemaClassCollection.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySchemaClassCollection.cs index ae07de8d521e5..c506669acc835 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySchemaClassCollection.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySchemaClassCollection.cs @@ -111,7 +111,7 @@ public void AddRange(ActiveDirectorySchemaClass[] schemaClasses) { if (schemaClass == null) { - throw new ArgumentException(nameof(schemaClasses)); + throw new ArgumentException(null, nameof(schemaClasses)); } } @@ -132,7 +132,7 @@ public void AddRange(ActiveDirectorySchemaClassCollection schemaClasses) { if (schemaClass == null) { - throw new ArgumentException(nameof(schemaClasses)); + throw new ArgumentException(null, nameof(schemaClasses)); } } @@ -154,7 +154,7 @@ public void AddRange(ReadOnlyActiveDirectorySchemaClassCollection schemaClasses) { if (schemaClass == null) { - throw new ArgumentException(nameof(schemaClasses)); + throw new ArgumentException(null, nameof(schemaClasses)); } } @@ -360,7 +360,7 @@ protected override void OnValidate(object value) if (!(value is ActiveDirectorySchemaClass)) { - throw new ArgumentException(nameof(value)); + throw new ArgumentException(null, nameof(value)); } if (!((ActiveDirectorySchemaClass)value).isBound) diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySchemaPropertyCollection.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySchemaPropertyCollection.cs index 0e312f9b392cb..5bea1fa12e76e 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySchemaPropertyCollection.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySchemaPropertyCollection.cs @@ -109,7 +109,7 @@ public void AddRange(ActiveDirectorySchemaProperty[] properties) { if (property == null) { - throw new ArgumentException(nameof(properties)); + throw new ArgumentException(null, nameof(properties)); } } @@ -130,7 +130,7 @@ public void AddRange(ActiveDirectorySchemaPropertyCollection properties) { if (property == null) { - throw new ArgumentException(nameof(properties)); + throw new ArgumentException(null, nameof(properties)); } } @@ -153,7 +153,7 @@ public void AddRange(ReadOnlyActiveDirectorySchemaPropertyCollection properties) { if (property == null) { - throw new ArgumentException(nameof(properties)); + throw new ArgumentException(null, nameof(properties)); } } @@ -369,7 +369,7 @@ protected override void OnValidate(object value) if (value == null) throw new ArgumentNullException(nameof(value)); if (!(value is ActiveDirectorySchemaProperty)) - throw new ArgumentException(nameof(value)); + throw new ArgumentException(null, nameof(value)); if (!((ActiveDirectorySchemaProperty)value).isBound) throw new InvalidOperationException(SR.Format(SR.SchemaObjectNotCommitted, ((ActiveDirectorySchemaProperty)value).Name)); diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteCollection.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteCollection.cs index 88beabbb7b375..5e85364b26da9 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteCollection.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteCollection.cs @@ -232,7 +232,7 @@ protected override void OnValidate(object value) if (value == null) throw new ArgumentNullException(nameof(value)); if (!(value is ActiveDirectorySite)) - throw new ArgumentException(nameof(value)); + throw new ArgumentException(null, nameof(value)); if (!((ActiveDirectorySite)value).existing) throw new InvalidOperationException(SR.Format(SR.SiteNotCommitted, ((ActiveDirectorySite)value).Name)); diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteLink.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteLink.cs index e35ece7285cfe..244b020f7b3f3 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteLink.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteLink.cs @@ -268,7 +268,7 @@ public int Cost throw new ObjectDisposedException(GetType().Name); if (value < 0) - throw new ArgumentException(nameof(value)); + throw new ArgumentException(null, nameof(value)); try { diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteLinkCollection.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteLinkCollection.cs index 24d230c920a80..3f6afc747b36a 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteLinkCollection.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteLinkCollection.cs @@ -226,7 +226,7 @@ protected override void OnValidate(object value) if (value == null) throw new ArgumentNullException(nameof(value)); if (!(value is ActiveDirectorySiteLink)) - throw new ArgumentException(nameof(value)); + throw new ArgumentException(null, nameof(value)); if (!((ActiveDirectorySiteLink)value).existing) throw new InvalidOperationException(SR.Format(SR.SiteLinkNotCommitted, ((ActiveDirectorySiteLink)value).Name)); diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySubnetCollection.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySubnetCollection.cs index b270eab2247fb..540be8cbfc5c0 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySubnetCollection.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySubnetCollection.cs @@ -68,7 +68,7 @@ public void AddRange(ActiveDirectorySubnet[] subnets) { if (s == null) { - throw new ArgumentException(nameof(subnets)); + throw new ArgumentException(null, nameof(subnets)); } } @@ -263,7 +263,7 @@ protected override void OnValidate(object value) if (value == null) throw new ArgumentNullException(nameof(value)); if (!(value is ActiveDirectorySubnet)) - throw new ArgumentException(nameof(value)); + throw new ArgumentException(null, nameof(value)); if (!((ActiveDirectorySubnet)value).existing) throw new InvalidOperationException(SR.Format(SR.SubnetNotCommitted, ((ActiveDirectorySubnet)value).Name)); diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/DirectoryServerCollection.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/DirectoryServerCollection.cs index 20ee51fd55c60..64de6d61b67e8 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/DirectoryServerCollection.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/DirectoryServerCollection.cs @@ -115,7 +115,7 @@ public void AddRange(DirectoryServer[] servers) { if (s == null) { - throw new ArgumentException(nameof(servers)); + throw new ArgumentException(null, nameof(servers)); } } @@ -386,7 +386,7 @@ protected override void OnValidate(object value) else { if (!(value is DirectoryServer)) - throw new ArgumentException(nameof(value)); + throw new ArgumentException(null, nameof(value)); } } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/LinearGradientBrush.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/LinearGradientBrush.cs index 19228b5266f03..666eb631d7b37 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/LinearGradientBrush.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/LinearGradientBrush.cs @@ -232,14 +232,14 @@ public bool GammaCorrection throw new NullReferenceException(); if (value.Positions == null) - throw new ArgumentNullException("source"); + throw new ArgumentException(SR.Format(SR.InvalidArgumentValue, "value.Positions", value.Positions), nameof(value)); int count = value.Factors.Length; if (count == 0 || value.Positions.Length == 0) throw new ArgumentException(SR.BlendObjectMustHaveTwoElements); if (count >= 2 && count != value.Positions.Length) - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(value)); if (count >= 2 && value.Positions[0] != 0.0F) throw new ArgumentException(SR.BlendObjectFirstElementInvalid); if (count >= 2 && value.Positions[count - 1] != 1.0F) diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/PathGradientBrush.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/PathGradientBrush.cs index bae8b7a6121d2..f416ff221aa69 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/PathGradientBrush.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Drawing2D/PathGradientBrush.cs @@ -185,10 +185,8 @@ public Blend Blend if (value == null || value.Factors == null) throw new NullReferenceException(); - // The Desktop implementation throws ArgumentNullException("source") because it never validates the value of value.Positions, and then passes it - // on to Marshal.Copy(value.Positions, 0, positions, count);. The first argument of Marshal.Copy is source, hence this exception. if (value.Positions == null) - throw new ArgumentNullException("source"); + throw new ArgumentException(SR.Format(SR.InvalidArgumentValue, "value.Positions", value.Positions), nameof(value)); int count = value.Factors.Length; @@ -196,7 +194,7 @@ public Blend Blend if (count == 0 || value.Positions.Length == 0) throw new ArgumentException(SR.BlendObjectMustHaveTwoElements); if (count >= 2 && count != value.Positions.Length) - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(value)); if (count >= 2 && value.Positions[0] != 0.0F) throw new ArgumentException(SR.BlendObjectFirstElementInvalid); if (count >= 2 && value.Positions[count - 1] != 1.0F) @@ -298,16 +296,12 @@ public ColorBlend InterpolationColors } set { - // The Desktop implementation will throw various exceptions - ranging from NullReferenceExceptions to Argument(OutOfRange)Exceptions - // depending on how sane the input is. These checks exist to replicate the exact Desktop behavior. int count = value.Colors.Length; if (value.Positions == null) - throw new ArgumentNullException("source"); - if (value.Colors.Length > value.Positions.Length) - throw new ArgumentOutOfRangeException(); - if (value.Colors.Length < value.Positions.Length) - throw new ArgumentException(); + throw new ArgumentException(SR.Format(SR.InvalidArgumentValue, "value.Positions", value.Positions), nameof(value)); + if (value.Colors.Length != value.Positions.Length) + throw new ArgumentOutOfRangeException(nameof(value)); float[] positions = value.Positions; int[] argbs = new int[count]; diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Font.Windows.cs index bfa06594420bc..41ed7b89b7b40 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.Windows.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Font.Windows.cs @@ -306,7 +306,7 @@ public static unsafe Font FromLogFont(object lf, IntPtr hdc) { // If we don't actually have an object that is LOGFONT in size, trying to pass // it to GDI+ is likely to cause an AV. - throw new ArgumentException(); + throw new ArgumentException(null, nameof(lf)); } // Now that we know the marshalled size is the same as LOGFONT, copy in the data diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs index b030638dda613..bbabbf88ed0b8 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs @@ -285,7 +285,7 @@ public unsafe void ToLogFont(object logFont, Graphics graphics) { // If we don't actually have an object that is LOGFONT in size, trying to pass // it to GDI+ is likely to cause an AV. - throw new ArgumentException(); + throw new ArgumentException(null, nameof(logFont)); } Interop.User32.LOGFONT nativeLogFont = ToLogFontInternal(graphics); diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.cs index 02021231f9f29..a71a09d6e793e 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Icon.Windows.cs @@ -639,9 +639,8 @@ public void Save(Stream outputStream) { try { - // We threw this way on NetFX if (outputStream == null) - throw new ArgumentNullException("dataStream"); + throw new ArgumentNullException(nameof(outputStream)); picture.SaveAsFile(new GPStream(outputStream, makeSeekable: false), -1, out int temp); } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.cs index 3b150283b5dd6..60c016124d99e 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Text/PrivateFontCollection.cs @@ -60,16 +60,16 @@ public void AddFontFile(string filename) { if (_nativeFontCollection == IntPtr.Zero) { +#pragma warning disable CA2208 // Instantiate argument exceptions correctly // This is the default behavior on Desktop. The ArgumentException originates from GdipPrivateAddFontFile which would // refuse the null pointer. throw new ArgumentException(); +#pragma warning restore CA2208 } if (filename == null) { - // This is the default behavior on Desktop. The name "path" originates from Path.GetFullPath or similar which would refuse - // a null value. - throw new ArgumentNullException("path"); + throw new ArgumentNullException(nameof(filename)); } // this ensure the filename is valid (or throw the correct exception) diff --git a/src/libraries/System.Drawing.Common/tests/Drawing2D/LinearGradientBrushTests.cs b/src/libraries/System.Drawing.Common/tests/Drawing2D/LinearGradientBrushTests.cs index bcc33b61b72d5..2140688e8e8ba 100644 --- a/src/libraries/System.Drawing.Common/tests/Drawing2D/LinearGradientBrushTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Drawing2D/LinearGradientBrushTests.cs @@ -358,11 +358,11 @@ public void Blend_SetNullBlendFactors_ThrowsNullReferenceException() } [ConditionalFact(Helpers.IsDrawingSupported)] - public void Blend_SetNullBlendPositions_ThrowsArgumentNullException() + public void Blend_SetNullBlendPositions_ThrowsArgumentException() { using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) { - AssertExtensions.Throws("source", () => brush.Blend = new Blend { Factors = new float[2], Positions = null }); + AssertExtensions.Throws("value", "source", () => brush.Blend = new Blend { Factors = new float[2], Positions = null }); } } @@ -371,7 +371,7 @@ public void Blend_SetFactorsLengthGreaterThanPositionsLength_ThrowsArgumentOutOf { using (var brush = new LinearGradientBrush(new Rectangle(1, 2, 3, 4), Color.Plum, Color.Red, 45, true)) { - AssertExtensions.Throws(null, () => brush.Blend = new Blend { Factors = new float[2], Positions = new float[1] }); + AssertExtensions.Throws("value", null, () => brush.Blend = new Blend { Factors = new float[2], Positions = new float[1] }); } } diff --git a/src/libraries/System.Drawing.Common/tests/Drawing2D/PathGradientBrushTests.cs b/src/libraries/System.Drawing.Common/tests/Drawing2D/PathGradientBrushTests.cs index 3046c01641846..3019394844d4d 100644 --- a/src/libraries/System.Drawing.Common/tests/Drawing2D/PathGradientBrushTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Drawing2D/PathGradientBrushTests.cs @@ -350,7 +350,7 @@ public void Blend_InvalidFactorPositionsLengthMismatch_ThrowsArgumentOutOfRangeE using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) { - AssertExtensions.Throws(null, () => brush.Blend = invalidBlend); + AssertExtensions.Throws("value", null, () => brush.Blend = invalidBlend); } } @@ -366,11 +366,11 @@ public void Blend_Null_ThrowsNullReferenceException() } [ConditionalFact(Helpers.IsDrawingSupported)] - public void Blend_NullBlendProperites_ThrowsArgumentNullException() + public void Blend_NullBlendProperites_ThrowsArgumentException() { using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) { - AssertExtensions.Throws("source", () => + AssertExtensions.Throws("value", "source", () => brush.Blend = new Blend() { Factors = new float[0], Positions = null }); } } @@ -651,11 +651,11 @@ public void InterpolationColors_NullColors_ThrowsNullReferenceException() } [ConditionalFact(Helpers.IsDrawingSupported)] - public void InterpolationColors_NullPoints_ArgumentNullException() + public void InterpolationColors_NullPoints_ArgumentException() { using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) { - AssertExtensions.Throws("source", () => + AssertExtensions.Throws("value", "source", () => brush.InterpolationColors = new ColorBlend() { Colors = new Color[1], Positions = null }); } } @@ -680,11 +680,11 @@ public void InterpolationColors_EmptyColors_ArgumentException() } [ConditionalFact(Helpers.IsDrawingSupported)] - public void InterpolationColors_PointsLengthGreaterThenColorsLength_ArgumentException() + public void InterpolationColors_PointsLengthGreaterThenColorsLength_ArgumentOutOfRangeException() { using (PathGradientBrush brush = new PathGradientBrush(_defaultFloatPoints)) { - AssertExtensions.Throws(null, () => + AssertExtensions.Throws("value", null, () => brush.InterpolationColors = new ColorBlend() { Colors = new Color[1], Positions = new float[2] }); } } diff --git a/src/libraries/System.Drawing.Common/tests/IconTests.cs b/src/libraries/System.Drawing.Common/tests/IconTests.cs index a201c9bce16e3..440fd59f2be77 100644 --- a/src/libraries/System.Drawing.Common/tests/IconTests.cs +++ b/src/libraries/System.Drawing.Common/tests/IconTests.cs @@ -525,7 +525,7 @@ public void Save_NullOutputStreamNoIconData_ThrowsArgumentNullException() var icon = Icon.FromHandle(source.Handle); icon.Dispose(); - AssertExtensions.Throws("dataStream", () => icon.Save(null)); + AssertExtensions.Throws("outputStream", "dataStream", () => icon.Save(null)); } } diff --git a/src/libraries/System.Drawing.Common/tests/Text/PrivateFontCollectionTests.cs b/src/libraries/System.Drawing.Common/tests/Text/PrivateFontCollectionTests.cs index af934a15f458a..364ba09bdb9dd 100644 --- a/src/libraries/System.Drawing.Common/tests/Text/PrivateFontCollectionTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Text/PrivateFontCollectionTests.cs @@ -107,7 +107,7 @@ public void AddFontFile_NullFileName_ThrowsArgumentNullException() { using (var fontCollection = new PrivateFontCollection()) { - AssertExtensions.Throws("path", () => fontCollection.AddFontFile(null)); + AssertExtensions.Throws("filename", "path", () => fontCollection.AddFontFile(null)); } } diff --git a/src/libraries/System.Management/src/Resources/Strings.resx b/src/libraries/System.Management/src/Resources/Strings.resx index f740f60b40f99..40f915ba6f640 100644 --- a/src/libraries/System.Management/src/Resources/Strings.resx +++ b/src/libraries/System.Management/src/Resources/Strings.resx @@ -1,4 +1,5 @@ - + + @@ -292,4 +293,7 @@ The native library '{0}' does not have all required functions. Please, update the .NET Framework. - + + The Query string supplied was invalid or improperly formed. Token `{0}` is expected + + \ No newline at end of file diff --git a/src/libraries/System.Management/src/System/Management/ManagementDateTime.cs b/src/libraries/System.Management/src/System/Management/ManagementDateTime.cs index 27114f9453b21..6a71452dc1120 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementDateTime.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementDateTime.cs @@ -415,7 +415,7 @@ public static string ToDmtfTimeInterval(TimeSpan timespan) // and also negative timespan cannot be represented in DMTF if (timespan.Days > MAXDATE_INTIMESPAN || timespan < TimeSpan.Zero) { - throw new System.ArgumentOutOfRangeException(); + throw new System.ArgumentOutOfRangeException(nameof(timespan)); } dmtftimespan = (dmtftimespan + timespan.Hours.ToString(frmInt32).PadLeft(2, '0')); diff --git a/src/libraries/System.Management/src/System/Management/ManagementQuery.cs b/src/libraries/System.Management/src/System/Management/ManagementQuery.cs index 62797f9dbd3e5..1c49c3019e4de 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementQuery.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementQuery.cs @@ -1040,13 +1040,13 @@ protected internal override void ParseQuery(string query) // Should start with "select" if ((q.Length < keyword.Length) || (0 != string.Compare(q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) - throw new ArgumentException(SR.InvalidQuery, "select"); + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, keyword), nameof(query)); q = q.Remove(0, keyword.Length).TrimStart(null); // Next should be a '*' if (0 != q.IndexOf('*', 0)) - throw new ArgumentException(SR.InvalidQuery, "*"); + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, "*"), nameof(query)); q = q.Remove(0, 1).TrimStart(null); @@ -1055,7 +1055,7 @@ protected internal override void ParseQuery(string query) if ((q.Length < keyword.Length) || (0 != string.Compare(q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) - throw new ArgumentException(SR.InvalidQuery, "from"); + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, keyword), nameof(query)); q = q.Remove(0, keyword.Length).TrimStart(null); @@ -1064,7 +1064,7 @@ protected internal override void ParseQuery(string query) if ((q.Length < keyword.Length) || (0 != string.Compare(q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) - throw new ArgumentException(SR.InvalidQuery, "meta_class"); + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, keyword), nameof(query)); q = q.Remove(0, keyword.Length).TrimStart(null); @@ -1076,7 +1076,7 @@ protected internal override void ParseQuery(string query) if ((q.Length < keyword.Length) || (0 != string.Compare(q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) - throw new ArgumentException(SR.InvalidQuery, "where"); + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, keyword), nameof(query)); q = q.Remove(0, keyword.Length); @@ -1650,7 +1650,7 @@ protected internal override void ParseQuery(string query) //Find "associators" clause if (0 != string.Compare(q, 0, TokenAssociators, 0, TokenAssociators.Length, StringComparison.OrdinalIgnoreCase)) - throw new ArgumentException(SR.InvalidQuery, "associators"); // Invalid query + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, TokenAssociators), nameof(query)); // Invalid query // Strip off the clause q = q.Remove(0, TokenAssociators.Length); @@ -1663,7 +1663,7 @@ protected internal override void ParseQuery(string query) // Next token should be "of" if (0 != string.Compare(q, 0, TokenOf, 0, TokenOf.Length, StringComparison.OrdinalIgnoreCase)) - throw new ArgumentException(SR.InvalidQuery, "of"); // Invalid query + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, TokenOf), nameof(query)); // Invalid query // Strip off the clause and leading WS q = q.Remove(0, TokenOf.Length).TrimStart(null); @@ -1687,7 +1687,7 @@ protected internal override void ParseQuery(string query) { // Next should be the "where" clause if (0 != string.Compare(q, 0, TokenWhere, 0, TokenWhere.Length, StringComparison.OrdinalIgnoreCase)) - throw new ArgumentException(SR.InvalidQuery, "where"); // Invalid query + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, TokenWhere), nameof(query)); // Invalid query q = q.Remove(0, TokenWhere.Length); @@ -2167,7 +2167,7 @@ protected internal override void ParseQuery(string query) //Find "references" clause if (0 != string.Compare(q, 0, TokenReferences, 0, TokenReferences.Length, StringComparison.OrdinalIgnoreCase)) - throw new ArgumentException(SR.InvalidQuery, "references"); // Invalid query + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, TokenReferences), nameof(query)); // Invalid query // Strip off the clause q = q.Remove(0, TokenReferences.Length); @@ -2180,7 +2180,7 @@ protected internal override void ParseQuery(string query) // Next token should be "of" if (0 != string.Compare(q, 0, TokenOf, 0, TokenOf.Length, StringComparison.OrdinalIgnoreCase)) - throw new ArgumentException(SR.InvalidQuery, "of"); // Invalid query + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, TokenOf), nameof(query)); // Invalid query // Strip off the clause and leading WS q = q.Remove(0, TokenOf.Length).TrimStart(null); @@ -2204,7 +2204,7 @@ protected internal override void ParseQuery(string query) { // Next should be the "where" clause if (0 != string.Compare(q, 0, TokenWhere, 0, TokenWhere.Length, StringComparison.OrdinalIgnoreCase)) - throw new ArgumentException(SR.InvalidQuery, "where"); // Invalid query + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, TokenWhere), nameof(query)); // Invalid query q = q.Remove(0, TokenWhere.Length); @@ -3043,13 +3043,13 @@ protected internal override void ParseQuery(string query) q = q.Remove(0, keyword.Length).TrimStart(null); if (!q.StartsWith("*", StringComparison.Ordinal)) - throw new ArgumentException(SR.InvalidQuery, "*"); + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, "*"), nameof(query)); q = q.Remove(0, 1).TrimStart(null); //Find "from" clause keyword = "from "; if ((q.Length < keyword.Length) || (0 != string.Compare(q, 0, keyword, 0, keyword.Length, StringComparison.OrdinalIgnoreCase))) - throw new ArgumentException(SR.InvalidQuery, "from"); + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, keyword), nameof(query)); ParseToken(ref q, keyword, null, ref bFound, ref eventClassName); //Find "within" clause @@ -3119,7 +3119,7 @@ protected internal override void ParseQuery(string query) q = q.Remove(0, keyword.Length); if (q.Length == 0) //bad query - throw new ArgumentException(SR.InvalidQuery, "having"); + throw new ArgumentException(SR.Format(SR.InvalidQueryTokenExpected, keyword), nameof(query)); havingCondition = q; } diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/HttpListenerResponse.cs b/src/libraries/System.Net.HttpListener/src/System/Net/HttpListenerResponse.cs index 41e3f78d340c8..97c8339c3b95f 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/HttpListenerResponse.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/HttpListenerResponse.cs @@ -188,7 +188,7 @@ public string StatusDescription char c = (char)(0x000000ff & (uint)value[i]); if ((c <= 31 && c != (byte)'\t') || c == 127) { - throw new ArgumentException(SR.net_WebHeaderInvalidControlChars, "name"); + throw new ArgumentException(SR.net_WebHeaderInvalidControlChars, nameof(value)); } } diff --git a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.Headers.cs b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.Headers.cs index 112c841b8594a..f52b79f355844 100644 --- a/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.Headers.cs +++ b/src/libraries/System.Net.HttpListener/tests/HttpListenerResponseTests.Headers.cs @@ -436,7 +436,7 @@ public async Task StatusDescription_SetInvalid_ThrowsArgumentException(string st { using (HttpListenerResponse response = await GetResponse()) { - AssertExtensions.Throws("name", () => response.StatusDescription = statusDescription); + AssertExtensions.Throws("value", () => response.StatusDescription = statusDescription); Assert.Equal("OK", response.StatusDescription); } } diff --git a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPGlobalProperties.cs b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPGlobalProperties.cs index 315915b5ed0c3..39220cab5c204 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPGlobalProperties.cs +++ b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPGlobalProperties.cs @@ -380,7 +380,7 @@ public override IcmpV6Statistics GetIcmpV6Statistics() public override async Task GetUnicastAddressesAsync() { // Wait for the address table to stabilize. - var tcs = new TaskCompletionSource(TaskContinuationOptions.RunContinuationsAsynchronously); + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); if (!TeredoHelper.UnsafeNotifyStableUnicastIpAddressTable(s => ((TaskCompletionSource)s).TrySetResult(true), tcs)) { await tcs.Task.ConfigureAwait(false); diff --git a/src/libraries/System.Net.Primitives/src/System/Net/CookieContainer.cs b/src/libraries/System.Net.Primitives/src/System/Net/CookieContainer.cs index 75f68bb98086e..af1f75ebc9d49 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/CookieContainer.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/CookieContainer.cs @@ -118,7 +118,7 @@ public CookieContainer(int capacity) { if (capacity <= 0) { - throw new ArgumentException(SR.net_toosmall, "Capacity"); + throw new ArgumentException(SR.net_toosmall, nameof(capacity)); } m_maxCookies = capacity; } @@ -132,7 +132,7 @@ public CookieContainer(int capacity, int perDomainCapacity, int maxCookieSize) : m_maxCookiesPerDomain = perDomainCapacity; if (maxCookieSize <= 0) { - throw new ArgumentException(SR.net_toosmall, "MaxCookieSize"); + throw new ArgumentException(SR.net_toosmall, nameof(maxCookieSize)); } m_maxCookieSize = maxCookieSize; } @@ -230,7 +230,7 @@ public void Add(Cookie cookie) { throw new ArgumentException( SR.Format(SR.net_emptystringcall, nameof(cookie) + "." + nameof(cookie.Domain)), - nameof(cookie) + "." + nameof(cookie.Domain)); + nameof(cookie)); } Uri? uri; diff --git a/src/libraries/System.Net.Primitives/tests/UnitTests/CookieContainerTest.cs b/src/libraries/System.Net.Primitives/tests/UnitTests/CookieContainerTest.cs index d3ce1f523d0ec..7bd84309abf0c 100644 --- a/src/libraries/System.Net.Primitives/tests/UnitTests/CookieContainerTest.cs +++ b/src/libraries/System.Net.Primitives/tests/UnitTests/CookieContainerTest.cs @@ -486,7 +486,7 @@ public void Ctor_Capacity_Success() [Fact] public void Ctor_Capacity_Invalid() { - AssertExtensions.Throws("Capacity", () => new CookieContainer(0)); // Capacity <= 0 + AssertExtensions.Throws("capacity", () => new CookieContainer(0)); // Capacity <= 0 } [Fact] @@ -595,7 +595,7 @@ public void Add_Cookie_Invalid() { CookieContainer cc = new CookieContainer(); Assert.Throws(() => cc.Add((Cookie)null)); // Null cookie - AssertExtensions.Throws("cookie.Domain", () => cc.Add(new Cookie("name", "value", "", ""))); // Empty domain + AssertExtensions.Throws("cookie", () => cc.Add(new Cookie("name", "value", "", ""))); // Empty domain cc.MaxCookieSize = 1; Assert.Throws(() => cc.Add(new Cookie("name", "long-text", "", "contoso.com"))); // Value.Length > MaxCookieSize @@ -625,11 +625,11 @@ public void Capacity_ShrinkNoneExpired_RemovesAll() [Fact] public void Ctor_CapacityPerDomainCapacityMaxCookieSize_Invalid() { - AssertExtensions.Throws("Capacity", () => new CookieContainer(0, 10, 5)); // Capacity <= 0 + AssertExtensions.Throws("capacity", () => new CookieContainer(0, 10, 5)); // Capacity <= 0 Assert.Throws(() => new CookieContainer(5, 0, 5)); // Per domain capacity <= 0 Assert.Throws(() => new CookieContainer(5, 10, 5)); // Per domain capacity > Capacity - AssertExtensions.Throws("MaxCookieSize", () => new CookieContainer(15, 10, 0)); // Max cookie size <= 0 + AssertExtensions.Throws("maxCookieSize", () => new CookieContainer(15, 10, 0)); // Max cookie size <= 0 } [Fact] diff --git a/src/libraries/System.Net.Sockets/src/Resources/Strings.resx b/src/libraries/System.Net.Sockets/src/Resources/Strings.resx index 3078fabf5d5fd..62f9bb2b41db9 100644 --- a/src/libraries/System.Net.Sockets/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Sockets/src/Resources/Strings.resx @@ -1,4 +1,5 @@ - + + @@ -192,8 +193,8 @@ The specified value cannot be negative. - - Argument must be between {0} and {1}. + + Argument '{2}' must be between {0} and {1}. Sockets on this platform are invalid for use after a failed connection attempt. @@ -258,4 +259,7 @@ Asynchronous operations are not allowed on this socket. The underlying OS handle might have been already bound to an IO completion port. - + + Null is not a valid value for {0}. + + \ No newline at end of file diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index 2e3f3d50ada63..e5eda8e009823 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -1908,7 +1908,7 @@ public void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName opti } if (lingerOption.LingerTime < 0 || lingerOption.LingerTime > (int)ushort.MaxValue) { - throw new ArgumentException(SR.Format(SR.ArgumentOutOfRange_Bounds_Lower_Upper, 0, (int)ushort.MaxValue), "optionValue.LingerTime"); + throw new ArgumentException(SR.Format(SR.ArgumentOutOfRange_Bounds_Lower_Upper_Named, 0, (int)ushort.MaxValue, "optionValue.LingerTime"), nameof(optionValue)); } SetLingerOption(lingerOption); } @@ -3816,7 +3816,7 @@ public bool AcceptAsync(SocketAsyncEventArgs e) } if (e.HasMultipleBuffers) { - throw new ArgumentException(SR.net_multibuffernotsupported, "BufferList"); + throw new ArgumentException(SR.net_multibuffernotsupported, nameof(e)); } if (_rightEndPoint == null) { @@ -3979,11 +3979,11 @@ public static bool ConnectAsync(SocketType socketType, ProtocolType protocolType } if (e.HasMultipleBuffers) { - throw new ArgumentException(SR.net_multibuffernotsupported, "BufferList"); + throw new ArgumentException(SR.net_multibuffernotsupported, nameof(e)); } if (e.RemoteEndPoint == null) { - throw new ArgumentNullException("remoteEP"); + throw new ArgumentException(SR.Format(SR.InvalidNullArgument, "e.RemoteEndPoint"), nameof(e)); } EndPoint endPointSnapshot = e.RemoteEndPoint; @@ -4116,11 +4116,11 @@ public bool ReceiveFromAsync(SocketAsyncEventArgs e) } if (e.RemoteEndPoint == null) { - throw new ArgumentNullException(nameof(e.RemoteEndPoint)); + throw new ArgumentException(SR.Format(SR.InvalidNullArgument, "e.RemoteEndPoint"), nameof(e)); } if (!CanTryAddressFamily(e.RemoteEndPoint.AddressFamily)) { - throw new ArgumentException(SR.Format(SR.net_InvalidEndPointAddressFamily, e.RemoteEndPoint.AddressFamily, _addressFamily), "RemoteEndPoint"); + throw new ArgumentException(SR.Format(SR.net_InvalidEndPointAddressFamily, e.RemoteEndPoint.AddressFamily, _addressFamily), nameof(e)); } SocketPal.CheckDualModeReceiveSupport(this); @@ -4166,11 +4166,11 @@ public bool ReceiveMessageFromAsync(SocketAsyncEventArgs e) } if (e.RemoteEndPoint == null) { - throw new ArgumentNullException(nameof(e.RemoteEndPoint)); + throw new ArgumentException(SR.Format(SR.InvalidNullArgument, "e.RemoteEndPoint"), nameof(e)); } if (!CanTryAddressFamily(e.RemoteEndPoint.AddressFamily)) { - throw new ArgumentException(SR.Format(SR.net_InvalidEndPointAddressFamily, e.RemoteEndPoint.AddressFamily, _addressFamily), "RemoteEndPoint"); + throw new ArgumentException(SR.Format(SR.net_InvalidEndPointAddressFamily, e.RemoteEndPoint.AddressFamily, _addressFamily), nameof(e)); } SocketPal.CheckDualModeReceiveSupport(this); @@ -4250,7 +4250,7 @@ public bool SendPacketsAsync(SocketAsyncEventArgs e) } if (e.SendPacketsElements == null) { - throw new ArgumentNullException("e.SendPacketsElements"); + throw new ArgumentException(SR.Format(SR.InvalidNullArgument, "e.SendPacketsElements"), nameof(e)); } if (!Connected) { @@ -4288,7 +4288,7 @@ public bool SendToAsync(SocketAsyncEventArgs e) } if (e.RemoteEndPoint == null) { - throw new ArgumentNullException(nameof(RemoteEndPoint)); + throw new ArgumentException(SR.Format(SR.InvalidNullArgument, "e.RemoteEndPoint"), nameof(e)); } // Prepare SocketAddress diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs index 655534f857ca0..8c3af3465b9df 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs @@ -454,8 +454,8 @@ public void SetSocketOption_Linger_NotLingerOption_Throws_Argument() [Fact] public void SetSocketOption_Linger_InvalidLingerTime_Throws_Argument() { - AssertExtensions.Throws("optionValue.LingerTime", () => GetSocket().SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(true, -1))); - AssertExtensions.Throws("optionValue.LingerTime", () => GetSocket().SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(true, (int)ushort.MaxValue + 1))); + AssertExtensions.Throws("optionValue", () => GetSocket().SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(true, -1))); + AssertExtensions.Throws("optionValue", () => GetSocket().SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(true, (int)ushort.MaxValue + 1))); } [Fact] @@ -516,7 +516,7 @@ public void AcceptAsync_BufferList_Throws_Argument() BufferList = s_buffers }; - AssertExtensions.Throws("BufferList", () => GetSocket().AcceptAsync(eventArgs)); + AssertExtensions.Throws("e", () => GetSocket().AcceptAsync(eventArgs)); } [Fact] @@ -598,13 +598,13 @@ public void ConnectAsync_Static_BufferList_Throws_Argument() BufferList = s_buffers }; - AssertExtensions.Throws("BufferList", () => Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, eventArgs)); + AssertExtensions.Throws("e", () => Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, eventArgs)); } [Fact] - public void ConnectAsync_Static_NullRemoteEndPoint_Throws_ArgumentNull() + public void ConnectAsync_Static_NullRemoteEndPoint_Throws_ArgumentException() { - Assert.Throws(() => Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, s_eventArgs)); + Assert.Throws("e", () => Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, s_eventArgs)); } [Fact] @@ -620,9 +620,9 @@ public void ReceiveFromAsync_NullAsyncEventArgs_Throws_ArgumentNull() } [Fact] - public void ReceiveFromAsync_NullRemoteEndPoint_Throws_ArgumentNull() + public void ReceiveFromAsync_NullRemoteEndPoint_Throws_ArgumentException() { - Assert.Throws(() => GetSocket().ReceiveFromAsync(s_eventArgs)); + Assert.Throws("e", () => GetSocket().ReceiveFromAsync(s_eventArgs)); } [Fact] @@ -632,7 +632,7 @@ public void ReceiveFromAsync_AddressFamily_Throws_Argument() RemoteEndPoint = new IPEndPoint(IPAddress.IPv6Loopback, 1) }; - AssertExtensions.Throws("RemoteEndPoint", () => GetSocket(AddressFamily.InterNetwork).ReceiveFromAsync(eventArgs)); + AssertExtensions.Throws("e", () => GetSocket(AddressFamily.InterNetwork).ReceiveFromAsync(eventArgs)); } [Fact] @@ -642,9 +642,9 @@ public void ReceiveMessageFromAsync_NullAsyncEventArgs_Throws_ArgumentNull() } [Fact] - public void ReceiveMessageFromAsync_NullRemoteEndPoint_Throws_ArgumentNull() + public void ReceiveMessageFromAsync_NullRemoteEndPoint_Throws_ArgumentException() { - Assert.Throws(() => GetSocket().ReceiveMessageFromAsync(s_eventArgs)); + Assert.Throws("e", () => GetSocket().ReceiveMessageFromAsync(s_eventArgs)); } [Fact] @@ -654,7 +654,7 @@ public void ReceiveMessageFromAsync_AddressFamily_Throws_Argument() RemoteEndPoint = new IPEndPoint(IPAddress.IPv6Loopback, 1) }; - AssertExtensions.Throws("RemoteEndPoint", () => GetSocket(AddressFamily.InterNetwork).ReceiveMessageFromAsync(eventArgs)); + AssertExtensions.Throws("e", () => GetSocket(AddressFamily.InterNetwork).ReceiveMessageFromAsync(eventArgs)); } [Fact] @@ -670,9 +670,9 @@ public void SendPacketsAsync_NullAsyncEventArgs_Throws_ArgumentNull() } [Fact] - public void SendPacketsAsync_NullSendPacketsElements_Throws_ArgumentNull() + public void SendPacketsAsync_NullSendPacketsElements_Throws_ArgumentException() { - Assert.Throws(() => GetSocket().SendPacketsAsync(s_eventArgs)); + Assert.Throws("e", () => GetSocket().SendPacketsAsync(s_eventArgs)); } [Fact] @@ -694,7 +694,7 @@ public void SendToAsync_NullAsyncEventArgs_Throws_ArgumentNull() [Fact] public void SendToAsync_NullRemoteEndPoint_Throws_ArgumentNull() { - Assert.Throws(() => GetSocket().SendToAsync(s_eventArgs)); + Assert.Throws(() => GetSocket().SendToAsync(s_eventArgs)); } [Theory] diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendTo.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendTo.cs index c767e30b8f143..d10c877558277 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendTo.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendTo.cs @@ -47,7 +47,7 @@ public async Task NullEndpoint_Throws() { using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - await Assert.ThrowsAsync(() => SendToAsync(socket, new byte[1], null)); + await Assert.ThrowsAnyAsync(() => SendToAsync(socket, new byte[1], null)); } [Fact] diff --git a/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs b/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs index ae3a1a4e5ffcf..2214534a9d5ab 100644 --- a/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs +++ b/src/libraries/System.Net.WebHeaderCollection/src/System/Net/WebHeaderCollection.cs @@ -378,7 +378,7 @@ public void Add(string header) { if (value != null && value.Length > ushort.MaxValue) { - throw new ArgumentOutOfRangeException(nameof(value), value, SR.Format(CultureInfo.InvariantCulture, SR.net_headers_toolong, ushort.MaxValue)); + throw new ArgumentOutOfRangeException(nameof(header), value, SR.Format(CultureInfo.InvariantCulture, SR.net_headers_toolong, ushort.MaxValue)); } } InvalidateCachedArrays(); diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs index 023d795019d41..1561e99a72434 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs @@ -581,9 +581,7 @@ public DateTime AddYears(int value) { if (value < -10000 || value > 10000) { - // DateTimeOffset.AddYears(int years) is implemented on top of DateTime.AddYears(int value). Use the more appropriate - // parameter name out of the two for the exception. - throw new ArgumentOutOfRangeException("years", SR.ArgumentOutOfRange_DateTimeBadYears); + throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_DateTimeBadYears); } return AddMonths(value * 12); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs index 0075e697cd63f..71011882bd9e3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs @@ -1103,7 +1103,9 @@ public static CultureInfo GetCultureInfo(string name, string altName) } catch (ArgumentException) { +#pragma warning disable CA2208 // Instantiate argument exceptions correctly, combination of arguments used throw new CultureNotFoundException("name/altName", SR.Format(SR.Argument_OneOfCulturesNotSupported, name, altName)); +#pragma warning restore CA2208 } lock (nameTable) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/BinaryWriter.cs b/src/libraries/System.Private.CoreLib/src/System/IO/BinaryWriter.cs index 80fd193b5824b..b4393da162f44 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/BinaryWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/BinaryWriter.cs @@ -394,7 +394,7 @@ public virtual unsafe void Write(string value) { if (charStart < 0 || charCount < 0 || charStart > value.Length - charCount) { - throw new ArgumentOutOfRangeException(nameof(charCount)); + throw new ArgumentOutOfRangeException(nameof(value)); } fixed (char* pChars = value) { diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs index 6c17ca92ac85a..20fc078c95467 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs @@ -408,7 +408,7 @@ public override long Position throw new IOException(SR.IO_SeekBeforeBegin); long newPosition = (long)value - (long)_mem; if (newPosition < 0) - throw new ArgumentOutOfRangeException("offset", SR.ArgumentOutOfRange_UnmanagedMemStreamLength); + throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_UnmanagedMemStreamLength); Interlocked.Exchange(ref _position, newPosition); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs index 1b18fd5eca51f..bdff2d05df01e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs @@ -1144,7 +1144,9 @@ public StringBuilder Remove(int startIndex, int length) return this; } +#pragma warning disable CA1830 // Prefer strongly-typed Append and Insert method overloads on StringBuilder. No need to fix for the builder itself public StringBuilder Append(bool value) => Append(value.ToString()); +#pragma warning restore CA1830 public StringBuilder Append(char value) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs index 8bdf89070a9ad..9abd9ac2aa98a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs @@ -243,7 +243,7 @@ public bool TrySetApartmentState(ApartmentState state) break; default: - throw new ArgumentOutOfRangeException(SR.ArgumentOutOfRange_Enum, nameof(state)); + throw new ArgumentOutOfRangeException(nameof(state), SR.ArgumentOutOfRange_Enum); } return TrySetApartmentStateUnchecked(state); diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.Enum.cs b/src/libraries/System.Private.CoreLib/src/System/Type.Enum.cs index 59f244f6c3477..d041c32b7b534 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.Enum.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.Enum.cs @@ -23,7 +23,7 @@ public virtual bool IsEnumDefined(object value) throw new ArgumentNullException(nameof(value)); if (!IsEnum) - throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); + throw new ArgumentException(SR.Arg_MustBeEnum, nameof(value)); // Check if both of them are of the same type Type valueType = value.GetType(); @@ -70,7 +70,7 @@ public virtual bool IsEnumDefined(object value) throw new ArgumentNullException(nameof(value)); if (!IsEnum) - throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); + throw new ArgumentException(SR.Arg_MustBeEnum, nameof(value)); Type valueType = value.GetType(); diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index aeb60457d9741..76aa11bc20491 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -267,7 +267,7 @@ public static Type[] GetTypeArray(object[] args) for (int i = 0; i < cls.Length; i++) { if (args[i] == null) - throw new ArgumentNullException(); + throw new ArgumentException(SR.ArgumentNull_ArrayValue, nameof(args)); cls[i] = args[i].GetType(); } return cls; diff --git a/src/libraries/System.Private.Uri/src/Resources/Strings.resx b/src/libraries/System.Private.Uri/src/Resources/Strings.resx index 16e3b576da63a..92a87cd44ccaa 100644 --- a/src/libraries/System.Private.Uri/src/Resources/Strings.resx +++ b/src/libraries/System.Private.Uri/src/Resources/Strings.resx @@ -192,6 +192,9 @@ The given key '{0}' was not present in the dictionary. + + Null is not a valid value for {0}. + UriParser's base InitializeAndValidate may only be called once on a single Uri instance and only from an override of InitializeAndValidate. diff --git a/src/libraries/System.Private.Uri/src/System/Uri.cs b/src/libraries/System.Private.Uri/src/System/Uri.cs index a13566ee3415b..2ed3c4ec70146 100644 --- a/src/libraries/System.Private.Uri/src/System/Uri.cs +++ b/src/libraries/System.Private.Uri/src/System/Uri.cs @@ -436,7 +436,7 @@ protected Uri(SerializationInfo serializationInfo, StreamingContext streamingCon uriString = serializationInfo.GetString("RelativeUri"); // Do not rename (binary serialization) if ((object?)uriString == null) - throw new ArgumentNullException(nameof(uriString)); + throw new ArgumentException(SR.Format(SR.InvalidNullArgument, "RelativeUri"), nameof(serializationInfo)); CreateThis(uriString, false, UriKind.Relative); DebugSetLeftCtor(); @@ -1504,7 +1504,7 @@ public static bool CheckSchemeName(string? schemeName) (uint)(digit - '0') <= '9' - '0' ? digit - '0' : (uint)(digit - 'A') <= 'F' - 'A' ? digit - 'A' + 10 : (uint)(digit - 'a') <= 'f' - 'a' ? digit - 'a' + 10 : - throw new ArgumentException(nameof(digit)); + throw new ArgumentException(null, nameof(digit)); public override int GetHashCode() { diff --git a/src/libraries/System.Private.Uri/tests/ExtendedFunctionalTests/UriTests.cs b/src/libraries/System.Private.Uri/tests/ExtendedFunctionalTests/UriTests.cs index 3aeb6238fbf48..2561e785c6e66 100644 --- a/src/libraries/System.Private.Uri/tests/ExtendedFunctionalTests/UriTests.cs +++ b/src/libraries/System.Private.Uri/tests/ExtendedFunctionalTests/UriTests.cs @@ -180,7 +180,7 @@ public static void TestHexMethods() [Fact] public static void TestHexMethods_Invalid() { - AssertExtensions.Throws(null, () => Uri.FromHex('?')); + AssertExtensions.Throws("digit", () => Uri.FromHex('?')); Assert.Throws(() => Uri.HexEscape('\x100')); int index = -1; Assert.Throws(() => Uri.HexUnescape("%75", ref index)); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/NameTable.cs b/src/libraries/System.Private.Xml/src/System/Xml/NameTable.cs index 5bb3c734340a7..0ee36591cc7d7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/NameTable.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/NameTable.cs @@ -103,7 +103,7 @@ public override string Add(char[] key, int start, int len) // Compatibility check for len < 0, just throw the same exception as new string(key, start, len) if (len < 0) { - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(len)); } int hashCode = ComputeHash32(key, start, len); diff --git a/src/libraries/System.Reflection.Extensions/tests/RuntimeReflectionExtensionTests.cs b/src/libraries/System.Reflection.Extensions/tests/RuntimeReflectionExtensionTests.cs index f3ca59bbca687..5464877b54c54 100644 --- a/src/libraries/System.Reflection.Extensions/tests/RuntimeReflectionExtensionTests.cs +++ b/src/libraries/System.Reflection.Extensions/tests/RuntimeReflectionExtensionTests.cs @@ -165,7 +165,7 @@ public void GetRuntimeEvent() }); - Assert.Throws(null, () => + Assert.Throws("name", () => { typeof(RuntimeReflectionExtensionsTests).GetRuntimeEvent(null); }); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/ComAwareEventInfoTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/ComAwareEventInfoTests.cs index f3513d414c075..243133c3b3cb0 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/ComAwareEventInfoTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/ComAwareEventInfoTests.cs @@ -39,7 +39,7 @@ public void Ctor_NullType_ThrowsNullReferenceException() [Fact] public void Ctor_NullEventName_ThrowsArgumentNullException() { - AssertExtensions.Throws(null, () => new ComAwareEventInfo(typeof(NonComObject), null)); + AssertExtensions.Throws("name", () => new ComAwareEventInfo(typeof(NonComObject), null)); } [Fact] diff --git a/src/libraries/System.Runtime/tests/System/DateTimeOffsetTests.cs b/src/libraries/System.Runtime/tests/System/DateTimeOffsetTests.cs index d62cb75547c15..0d146b4cd2c6f 100644 --- a/src/libraries/System.Runtime/tests/System/DateTimeOffsetTests.cs +++ b/src/libraries/System.Runtime/tests/System/DateTimeOffsetTests.cs @@ -357,8 +357,8 @@ public static void AddYears(DateTimeOffset dateTimeOffset, int years, DateTimeOf [Fact] public static void AddYears_NewDateOutOfRange_ThrowsArgumentOutOfRangeException() { - AssertExtensions.Throws("years", () => DateTimeOffset.Now.AddYears(10001)); - AssertExtensions.Throws("years", () => DateTimeOffset.Now.AddYears(-10001)); + AssertExtensions.Throws("value", () => DateTimeOffset.Now.AddYears(10001)); + AssertExtensions.Throws("value", () => DateTimeOffset.Now.AddYears(-10001)); AssertExtensions.Throws("months", () => DateTimeOffset.MaxValue.AddYears(1)); AssertExtensions.Throws("months", () => DateTimeOffset.MinValue.AddYears(-1)); diff --git a/src/libraries/System.Runtime/tests/System/DateTimeTests.cs b/src/libraries/System.Runtime/tests/System/DateTimeTests.cs index 654a103cc9af0..c1d68a264deec 100644 --- a/src/libraries/System.Runtime/tests/System/DateTimeTests.cs +++ b/src/libraries/System.Runtime/tests/System/DateTimeTests.cs @@ -383,8 +383,8 @@ public void AddYears_Invoke_ReturnsExpected(DateTime dateTime, int years, DateTi public static IEnumerable AddYears_OutOfRange_TestData() { - yield return new object[] { DateTime.Now, 10001, "years" }; - yield return new object[] { DateTime.Now, -10001, "years" }; + yield return new object[] { DateTime.Now, 10001, "value" }; + yield return new object[] { DateTime.Now, -10001, "value" }; yield return new object[] { DateTime.MaxValue, 1, "months" }; yield return new object[] { DateTime.MinValue, -1, "months" }; } diff --git a/src/libraries/System.Runtime/tests/System/GCTests.cs b/src/libraries/System.Runtime/tests/System/GCTests.cs index 097f2dcac805b..4c8c309167735 100644 --- a/src/libraries/System.Runtime/tests/System/GCTests.cs +++ b/src/libraries/System.Runtime/tests/System/GCTests.cs @@ -25,7 +25,7 @@ public static void AddMemoryPressure_InvalidBytesAllocated_ThrowsArgumentOutOfRa if (s_is32Bits) { - AssertExtensions.Throws("pressure", () => GC.AddMemoryPressure((long)int.MaxValue + 1)); // Bytes allocated > int.MaxValue on 32 bit platforms + AssertExtensions.Throws("bytesAllocated", () => GC.AddMemoryPressure((long)int.MaxValue + 1)); // Bytes allocated > int.MaxValue on 32 bit platforms } } diff --git a/src/libraries/System.Runtime/tests/System/Type/TypeTests.Get.cs b/src/libraries/System.Runtime/tests/System/Type/TypeTests.Get.cs index 5f19479bc6211..9e3e3d2c2372d 100644 --- a/src/libraries/System.Runtime/tests/System/Type/TypeTests.Get.cs +++ b/src/libraries/System.Runtime/tests/System/Type/TypeTests.Get.cs @@ -71,7 +71,7 @@ public void GetInterface_Invoke_ReturnsExpected(Type type, string name, bool ign [Fact] public void GetInterface_NullName_ThrowsArgumentNullException() { - AssertExtensions.Throws(null, () => typeof(int).GetInterface(null)); + AssertExtensions.Throws("fullname", () => typeof(int).GetInterface(null)); } [Fact] diff --git a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/CommonObjectSecurity.cs b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/CommonObjectSecurity.cs index 1ff7c7c416486..a1665aa92070c 100644 --- a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/CommonObjectSecurity.cs +++ b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/CommonObjectSecurity.cs @@ -336,7 +336,7 @@ protected override bool ModifyAccess(AccessControlModification modification, Acc else { Debug.Fail("rule.AccessControlType unrecognized"); - throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)rule.AccessControlType), "rule.AccessControlType"); + throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)rule.AccessControlType), nameof(rule)); } modified = result; diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/DSA.Xml.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/DSA.Xml.cs index cfa242d50fb96..f32e384c70e94 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/DSA.Xml.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/DSA.Xml.cs @@ -127,10 +127,12 @@ public override string ToXmlString(bool includePrivateParameters) { if (keyParameters.X == null) { +#pragma warning disable CA2208 // Instantiate argument exceptions correctly // .NET Framework compat when a 3rd party type lets X be null when // includePrivateParameters is true // (the exception would have been from Convert.ToBase64String) throw new ArgumentNullException("inArray"); +#pragma warning restore CA2208 } XmlKeyHelper.WriteCryptoBinary(nameof(DSAParameters.X), keyParameters.X, builder); diff --git a/src/libraries/System.Security.Cryptography.Encoding/src/System/Security/Cryptography/PemEncoding.cs b/src/libraries/System.Security.Cryptography.Encoding/src/System/Security/Cryptography/PemEncoding.cs index 7232a72205c9c..0315d5ba4b3e0 100644 --- a/src/libraries/System.Security.Cryptography.Encoding/src/System/Security/Cryptography/PemEncoding.cs +++ b/src/libraries/System.Security.Cryptography.Encoding/src/System/Security/Cryptography/PemEncoding.cs @@ -438,7 +438,7 @@ static int WriteBase64(ReadOnlySpan bytes, Span dest, int offset) if (!success) { Debug.Fail("Convert.TryToBase64Chars failed with a pre-sized buffer"); - throw new ArgumentException(); + throw new ArgumentException(null, nameof(destination)); } return base64Written; @@ -528,7 +528,7 @@ public static char[] Write(ReadOnlySpan label, ReadOnlySpan data) if (!TryWrite(label, data, buffer, out int charsWritten)) { Debug.Fail("TryWrite failed with a pre-sized buffer"); - throw new ArgumentException(); + throw new ArgumentException(null, nameof(data)); } Debug.Assert(charsWritten == encodedSize); diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography.Pkcs/src/Resources/Strings.resx index 117980b01ba6e..aa366d559ef7d 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Resources/Strings.resx @@ -1,4 +1,5 @@ - + + @@ -57,8 +58,8 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - String cannot be empty or null. + + The `{0}` string cannot be empty or null. Only single dimensional arrays are supported for the requested action. @@ -214,10 +215,10 @@ New Pkcs12SafeBag values cannot be added to a Pkcs12SafeContents that was read from existing data. - This decryption operation applies to 'Pkcs12ConfidentialityMode.{0}', but the target object is in 'Pkcs12ConfidentialityMode.{1}'. + This decryption operation applies to 'Pkcs12ConfidentialityMode.{0}', but the target object is in 'Pkcs12ConfidentialityMode.{1}'. - This verification operation applies to 'Pkcs12IntegrityMode.{0}', but the target object is in 'Pkcs12IntegrityMode.{1}'. + This verification operation applies to 'Pkcs12IntegrityMode.{0}', but the target object is in 'Pkcs12IntegrityMode.{1}'. Invalid signature paramters. @@ -294,4 +295,4 @@ Certificate already present in the collection. - + \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Pkcs12Builder.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Pkcs12Builder.cs index 4290deb59336b..be3874b32d4bb 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Pkcs12Builder.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Pkcs12Builder.cs @@ -41,7 +41,7 @@ public sealed class Pkcs12Builder if (pbeParameters == null) throw new ArgumentNullException(nameof(pbeParameters)); if (pbeParameters.IterationCount < 1) - throw new ArgumentOutOfRangeException(nameof(pbeParameters.IterationCount)); + throw new ArgumentOutOfRangeException(nameof(pbeParameters)); if (safeContents.ConfidentialityMode != Pkcs12ConfidentialityMode.None) throw new ArgumentException(SR.Cryptography_Pkcs12_CannotProcessEncryptedSafeContents, nameof(safeContents)); if (IsSealed) @@ -89,7 +89,7 @@ public sealed class Pkcs12Builder if (pbeParameters == null) throw new ArgumentNullException(nameof(pbeParameters)); if (pbeParameters.IterationCount < 1) - throw new ArgumentOutOfRangeException(nameof(pbeParameters.IterationCount)); + throw new ArgumentOutOfRangeException(nameof(pbeParameters)); if (safeContents.ConfidentialityMode != Pkcs12ConfidentialityMode.None) throw new ArgumentException(SR.Cryptography_Pkcs12_CannotProcessEncryptedSafeContents, nameof(safeContents)); if (IsSealed) diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Pkcs9AttributeObject.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Pkcs9AttributeObject.cs index 11bb644cafa87..cb86b388484ea 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Pkcs9AttributeObject.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Pkcs9AttributeObject.cs @@ -32,12 +32,12 @@ public Pkcs9AttributeObject(AsnEncodedData asnEncodedData) : base(asnEncodedData) { if (asnEncodedData.Oid == null) - throw new ArgumentNullException(nameof(asnEncodedData.Oid)); + throw new ArgumentException(SR.Format(SR.Arg_EmptyOrNullString_Named, "asnEncodedData.Oid"), nameof(asnEncodedData)); string? szOid = base.Oid!.Value; if (szOid == null) - throw new ArgumentNullException("oid.Value"); + throw new ArgumentException(SR.Format(SR.Arg_EmptyOrNullString_Named, "oid.Value"), nameof(asnEncodedData)); if (szOid.Length == 0) - throw new ArgumentException(SR.Arg_EmptyOrNullString, "oid.Value"); + throw new ArgumentException(SR.Format(SR.Arg_EmptyOrNullString_Named, "oid.Value"), nameof(asnEncodedData)); } internal Pkcs9AttributeObject(Oid oid) diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignedCms.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignedCms.cs index d45d274e7639b..74646c7186cd3 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignedCms.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignedCms.cs @@ -45,7 +45,7 @@ public SignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo content if (contentInfo == null) throw new ArgumentNullException(nameof(contentInfo)); if (contentInfo.Content == null) - throw new ArgumentNullException("contentInfo.Content"); + throw new ArgumentException(SR.Format(SR.Arg_EmptyOrNullString_Named, "contentInfo.Content"), nameof(contentInfo)); // Normalize the subject identifier type the same way as .NET Framework. // This value is only used in the zero-argument ComputeSignature overload, diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs index 9247ae50b14bf..3d1e349f52985 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs @@ -358,9 +358,7 @@ public void RemoveCounterSignature(int index) { if (index < 0) { - // In .NET Framework RemoveCounterSignature doesn't bounds check, but the helper it calls does. - // In the helper the argument is called "childIndex". - throw new ArgumentOutOfRangeException("childIndex"); + throw new ArgumentOutOfRangeException(nameof(index)); } // The SignerInfo class is a projection of data contained within the SignedCms. diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs9AttributeTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs9AttributeTests.cs index 9591a1bce1a5b..79aa1a42805f5 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs9AttributeTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs9AttributeTests.cs @@ -24,7 +24,7 @@ public static void Pkcs9AttributeAsnEncodedDataCtorNullOid() { AsnEncodedData a = new AsnEncodedData(new byte[3]); object ign; - Assert.Throws(() => ign = new Pkcs9AttributeObject(a)); + AssertExtensions.Throws("asnEncodedData", "asnEncodedData.Oid", () => ign = new Pkcs9AttributeObject(a)); } [Fact] @@ -112,7 +112,7 @@ public static void Pkcs9AttributeAsnEncodedDataCtorNullOidValue() AsnEncodedData a = new AsnEncodedData(oid, new byte[3]); object ign; - Assert.Throws(() => ign = new Pkcs9AttributeObject(a)); + AssertExtensions.Throws("asnEncodedData", "oid.Value", () => ign = new Pkcs9AttributeObject(a)); } [Fact] @@ -123,7 +123,7 @@ public static void Pkcs9AttributeAsnEncodedDataCtorEmptyOidValue() AsnEncodedData a = new AsnEncodedData(oid, new byte[3]); object ign; - AssertExtensions.Throws("oid.Value", () => ign = new Pkcs9AttributeObject(a)); + AssertExtensions.Throws("asnEncodedData", "oid.Value", () => ign = new Pkcs9AttributeObject(a)); } [Fact] diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs index 34a48544a868b..ddfa1dd7f7976 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs @@ -481,6 +481,7 @@ public static void RemoveCounterSignature_Negative() SignerInfo signer = cms.SignerInfos[0]; ArgumentOutOfRangeException ex = AssertExtensions.Throws( + "index", "childIndex", () => signer.RemoveCounterSignature(-1)); diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography.X509Certificates/src/Resources/Strings.resx index 37fc7642786bc..d5e8ac308897f 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Resources/Strings.resx @@ -1,4 +1,5 @@ - + + @@ -66,6 +67,9 @@ String cannot be empty or null. + + The '{0}' string cannot be empty or null. + Illegal enum value: {0}. @@ -74,7 +78,7 @@ Invalid type. - + Non-negative number required. @@ -223,7 +227,7 @@ The provided hash value is not the expected size for the specified hash algorithm. - The Disallowed store is not supported on this platform, but already has data. All files under '{0}' must be removed. + The Disallowed store is not supported on this platform, but already has data. All files under '{0}' must be removed. Unix LocalMachine X509Stores are read-only for all users. @@ -235,7 +239,7 @@ The Disallowed store is not supported on this platform. - The {0} value cannot be set on Unix. + The {0} value cannot be set on Unix. '{0}' is not a known hash algorithm. @@ -286,7 +290,7 @@ The X509 certificate store is read-only. - The platform does not have a definition for an X509 certificate store named '{0}' with a StoreLocation of '{1}', and does not support creating it. + The platform does not have a definition for an X509 certificate store named '{0}' with a StoreLocation of '{1}', and does not support creating it. Enumeration has not started. Call MoveNext. @@ -417,4 +421,4 @@ Key is not a valid private key. - + \ No newline at end of file diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Extension.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Extension.cs index af33813026922..84d5cb3eae3e9 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Extension.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509Extension.cs @@ -31,7 +31,7 @@ public X509Extension(Oid oid, byte[] rawData, bool critical) if (base.Oid == null || base.Oid.Value == null) throw new ArgumentNullException(nameof(oid)); if (base.Oid.Value.Length == 0) - throw new ArgumentException(SR.Arg_EmptyOrNullString, "oid.Value"); + throw new ArgumentException(SR.Format(SR.Arg_EmptyOrNullString_Named, "oid.Value"), nameof(oid)); Critical = critical; } diff --git a/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/SID.cs b/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/SID.cs index 81da0b439bb03..19782152c0169 100644 --- a/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/SID.cs +++ b/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/SID.cs @@ -640,7 +640,9 @@ public SecurityIdentifier(WellKnownSidType sidType, SecurityIdentifier? domainSi if (error == Interop.Errors.ERROR_INVALID_PARAMETER) { +#pragma warning disable CA2208 // Instantiate argument exceptions correctly, combination of arguments used throw new ArgumentException(new Win32Exception(error).Message, "sidType/domainSid"); +#pragma warning restore CS2208 } else if (error != Interop.Errors.ERROR_SUCCESS) { diff --git a/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/WindowsIdentity.cs b/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/WindowsIdentity.cs index be5c623b29967..0c4e03d627194 100644 --- a/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/WindowsIdentity.cs +++ b/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/WindowsIdentity.cs @@ -134,11 +134,8 @@ public WindowsIdentity(string sUserPrincipalName) sourceContext.SourceName = new byte[TOKEN_SOURCE.TOKEN_SOURCE_LENGTH]; Buffer.BlockCopy(sourceName, 0, sourceContext.SourceName, 0, sourceName.Length); - // .NET Framework compat: Desktop never null-checks sUserPrincipalName. Actual behavior is that the null makes it down to Encoding.Unicode.GetBytes() which then throws - // the ArgumentNullException (provided that the prior LSA calls didn't fail first.) To make this compat decision explicit, we'll null check ourselves - // and simulate the exception from Encoding.Unicode.GetBytes(). if (sUserPrincipalName == null) - throw new ArgumentNullException("s"); + throw new ArgumentNullException(nameof(sUserPrincipalName)); byte[] upnBytes = Encoding.Unicode.GetBytes(sUserPrincipalName); if (upnBytes.Length > ushort.MaxValue) diff --git a/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionScope.cs b/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionScope.cs index 71e2285e792a5..acd51f7c186fc 100644 --- a/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionScope.cs +++ b/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionScope.cs @@ -211,7 +211,7 @@ TransactionScopeAsyncFlowOption asyncFlowOption // If the requested IsolationLevel is stronger than that of the specified transaction, throw. if ((IsolationLevel.Unspecified != transactionOptions.IsolationLevel) && (_expectedCurrent.IsolationLevel != transactionOptions.IsolationLevel)) { - throw new ArgumentException(SR.TransactionScopeIsolationLevelDifferentFromTransaction, "transactionOptions.IsolationLevel"); + throw new ArgumentException(SR.TransactionScopeIsolationLevelDifferentFromTransaction, nameof(transactionOptions)); } } } @@ -293,7 +293,7 @@ TransactionScopeAsyncFlowOption asyncFlowOption // If the requested IsolationLevel is stronger than that of the specified transaction, throw. if ((IsolationLevel.Unspecified != transactionOptions.IsolationLevel) && (_expectedCurrent.IsolationLevel != transactionOptions.IsolationLevel)) { - throw new ArgumentException(SR.TransactionScopeIsolationLevelDifferentFromTransaction, "transactionOptions.IsolationLevel"); + throw new ArgumentException(SR.TransactionScopeIsolationLevelDifferentFromTransaction, nameof(transactionOptions)); } } } diff --git a/src/libraries/System.Windows.Extensions/src/System/Drawing/FontConverter.cs b/src/libraries/System.Windows.Extensions/src/System/Drawing/FontConverter.cs index aaea6553cf598..af1308e860eac 100644 --- a/src/libraries/System.Windows.Extensions/src/System/Drawing/FontConverter.cs +++ b/src/libraries/System.Windows.Extensions/src/System/Drawing/FontConverter.cs @@ -173,7 +173,7 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c catch { // Exception from converter is too generic. - throw new ArgumentException(SR.Format(SR.TextParseFailedFormat, font, $"name{separator} size[units[{separator} style=style1[{separator} style2{separator} ...]]]"), nameof(sizeStr)); + throw new ArgumentException(SR.Format(SR.TextParseFailedFormat, font, $"name{separator} size[units[{separator} style=style1[{separator} style2{separator} ...]]]"), nameof(value)); } } diff --git a/src/libraries/System.Windows.Extensions/tests/System/Drawing/FontConverterTests.cs b/src/libraries/System.Windows.Extensions/tests/System/Drawing/FontConverterTests.cs index 02a01346d208f..951ccfaeb9193 100644 --- a/src/libraries/System.Windows.Extensions/tests/System/Drawing/FontConverterTests.cs +++ b/src/libraries/System.Windows.Extensions/tests/System/Drawing/FontConverterTests.cs @@ -131,7 +131,7 @@ private static bool EmptyFontPresent public static TheoryData ArgumentExceptionFontConverterData() => new TheoryData() { { $"Courier New{s_Separator} 11 px{s_Separator} type=Bold{s_Separator} Italic", "units", null }, - { $"Courier New{s_Separator} {s_Separator} Style=Bold", "sizeStr", null }, + { $"Courier New{s_Separator} {s_Separator} Style=Bold", "value", null }, { $"Courier New{s_Separator} 11{s_Separator} Style=", "value", null }, { $"Courier New{s_Separator} 11{s_Separator} Style=RandomEnum", null, null }, { $"Arial{s_Separator} 10{s_Separator} style=bold{s_Separator}", "value", null }, diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/GC.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/GC.Mono.cs index 945356c17dec5..b7ac9cfaf4cdf 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/GC.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/GC.Mono.cs @@ -113,7 +113,7 @@ public static int GetGeneration(WeakReference wo) { object? obj = wo.Target; if (obj == null) - throw new ArgumentException(); + throw new ArgumentException(null, nameof(wo)); return GetGeneration(obj); } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs index 00bcc90d59bf8..4ee8768fcb03a 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs @@ -261,7 +261,7 @@ public void AddInterfaceImplementation(Type interfaceType) if (interfaceType == null) throw new ArgumentNullException(nameof(interfaceType)); if (interfaceType.IsByRef) - throw new ArgumentException(nameof(interfaceType)); + throw new ArgumentException(SR.Argument_CannotGetTypeTokenForByRef); check_not_created(); if (interfaces != null) @@ -479,7 +479,7 @@ public ConstructorBuilder DefineDefaultConstructor(MethodAttributes attributes) if (IsInterface) throw new InvalidOperationException(); if ((attributes & (MethodAttributes.Static | MethodAttributes.Virtual)) > 0) - throw new ArgumentException(nameof(attributes)); + throw new ArgumentException(SR.Arg_NoStaticVirtual); if (parent != null) parent_type = parent; @@ -1515,7 +1515,7 @@ public EventBuilder DefineEvent(string name, EventAttributes attributes, Type ev { check_name(nameof(name), name); if (eventtype == null) - throw new ArgumentNullException("type"); + throw new ArgumentNullException(nameof(eventtype)); check_not_created(); if (eventtype.IsByRef) throw new ArgumentException(SR.Argument_CannotGetTypeTokenForByRef); @@ -1597,7 +1597,7 @@ public void SetParent(Type? parent) else { if (parent.IsInterface) - throw new ArgumentException(nameof(parent)); + throw new ArgumentException(SR.Argument_CannotSetParentToInterface); this.parent = parent; } this.parent = ResolveUserType(this.parent); @@ -1878,7 +1878,7 @@ public static FieldInfo GetField(Type type, FieldInfo field) throw new ArgumentException("The specified field must be declared on a generic type definition.", nameof(field)); if (field.DeclaringType != type.GetGenericTypeDefinition()) - throw new ArgumentException("field declaring type is not the generic type definition of type", "method"); + throw new ArgumentException("field declaring type is not the generic type definition of type", nameof(field)); FieldInfo res = type.GetField(field); if (res == null) diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.Mono.cs index 5dcda6d90fed6..7c80ba8fb5c6b 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.Mono.cs @@ -8,8 +8,10 @@ public partial class RuntimeHelpers { public static void InitializeArray(Array array, RuntimeFieldHandle fldHandle) { - if (array == null || fldHandle.Value == IntPtr.Zero) - throw new ArgumentNullException(); + if (array == null) + throw new ArgumentNullException(nameof(array)); + if (fldHandle.Value == IntPtr.Zero) + throw new ArgumentNullException(nameof(fldHandle)); InitializeArray(array, fldHandle.Value); } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeType.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeType.Mono.cs index 9628d4956bcf0..71ff174e23d24 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeType.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeType.Mono.cs @@ -873,7 +873,7 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) protected override PropertyInfo? GetPropertyImpl( string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { - if (name == null) throw new ArgumentNullException(); + if (name == null) throw new ArgumentNullException(nameof(name)); ListBuilder candidates = GetPropertyCandidates(name, bindingAttr, types, false); @@ -911,7 +911,7 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) public override EventInfo? GetEvent(string name, BindingFlags bindingAttr) { - if (name == null) throw new ArgumentNullException(); + if (name == null) throw new ArgumentNullException(nameof(name)); bool ignoreCase; MemberListType listType; @@ -978,7 +978,7 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) public override Type? GetInterface(string fullname, bool ignoreCase) { - if (fullname == null) throw new ArgumentNullException(); + if (fullname == null) throw new ArgumentNullException(nameof(fullname)); BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.NonPublic; @@ -1031,7 +1031,7 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) public override Type? GetNestedType(string fullname, BindingFlags bindingAttr) { - if (fullname == null) throw new ArgumentNullException(); + if (fullname == null) throw new ArgumentNullException(nameof(fullname)); bool ignoreCase; bindingAttr &= ~BindingFlags.Static; @@ -1059,7 +1059,7 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { - if (name == null) throw new ArgumentNullException(); + if (name == null) throw new ArgumentNullException(nameof(name)); ListBuilder methods = default; ListBuilder constructors = default; From 5b112c310f9ea28ca7a06941787f2bea7eb315eb Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 15 May 2020 17:30:17 -0400 Subject: [PATCH 233/420] More HTTP/2 performance (and a few functional) improvements (#36246) * Use span instead of array for StatusHeaderName * Fix potential leak into CancellationToken We need to dispose of the linked token source we create. Also cleaned up some unnecessarily complicated code nearby. * Fix HttpConnectionBase.LogExceptions My previous changes here were flawed for the sync-completing case, and also accidentally introduced a closure. * Clean up protocol state if/else cascades into switches * Consolidate a bunch of exception throws into helpers * Fix cancellation handling of WaitFor100ContinueAsync * Change AsyncMutex's linked list to be circular * Remove linked token sources Rather than creating temporary linked token sources with the request body source and the supplied cancellation token, we can instead just register with the supplied token to cancel the request body source. This is valid because canceling any part of sending a request cancels any further sending of that request, not just that one constituent operation. * Avoid registering for linked cancellation until absolutely necessary We can avoid registering with the cancellation token until after we know that our send is completing asynchronously. * Remove closure/delegate allocation from WaitForDataAsync `this` was being closed over accidentally. I can't wait for static lambdas. * Avoid a temporary list for storing trailers Since it only exists to be defensive but we don't expect response.TrailingHeaders to be accessed until after the whole response has been received, we can store the headers into an HttpResponseHeaders instance and swap that instance in at the end. Best and common case, we avoid the list. Worst and uncommon case, we pay the overhead of the extra HttpResponseHeaders instead of the List. * Delete dead AcquireWriteLockAsync method * Reduce header frame overhead Minor optimizations to improve the asm * Remove unnecessary throws with GetShutdownException * Avoid extra lock in SendHeadersAsync * Move Http2Stream construction out of lock Makes a significant impact on reducing lock contention. * Streamline RemoveStream Including moving credit adjustment out of the lock * Move response message allocation to ctor Remove it from within the lock * Reorder interfaces on Http2Stream IHttpTrace doesn't need to be prioritized. * Address PR feedback --- .../HttpClientHandlerTest.Cancellation.cs | 36 +- .../Net/Http/Headers/HttpResponseHeaders.cs | 2 + .../System/Net/Http/HttpResponseMessage.cs | 37 +- .../SocketsHttpHandler/Http2Connection.cs | 366 +++++++----------- .../Http/SocketsHttpHandler/Http2Stream.cs | 316 ++++++++------- .../SocketsHttpHandler/HttpConnectionBase.cs | 27 +- .../src/System/Threading/AsyncMutex.cs | 108 +++--- 7 files changed, 416 insertions(+), 476 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs index 6d87c677fd020..679b5406f8170 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cancellation.cs @@ -437,7 +437,7 @@ public static IEnumerable PostAsync_Cancel_CancellationTokenPassedToCo bool called = false; var content = new StreamContent(new DelegateStream( canReadFunc: () => true, - readAsyncFunc: (buffer, offset, count, cancellationToken) => + readAsyncFunc: async (buffer, offset, count, cancellationToken) => { int result = 1; if (called) @@ -445,11 +445,17 @@ public static IEnumerable PostAsync_Cancel_CancellationTokenPassedToCo result = 0; Assert.False(cancellationToken.IsCancellationRequested); tokenSource.Cancel(); - Assert.True(cancellationToken.IsCancellationRequested); + + // Wait for cancellation to occur. It should be very quickly after it's been requested. + var tcs = new TaskCompletionSource(); + using (cancellationToken.Register(() => tcs.SetResult(true))) + { + await tcs.Task; + } } called = true; - return Task.FromResult(result); + return result; } )); yield return new object[] { content, tokenSource }; @@ -467,7 +473,7 @@ public static IEnumerable PostAsync_Cancel_CancellationTokenPassedToCo lengthFunc: () => 1, positionGetFunc: () => 0, positionSetFunc: _ => {}, - readAsyncFunc: (buffer, offset, count, cancellationToken) => + readAsyncFunc: async (buffer, offset, count, cancellationToken) => { int result = 1; if (called) @@ -475,11 +481,17 @@ public static IEnumerable PostAsync_Cancel_CancellationTokenPassedToCo result = 0; Assert.False(cancellationToken.IsCancellationRequested); tokenSource.Cancel(); - Assert.True(cancellationToken.IsCancellationRequested); + + // Wait for cancellation to occur. It should be very quickly after it's been requested. + var tcs = new TaskCompletionSource(); + using (cancellationToken.Register(() => tcs.SetResult(true))) + { + await tcs.Task; + } } called = true; - return Task.FromResult(result); + return result; } ))); yield return new object[] { content, tokenSource }; @@ -497,7 +509,7 @@ public static IEnumerable PostAsync_Cancel_CancellationTokenPassedToCo lengthFunc: () => 1, positionGetFunc: () => 0, positionSetFunc: _ => {}, - readAsyncFunc: (buffer, offset, count, cancellationToken) => + readAsyncFunc: async (buffer, offset, count, cancellationToken) => { int result = 1; if (called) @@ -505,11 +517,17 @@ public static IEnumerable PostAsync_Cancel_CancellationTokenPassedToCo result = 0; Assert.False(cancellationToken.IsCancellationRequested); tokenSource.Cancel(); - Assert.True(cancellationToken.IsCancellationRequested); + + // Wait for cancellation to occur. It should be very quickly after it's been requested. + var tcs = new TaskCompletionSource(); + using (cancellationToken.Register(() => tcs.SetResult(true))) + { + await tcs.Task; + } } called = true; - return Task.FromResult(result); + return result; } ))); yield return new object[] { content, tokenSource }; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs index 8da6741d18748..38643801d34e2 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs @@ -147,6 +147,8 @@ internal HttpResponseHeaders(bool containsTrailingHeaders = false) _containsTrailingHeaders = containsTrailingHeaders; } + internal bool ContainsTrailingHeaders => _containsTrailingHeaders; + internal override void AddHeaders(HttpHeaders sourceHeaders) { base.AddHeaders(sourceHeaders); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs index b0763db9560bb..9873b4246f554 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Net.Http.Headers; using System.Text; @@ -106,28 +107,28 @@ public HttpStatusCode StatusCode internal void SetReasonPhraseWithoutValidation(string value) => _reasonPhrase = value; - public HttpResponseHeaders Headers + public HttpResponseHeaders Headers => _headers ??= new HttpResponseHeaders(); + + public HttpResponseHeaders TrailingHeaders => _trailingHeaders ??= new HttpResponseHeaders(containsTrailingHeaders: true); + + /// Stores the supplied trailing headers into this instance. + /// + /// In the common/desired case where response.TrailingHeaders isn't accessed until after the whole payload has been + /// received, will still be null, and we can simply store the supplied instance into + /// and assume ownership of the instance. In the uncommon case where it was accessed, + /// we add all of the headers to the existing instance. + /// + internal void StoreReceivedTrailingHeaders(HttpResponseHeaders headers) { - get + Debug.Assert(headers.ContainsTrailingHeaders); + + if (_trailingHeaders is null) { - if (_headers == null) - { - _headers = new HttpResponseHeaders(); - } - return _headers; + _trailingHeaders = headers; } - } - - public HttpResponseHeaders TrailingHeaders - { - get + else { - if (_trailingHeaders == null) - { - _trailingHeaders = new HttpResponseHeaders(containsTrailingHeaders: true); - } - - return _trailingHeaders; + _trailingHeaders.AddHeaders(headers); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs index 00b9bc1d2cb6b..9af644504a03e 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs @@ -5,6 +5,7 @@ using System.Buffers.Binary; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Net.Http.Headers; using System.Net.Http.HPack; @@ -133,17 +134,17 @@ public async ValueTask SetupAsync() s_http2ConnectionPreface.AsSpan().CopyTo(_outgoingBuffer.AvailableSpan); _outgoingBuffer.Commit(s_http2ConnectionPreface.Length); - // Send SETTINGS frame - WriteFrameHeader(new FrameHeader(FrameHeader.SettingLength, FrameType.Settings, FrameFlags.None, 0)); - - // Disable push promise + // Send SETTINGS frame. Disable push promise. + FrameHeader.WriteTo(_outgoingBuffer.AvailableSpan, FrameHeader.SettingLength, FrameType.Settings, FrameFlags.None, streamId: 0); + _outgoingBuffer.Commit(FrameHeader.Size); BinaryPrimitives.WriteUInt16BigEndian(_outgoingBuffer.AvailableSpan, (ushort)SettingId.EnablePush); _outgoingBuffer.Commit(2); BinaryPrimitives.WriteUInt32BigEndian(_outgoingBuffer.AvailableSpan, 0); _outgoingBuffer.Commit(4); // Send initial connection-level WINDOW_UPDATE - WriteFrameHeader(new FrameHeader(FrameHeader.WindowUpdateLength, FrameType.WindowUpdate, FrameFlags.None, 0)); + FrameHeader.WriteTo(_outgoingBuffer.AvailableSpan, FrameHeader.WindowUpdateLength, FrameType.WindowUpdate, FrameFlags.None, streamId: 0); + _outgoingBuffer.Commit(FrameHeader.Size); BinaryPrimitives.WriteUInt32BigEndian(_outgoingBuffer.AvailableSpan, (ConnectionWindowSize - DefaultInitialWindowSize)); _outgoingBuffer.Commit(4); @@ -195,7 +196,7 @@ private async ValueTask ReadFrameAsync(bool initialFrame = false) // Parse the frame header from our read buffer and validate it. FrameHeader frameHeader = FrameHeader.ReadFrom(_incomingBuffer.ActiveSpan); - if (frameHeader.Length > FrameHeader.MaxLength) + if (frameHeader.PayloadLength > FrameHeader.MaxPayloadLength) { if (initialFrame && NetEventSource.IsEnabled) { @@ -204,21 +205,21 @@ private async ValueTask ReadFrameAsync(bool initialFrame = false) } _incomingBuffer.Discard(FrameHeader.Size); - throw new Http2ConnectionException(initialFrame ? Http2ProtocolErrorCode.ProtocolError : Http2ProtocolErrorCode.FrameSizeError); + ThrowProtocolError(initialFrame ? Http2ProtocolErrorCode.ProtocolError : Http2ProtocolErrorCode.FrameSizeError); } _incomingBuffer.Discard(FrameHeader.Size); // Ensure we've read the frame contents into our buffer. - if (_incomingBuffer.ActiveLength < frameHeader.Length) + if (_incomingBuffer.ActiveLength < frameHeader.PayloadLength) { - _incomingBuffer.EnsureAvailableSpace(frameHeader.Length - _incomingBuffer.ActiveLength); + _incomingBuffer.EnsureAvailableSpace(frameHeader.PayloadLength - _incomingBuffer.ActiveLength); do { int bytesRead = await _stream.ReadAsync(_incomingBuffer.AvailableMemory).ConfigureAwait(false); _incomingBuffer.Commit(bytesRead); - if (bytesRead == 0) ThrowPrematureEOF(frameHeader.Length); + if (bytesRead == 0) ThrowPrematureEOF(frameHeader.PayloadLength); } - while (_incomingBuffer.ActiveLength < frameHeader.Length); + while (_incomingBuffer.ActiveLength < frameHeader.PayloadLength); } // Return the read frame header. @@ -236,7 +237,7 @@ private async Task ProcessIncomingFramesAsync() FrameHeader frameHeader = await ReadFrameAsync(initialFrame: true).ConfigureAwait(false); if (frameHeader.Type != FrameType.Settings || frameHeader.AckFlag) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } if (NetEventSource.IsEnabled) Trace($"Frame 0: {frameHeader}."); @@ -318,7 +319,8 @@ private async Task ProcessIncomingFramesAsync() case FrameType.PushPromise: // Should not happen, since we disable this in our initial SETTINGS case FrameType.Continuation: // Should only be received while processing headers in ProcessHeadersFrame default: - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); + break; } } } @@ -338,7 +340,7 @@ private async Task ProcessIncomingFramesAsync() { if (streamId <= 0 || streamId >= _nextStream) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } lock (SyncObject) @@ -369,10 +371,10 @@ private async ValueTask ProcessHeadersFrame(FrameHeader frameHeader) http2Stream?.OnHeadersStart(); _hpackDecoder.Decode( - GetFrameData(_incomingBuffer.ActiveSpan.Slice(0, frameHeader.Length), frameHeader.PaddedFlag, frameHeader.PriorityFlag), + GetFrameData(_incomingBuffer.ActiveSpan.Slice(0, frameHeader.PayloadLength), frameHeader.PaddedFlag, frameHeader.PriorityFlag), frameHeader.EndHeadersFlag, http2Stream); - _incomingBuffer.Discard(frameHeader.Length); + _incomingBuffer.Discard(frameHeader.PayloadLength); while (!frameHeader.EndHeadersFlag) { @@ -380,14 +382,14 @@ private async ValueTask ProcessHeadersFrame(FrameHeader frameHeader) if (frameHeader.Type != FrameType.Continuation || frameHeader.StreamId != streamId) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } _hpackDecoder.Decode( - _incomingBuffer.ActiveSpan.Slice(0, frameHeader.Length), + _incomingBuffer.ActiveSpan.Slice(0, frameHeader.PayloadLength), frameHeader.EndHeadersFlag, http2Stream); - _incomingBuffer.Discard(frameHeader.Length); + _incomingBuffer.Discard(frameHeader.PayloadLength); } _hpackDecoder.CompleteDecode(); @@ -404,7 +406,7 @@ private ReadOnlySpan GetFrameData(ReadOnlySpan frameData, bool hasPa { if (frameData.Length == 0) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } int padLength = frameData[0]; @@ -412,7 +414,7 @@ private ReadOnlySpan GetFrameData(ReadOnlySpan frameData, bool hasPa if (frameData.Length < padLength) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } frameData = frameData.Slice(0, frameData.Length - padLength); @@ -422,7 +424,7 @@ private ReadOnlySpan GetFrameData(ReadOnlySpan frameData, bool hasPa { if (frameData.Length < FrameHeader.PriorityInfoLength) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } // We ignore priority info. @@ -443,7 +445,7 @@ private void ProcessAltSvcFrame(FrameHeader frameHeader) if (NetEventSource.IsEnabled) Trace($"{frameHeader}"); Debug.Assert(frameHeader.Type == FrameType.AltSvc); - ReadOnlySpan span = _incomingBuffer.ActiveSpan.Slice(0, frameHeader.Length); + ReadOnlySpan span = _incomingBuffer.ActiveSpan.Slice(0, frameHeader.PayloadLength); if (BinaryPrimitives.TryReadUInt16BigEndian(span, out ushort originLength)) { @@ -464,7 +466,7 @@ private void ProcessAltSvcFrame(FrameHeader frameHeader) } } - _incomingBuffer.Discard(frameHeader.Length); + _incomingBuffer.Discard(frameHeader.PayloadLength); } private void ProcessDataFrame(FrameHeader frameHeader) @@ -476,7 +478,7 @@ private void ProcessDataFrame(FrameHeader frameHeader) // Note, http2Stream will be null if this is a closed stream. // Just ignore the frame in this case. - ReadOnlySpan frameData = GetFrameData(_incomingBuffer.ActiveSpan.Slice(0, frameHeader.Length), hasPad: frameHeader.PaddedFlag, hasPriority: false); + ReadOnlySpan frameData = GetFrameData(_incomingBuffer.ActiveSpan.Slice(0, frameHeader.PayloadLength), hasPad: frameHeader.PaddedFlag, hasPriority: false); if (http2Stream != null) { @@ -490,7 +492,7 @@ private void ProcessDataFrame(FrameHeader frameHeader) ExtendWindow(frameData.Length); } - _incomingBuffer.Discard(frameHeader.Length); + _incomingBuffer.Discard(frameHeader.PayloadLength); } private void ProcessSettingsFrame(FrameHeader frameHeader) @@ -499,19 +501,19 @@ private void ProcessSettingsFrame(FrameHeader frameHeader) if (frameHeader.StreamId != 0) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } if (frameHeader.AckFlag) { - if (frameHeader.Length != 0) + if (frameHeader.PayloadLength != 0) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.FrameSizeError); + ThrowProtocolError(Http2ProtocolErrorCode.FrameSizeError); } if (!_expectingSettingsAck) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } // We only send SETTINGS once initially, so we don't need to do anything in response to the ACK. @@ -520,13 +522,13 @@ private void ProcessSettingsFrame(FrameHeader frameHeader) } else { - if ((frameHeader.Length % 6) != 0) + if ((frameHeader.PayloadLength % 6) != 0) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.FrameSizeError); + ThrowProtocolError(Http2ProtocolErrorCode.FrameSizeError); } // Parse settings and process the ones we care about. - ReadOnlySpan settings = _incomingBuffer.ActiveSpan.Slice(0, frameHeader.Length); + ReadOnlySpan settings = _incomingBuffer.ActiveSpan.Slice(0, frameHeader.PayloadLength); while (settings.Length > 0) { Debug.Assert((settings.Length % 6) == 0); @@ -545,7 +547,7 @@ private void ProcessSettingsFrame(FrameHeader frameHeader) case SettingId.InitialWindowSize: if (settingValue > 0x7FFFFFFF) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.FlowControlError); + ThrowProtocolError(Http2ProtocolErrorCode.FlowControlError); } ChangeInitialWindowSize((int)settingValue); @@ -554,7 +556,7 @@ private void ProcessSettingsFrame(FrameHeader frameHeader) case SettingId.MaxFrameSize: if (settingValue < 16384 || settingValue > 16777215) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } // We don't actually store this value; we always send frames of the minimum size (16K). @@ -567,7 +569,7 @@ private void ProcessSettingsFrame(FrameHeader frameHeader) } } - _incomingBuffer.Discard(frameHeader.Length); + _incomingBuffer.Discard(frameHeader.PayloadLength); // Send acknowledgement // Don't wait for completion, which could happen asynchronously. @@ -611,14 +613,14 @@ private void ProcessPriorityFrame(FrameHeader frameHeader) { Debug.Assert(frameHeader.Type == FrameType.Priority); - if (frameHeader.StreamId == 0 || frameHeader.Length != FrameHeader.PriorityInfoLength) + if (frameHeader.StreamId == 0 || frameHeader.PayloadLength != FrameHeader.PriorityInfoLength) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } // Ignore priority info. - _incomingBuffer.Discard(frameHeader.Length); + _incomingBuffer.Discard(frameHeader.PayloadLength); } private void ProcessPingFrame(FrameHeader frameHeader) @@ -627,18 +629,18 @@ private void ProcessPingFrame(FrameHeader frameHeader) if (frameHeader.StreamId != 0) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } if (frameHeader.AckFlag) { // We never send PING, so an ACK indicates a protocol error - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } - if (frameHeader.Length != FrameHeader.PingLength) + if (frameHeader.PayloadLength != FrameHeader.PingLength) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.FrameSizeError); + ThrowProtocolError(Http2ProtocolErrorCode.FrameSizeError); } // We don't wait for SendPingAckAsync to complete before discarding @@ -650,16 +652,16 @@ private void ProcessPingFrame(FrameHeader frameHeader) LogExceptions(SendPingAckAsync(pingContentLong)); - _incomingBuffer.Discard(frameHeader.Length); + _incomingBuffer.Discard(frameHeader.PayloadLength); } private void ProcessWindowUpdateFrame(FrameHeader frameHeader) { Debug.Assert(frameHeader.Type == FrameType.WindowUpdate); - if (frameHeader.Length != FrameHeader.WindowUpdateLength) + if (frameHeader.PayloadLength != FrameHeader.WindowUpdateLength) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.FrameSizeError); + ThrowProtocolError(Http2ProtocolErrorCode.FrameSizeError); } int amount = BinaryPrimitives.ReadInt32BigEndian(_incomingBuffer.ActiveSpan) & 0x7FFFFFFF; @@ -668,10 +670,10 @@ private void ProcessWindowUpdateFrame(FrameHeader frameHeader) Debug.Assert(amount >= 0); if (amount == 0) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } - _incomingBuffer.Discard(frameHeader.Length); + _incomingBuffer.Discard(frameHeader.PayloadLength); if (frameHeader.StreamId == 0) { @@ -694,28 +696,28 @@ private void ProcessRstStreamFrame(FrameHeader frameHeader) { Debug.Assert(frameHeader.Type == FrameType.RstStream); - if (frameHeader.Length != FrameHeader.RstStreamLength) + if (frameHeader.PayloadLength != FrameHeader.RstStreamLength) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.FrameSizeError); + ThrowProtocolError(Http2ProtocolErrorCode.FrameSizeError); } if (frameHeader.StreamId == 0) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } Http2Stream? http2Stream = GetStream(frameHeader.StreamId); if (http2Stream == null) { // Ignore invalid stream ID, as per RFC - _incomingBuffer.Discard(frameHeader.Length); + _incomingBuffer.Discard(frameHeader.PayloadLength); return; } var protocolError = (Http2ProtocolErrorCode)BinaryPrimitives.ReadInt32BigEndian(_incomingBuffer.ActiveSpan); if (NetEventSource.IsEnabled) Trace(frameHeader.StreamId, $"{nameof(protocolError)}={protocolError}"); - _incomingBuffer.Discard(frameHeader.Length); + _incomingBuffer.Discard(frameHeader.PayloadLength); if (protocolError == Http2ProtocolErrorCode.RefusedStream) { @@ -731,16 +733,16 @@ private void ProcessGoAwayFrame(FrameHeader frameHeader) { Debug.Assert(frameHeader.Type == FrameType.GoAway); - if (frameHeader.Length < FrameHeader.GoAwayMinLength) + if (frameHeader.PayloadLength < FrameHeader.GoAwayMinLength) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.FrameSizeError); + ThrowProtocolError(Http2ProtocolErrorCode.FrameSizeError); } // GoAway frames always apply to the whole connection, never to a single stream. // According to RFC 7540 section 6.8, this should be a connection error. if (frameHeader.StreamId != 0) { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + ThrowProtocolError(); } int lastValidStream = (int)(BinaryPrimitives.ReadUInt32BigEndian(_incomingBuffer.ActiveSpan) & 0x7FFFFFFF); @@ -749,7 +751,7 @@ private void ProcessGoAwayFrame(FrameHeader frameHeader) StartTerminatingConnection(lastValidStream, new Http2ConnectionException(errorCode)); - _incomingBuffer.Discard(frameHeader.Length); + _incomingBuffer.Discard(frameHeader.PayloadLength); } internal async Task FlushAsync(CancellationToken cancellationToken = default) @@ -800,7 +802,7 @@ private async ValueTask> StartWriteAsync(int writeBytes, Cancellati if (_abortException != null) { _writerLock.Exit(); - throw new IOException(SR.net_http_request_aborted, _abortException); + ThrowRequestAborted(_abortException); } // Flush anything necessary, and return back the write buffer to use. @@ -891,58 +893,12 @@ private void EndWrite(bool forceFlush) } } - private async ValueTask AcquireWriteLockAsync(CancellationToken cancellationToken) - { - ValueTask acquireLockTask = _writerLock.EnterAsync(cancellationToken); - if (acquireLockTask.IsCompletedSuccessfully) - { - acquireLockTask.GetAwaiter().GetResult(); // to enable the value task sources to be pooled - } - else - { - Interlocked.Increment(ref _pendingWriters); - - try - { - await acquireLockTask.ConfigureAwait(false); - } - catch - { - if (Interlocked.Decrement(ref _pendingWriters) == 0) - { - // If a pending waiter is canceled, we may end up in a situation where a previously written frame - // saw that there were pending writers and as such deferred its flush to them, but if/when that pending - // writer is canceled, nothing may end up flushing the deferred work (at least not promptly). To compensate, - // if a pending writer does end up being canceled, we flush asynchronously. We can't check whether there's such - // a pending operation because we failed to acquire the lock that protects that state. But we can at least only - // do the flush if our decrement caused the pending count to reach 0: if it's still higher than zero, then there's - // at least one other pending writer who can handle the flush. Worst case, we pay for a flush that ends up being - // a nop. Note: we explicitly do not pass in the cancellationToken; if we're here, it's almost certainly because - // cancellation was requested, and it's because of that cancellation that we need to flush. - LogExceptions(FlushAsync(cancellationToken: default)); - } - - throw; - } - - Interlocked.Decrement(ref _pendingWriters); - } - - // If the connection has been aborted, then fail now instead of trying to send more data. - if (_abortException != null) - { - _writerLock.Exit(); - throw new IOException(SR.net_http_request_aborted, _abortException); - } - } - private async Task SendSettingsAckAsync() { Memory writeBuffer = await StartWriteAsync(FrameHeader.Size).ConfigureAwait(false); if (NetEventSource.IsEnabled) Trace("Started writing."); - FrameHeader frameHeader = new FrameHeader(0, FrameType.Settings, FrameFlags.Ack, 0); - frameHeader.WriteTo(writeBuffer); + FrameHeader.WriteTo(writeBuffer.Span, 0, FrameType.Settings, FrameFlags.Ack, streamId: 0); FinishWrite(FlushTiming.AfterPendingWrites); } @@ -953,12 +909,9 @@ private async Task SendPingAckAsync(long pingContent) Memory writeBuffer = await StartWriteAsync(FrameHeader.Size + FrameHeader.PingLength).ConfigureAwait(false); if (NetEventSource.IsEnabled) Trace("Started writing."); - FrameHeader frameHeader = new FrameHeader(FrameHeader.PingLength, FrameType.Ping, FrameFlags.Ack, 0); - frameHeader.WriteTo(writeBuffer); - writeBuffer = writeBuffer.Slice(FrameHeader.Size); - Debug.Assert(sizeof(long) == FrameHeader.PingLength); - BinaryPrimitives.WriteInt64BigEndian(writeBuffer.Span, pingContent); + FrameHeader.WriteTo(writeBuffer.Span, FrameHeader.PingLength, FrameType.Ping, FrameFlags.Ack, streamId: 0); + BinaryPrimitives.WriteInt64BigEndian(writeBuffer.Span.Slice(FrameHeader.Size), pingContent); FinishWrite(FlushTiming.AfterPendingWrites); } @@ -968,11 +921,8 @@ private async Task SendRstStreamAsync(int streamId, Http2ProtocolErrorCode error Memory writeBuffer = await StartWriteAsync(FrameHeader.Size + FrameHeader.RstStreamLength).ConfigureAwait(false); if (NetEventSource.IsEnabled) Trace(streamId, $"Started writing. {nameof(errorCode)}={errorCode}"); - FrameHeader frameHeader = new FrameHeader(FrameHeader.RstStreamLength, FrameType.RstStream, FrameFlags.None, streamId); - frameHeader.WriteTo(writeBuffer); - writeBuffer = writeBuffer.Slice(FrameHeader.Size); - - BinaryPrimitives.WriteInt32BigEndian(writeBuffer.Span, (int)errorCode); + FrameHeader.WriteTo(writeBuffer.Span, FrameHeader.RstStreamLength, FrameType.RstStream, FrameFlags.None, streamId); + BinaryPrimitives.WriteInt32BigEndian(writeBuffer.Span.Slice(FrameHeader.Size), (int)errorCode); FinishWrite(FlushTiming.Now); // ensure cancellation is seen as soon as possible } @@ -1206,7 +1156,8 @@ private void WriteHeaders(HttpRequestMessage request, ref ArrayBuffer headerBuff } } - private HttpRequestException GetShutdownException() + [DoesNotReturn] + private void ThrowShutdownException() { Debug.Assert(Monitor.IsEntered(SyncObject)); @@ -1233,7 +1184,7 @@ private HttpRequestException GetShutdownException() innerException = new ObjectDisposedException(nameof(Http2Connection)); } - return new HttpRequestException(SR.net_http_client_execution_error, innerException, allowRetry: RequestRetryType.RetryOnSameOrNextProxy); + ThrowRetry(SR.net_http_client_execution_error, innerException); } private async ValueTask SendHeadersAsync(HttpRequestMessage request, CancellationToken cancellationToken, bool mustFlush) @@ -1261,7 +1212,8 @@ private async ValueTask SendHeadersAsync(HttpRequestMessage request { Debug.Assert(_disposed || _lastStreamId != -1); Debug.Assert(_httpStreams.Count == 0); - throw GetShutdownException(); + ThrowShutdownException(); + throw; // unreachable } } @@ -1276,15 +1228,20 @@ private async ValueTask SendHeadersAsync(HttpRequestMessage request Debug.Assert(remaining.Length > 0); // Calculate the total number of bytes we're going to use (content + headers). - int frameCount = ((remaining.Length - 1) / FrameHeader.MaxLength) + 1; + int frameCount = ((remaining.Length - 1) / FrameHeader.MaxPayloadLength) + 1; int totalSize = remaining.Length + (frameCount * FrameHeader.Size); ReadOnlyMemory current; - (current, remaining) = SplitBuffer(remaining, FrameHeader.MaxLength); + (current, remaining) = SplitBuffer(remaining, FrameHeader.MaxPayloadLength); FrameFlags flags = (remaining.Length == 0 ? FrameFlags.EndHeaders : FrameFlags.None) | (request.Content == null ? FrameFlags.EndStream : FrameFlags.None); + // Construct and initialize the new Http2Stream instance. It's stream ID must be set below + // before the instance is used and stored into the dictionary. However, we construct it here + // so as to avoid the allocation and initialization expense while holding multiple locks. + var http2Stream = new Http2Stream(request, this, _initialWindowSize); + // Start the write. This serializes access to write to the connection, and ensures that HEADERS // and CONTINUATION frames stay together, as they must do. We use the lock as well to ensure new // streams are created and started in order. @@ -1293,7 +1250,6 @@ private async ValueTask SendHeadersAsync(HttpRequestMessage request { // Allocate the next available stream ID. Note that if we fail before sending the headers, // we'll just skip this stream ID, which is fine. - int streamId; lock (SyncObject) { if (_nextStream == MaxStreamId || _disposed || _lastStreamId != -1) @@ -1301,44 +1257,43 @@ private async ValueTask SendHeadersAsync(HttpRequestMessage request // We ran out of stream IDs or we raced between acquiring the connection from the pool and shutting down. // Throw a retryable request exception. This will cause retry logic to kick in // and perform another connection attempt. The user should never see this exception. - throw GetShutdownException(); + ThrowShutdownException(); } - streamId = _nextStream; - // Client-initiated streams are always odd-numbered, so increase by 2. + http2Stream.StreamId = _nextStream; _nextStream += 2; + + // We're about to flush the HEADERS frame, so add the stream to the dictionary now. + // The lifetime of the stream is now controlled by the stream itself and the connection. + // This can fail if the connection is shutting down, in which case we will cancel sending this frame. + _httpStreams.Add(http2Stream.StreamId, http2Stream); } - if (NetEventSource.IsEnabled) Trace(streamId, $"Started writing. {nameof(totalSize)}={totalSize}"); + if (NetEventSource.IsEnabled) Trace(http2Stream.StreamId, $"Started writing. {nameof(totalSize)}={totalSize}"); // Copy the HEADERS frame. - new FrameHeader(current.Length, FrameType.Headers, flags, streamId).WriteTo(writeBuffer.Span); + FrameHeader.WriteTo(writeBuffer.Span, current.Length, FrameType.Headers, flags, http2Stream.StreamId); writeBuffer = writeBuffer.Slice(FrameHeader.Size); current.CopyTo(writeBuffer); writeBuffer = writeBuffer.Slice(current.Length); - if (NetEventSource.IsEnabled) Trace(streamId, $"Wrote HEADERS frame. Length={current.Length}, flags={flags}"); + if (NetEventSource.IsEnabled) Trace(http2Stream.StreamId, $"Wrote HEADERS frame. Length={current.Length}, flags={flags}"); // Copy CONTINUATION frames, if any. while (remaining.Length > 0) { - (current, remaining) = SplitBuffer(remaining, FrameHeader.MaxLength); + (current, remaining) = SplitBuffer(remaining, FrameHeader.MaxPayloadLength); flags = remaining.Length == 0 ? FrameFlags.EndHeaders : FrameFlags.None; - new FrameHeader(current.Length, FrameType.Continuation, flags, streamId).WriteTo(writeBuffer.Span); + FrameHeader.WriteTo(writeBuffer.Span, current.Length, FrameType.Continuation, flags, http2Stream.StreamId); writeBuffer = writeBuffer.Slice(FrameHeader.Size); current.CopyTo(writeBuffer); writeBuffer = writeBuffer.Slice(current.Length); - if (NetEventSource.IsEnabled) Trace(streamId, $"Wrote CONTINUATION frame. Length={current.Length}, flags={flags}"); + if (NetEventSource.IsEnabled) Trace(http2Stream.StreamId, $"Wrote CONTINUATION frame. Length={current.Length}, flags={flags}"); } Debug.Assert(writeBuffer.Length == 0); - // We're about to flush the HEADERS frame, so add the stream to the dictionary now. - // The lifetime of the stream is now controlled by the stream itself and the connection. - // This can fail if the connection is shutting down, in which case we will cancel sending this frame. - Http2Stream http2Stream = AddStream(streamId, request); - FinishWrite(mustFlush || (flags & FrameFlags.EndStream) != 0 ? FlushTiming.AfterPendingWrites : FlushTiming.Eventually); return http2Stream; } @@ -1365,7 +1320,7 @@ private async Task SendStreamDataAsync(int streamId, ReadOnlyMemory buffer while (remaining.Length > 0) { - int frameSize = Math.Min(remaining.Length, FrameHeader.MaxLength); + int frameSize = Math.Min(remaining.Length, FrameHeader.MaxPayloadLength); // Once credit had been granted, we want to actually consume those bytes. frameSize = await _connectionWindow.RequestCreditAsync(frameSize, cancellationToken).ConfigureAwait(false); @@ -1387,14 +1342,8 @@ private async Task SendStreamDataAsync(int streamId, ReadOnlyMemory buffer throw; } - FrameHeader frameHeader = new FrameHeader(current.Length, FrameType.Data, FrameFlags.None, streamId); - frameHeader.WriteTo(writeBuffer); - writeBuffer = writeBuffer.Slice(FrameHeader.Size); - - current.CopyTo(writeBuffer); - writeBuffer = writeBuffer.Slice(current.Length); - - Debug.Assert(writeBuffer.Length == 0); + FrameHeader.WriteTo(writeBuffer.Span, current.Length, FrameType.Data, FrameFlags.None, streamId); + current.CopyTo(writeBuffer.Slice(FrameHeader.Size)); FinishWrite(FlushTiming.Eventually); // no need to flush, as the request content may do so explicitly, or worst case we'll do so as part of the end data frame } @@ -1405,8 +1354,7 @@ private async Task SendEndStreamAsync(int streamId) Memory writeBuffer = await StartWriteAsync(FrameHeader.Size).ConfigureAwait(false); if (NetEventSource.IsEnabled) Trace(streamId, "Started writing."); - FrameHeader frameHeader = new FrameHeader(0, FrameType.Data, FrameFlags.EndStream, streamId); - frameHeader.WriteTo(writeBuffer); + FrameHeader.WriteTo(writeBuffer.Span, 0, FrameType.Data, FrameFlags.EndStream, streamId); FinishWrite(FlushTiming.AfterPendingWrites); // finished sending request body, so flush soon (but ok to wait for pending packets) } @@ -1419,11 +1367,8 @@ private async Task SendWindowUpdateAsync(int streamId, int amount) Memory writeBuffer = await StartWriteAsync(FrameHeader.Size + FrameHeader.WindowUpdateLength).ConfigureAwait(false); if (NetEventSource.IsEnabled) Trace(streamId, $"Started writing. {nameof(amount)}={amount}"); - FrameHeader frameHeader = new FrameHeader(FrameHeader.WindowUpdateLength, FrameType.WindowUpdate, FrameFlags.None, streamId); - frameHeader.WriteTo(writeBuffer); - writeBuffer = writeBuffer.Slice(FrameHeader.Size); - - BinaryPrimitives.WriteInt32BigEndian(writeBuffer.Span, amount); + FrameHeader.WriteTo(writeBuffer.Span, FrameHeader.WindowUpdateLength, FrameType.WindowUpdate, FrameFlags.None, streamId); + BinaryPrimitives.WriteInt32BigEndian(writeBuffer.Span.Slice(FrameHeader.Size), amount); FinishWrite(FlushTiming.Now); // make sure window updates are seen as soon as possible } @@ -1452,15 +1397,6 @@ private void ExtendWindow(int amount) LogExceptions(SendWindowUpdateAsync(0, windowUpdateSize)); } - private void WriteFrameHeader(FrameHeader frameHeader) - { - if (NetEventSource.IsEnabled) Trace($"{frameHeader}"); - Debug.Assert(_outgoingBuffer.AvailableMemory.Length >= FrameHeader.Size); - - frameHeader.WriteTo(_outgoingBuffer.AvailableSpan); - _outgoingBuffer.Commit(FrameHeader.Size); - } - /// Abort all streams and cause further processing to fail. /// Exception causing Abort to be called. private void Abort(Exception abortException) @@ -1648,15 +1584,15 @@ private enum FrameType : byte Last = 10 } - private struct FrameHeader + private readonly struct FrameHeader { - public int Length; - public FrameType Type; - public FrameFlags Flags; - public int StreamId; + public readonly int PayloadLength; + public readonly FrameType Type; + public readonly FrameFlags Flags; + public readonly int StreamId; public const int Size = 9; - public const int MaxLength = 16384; + public const int MaxPayloadLength = 16384; public const int SettingLength = 6; // per setting (total SETTINGS length must be a multiple of this) public const int PriorityInfoLength = 5; // for both PRIORITY frame and priority info within HEADERS @@ -1665,11 +1601,11 @@ private struct FrameHeader public const int RstStreamLength = 4; public const int GoAwayMinLength = 8; - public FrameHeader(int length, FrameType type, FrameFlags flags, int streamId) + public FrameHeader(int payloadLength, FrameType type, FrameFlags flags, int streamId) { Debug.Assert(streamId >= 0); - Length = length; + PayloadLength = payloadLength; Type = type; Flags = flags; StreamId = streamId; @@ -1685,36 +1621,31 @@ public static FrameHeader ReadFrom(ReadOnlySpan buffer) { Debug.Assert(buffer.Length >= Size); - return new FrameHeader( - (buffer[0] << 16) | (buffer[1] << 8) | buffer[2], - (FrameType)buffer[3], - (FrameFlags)buffer[4], - (int)((uint)((buffer[5] << 24) | (buffer[6] << 16) | (buffer[7] << 8) | buffer[8]) & 0x7FFFFFFF)); + FrameFlags flags = (FrameFlags)buffer[4]; // do first to avoid some bounds checks + int payloadLength = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; + FrameType type = (FrameType)buffer[3]; + int streamId = (int)(BinaryPrimitives.ReadUInt32BigEndian(buffer.Slice(5)) & 0x7FFFFFFF); + + return new FrameHeader(payloadLength, type, flags, streamId); } - public void WriteTo(Span buffer) + public static void WriteTo(Span destination, int payloadLength, FrameType type, FrameFlags flags, int streamId) { - Debug.Assert(buffer.Length >= Size); - Debug.Assert(Type <= FrameType.Last); - Debug.Assert((Flags & FrameFlags.ValidBits) == Flags); - Debug.Assert(Length <= MaxLength); + Debug.Assert(destination.Length >= Size); + Debug.Assert(type <= FrameType.Last); + Debug.Assert((flags & FrameFlags.ValidBits) == flags); + Debug.Assert((uint)payloadLength <= MaxPayloadLength); - buffer[0] = (byte)((Length & 0x00FF0000) >> 16); - buffer[1] = (byte)((Length & 0x0000FF00) >> 8); - buffer[2] = (byte)(Length & 0x000000FF); - - buffer[3] = (byte)Type; - buffer[4] = (byte)Flags; - - buffer[5] = (byte)((StreamId & 0xFF000000) >> 24); - buffer[6] = (byte)((StreamId & 0x00FF0000) >> 16); - buffer[7] = (byte)((StreamId & 0x0000FF00) >> 8); - buffer[8] = (byte)(StreamId & 0x000000FF); + // This ordering helps eliminate bounds checks. + BinaryPrimitives.WriteInt32BigEndian(destination.Slice(5), streamId); + destination[4] = (byte)flags; + destination[0] = (byte)((payloadLength & 0x00FF0000) >> 16); + destination[1] = (byte)((payloadLength & 0x0000FF00) >> 8); + destination[2] = (byte)(payloadLength & 0x000000FF); + destination[3] = (byte)type; } - public void WriteTo(Memory buffer) => WriteTo(buffer.Span); - - public override string ToString() => $"StreamId={StreamId}; Type={Type}; Flags={Flags}; Length={Length}"; // Description for diagnostic purposes + public override string ToString() => $"StreamId={StreamId}; Type={Type}; Flags={Flags}; PayloadLength={PayloadLength}"; // Description for diagnostic purposes } [Flags] @@ -1835,26 +1766,6 @@ public sealed override async Task SendAsync(HttpRequestMess } } - private Http2Stream AddStream(int streamId, HttpRequestMessage request) - { - lock (SyncObject) - { - if (_disposed || _lastStreamId != -1) - { - // The connection is shutting down. - // Throw a retryable request exception. This will cause retry logic to kick in - // and perform another connection attempt. The user should never see this exception. - throw GetShutdownException(); - } - - Http2Stream http2Stream = new Http2Stream(request, this, streamId, _initialWindowSize); - - _httpStreams.Add(streamId, http2Stream); - - return http2Stream; - } - } - private void RemoveStream(Http2Stream http2Stream) { if (NetEventSource.IsEnabled) Trace(http2Stream.StreamId, ""); @@ -1862,27 +1773,25 @@ private void RemoveStream(Http2Stream http2Stream) lock (SyncObject) { - if (!_httpStreams.Remove(http2Stream.StreamId, out Http2Stream? removed)) + if (!_httpStreams.Remove(http2Stream.StreamId)) { Debug.Fail($"Stream {http2Stream.StreamId} not found in dictionary during RemoveStream???"); return; } - _concurrentStreams.AdjustCredit(1); - - Debug.Assert(removed == http2Stream, "_httpStreams.TryRemove returned unexpected stream"); - if (_httpStreams.Count == 0) { // If this was last pending request, get timestamp so we can monitor idle time. _idleSinceTickCount = Environment.TickCount64; - } - if (_disposed || _lastStreamId != -1) - { - CheckForShutdown(); + if (_disposed || _lastStreamId != -1) + { + CheckForShutdown(); + } } } + + _concurrentStreams.AdjustCredit(1); } public sealed override string ToString() => $"{nameof(Http2Connection)}({_pool})"; // Description for diagnostic purposes @@ -1898,5 +1807,20 @@ private void RemoveStream(Http2Stream http2Stream) memberName, // method name message); // message + [DoesNotReturn] + private static void ThrowRetry(string message, Exception innerException) => + throw new HttpRequestException(message, innerException, allowRetry: RequestRetryType.RetryOnSameOrNextProxy); + + [DoesNotReturn] + private static void ThrowRequestAborted(Exception? innerException = null) => + throw new IOException(SR.net_http_request_aborted, innerException); + + [DoesNotReturn] + private static void ThrowProtocolError() => + ThrowProtocolError(Http2ProtocolErrorCode.ProtocolError); + + [DoesNotReturn] + private static void ThrowProtocolError(Http2ProtocolErrorCode errorCode) => + throw new Http2ConnectionException(errorCode); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs index 6c66a674017b0..146a48da27d18 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs @@ -18,7 +18,7 @@ namespace System.Net.Http { internal sealed partial class Http2Connection { - private sealed class Http2Stream : IValueTaskSource, IHttpTrace, IHttpHeadersHandler + private sealed class Http2Stream : IValueTaskSource, IHttpHeadersHandler, IHttpTrace { private const int InitialStreamBufferSize = #if DEBUG @@ -27,14 +27,13 @@ private sealed class Http2Stream : IValueTaskSource, IHttpTrace, IHttpHeadersHan 1024; #endif - private static readonly byte[] s_statusHeaderName = Encoding.ASCII.GetBytes(":status"); + private static ReadOnlySpan StatusHeaderName => new byte[] { (byte)':', (byte)'s', (byte)'t', (byte)'a', (byte)'t', (byte)'u', (byte)'s' }; private readonly Http2Connection _connection; - private readonly int _streamId; private readonly HttpRequestMessage _request; private HttpResponseMessage? _response; /// Stores any trailers received after returning the response content to the caller. - private List>? _trailers; + private HttpResponseHeaders? _trailers; private ArrayBuffer _responseBuffer; // mutable struct, do not make this readonly private int _pendingWindowUpdate; @@ -81,9 +80,6 @@ private sealed class Http2Stream : IValueTaskSource, IHttpTrace, IHttpHeadersHan private readonly CancellationTokenSource? _requestBodyCancellationSource; - // This is a linked token combining the above source and the user-supplied token to SendRequestBodyAsync - private CancellationToken _requestBodyCancellationToken; - private readonly TaskCompletionSource? _expect100ContinueWaiter; private int _headerBudgetRemaining; @@ -93,11 +89,10 @@ private sealed class Http2Stream : IValueTaskSource, IHttpTrace, IHttpHeadersHan // See comment on ConnectionWindowThreshold. private const int StreamWindowThreshold = StreamWindowSize / 8; - public Http2Stream(HttpRequestMessage request, Http2Connection connection, int streamId, int initialWindowSize) + public Http2Stream(HttpRequestMessage request, Http2Connection connection, int initialWindowSize) { _request = request; _connection = connection; - _streamId = streamId; _requestCompletionState = StreamCompletionState.InProgress; _responseCompletionState = StreamCompletionState.InProgress; @@ -134,12 +129,19 @@ public Http2Stream(HttpRequestMessage request, Http2Connection connection, int s } } + _response = new HttpResponseMessage() + { + Version = HttpVersion.Version20, + RequestMessage = _request, + Content = new HttpConnectionResponseContent() + }; + if (NetEventSource.IsEnabled) Trace($"{request}, {nameof(initialWindowSize)}={initialWindowSize}"); } private object SyncObject => this; // this isn't handed out to code that may lock on it - public int StreamId => _streamId; + public int StreamId { get; set; } public HttpResponseMessage GetAndClearResponse() { @@ -162,28 +164,44 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken) } if (NetEventSource.IsEnabled) Trace($"{_request.Content}"); - Debug.Assert(_requestBodyCancellationSource != null); - // Create a linked cancellation token source so that we can cancel the request in the event of receiving RST_STREAM - // and similiar situations where we need to cancel the request body (see Cancel method). - _requestBodyCancellationToken = cancellationToken.CanBeCanceled ? - CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _requestBodyCancellationSource.Token).Token : - _requestBodyCancellationSource.Token; - + // Cancel the request body sending if cancellation is requested on the supplied cancellation token. + // Normally we might create a linked token, but once cancellation is requested, we can't recover anyway, + // so it's fine to cancel the source representing the whole request body, and doing so allows us to avoid + // creating another CTS instance and the associated nodes inside of it. With this, cancellation will be + // requested on _requestBodyCancellationSource when we need to cancel the request stream for any reason, + // such as receiving an RST_STREAM or when the passed in token has cancellation requested. However, to + // avoid unnecessarily registering with the cancellation token unless we have to, we wait to do so until + // either we know we need to do a Expect: 100-continue send or until we know that the copying of our + // content completed asynchronously. + CancellationTokenRegistration linkedRegistration = default; try { bool sendRequestContent = true; if (_expect100ContinueWaiter != null) { - sendRequestContent = await WaitFor100ContinueAsync(_requestBodyCancellationToken).ConfigureAwait(false); + linkedRegistration = RegisterRequestBodyCancellation(cancellationToken); + sendRequestContent = await WaitFor100ContinueAsync(_requestBodyCancellationSource.Token).ConfigureAwait(false); } if (sendRequestContent) { - using (Http2WriteStream writeStream = new Http2WriteStream(this)) + using var writeStream = new Http2WriteStream(this); + + ValueTask vt = _request.Content.InternalCopyToAsync(writeStream, context: null, _requestBodyCancellationSource.Token); + if (vt.IsCompleted) { - await _request.Content.InternalCopyToAsync(writeStream, null, _requestBodyCancellationToken).ConfigureAwait(false); + vt.GetAwaiter().GetResult(); + } + else + { + if (linkedRegistration.Equals(default)) + { + linkedRegistration = RegisterRequestBodyCancellation(cancellationToken); + } + + await vt.ConfigureAwait(false); } } @@ -192,9 +210,7 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken) catch (Exception e) { if (NetEventSource.IsEnabled) Trace($"Failed to send request body: {e}"); - - bool signalWaiter = false; - bool sendReset = false; + bool signalWaiter; Debug.Assert(!Monitor.IsEntered(SyncObject)); lock (SyncObject) @@ -213,19 +229,15 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken) } // This should not cause RST_STREAM to be sent because the request is still marked as in progress. + bool sendReset; (signalWaiter, sendReset) = CancelResponseBody(); Debug.Assert(!sendReset); _requestCompletionState = StreamCompletionState.Failed; - sendReset = true; Complete(); } - if (sendReset) - { - SendReset(); - } - + SendReset(); if (signalWaiter) { _waitSource.SetResult(true); @@ -233,6 +245,10 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken) throw; } + finally + { + linkedRegistration.Dispose(); + } // New scope here to avoid variable name conflict on "sendReset" { @@ -241,21 +257,14 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken) lock (SyncObject) { Debug.Assert(_requestCompletionState == StreamCompletionState.InProgress, $"Request already completed with state={_requestCompletionState}"); - _requestCompletionState = StreamCompletionState.Completed; - if (_responseCompletionState == StreamCompletionState.Failed) + + if (_responseCompletionState != StreamCompletionState.InProgress) { // Note, we can reach this point if the response stream failed but cancellation didn't propagate before we finished. - sendReset = true; + sendReset = _responseCompletionState == StreamCompletionState.Failed; Complete(); } - else - { - if (_responseCompletionState == StreamCompletionState.Completed) - { - Complete(); - } - } } if (sendReset) @@ -266,7 +275,7 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken) { // Send EndStream asynchronously and without cancellation. // If this fails, it means that the connection is aborting and we will be reset. - _connection.LogExceptions(_connection.SendEndStreamAsync(_streamId)); + _connection.LogExceptions(_connection.SendEndStreamAsync(StreamId)); } } } @@ -277,29 +286,31 @@ public async Task SendRequestBodyAsync(CancellationToken cancellationToken) // If we get response status >= 300, we will not send the request body. public async ValueTask WaitFor100ContinueAsync(CancellationToken cancellationToken) { - Debug.Assert(_request.Content != null); + Debug.Assert(_request?.Content != null); if (NetEventSource.IsEnabled) Trace($"Waiting to send request body content for 100-Continue."); - // use TCS created in constructor. It will complete when one of two things occurs: - // 1. if a timer fires before we receive the relevant response from the server. - // 2. if we receive the relevant response from the server before a timer fires. - // In the first case, we could run this continuation synchronously, but in the latter, we shouldn't, - // as we could end up starting the body copy operation on the main event loop thread, which could - // then starve the processing of other requests. So, we make the TCS RunContinuationsAsynchronously. - bool sendRequestContent; + // Use TCS created in constructor. It will complete when one of three things occurs: + // 1. we receive the relevant response from the server. + // 2. the timer fires before we receive the relevant response from the server. + // 3. cancellation is requested before we receive the relevant response from the server. + // We need to run the continuation asynchronously for cases 1 and 3 (for 1 so that we don't starve the body copy operation, and + // for 3 so that we don't run a lot of work as part of code calling Cancel), so the TCS is created to run continuations asynchronously. + // We await the created Timer's disposal so that we ensure any work associated with it has quiesced prior to this method + // returning, just in case this object is pooled and potentially reused for another operation in the future. TaskCompletionSource waiter = _expect100ContinueWaiter!; - using (var expect100Timer = new Timer(s => + using (cancellationToken.UnsafeRegister(s => ((TaskCompletionSource)s!).TrySetResult(false), waiter)) + await using (new Timer(s => { var thisRef = (Http2Stream)s!; if (NetEventSource.IsEnabled) thisRef.Trace($"100-Continue timer expired."); thisRef._expect100ContinueWaiter?.TrySetResult(true); - }, this, _connection._pool.Settings._expect100ContinueTimeout, Timeout.InfiniteTimeSpan)) + }, this, _connection._pool.Settings._expect100ContinueTimeout, Timeout.InfiniteTimeSpan).ConfigureAwait(false)) { - sendRequestContent = await waiter.Task.ConfigureAwait(false); - // By now, either we got a response from the server or the timer expired. + bool shouldSendContent = await waiter.Task.ConfigureAwait(false); + // By now, either we got a response from the server or the timer expired or cancellation was requested. + CancellationHelper.ThrowIfCancellationRequested(cancellationToken); + return shouldSendContent; } - - return sendRequestContent; } private void SendReset() @@ -315,7 +326,7 @@ private void SendReset() // Don't send a RST_STREAM if we've already received one from the server. if (_resetException == null) { - _connection.LogExceptions(_connection.SendRstStreamAsync(_streamId, Http2ProtocolErrorCode.Cancel)); + _connection.LogExceptions(_connection.SendRstStreamAsync(StreamId, Http2ProtocolErrorCode.Cancel)); } } @@ -357,11 +368,8 @@ private void Cancel() (signalWaiter, sendReset) = CancelResponseBody(); } - if (requestBodyCancellationSource != null) - { - // When cancellation propagates, SendRequestBodyAsync will set _requestCompletionState to Failed - requestBodyCancellationSource.Cancel(); - } + // When cancellation propagates, SendRequestBodyAsync will set _requestCompletionState to Failed + requestBodyCancellationSource?.Cancel(); if (sendReset) { @@ -436,7 +444,7 @@ void IHttpHeadersHandler.OnStaticIndexedHeader(int index, ReadOnlySpan val public void OnHeader(ReadOnlySpan name, ReadOnlySpan value) { if (NetEventSource.IsEnabled) Trace($"{Encoding.ASCII.GetString(name)}: {Encoding.ASCII.GetString(value)}"); - Debug.Assert(name != null && name.Length > 0); + Debug.Assert(name.Length > 0); _headerBudgetRemaining -= name.Length + value.Length; if (_headerBudgetRemaining < 0) @@ -462,7 +470,7 @@ public void OnHeader(ReadOnlySpan name, ReadOnlySpan value) throw new HttpRequestException(SR.net_http_invalid_response_pseudo_header_in_trailer); } - if (name.SequenceEqual(s_statusHeaderName)) + if (name.SequenceEqual(StatusHeaderName)) { if (_responseProtocolState != ResponseProtocolState.ExpectingStatus) { @@ -471,13 +479,8 @@ public void OnHeader(ReadOnlySpan name, ReadOnlySpan value) } int statusValue = ParseStatusCode(value); - _response = new HttpResponseMessage() - { - Version = HttpVersion.Version20, - RequestMessage = _request, - Content = new HttpConnectionResponseContent(), - StatusCode = (HttpStatusCode)statusValue - }; + Debug.Assert(_response != null); + _response.StatusCode = (HttpStatusCode)statusValue; if (statusValue < 200) { @@ -537,7 +540,7 @@ public void OnHeader(ReadOnlySpan name, ReadOnlySpan value) { Debug.Assert(_trailers != null); string headerValue = descriptor.GetHeaderValue(value); - _trailers.Add(KeyValuePair.Create((descriptor.HeaderType & HttpHeaderType.Request) == HttpHeaderType.Request ? descriptor.AsCustomHeader() : descriptor, headerValue)); + _trailers.TryAddWithoutValidation((descriptor.HeaderType & HttpHeaderType.Request) == HttpHeaderType.Request ? descriptor.AsCustomHeader() : descriptor, headerValue); } else if ((descriptor.HeaderType & HttpHeaderType.Content) == HttpHeaderType.Content) { @@ -560,20 +563,20 @@ public void OnHeadersStart() Debug.Assert(!Monitor.IsEntered(SyncObject)); lock (SyncObject) { - if (_responseProtocolState == ResponseProtocolState.Aborted) + switch (_responseProtocolState) { - return; - } - - if (_responseProtocolState != ResponseProtocolState.ExpectingStatus && _responseProtocolState != ResponseProtocolState.ExpectingData) - { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); - } - - if (_responseProtocolState == ResponseProtocolState.ExpectingData) - { - _responseProtocolState = ResponseProtocolState.ExpectingTrailingHeaders; - _trailers ??= new List>(); + case ResponseProtocolState.ExpectingStatus: + case ResponseProtocolState.Aborted: + break; + + case ResponseProtocolState.ExpectingData: + _responseProtocolState = ResponseProtocolState.ExpectingTrailingHeaders; + _trailers ??= new HttpResponseHeaders(containsTrailingHeaders: true); + break; + + default: + ThrowProtocolError(); + break; } } } @@ -584,45 +587,38 @@ public void OnHeadersComplete(bool endStream) bool signalWaiter; lock (SyncObject) { - if (_responseProtocolState == ResponseProtocolState.Aborted) + switch (_responseProtocolState) { - return; - } + case ResponseProtocolState.Aborted: + return; - if (_responseProtocolState != ResponseProtocolState.ExpectingHeaders && _responseProtocolState != ResponseProtocolState.ExpectingTrailingHeaders && _responseProtocolState != ResponseProtocolState.ExpectingIgnoredHeaders) - { - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); - } + case ResponseProtocolState.ExpectingHeaders: + _responseProtocolState = endStream ? ResponseProtocolState.Complete : ResponseProtocolState.ExpectingData; + break; - if (_responseProtocolState == ResponseProtocolState.ExpectingHeaders) - { - _responseProtocolState = endStream ? ResponseProtocolState.Complete : ResponseProtocolState.ExpectingData; - } - else if (_responseProtocolState == ResponseProtocolState.ExpectingTrailingHeaders) - { - if (!endStream) - { - if (NetEventSource.IsEnabled) Trace("Trailing headers received without endStream"); - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); - } + case ResponseProtocolState.ExpectingTrailingHeaders: + if (!endStream) + { + if (NetEventSource.IsEnabled) Trace("Trailing headers received without endStream"); + ThrowProtocolError(); + } + _responseProtocolState = ResponseProtocolState.Complete; + break; - _responseProtocolState = ResponseProtocolState.Complete; - } - else if (_responseProtocolState == ResponseProtocolState.ExpectingIgnoredHeaders) - { - if (endStream) - { - // we should not get endStream while processing 1xx response. - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); - } + case ResponseProtocolState.ExpectingIgnoredHeaders: + if (endStream) + { + // we should not get endStream while processing 1xx response. + ThrowProtocolError(); + } - _responseProtocolState = ResponseProtocolState.ExpectingStatus; - // We should wait for final response before signaling to waiter. - return; - } - else - { - _responseProtocolState = ResponseProtocolState.ExpectingData; + // We should wait for final response before signaling to waiter. + _responseProtocolState = ResponseProtocolState.ExpectingStatus; + return; + + default: + ThrowProtocolError(); + break; } if (endStream) @@ -656,21 +652,24 @@ public void OnResponseData(ReadOnlySpan buffer, bool endStream) bool signalWaiter; lock (SyncObject) { - if (_responseProtocolState == ResponseProtocolState.Aborted) + switch (_responseProtocolState) { - return; - } + case ResponseProtocolState.ExpectingData: + break; - if (_responseProtocolState != ResponseProtocolState.ExpectingData) - { - // Flow control messages are not valid in this state. - throw new Http2ConnectionException(Http2ProtocolErrorCode.ProtocolError); + case ResponseProtocolState.Aborted: + return; + + default: + // Flow control messages are not valid in this state. + ThrowProtocolError(); + break; } if (_responseBuffer.ActiveLength + buffer.Length > StreamWindowSize) { // Window size exceeded. - throw new Http2ConnectionException(Http2ProtocolErrorCode.FlowControlError); + ThrowProtocolError(Http2ProtocolErrorCode.FlowControlError); } _responseBuffer.EnsureAvailableSpace(buffer.Length); @@ -782,19 +781,19 @@ private void CheckResponseBodyState() { Debug.Assert(Monitor.IsEntered(SyncObject)); - if (_resetException != null) + if (_resetException is Exception resetException) { if (_canRetry) { - throw new HttpRequestException(SR.net_http_request_aborted, _resetException, allowRetry: RequestRetryType.RetryOnSameOrNextProxy); + ThrowRetry(SR.net_http_request_aborted, resetException); } - throw new IOException(SR.net_http_request_aborted, _resetException); + ThrowRequestAborted(resetException); } if (_responseProtocolState == ResponseProtocolState.Aborted) { - throw new IOException(SR.net_http_request_aborted); + ThrowRequestAborted(); } } @@ -856,7 +855,7 @@ public async Task ReadResponseHeadersAsync(CancellationToken cancellationToken) { // If there are any trailers, copy them over to the response. Normally this would be handled by // the response stream hitting EOF, but if there is no response body, we do it here. - CopyTrailersToResponseMessage(_response); + MoveTrailersToResponseMessage(_response); responseContent.SetStream(EmptyReadStream.Instance); } else @@ -892,7 +891,7 @@ private void ExtendWindow(int amount) int windowUpdateSize = _pendingWindowUpdate; _pendingWindowUpdate = 0; - _connection.LogExceptions(_connection.SendWindowUpdateAsync(_streamId, windowUpdateSize)); + _connection.LogExceptions(_connection.SendWindowUpdateAsync(StreamId, windowUpdateSize)); } private (bool wait, int bytesRead) TryReadFromBuffer(Span buffer, bool partOfSyncRead = false) @@ -951,7 +950,7 @@ public int ReadData(Span buffer, HttpResponseMessage responseMessage) else { // We've hit EOF. Pull in from the Http2Stream any trailers that were temporarily stored there. - CopyTrailersToResponseMessage(responseMessage); + MoveTrailersToResponseMessage(responseMessage); } return bytesRead; @@ -980,7 +979,7 @@ public async ValueTask ReadDataAsync(Memory buffer, HttpResponseMessa else { // We've hit EOF. Pull in from the Http2Stream any trailers that were temporarily stored there. - CopyTrailersToResponseMessage(responseMessage); + MoveTrailersToResponseMessage(responseMessage); } return bytesRead; @@ -991,7 +990,7 @@ public void CopyTo(HttpResponseMessage responseMessage, Stream destination, int byte[] buffer = ArrayPool.Shared.Rent(bufferSize); try { - // Generallly the same logic as in ReadData, but wrapped in a loop where every read segment is written to the destination. + // Generally the same logic as in ReadData, but wrapped in a loop where every read segment is written to the destination. while (true) { (bool wait, int bytesRead) = TryReadFromBuffer(buffer, partOfSyncRead: true); @@ -1011,7 +1010,7 @@ public void CopyTo(HttpResponseMessage responseMessage, Stream destination, int else { // We've hit EOF. Pull in from the Http2Stream any trailers that were temporarily stored there. - CopyTrailersToResponseMessage(responseMessage); + MoveTrailersToResponseMessage(responseMessage); return; } } @@ -1027,7 +1026,7 @@ public async Task CopyToAsync(HttpResponseMessage responseMessage, Stream destin byte[] buffer = ArrayPool.Shared.Rent(bufferSize); try { - // Generallly the same logic as in ReadDataAsync, but wrapped in a loop where every read segment is written to the destination. + // Generally the same logic as in ReadDataAsync, but wrapped in a loop where every read segment is written to the destination. while (true) { (bool wait, int bytesRead) = TryReadFromBuffer(buffer); @@ -1047,7 +1046,7 @@ public async Task CopyToAsync(HttpResponseMessage responseMessage, Stream destin else { // We've hit EOF. Pull in from the Http2Stream any trailers that were temporarily stored there. - CopyTrailersToResponseMessage(responseMessage); + MoveTrailersToResponseMessage(responseMessage); return; } } @@ -1058,36 +1057,24 @@ public async Task CopyToAsync(HttpResponseMessage responseMessage, Stream destin } } - private void CopyTrailersToResponseMessage(HttpResponseMessage responseMessage) + private void MoveTrailersToResponseMessage(HttpResponseMessage responseMessage) { - if (_trailers != null && _trailers.Count > 0) + if (_trailers != null) { - foreach (KeyValuePair trailer in _trailers) - { - responseMessage.TrailingHeaders.TryAddWithoutValidation(trailer.Key, trailer.Value); - } - _trailers.Clear(); + responseMessage.StoreReceivedTrailingHeaders(_trailers); } } private async ValueTask SendDataAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken) { + Debug.Assert(_requestBodyCancellationSource != null); + // Deal with [ActiveIssue("https://github.com/dotnet/runtime/issues/17492")] // Custom HttpContent classes do not get passed the cancellationToken. // So, inject the expected CancellationToken here, to ensure we can cancel the request body send if needed. - CancellationTokenSource? customCancellationSource = null; - if (!cancellationToken.CanBeCanceled) - { - cancellationToken = _requestBodyCancellationToken; - } - else if (cancellationToken != _requestBodyCancellationToken) - { - // User passed a custom CancellationToken. - // We can't tell if it includes our Token or not, so assume it doesn't. - customCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _requestBodyCancellationSource!.Token); - cancellationToken = customCancellationSource.Token; - } - + CancellationTokenRegistration linkedRegistration = cancellationToken.CanBeCanceled && cancellationToken != _requestBodyCancellationSource.Token ? + RegisterRequestBodyCancellation(cancellationToken) : + default; try { while (buffer.Length > 0) @@ -1104,12 +1091,12 @@ private async ValueTask SendDataAsync(ReadOnlyMemory buffer, CancellationT { if (_creditWaiter is null) { - _creditWaiter = new CancelableCreditWaiter(SyncObject, cancellationToken); + _creditWaiter = new CancelableCreditWaiter(SyncObject, _requestBodyCancellationSource.Token); } else { Debug.Assert(!_creditWaiter.IsPending); - _creditWaiter.ResetForAwait(cancellationToken); + _creditWaiter.ResetForAwait(_requestBodyCancellationSource.Token); } _creditWaiter.Amount = buffer.Length; } @@ -1125,12 +1112,12 @@ private async ValueTask SendDataAsync(ReadOnlyMemory buffer, CancellationT ReadOnlyMemory current; (current, buffer) = SplitBuffer(buffer, sendSize); - await _connection.SendStreamDataAsync(_streamId, current, cancellationToken).ConfigureAwait(false); + await _connection.SendStreamDataAsync(StreamId, current, _requestBodyCancellationSource.Token).ConfigureAwait(false); } } finally { - customCancellationSource?.Dispose(); + linkedRegistration.Dispose(); } } @@ -1156,6 +1143,9 @@ private void CloseResponseBody() _responseBuffer.Dispose(); } + private CancellationTokenRegistration RegisterRequestBodyCancellation(CancellationToken cancellationToken) => + cancellationToken.UnsafeRegister(s => ((CancellationTokenSource)s!).Cancel(), _requestBodyCancellationSource); + // This object is itself usable as a backing source for ValueTask. Since there's only ever one awaiter // for this object's state transitions at a time, we allow the object to be awaited directly. All functionality // associated with the implementation is just delegated to the ManualResetValueTaskSourceCore. @@ -1212,7 +1202,7 @@ private ValueTask WaitForDataAsync(CancellationToken cancellationToken) { // Wake up the wait. It will then immediately check whether cancellation was requested and throw if it was. thisRef._waitSource.SetException(ExceptionDispatchInfo.SetCurrentStackTrace( - CancellationHelper.CreateOperationCanceledException(null, _waitSourceCancellation.Token))); + CancellationHelper.CreateOperationCanceledException(null, thisRef._waitSourceCancellation.Token))); } }, this); @@ -1228,7 +1218,7 @@ private ValueTask WaitForDataAsync(CancellationToken cancellationToken) } public void Trace(string message, [CallerMemberName] string? memberName = null) => - _connection.Trace(_streamId, message, memberName); + _connection.Trace(StreamId, message, memberName); private enum ResponseProtocolState : byte { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs index f02edd7461720..a516450542eb7 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Net.Http.Headers; @@ -117,11 +118,27 @@ internal static void IgnoreExceptions(ValueTask task) } /// Awaits a task, logging any resulting exceptions (which are otherwise ignored). - internal void LogExceptions(Task task) => - task.ContinueWith(t => + internal void LogExceptions(Task task) + { + if (task.IsCompleted) + { + if (task.IsFaulted) + { + LogFaulted(this, task); + } + } + else { - Exception? e = t.Exception?.InnerException; // Access Exception even if not tracing, to avoid TaskScheduler.UnobservedTaskException firing - if (NetEventSource.IsEnabled) Trace($"Exception from asynchronous processing: {e}"); - }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default); + task.ContinueWith((t, state) => LogFaulted((HttpConnectionBase)state!, t), this, + CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default); + } + + static void LogFaulted(HttpConnectionBase connection, Task task) + { + Debug.Assert(task.IsFaulted); + Exception? e = task.Exception!.InnerException; // Access Exception even if not tracing, to avoid TaskScheduler.UnobservedTaskException firing + if (NetEventSource.IsEnabled) connection.Trace($"Exception from asynchronous processing: {e}"); + } + } } } diff --git a/src/libraries/System.Net.Http/src/System/Threading/AsyncMutex.cs b/src/libraries/System.Net.Http/src/System/Threading/AsyncMutex.cs index 6c85c584619ae..1065304f074b2 100644 --- a/src/libraries/System.Net.Http/src/System/Threading/AsyncMutex.cs +++ b/src/libraries/System.Net.Http/src/System/Threading/AsyncMutex.cs @@ -42,9 +42,11 @@ internal sealed class AsyncMutex /// with an initial count of 0. /// private bool _lockedSemaphoreFull = true; - /// The head of the double-linked waiting queue. Waiters are dequeued from the head. - private Waiter? _waitersHead; - /// The tail of the double-linked waiting queue. Waiters are added at the tail. + /// The tail of the double-linked circular waiting queue. + /// + /// Waiters are added at the tail. + /// Items are dequeued from the head (tail.Prev). + /// private Waiter? _waitersTail; /// A pool of waiter objects that are ready to be reused. /// @@ -94,25 +96,25 @@ ValueTask Contended(CancellationToken cancellationToken) // Now that we're holding the lock, check to see whether the async lock is acquirable. if (!_lockedSemaphoreFull) { + // If we are able to acquire the lock, we're done. _lockedSemaphoreFull = true; return default; } + + // The lock couldn't be acquired. + // Add the waiter to the linked list of waiters. + if (_waitersTail is null) + { + w.Next = w.Prev = w; + } else { - // Add it to the linked list of waiters. - if (_waitersTail is null) - { - Debug.Assert(_waitersHead is null); - _waitersTail = _waitersHead = w; - } - else - { - Debug.Assert(_waitersHead != null); - w.Prev = _waitersTail; - _waitersTail.Next = w; - _waitersTail = w; - } + Debug.Assert(_waitersTail.Next != null && _waitersTail.Prev != null); + w.Next = _waitersTail; + w.Prev = _waitersTail.Prev; + w.Prev.Next = w.Next.Prev = w; } + _waitersTail = w; } // At this point the waiter was added to the list of waiters, so we want to @@ -136,14 +138,11 @@ static void OnCancellation(object? state) lock (m.SyncObj) { - bool inList = w.Next != null || w.Prev != null || m._waitersHead == w; + bool inList = w.Next != null; if (inList) { - // The waiter was still in the list. - Debug.Assert( - m._waitersHead == w || - (m._waitersTail == w && w.Prev != null && w.Next is null) || - (w.Next != null && w.Prev != null)); + // The waiter is in the list. + Debug.Assert(w.Prev != null); // The gate counter was decremented when this waiter was added. We need // to undo that. Since the waiter is still in the list, the lock must @@ -156,33 +155,19 @@ static void OnCancellation(object? state) // release it, they will appropriately update state. Interlocked.Increment(ref m._gate); - // Remove it from the list. - if (m._waitersHead == w && m._waitersTail == w) - { - // It's the only node in the list. - m._waitersHead = m._waitersTail = null; - } - else if (m._waitersTail == w) - { - // It's the most recently queued item in the list. - m._waitersTail = w.Prev; - Debug.Assert(m._waitersTail != null); - m._waitersTail.Next = null; - } - else if (m._waitersHead == w) + if (w.Next == w) { - // It's the next item to be removed from the list. - m._waitersHead = w.Next; - Debug.Assert(m._waitersHead != null); - m._waitersHead.Prev = null; + Debug.Assert(m._waitersTail == w); + m._waitersTail = null; } else { - // It's in the middle of the list. - Debug.Assert(w.Next != null); - Debug.Assert(w.Prev != null); - w.Next.Prev = w.Prev; + w.Next!.Prev = w.Prev; w.Prev.Next = w.Next; + if (m._waitersTail == w) + { + m._waitersTail = w.Next; + } } // Remove it from the list. @@ -217,34 +202,37 @@ public void Exit() void Contended() { Waiter? w; - lock (SyncObj) { Debug.Assert(_lockedSemaphoreFull); - // Wake up the next waiter in the list. - w = _waitersHead; - if (w != null) + w = _waitersTail; + if (w is null) { - // Remove the waiter. - _waitersHead = w.Next; - if (w.Next != null) + _lockedSemaphoreFull = false; + } + else + { + Debug.Assert(w.Next != null && w.Prev != null); + Debug.Assert(w.Next != w || w.Prev == w); + Debug.Assert(w.Prev != w || w.Next == w); + + if (w.Next == w) { - w.Next.Prev = null; + _waitersTail = null; } else { - Debug.Assert(_waitersTail == w); - _waitersTail = null; + w = w.Prev; // get the head + Debug.Assert(w.Next != null && w.Prev != null); + Debug.Assert(w.Next != w && w.Prev != w); + + w.Next.Prev = w.Prev; + w.Prev.Next = w.Next; } + w.Next = w.Prev = null; } - else - { - // There wasn't a waiter. Mark that the async lock is no longer full. - Debug.Assert(_waitersTail is null); - _lockedSemaphoreFull = false; - } } // Either there wasn't a waiter, or we got one and successfully removed it from the list, From c7a246c000747ec728ac862b7a503348b103df0e Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 15 May 2020 17:47:15 -0400 Subject: [PATCH 234/420] Delete DebugThreadTracking from networking code (#36549) The System.Net.* libs in dotnet/runtime inherited this from .NET Framework. To my knowledge it's not once helped flag any issues in dotnet/runtime, it's only built into debug builds, it's become very inconsistent as the code base has evolved, and it's just cluttering stuff up. So, goodbye. --- .../DebugCriticalHandleMinusOneIsInvalid.cs | 1 - ...ugCriticalHandleZeroOrMinusOneIsInvalid.cs | 1 - .../Net/DebugSafeHandleMinusOneIsInvalid.cs | 1 - .../System/Net/Logging/DebugThreadTracking.cs | 158 ----- .../src/System.Net.Http.csproj | 4 +- .../src/System.Net.HttpListener.csproj | 2 - .../src/System.Net.Mail.csproj | 4 +- .../Unit/System.Net.Mail.Unit.Tests.csproj | 4 +- .../src/System.Net.NameResolution.csproj | 2 - .../PalTests/Fakes/DebugThreadTracking.cs | 42 -- ...System.Net.NameResolution.Pal.Tests.csproj | 1 - .../src/System.Net.Requests.csproj | 2 - .../src/System/Net/HttpWebRequest.cs | 219 +++---- .../src/System/Net/TimerThread.cs | 191 +++--- .../src/System.Net.Security.csproj | 2 - .../Net/Security/AuthenticatedStream.cs | 31 +- .../System/Net/Security/NegotiateStream.cs | 397 ++++--------- .../src/System.Net.Sockets.csproj | 2 - .../BaseOverlappedAsyncResult.Windows.cs | 102 ++-- .../src/System/Net/Sockets/NetworkStream.cs | 559 +++++++----------- .../src/System/Net/Sockets/TCPClient.cs | 13 +- 21 files changed, 595 insertions(+), 1143 deletions(-) delete mode 100644 src/libraries/Common/src/System/Net/Logging/DebugThreadTracking.cs delete mode 100644 src/libraries/System.Net.NameResolution/tests/PalTests/Fakes/DebugThreadTracking.cs diff --git a/src/libraries/Common/src/System/Net/DebugCriticalHandleMinusOneIsInvalid.cs b/src/libraries/Common/src/System/Net/DebugCriticalHandleMinusOneIsInvalid.cs index 38c3a40d64884..eed8ccb978a81 100644 --- a/src/libraries/Common/src/System/Net/DebugCriticalHandleMinusOneIsInvalid.cs +++ b/src/libraries/Common/src/System/Net/DebugCriticalHandleMinusOneIsInvalid.cs @@ -33,7 +33,6 @@ private void Trace() ~DebugCriticalHandleMinusOneIsInvalid() { - DebugThreadTracking.SetThreadSource(ThreadKinds.Finalization); if (NetEventSource.IsEnabled) NetEventSource.Info(this, _trace); } } diff --git a/src/libraries/Common/src/System/Net/DebugCriticalHandleZeroOrMinusOneIsInvalid.cs b/src/libraries/Common/src/System/Net/DebugCriticalHandleZeroOrMinusOneIsInvalid.cs index 33bca4dee3f70..0d993cd60d738 100644 --- a/src/libraries/Common/src/System/Net/DebugCriticalHandleZeroOrMinusOneIsInvalid.cs +++ b/src/libraries/Common/src/System/Net/DebugCriticalHandleZeroOrMinusOneIsInvalid.cs @@ -33,7 +33,6 @@ private void Trace() ~DebugCriticalHandleZeroOrMinusOneIsInvalid() { - DebugThreadTracking.SetThreadSource(ThreadKinds.Finalization); if (NetEventSource.IsEnabled) NetEventSource.Info(this, _trace); } } diff --git a/src/libraries/Common/src/System/Net/DebugSafeHandleMinusOneIsInvalid.cs b/src/libraries/Common/src/System/Net/DebugSafeHandleMinusOneIsInvalid.cs index 5cf3352115cdd..4fd2c5b4e9850 100644 --- a/src/libraries/Common/src/System/Net/DebugSafeHandleMinusOneIsInvalid.cs +++ b/src/libraries/Common/src/System/Net/DebugSafeHandleMinusOneIsInvalid.cs @@ -33,7 +33,6 @@ private void Trace() ~DebugSafeHandleMinusOneIsInvalid() { - DebugThreadTracking.SetThreadSource(ThreadKinds.Finalization); if (NetEventSource.IsEnabled) NetEventSource.Info(this, _trace); } } diff --git a/src/libraries/Common/src/System/Net/Logging/DebugThreadTracking.cs b/src/libraries/Common/src/System/Net/Logging/DebugThreadTracking.cs deleted file mode 100644 index eba97da8e3b20..0000000000000 --- a/src/libraries/Common/src/System/Net/Logging/DebugThreadTracking.cs +++ /dev/null @@ -1,158 +0,0 @@ -// 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. - -#nullable enable -using System.Collections.Generic; - -namespace System.Net -{ - internal static class DebugThreadTracking - { - [ThreadStatic] - private static Stack? t_threadKindStack; - - private static Stack ThreadKindStack => t_threadKindStack ?? (t_threadKindStack = new Stack()); - - internal static ThreadKinds CurrentThreadKind => ThreadKindStack.Count > 0 ? ThreadKindStack.Peek() : ThreadKinds.Other; - - internal static IDisposable? SetThreadKind(ThreadKinds kind) - { - if ((kind & ThreadKinds.SourceMask) != ThreadKinds.Unknown) - { - throw new InternalException(kind); - } - - // Ignore during shutdown. - if (Environment.HasShutdownStarted) - { - return null; - } - - ThreadKinds threadKind = CurrentThreadKind; - ThreadKinds source = threadKind & ThreadKinds.SourceMask; - - // Special warnings when doing dangerous things on a thread. - if ((threadKind & ThreadKinds.User) != 0 && (kind & ThreadKinds.System) != 0) - { - if (NetEventSource.IsEnabled) NetEventSource.Error(null, "Thread changed from User to System; user's thread shouldn't be hijacked."); - } - - if ((threadKind & ThreadKinds.Async) != 0 && (kind & ThreadKinds.Sync) != 0) - { - if (NetEventSource.IsEnabled) NetEventSource.Error(null, "Thread changed from Async to Sync, may block an Async thread."); - } - else if ((threadKind & (ThreadKinds.Other | ThreadKinds.CompletionPort)) == 0 && (kind & ThreadKinds.Sync) != 0) - { - if (NetEventSource.IsEnabled) NetEventSource.Error(null, "Thread from a limited resource changed to Sync, may deadlock or bottleneck."); - } - - ThreadKindStack.Push( - (((kind & ThreadKinds.OwnerMask) == 0 ? threadKind : kind) & ThreadKinds.OwnerMask) | - (((kind & ThreadKinds.SyncMask) == 0 ? threadKind : kind) & ThreadKinds.SyncMask) | - (kind & ~(ThreadKinds.OwnerMask | ThreadKinds.SyncMask)) | - source); - - if (CurrentThreadKind != threadKind) - { - if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"Thread becomes:({CurrentThreadKind})"); - } - - return new ThreadKindFrame(); - } - - private class ThreadKindFrame : IDisposable - { - private readonly int _frameNumber; - - internal ThreadKindFrame() - { - _frameNumber = ThreadKindStack.Count; - } - - void IDisposable.Dispose() - { - // Ignore during shutdown. - if (Environment.HasShutdownStarted) - { - return; - } - - if (_frameNumber != ThreadKindStack.Count) - { - throw new InternalException(_frameNumber); - } - - ThreadKinds previous = ThreadKindStack.Pop(); - - if (CurrentThreadKind != previous && NetEventSource.IsEnabled) - { - if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"Thread reverts:({CurrentThreadKind})"); - } - } - } - - internal static void SetThreadSource(ThreadKinds source) - { - if ((source & ThreadKinds.SourceMask) != source || source == ThreadKinds.Unknown) - { - throw new ArgumentException("Must specify the thread source.", nameof(source)); - } - - if (ThreadKindStack.Count == 0) - { - ThreadKindStack.Push(source); - return; - } - - if (ThreadKindStack.Count > 1) - { - if (NetEventSource.IsEnabled) NetEventSource.Error(null, "SetThreadSource must be called at the base of the stack, or the stack has been corrupted."); - while (ThreadKindStack.Count > 1) - { - ThreadKindStack.Pop(); - } - } - - if (ThreadKindStack.Peek() != source) - { - if (NetEventSource.IsEnabled) NetEventSource.Error(null, "The stack has been corrupted."); - ThreadKinds last = ThreadKindStack.Pop() & ThreadKinds.SourceMask; - if (last != source && last != ThreadKinds.Other && NetEventSource.IsEnabled) - { - NetEventSource.Fail(null, $"Thread source changed.|Was:({last}) Now:({source})"); - } - ThreadKindStack.Push(source); - } - } - } - - [Flags] - internal enum ThreadKinds - { - Unknown = 0x0000, - - // Mutually exclusive. - User = 0x0001, // Thread has entered via an API. - System = 0x0002, // Thread has entered via a system callback (e.g. completion port) or is our own thread. - - // Mutually exclusive. - Sync = 0x0004, // Thread should block. - Async = 0x0008, // Thread should not block. - - // Mutually exclusive, not always known for a user thread. Never changes. - Timer = 0x0010, // Thread is the timer thread. (Can't call user code.) - CompletionPort = 0x0020, // Thread is a ThreadPool completion-port thread. - Worker = 0x0040, // Thread is a ThreadPool worker thread. - Finalization = 0x0080, // Thread is the finalization thread. - Other = 0x0100, // Unknown source. - - OwnerMask = User | System, - SyncMask = Sync | Async, - SourceMask = Timer | CompletionPort | Worker | Finalization | Other, - - // Useful "macros" - SafeSources = SourceMask & ~(Timer | Finalization), // Methods that "unsafe" sources can call must be explicitly marked. - ThreadPool = CompletionPort | Worker, // Like Thread.CurrentThread.IsThreadPoolThread - } -} diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index ee9e25ba90a99..2f7eb9dc48f43 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -1,4 +1,4 @@ - + Library System.Net.Http @@ -300,8 +300,6 @@ Link="Common\System\Net\NegotiationInfoClass.cs" /> - - - - \ No newline at end of file + diff --git a/src/libraries/System.Net.Mail/tests/Unit/System.Net.Mail.Unit.Tests.csproj b/src/libraries/System.Net.Mail/tests/Unit/System.Net.Mail.Unit.Tests.csproj index 5a721973b144b..d4da9df33459e 100644 --- a/src/libraries/System.Net.Mail/tests/Unit/System.Net.Mail.Unit.Tests.csproj +++ b/src/libraries/System.Net.Mail/tests/Unit/System.Net.Mail.Unit.Tests.csproj @@ -142,8 +142,6 @@ Link="Common\System\Collections\Generic\BidirectionalDictionary.cs" /> - - \ No newline at end of file + diff --git a/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj b/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj index 7d5e1cc07d29c..498f4e8fce267 100644 --- a/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj +++ b/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj @@ -10,8 +10,6 @@ - - - 0) { - // Copy all the new queues to the real queues. Since only this thread modifies the real queues, it doesn't have to lock it. - if (s_newQueues.Count > 0) + lock (s_newQueues) { - lock (s_newQueues) + for (LinkedListNode? node = s_newQueues.First; node != null; node = s_newQueues.First) { - for (LinkedListNode? node = s_newQueues.First; node != null; node = s_newQueues.First) - { - s_newQueues.Remove(node); - s_queues.AddLast(node); - } + s_newQueues.Remove(node); + s_queues.AddLast(node); } } + } - int now = Environment.TickCount; - int nextTick = 0; - bool haveNextTick = false; - for (LinkedListNode? node = s_queues.First; node != null; /* node = node.Next must be done in the body */) + int now = Environment.TickCount; + int nextTick = 0; + bool haveNextTick = false; + for (LinkedListNode? node = s_queues.First; node != null; /* node = node.Next must be done in the body */) + { + TimerQueue? queue = (TimerQueue?)node.Value.Target; + if (queue == null) { - TimerQueue? queue = (TimerQueue?)node.Value.Target; - if (queue == null) - { - LinkedListNode? next = node.Next; - s_queues.Remove(node); - node = next; - continue; - } - - // Fire() will always return values that should be interpreted as later than 'now' (that is, even if 'now' is - // returned, it is 0x100000000 milliseconds in the future). There's also a chance that Fire() will return a value - // intended as > 0x100000000 milliseconds from 'now'. Either case will just cause an extra scan through the timers. - int nextTickInstance; - if (queue.Fire(out nextTickInstance) && (!haveNextTick || IsTickBetween(now, nextTick, nextTickInstance))) - { - nextTick = nextTickInstance; - haveNextTick = true; - } + LinkedListNode? next = node.Next; + s_queues.Remove(node); + node = next; + continue; + } - node = node.Next; + // Fire() will always return values that should be interpreted as later than 'now' (that is, even if 'now' is + // returned, it is 0x100000000 milliseconds in the future). There's also a chance that Fire() will return a value + // intended as > 0x100000000 milliseconds from 'now'. Either case will just cause an extra scan through the timers. + int nextTickInstance; + if (queue.Fire(out nextTickInstance) && (!haveNextTick || IsTickBetween(now, nextTick, nextTickInstance))) + { + nextTick = nextTickInstance; + haveNextTick = true; } - // Figure out how long to wait, taking into account how long the loop took. - // Add 15 ms to compensate for poor TickCount resolution (want to guarantee a firing). - int newNow = Environment.TickCount; - int waitDuration = haveNextTick ? - (int)(IsTickBetween(now, nextTick, newNow) ? - Math.Min(unchecked((uint)(nextTick - newNow)), (uint)(int.MaxValue - TickCountResolution)) + TickCountResolution : - 0) : - ThreadIdleTimeoutMilliseconds; + node = node.Next; + } - if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"Waiting for {waitDuration}ms"); + // Figure out how long to wait, taking into account how long the loop took. + // Add 15 ms to compensate for poor TickCount resolution (want to guarantee a firing). + int newNow = Environment.TickCount; + int waitDuration = haveNextTick ? + (int)(IsTickBetween(now, nextTick, newNow) ? + Math.Min(unchecked((uint)(nextTick - newNow)), (uint)(int.MaxValue - TickCountResolution)) + TickCountResolution : + 0) : + ThreadIdleTimeoutMilliseconds; - int waitResult = WaitHandle.WaitAny(s_threadEvents, waitDuration, false); + if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"Waiting for {waitDuration}ms"); - // 0 is s_ThreadShutdownEvent - die. - if (waitResult == 0) - { - if (NetEventSource.IsEnabled) NetEventSource.Info(null, "Awoke, cause: Shutdown"); - running = false; - break; - } + int waitResult = WaitHandle.WaitAny(s_threadEvents, waitDuration, false); + + // 0 is s_ThreadShutdownEvent - die. + if (waitResult == 0) + { + if (NetEventSource.IsEnabled) NetEventSource.Info(null, "Awoke, cause: Shutdown"); + running = false; + break; + } - if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"Awoke, cause {(waitResult == WaitHandle.WaitTimeout ? "Timeout" : "Prod")}"); + if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"Awoke, cause {(waitResult == WaitHandle.WaitTimeout ? "Timeout" : "Prod")}"); - // If we timed out with nothing to do, shut down. - if (waitResult == WaitHandle.WaitTimeout && !haveNextTick) + // If we timed out with nothing to do, shut down. + if (waitResult == WaitHandle.WaitTimeout && !haveNextTick) + { + Interlocked.CompareExchange(ref s_threadState, (int)TimerThreadState.Idle, (int)TimerThreadState.Running); + // There could have been one more prod between the wait and the exchange. Check, and abort if necessary. + if (s_threadReadyEvent.WaitOne(0, false)) { - Interlocked.CompareExchange(ref s_threadState, (int)TimerThreadState.Idle, (int)TimerThreadState.Running); - // There could have been one more prod between the wait and the exchange. Check, and abort if necessary. - if (s_threadReadyEvent.WaitOne(0, false)) + if (Interlocked.CompareExchange(ref s_threadState, (int)TimerThreadState.Running, (int)TimerThreadState.Idle) == + (int)TimerThreadState.Idle) { - if (Interlocked.CompareExchange(ref s_threadState, (int)TimerThreadState.Running, (int)TimerThreadState.Idle) == - (int)TimerThreadState.Idle) - { - continue; - } + continue; } - - running = false; - break; } + + running = false; + break; } } - catch (Exception exception) - { - if (ExceptionCheck.IsFatal(exception)) - throw; + } + catch (Exception exception) + { + if (ExceptionCheck.IsFatal(exception)) + throw; - if (NetEventSource.IsEnabled) NetEventSource.Error(null, exception); + if (NetEventSource.IsEnabled) NetEventSource.Error(null, exception); - // The only options are to continue processing and likely enter an error-loop, - // shut down timers for this AppDomain, or shut down the AppDomain. Go with shutting - // down the AppDomain in debug, and going into a loop in retail, but try to make the - // loop somewhat slow. Note that in retail, this can only be triggered by OutOfMemory or StackOverflow, - // or an exception thrown within TimerThread - the rest are caught in Fire(). + // The only options are to continue processing and likely enter an error-loop, + // shut down timers for this AppDomain, or shut down the AppDomain. Go with shutting + // down the AppDomain in debug, and going into a loop in retail, but try to make the + // loop somewhat slow. Note that in retail, this can only be triggered by OutOfMemory or StackOverflow, + // or an exception thrown within TimerThread - the rest are caught in Fire(). #if !DEBUG - Thread.Sleep(1000); + Thread.Sleep(1000); #else - throw; + throw; #endif - } } } - - if (NetEventSource.IsEnabled) NetEventSource.Info(null, "Stop"); -#if DEBUG } -#endif + + if (NetEventSource.IsEnabled) NetEventSource.Info(null, "Stop"); } /// diff --git a/src/libraries/System.Net.Security/src/System.Net.Security.csproj b/src/libraries/System.Net.Security/src/System.Net.Security.csproj index 067df9b00fcf6..f2daece20c633 100644 --- a/src/libraries/System.Net.Security/src/System.Net.Security.csproj +++ b/src/libraries/System.Net.Security/src/System.Net.Security.csproj @@ -48,8 +48,6 @@ - (asyncResult); - } + _negoState.CheckThrow(true); + if (!_negoState.CanGetSecureStream) + { + return TaskToApm.End(asyncResult); + } - if (asyncResult == null) - { - throw new ArgumentNullException(nameof(asyncResult)); - } + if (asyncResult == null) + { + throw new ArgumentNullException(nameof(asyncResult)); + } - BufferAsyncResult? bufferResult = asyncResult as BufferAsyncResult; - if (bufferResult == null) - { - throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), nameof(asyncResult)); - } + BufferAsyncResult? bufferResult = asyncResult as BufferAsyncResult; + if (bufferResult == null) + { + throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), nameof(asyncResult)); + } - if (Interlocked.Exchange(ref _NestedRead, 0) == 0) - { - throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndRead")); - } + if (Interlocked.Exchange(ref _NestedRead, 0) == 0) + { + throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndRead")); + } - // No "artificial" timeouts implemented so far, InnerStream controls timeout. - bufferResult.InternalWaitForCompletion(); + // No "artificial" timeouts implemented so far, InnerStream controls timeout. + bufferResult.InternalWaitForCompletion(); - if (bufferResult.Result is Exception e) + if (bufferResult.Result is Exception e) + { + if (e is IOException) { - if (e is IOException) - { - ExceptionDispatchInfo.Throw(e); - } - - throw new IOException(SR.net_io_read, e); + ExceptionDispatchInfo.Throw(e); } - return bufferResult.Int32Result; -#if DEBUG + throw new IOException(SR.net_io_read, e); } -#endif + + return bufferResult.Int32Result; } - // - // + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) - { -#endif - _negoState.CheckThrow(true); + _negoState.CheckThrow(true); - if (!_negoState.CanGetSecureStream) - { - return TaskToApm.Begin(InnerStream.WriteAsync(buffer, offset, count), asyncCallback, asyncState); - } + if (!_negoState.CanGetSecureStream) + { + return TaskToApm.Begin(InnerStream.WriteAsync(buffer, offset, count), asyncCallback, asyncState); + } - BufferAsyncResult bufferResult = new BufferAsyncResult(this, buffer, offset, count, asyncState, asyncCallback); - AsyncProtocolRequest asyncRequest = new AsyncProtocolRequest(bufferResult); + BufferAsyncResult bufferResult = new BufferAsyncResult(this, buffer, offset, count, asyncState, asyncCallback); + AsyncProtocolRequest asyncRequest = new AsyncProtocolRequest(bufferResult); - ProcessWrite(buffer, offset, count, asyncRequest); - return bufferResult; -#if DEBUG - } -#endif + ProcessWrite(buffer, offset, count, asyncRequest); + return bufferResult; } public override void EndWrite(IAsyncResult asyncResult) { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User)) - { -#endif - _negoState.CheckThrow(true); + _negoState.CheckThrow(true); - if (!_negoState.CanGetSecureStream) - { - TaskToApm.End(asyncResult); - return; - } + if (!_negoState.CanGetSecureStream) + { + TaskToApm.End(asyncResult); + return; + } - if (asyncResult == null) - { - throw new ArgumentNullException(nameof(asyncResult)); - } + if (asyncResult == null) + { + throw new ArgumentNullException(nameof(asyncResult)); + } - BufferAsyncResult? bufferResult = asyncResult as BufferAsyncResult; - if (bufferResult == null) - { - throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), nameof(asyncResult)); - } + BufferAsyncResult? bufferResult = asyncResult as BufferAsyncResult; + if (bufferResult == null) + { + throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), nameof(asyncResult)); + } - if (Interlocked.Exchange(ref _NestedWrite, 0) == 0) - { - throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndWrite")); - } + if (Interlocked.Exchange(ref _NestedWrite, 0) == 0) + { + throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndWrite")); + } - // No "artificial" timeouts implemented so far, InnerStream controls timeout. - bufferResult.InternalWaitForCompletion(); + // No "artificial" timeouts implemented so far, InnerStream controls timeout. + bufferResult.InternalWaitForCompletion(); - if (bufferResult.Result is Exception e) + if (bufferResult.Result is Exception e) + { + if (e is IOException) { - if (e is IOException) - { - ExceptionDispatchInfo.Throw(e); - } - - throw new IOException(SR.net_io_write, e); + ExceptionDispatchInfo.Throw(e); } -#if DEBUG + + throw new IOException(SR.net_io_write, e); } -#endif } } } diff --git a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj index fea68b78eb5c1..3661f2bfafeda 100644 --- a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj +++ b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj @@ -51,8 +51,6 @@ - _streamSocket; @@ -124,34 +117,20 @@ public override int ReadTimeout { get { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) + int timeout = (int)_streamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout)!; + if (timeout == 0) { -#endif - int timeout = (int)_streamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout)!; - if (timeout == 0) - { - return -1; - } - return timeout; -#if DEBUG + return -1; } -#endif + return timeout; } set { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) + if (value <= 0 && value != System.Threading.Timeout.Infinite) { -#endif - if (value <= 0 && value != System.Threading.Timeout.Infinite) - { - throw new ArgumentOutOfRangeException(nameof(value), SR.net_io_timeout_use_gt_zero); - } - SetSocketTimeoutOption(SocketShutdown.Receive, value, false); -#if DEBUG + throw new ArgumentOutOfRangeException(nameof(value), SR.net_io_timeout_use_gt_zero); } -#endif + SetSocketTimeoutOption(SocketShutdown.Receive, value, false); } } @@ -161,34 +140,20 @@ public override int WriteTimeout { get { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) + int timeout = (int)_streamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout)!; + if (timeout == 0) { -#endif - int timeout = (int)_streamSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout)!; - if (timeout == 0) - { - return -1; - } - return timeout; -#if DEBUG + return -1; } -#endif + return timeout; } set { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) + if (value <= 0 && value != System.Threading.Timeout.Infinite) { -#endif - if (value <= 0 && value != System.Threading.Timeout.Infinite) - { - throw new ArgumentOutOfRangeException(nameof(value), SR.net_io_timeout_use_gt_zero); - } - SetSocketTimeoutOption(SocketShutdown.Send, value, false); -#if DEBUG + throw new ArgumentOutOfRangeException(nameof(value), SR.net_io_timeout_use_gt_zero); } -#endif + SetSocketTimeoutOption(SocketShutdown.Send, value, false); } } @@ -198,18 +163,11 @@ public virtual bool DataAvailable { get { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) - { -#endif - ThrowIfDisposed(); + ThrowIfDisposed(); - // Ask the socket how many bytes are available. If it's - // not zero, return true. - return _streamSocket.Available != 0; -#if DEBUG - } -#endif + // Ask the socket how many bytes are available. If it's + // not zero, return true. + return _streamSocket.Available != 0; } } @@ -259,44 +217,37 @@ public override long Seek(long offset, SeekOrigin origin) // Number of bytes we read, or 0 if the socket is closed. public override int Read(byte[] buffer, int offset, int size) { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) + bool canRead = CanRead; // Prevent race with Dispose. + ThrowIfDisposed(); + if (!canRead) { -#endif - bool canRead = CanRead; // Prevent race with Dispose. - ThrowIfDisposed(); - if (!canRead) - { - throw new InvalidOperationException(SR.net_writeonlystream); - } + throw new InvalidOperationException(SR.net_writeonlystream); + } - // Validate input parameters. - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - if ((uint)offset > buffer.Length) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } - if ((uint)size > buffer.Length - offset) - { - throw new ArgumentOutOfRangeException(nameof(size)); - } + // Validate input parameters. + if (buffer == null) + { + throw new ArgumentNullException(nameof(buffer)); + } + if ((uint)offset > buffer.Length) + { + throw new ArgumentOutOfRangeException(nameof(offset)); + } + if ((uint)size > buffer.Length - offset) + { + throw new ArgumentOutOfRangeException(nameof(size)); + } - try - { - return _streamSocket.Receive(buffer, offset, size, 0); - } - catch (Exception exception) when (!(exception is OutOfMemoryException)) - { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); - } -#if DEBUG + try + { + return _streamSocket.Receive(buffer, offset, size, 0); + } + catch (Exception exception) when (!(exception is OutOfMemoryException)) + { + // Some sort of error occurred on the socket call, + // set the SocketException as InnerException and throw. + throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); } -#endif } public override int Read(Span buffer) @@ -345,46 +296,39 @@ public override unsafe int ReadByte() // way to indicate an error. public override void Write(byte[] buffer, int offset, int size) { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) + bool canWrite = CanWrite; // Prevent race with Dispose. + ThrowIfDisposed(); + if (!canWrite) { -#endif - bool canWrite = CanWrite; // Prevent race with Dispose. - ThrowIfDisposed(); - if (!canWrite) - { - throw new InvalidOperationException(SR.net_readonlystream); - } + throw new InvalidOperationException(SR.net_readonlystream); + } - // Validate input parameters. - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - if ((uint)offset > buffer.Length) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } - if ((uint)size > buffer.Length - offset) - { - throw new ArgumentOutOfRangeException(nameof(size)); - } + // Validate input parameters. + if (buffer == null) + { + throw new ArgumentNullException(nameof(buffer)); + } + if ((uint)offset > buffer.Length) + { + throw new ArgumentOutOfRangeException(nameof(offset)); + } + if ((uint)size > buffer.Length - offset) + { + throw new ArgumentOutOfRangeException(nameof(size)); + } - try - { - // Since the socket is in blocking mode this will always complete - // after ALL the requested number of bytes was transferred. - _streamSocket.Send(buffer, offset, size, SocketFlags.None); - } - catch (Exception exception) when (!(exception is OutOfMemoryException)) - { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); - } -#if DEBUG + try + { + // Since the socket is in blocking mode this will always complete + // after ALL the requested number of bytes was transferred. + _streamSocket.Send(buffer, offset, size, SocketFlags.None); + } + catch (Exception exception) when (!(exception is OutOfMemoryException)) + { + // Some sort of error occurred on the socket call, + // set the SocketException as InnerException and throw. + throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); } -#endif } public override void Write(ReadOnlySpan buffer) @@ -416,61 +360,42 @@ public override void Write(ReadOnlySpan buffer) public void Close(int timeout) { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) + if (timeout < -1) { -#endif - if (timeout < -1) - { - throw new ArgumentOutOfRangeException(nameof(timeout)); - } - _closeTimeout = timeout; - Dispose(); -#if DEBUG + throw new ArgumentOutOfRangeException(nameof(timeout)); } -#endif + _closeTimeout = timeout; + Dispose(); } private volatile bool _disposed = false; protected override void Dispose(bool disposing) { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User)) + // Mark this as disposed before changing anything else. + bool disposed = _disposed; + _disposed = true; + if (!disposed && disposing) { -#endif - // Mark this as disposed before changing anything else. - bool disposed = _disposed; - _disposed = true; - if (!disposed && disposing) + // The only resource we need to free is the network stream, since this + // is based on the client socket, closing the stream will cause us + // to flush the data to the network, close the stream and (in the + // NetoworkStream code) close the socket as well. + _readable = false; + _writeable = false; + if (_ownsSocket) { - // The only resource we need to free is the network stream, since this - // is based on the client socket, closing the stream will cause us - // to flush the data to the network, close the stream and (in the - // NetoworkStream code) close the socket as well. - _readable = false; - _writeable = false; - if (_ownsSocket) - { - // If we own the Socket (false by default), close it - // ignoring possible exceptions (eg: the user told us - // that we own the Socket but it closed at some point of time, - // here we would get an ObjectDisposedException) - _streamSocket.InternalShutdown(SocketShutdown.Both); - _streamSocket.Close(_closeTimeout); - } + // If we own the Socket (false by default), close it + // ignoring possible exceptions (eg: the user told us + // that we own the Socket but it closed at some point of time, + // here we would get an ObjectDisposedException) + _streamSocket.InternalShutdown(SocketShutdown.Both); + _streamSocket.Close(_closeTimeout); } -#if DEBUG } -#endif + base.Dispose(disposing); } - ~NetworkStream() - { -#if DEBUG - DebugThreadTracking.SetThreadSource(ThreadKinds.Finalization); -#endif - Dispose(false); - } + ~NetworkStream() => Dispose(false); // BeginRead - provide async read functionality. // @@ -488,50 +413,43 @@ protected override void Dispose(bool disposing) // An IASyncResult, representing the read. public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback? callback, object? state) { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) + bool canRead = CanRead; // Prevent race with Dispose. + ThrowIfDisposed(); + if (!canRead) { -#endif - bool canRead = CanRead; // Prevent race with Dispose. - ThrowIfDisposed(); - if (!canRead) - { - throw new InvalidOperationException(SR.net_writeonlystream); - } + throw new InvalidOperationException(SR.net_writeonlystream); + } - // Validate input parameters. - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - if ((uint)offset > buffer.Length) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } - if ((uint)size > buffer.Length - offset) - { - throw new ArgumentOutOfRangeException(nameof(size)); - } + // Validate input parameters. + if (buffer == null) + { + throw new ArgumentNullException(nameof(buffer)); + } + if ((uint)offset > buffer.Length) + { + throw new ArgumentOutOfRangeException(nameof(offset)); + } + if ((uint)size > buffer.Length - offset) + { + throw new ArgumentOutOfRangeException(nameof(size)); + } - try - { - return _streamSocket.BeginReceive( - buffer, - offset, - size, - SocketFlags.None, - callback, - state); - } - catch (Exception exception) when (!(exception is OutOfMemoryException)) - { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); - } -#if DEBUG + try + { + return _streamSocket.BeginReceive( + buffer, + offset, + size, + SocketFlags.None, + callback, + state); + } + catch (Exception exception) when (!(exception is OutOfMemoryException)) + { + // Some sort of error occurred on the socket call, + // set the SocketException as InnerException and throw. + throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); } -#endif } // EndRead - handle the end of an async read. @@ -544,31 +462,24 @@ public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, Asyn // The number of bytes read. May throw an exception. public override int EndRead(IAsyncResult asyncResult) { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User)) - { -#endif - ThrowIfDisposed(); + ThrowIfDisposed(); - // Validate input parameters. - if (asyncResult == null) - { - throw new ArgumentNullException(nameof(asyncResult)); - } + // Validate input parameters. + if (asyncResult == null) + { + throw new ArgumentNullException(nameof(asyncResult)); + } - try - { - return _streamSocket.EndReceive(asyncResult); - } - catch (Exception exception) when (!(exception is OutOfMemoryException)) - { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); - } -#if DEBUG + try + { + return _streamSocket.EndReceive(asyncResult); + } + catch (Exception exception) when (!(exception is OutOfMemoryException)) + { + // Some sort of error occurred on the socket call, + // set the SocketException as InnerException and throw. + throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); } -#endif } // BeginWrite - provide async write functionality. @@ -587,51 +498,44 @@ public override int EndRead(IAsyncResult asyncResult) // An IASyncResult, representing the write. public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback? callback, object? state) { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) + bool canWrite = CanWrite; // Prevent race with Dispose. + ThrowIfDisposed(); + if (!canWrite) { -#endif - bool canWrite = CanWrite; // Prevent race with Dispose. - ThrowIfDisposed(); - if (!canWrite) - { - throw new InvalidOperationException(SR.net_readonlystream); - } + throw new InvalidOperationException(SR.net_readonlystream); + } - // Validate input parameters. - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - if ((uint)offset > buffer.Length) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } - if ((uint)size > buffer.Length - offset) - { - throw new ArgumentOutOfRangeException(nameof(size)); - } + // Validate input parameters. + if (buffer == null) + { + throw new ArgumentNullException(nameof(buffer)); + } + if ((uint)offset > buffer.Length) + { + throw new ArgumentOutOfRangeException(nameof(offset)); + } + if ((uint)size > buffer.Length - offset) + { + throw new ArgumentOutOfRangeException(nameof(size)); + } - try - { - // Call BeginSend on the Socket. - return _streamSocket.BeginSend( - buffer, - offset, - size, - SocketFlags.None, - callback, - state); - } - catch (Exception exception) when (!(exception is OutOfMemoryException)) - { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); - } -#if DEBUG + try + { + // Call BeginSend on the Socket. + return _streamSocket.BeginSend( + buffer, + offset, + size, + SocketFlags.None, + callback, + state); + } + catch (Exception exception) when (!(exception is OutOfMemoryException)) + { + // Some sort of error occurred on the socket call, + // set the SocketException as InnerException and throw. + throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); } -#endif } // Handle the end of an asynchronous write. @@ -640,31 +544,24 @@ public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, Asy // Returns: The number of bytes read. May throw an exception. public override void EndWrite(IAsyncResult asyncResult) { -#if DEBUG - using (DebugThreadTracking.SetThreadKind(ThreadKinds.User)) - { -#endif - ThrowIfDisposed(); + ThrowIfDisposed(); - // Validate input parameters. - if (asyncResult == null) - { - throw new ArgumentNullException(nameof(asyncResult)); - } + // Validate input parameters. + if (asyncResult == null) + { + throw new ArgumentNullException(nameof(asyncResult)); + } - try - { - _streamSocket.EndSend(asyncResult); - } - catch (Exception exception) when (!(exception is OutOfMemoryException)) - { - // Some sort of error occurred on the socket call, - // set the SocketException as InnerException and throw. - throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); - } -#if DEBUG + try + { + _streamSocket.EndSend(asyncResult); + } + catch (Exception exception) when (!(exception is OutOfMemoryException)) + { + // Some sort of error occurred on the socket call, + // set the SocketException as InnerException and throw. + throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); } -#endif } // ReadAsync - provide async read functionality. diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs index 9295802ed6977..71480cffbd6e0 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs @@ -427,18 +427,7 @@ protected virtual void Dispose(bool disposing) public void Dispose() => Dispose(true); - ~TcpClient() - { -#if DEBUG - DebugThreadTracking.SetThreadSource(ThreadKinds.Finalization); - using (DebugThreadTracking.SetThreadKind(ThreadKinds.System | ThreadKinds.Async)) - { -#endif - Dispose(false); -#if DEBUG - } -#endif - } + ~TcpClient() => Dispose(false); // Gets or sets the size of the receive buffer in bytes. public int ReceiveBufferSize From 26661be4909461a224dd561c24cb3ca81f0e291c Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Fri, 15 May 2020 15:01:32 -0700 Subject: [PATCH 235/420] Build an apphost with hostfxr and hostpolicy linked in (#36230) * hostfxr: Build most of hostfxr as a static library This is part of the work to create an apphost that bundles both hostfxr and hostpolicy. The main distinction between the static and shared versions of hostfxr is that the static version contains a hostpolicy resolver that references the hostpolicy symbols directly rather than loading them from a DLL. * hostpolicy: Build as a static library This change is part of the work to enable an apphost that bundles both hostfxr and hostpolicy. There's no distinction between hostpolicy that's built as a shared library and as a static library: the shared library is built by linking an empty object file with the static library. * corehost: Allow linking of hostfxr and hostpolicy with apphost Provide a hostfxr_iface class, that abstracts how the hostfxr functions called by the early stage in the hosting layer is resolved. * dotnet: Teach the muxer binary about hostfxr_iface * apphost: Teach apphost about hostfxr_iface This provides two implementations of hostfxr_iface: one for the static apphost, which bundles hostfxr and hostpolicy, and another for the conventional apphost, which loads them dynamically on startup. * Add exports for hostfxr and policy * Exports for unix * EXPORTS_LINKER_OPTION * use generateversionscript.awk from ENG * Move fxr files out of static * Fixes for Linux * Fix for win-x86 * move HEADERS next to SOURCES similarly to other files. * PR feedback (simplifying hostpolicy_resolver::try_get_dir for static host) * Publish static_apphost to Microsoft.NETCore.App.Host * bind to entry points without probing, when in a static host. * Add a test case * renamed hostfxr_iface --> hostfxr_resolver_t * renamed shared --> standalone * rename static_apphost --> singlefilehost * Signing exclusions for singlefilehost * switched StaticHost tst to a different asset (mostly a copy of StandaloneApp) * get_method_module_path Co-authored-by: Leandro Pereira Co-authored-by: Swaroop Sridhar --- eng/SignCheckExclusionsFile.txt | 1 + eng/Signing.props | 2 +- eng/native/functions.cmake | 8 +- .../native}/generateexportedsymbols.awk | 0 .../native}/generateversionscript.awk | 0 src/installer/corehost/cli/CMakeLists.txt | 4 +- .../corehost/cli/apphost/CMakeLists.txt | 48 +-------- .../cli/apphost/standalone/CMakeLists.txt | 54 ++++++++++ .../apphost/standalone/hostfxr_resolver_t.cpp | 61 ++++++++++++ .../cli/apphost/static/CMakeLists.txt | 63 ++++++++++++ .../cli/apphost/static/hostfxr_resolver_t.cpp | 63 ++++++++++++ .../apphost/static/hostpolicy_resolver.cpp | 59 +++++++++++ .../corehost/cli/dotnet/CMakeLists.txt | 4 + src/installer/corehost/cli/exe.cmake | 3 + src/installer/corehost/cli/fxr/CMakeLists.txt | 45 +-------- src/installer/corehost/cli/fxr/fx_muxer.cpp | 40 +++++--- src/installer/corehost/cli/fxr/hostfxr.cpp | 2 +- .../corehost/cli/fxr/hostpolicy_resolver.h | 6 +- .../cli/fxr/standalone/CMakeLists.txt | 65 ++++++++++++ .../corehost/cli/fxr/standalone/hostfxr.def | 21 ++++ .../fxr/standalone/hostfxr_unixexports.src | 20 ++++ .../{ => standalone}/hostpolicy_resolver.cpp | 3 + .../corehost/cli/fxr/static/CMakeLists.txt | 45 +++++++++ src/installer/corehost/cli/hostmisc/pal.h | 1 + .../corehost/cli/hostmisc/pal.unix.cpp | 10 ++ .../corehost/cli/hostmisc/pal.windows.cpp | 10 ++ .../corehost/cli/hostpolicy/CMakeLists.txt | 46 +-------- .../cli/hostpolicy/standalone/CMakeLists.txt | 59 +++++++++++ .../cli/hostpolicy/standalone/hostpolicy.def | 12 +++ .../standalone/hostpolicy_unixexports.src | 11 +++ .../cli/hostpolicy/static/CMakeLists.txt | 47 +++++++++ src/installer/corehost/cli/lib_static.cmake | 6 +- src/installer/corehost/corehost.cpp | 60 +++++------- src/installer/corehost/hostfxr_resolver_t.h | 40 ++++++++ ...s_NT.Microsoft.NETCore.DotNetAppHost.props | 1 + .../pkg/Microsoft.NETCore.App.Host.pkgproj | 3 +- .../TestProjects/StaticHostApp/Program.cs | 16 +++ .../StaticHostApp/StaticHostApp.csproj | 13 +++ .../AppHost.Bundle.Tests/StaticHost.cs | 98 +++++++++++++++++++ 39 files changed, 858 insertions(+), 192 deletions(-) rename {src/coreclr => eng/native}/generateexportedsymbols.awk (100%) rename {src/coreclr => eng/native}/generateversionscript.awk (100%) create mode 100644 src/installer/corehost/cli/apphost/standalone/CMakeLists.txt create mode 100644 src/installer/corehost/cli/apphost/standalone/hostfxr_resolver_t.cpp create mode 100644 src/installer/corehost/cli/apphost/static/CMakeLists.txt create mode 100644 src/installer/corehost/cli/apphost/static/hostfxr_resolver_t.cpp create mode 100644 src/installer/corehost/cli/apphost/static/hostpolicy_resolver.cpp create mode 100644 src/installer/corehost/cli/fxr/standalone/CMakeLists.txt create mode 100644 src/installer/corehost/cli/fxr/standalone/hostfxr.def create mode 100644 src/installer/corehost/cli/fxr/standalone/hostfxr_unixexports.src rename src/installer/corehost/cli/fxr/{ => standalone}/hostpolicy_resolver.cpp (97%) create mode 100644 src/installer/corehost/cli/fxr/static/CMakeLists.txt create mode 100644 src/installer/corehost/cli/hostpolicy/standalone/CMakeLists.txt create mode 100644 src/installer/corehost/cli/hostpolicy/standalone/hostpolicy.def create mode 100644 src/installer/corehost/cli/hostpolicy/standalone/hostpolicy_unixexports.src create mode 100644 src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt create mode 100644 src/installer/corehost/hostfxr_resolver_t.h create mode 100644 src/installer/test/Assets/TestProjects/StaticHostApp/Program.cs create mode 100644 src/installer/test/Assets/TestProjects/StaticHostApp/StaticHostApp.csproj create mode 100644 src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/StaticHost.cs diff --git a/eng/SignCheckExclusionsFile.txt b/eng/SignCheckExclusionsFile.txt index a63e461d075f0..fd2b824540457 100644 --- a/eng/SignCheckExclusionsFile.txt +++ b/eng/SignCheckExclusionsFile.txt @@ -7,6 +7,7 @@ ;; and SCD apps. If they are signed, the file that the SDK produces has an invalid signature and ;; can't be signed again. More info at https://github.com/dotnet/core-setup/pull/7549. *apphost.exe;;Template, https://github.com/dotnet/core-setup/pull/7549 +*singlefilehost.exe;;Template, https://github.com/dotnet/core-setup/pull/7549 *comhost.dll;;Template, https://github.com/dotnet/core-setup/pull/7549 *apphosttemplateapphostexe.exe;;Template, https://github.com/dotnet/core-setup/pull/7549 *comhosttemplatecomhostdll.dll;;Template, https://github.com/dotnet/core-setup/pull/7549 diff --git a/eng/Signing.props b/eng/Signing.props index 05f2a8bcb3957..5ceb96ac54bf9 100644 --- a/eng/Signing.props +++ b/eng/Signing.props @@ -24,7 +24,7 @@ - + diff --git a/eng/native/functions.cmake b/eng/native/functions.cmake index 060cff8987e35..49b0064499eb4 100644 --- a/eng/native/functions.cmake +++ b/eng/native/functions.cmake @@ -175,8 +175,8 @@ function(generate_exports_file) add_custom_command( OUTPUT ${outputFilename} - COMMAND ${AWK} -f ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT} ${INPUT_LIST} >${outputFilename} - DEPENDS ${INPUT_LIST} ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT} + COMMAND ${AWK} -f ${CLR_ENG_NATIVE_DIR}/${AWK_SCRIPT} ${INPUT_LIST} >${outputFilename} + DEPENDS ${INPUT_LIST} ${CLR_ENG_NATIVE_DIR}/${AWK_SCRIPT} COMMENT "Generating exports file ${outputFilename}" ) set_source_files_properties(${outputFilename} @@ -196,8 +196,8 @@ function(generate_exports_file_prefix inputFilename outputFilename prefix) add_custom_command( OUTPUT ${outputFilename} - COMMAND ${AWK} -f ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT} ${AWK_VARS} ${inputFilename} >${outputFilename} - DEPENDS ${inputFilename} ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT} + COMMAND ${AWK} -f ${CLR_ENG_NATIVE_DIR}/${AWK_SCRIPT} ${AWK_VARS} ${inputFilename} >${outputFilename} + DEPENDS ${inputFilename} ${CLR_ENG_NATIVE_DIR}/${AWK_SCRIPT} COMMENT "Generating exports file ${outputFilename}" ) set_source_files_properties(${outputFilename} diff --git a/src/coreclr/generateexportedsymbols.awk b/eng/native/generateexportedsymbols.awk similarity index 100% rename from src/coreclr/generateexportedsymbols.awk rename to eng/native/generateexportedsymbols.awk diff --git a/src/coreclr/generateversionscript.awk b/eng/native/generateversionscript.awk similarity index 100% rename from src/coreclr/generateversionscript.awk rename to eng/native/generateversionscript.awk diff --git a/src/installer/corehost/cli/CMakeLists.txt b/src/installer/corehost/cli/CMakeLists.txt index 15ce0fa117721..3c1bdb1f2f0ec 100644 --- a/src/installer/corehost/cli/CMakeLists.txt +++ b/src/installer/corehost/cli/CMakeLists.txt @@ -1,10 +1,10 @@ add_subdirectory(hostcommon) add_subdirectory(apphost) add_subdirectory(dotnet) -add_subdirectory(fxr) -add_subdirectory(hostpolicy) add_subdirectory(nethost) add_subdirectory(test_fx_ver) +add_subdirectory(fxr) +add_subdirectory(hostpolicy) add_subdirectory(test) diff --git a/src/installer/corehost/cli/apphost/CMakeLists.txt b/src/installer/corehost/cli/apphost/CMakeLists.txt index ba01e32ec47c7..ec7e8e3e2ce4b 100644 --- a/src/installer/corehost/cli/apphost/CMakeLists.txt +++ b/src/installer/corehost/cli/apphost/CMakeLists.txt @@ -2,49 +2,5 @@ # The .NET Foundation licenses this file to you under the MIT license. # See the LICENSE file in the project root for more information. -project(apphost) -set(DOTNET_PROJECT_NAME "apphost") - -# Add RPATH to the apphost binary that allows using local copies of shared libraries -# dotnet core depends on for special scenarios when system wide installation of such -# dependencies is not possible for some reason. -# This cannot be enabled for MacOS (Darwin) since its RPATH works in a different way, -# doesn't apply to libraries loaded via dlopen and most importantly, it is not transitive. -if (NOT CLR_CMAKE_TARGET_OSX) - set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) - set(CMAKE_INSTALL_RPATH "\$ORIGIN/netcoredeps") -endif() - -set(SKIP_VERSIONING 1) - -set(SOURCES - ./bundle_marker.cpp -) - -set(HEADERS - ./bundle_marker.h -) - -if(CLR_CMAKE_TARGET_WIN32) - list(APPEND SOURCES - apphost.windows.cpp) - - list(APPEND HEADERS - apphost.windows.h) -endif() - -include(../exe.cmake) - -add_definitions(-DFEATURE_APPHOST=1) - -# Disable manifest generation into the file .exe on Windows -if(CLR_CMAKE_TARGET_WIN32) - set_property(TARGET ${PROJECT_NAME} PROPERTY - LINK_FLAGS "/MANIFEST:NO" - ) -endif() - -# Specify non-default Windows libs to be used for Arm/Arm64 builds -if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64)) - target_link_libraries(apphost Advapi32.lib shell32.lib) -endif() +add_subdirectory(static) +add_subdirectory(standalone) diff --git a/src/installer/corehost/cli/apphost/standalone/CMakeLists.txt b/src/installer/corehost/cli/apphost/standalone/CMakeLists.txt new file mode 100644 index 0000000000000..60d9a103b12fb --- /dev/null +++ b/src/installer/corehost/cli/apphost/standalone/CMakeLists.txt @@ -0,0 +1,54 @@ +# 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. + +project(apphost) +set(DOTNET_PROJECT_NAME "apphost") + +# Add RPATH to the apphost binary that allows using local copies of shared libraries +# dotnet core depends on for special scenarios when system wide installation of such +# dependencies is not possible for some reason. +# This cannot be enabled for MacOS (Darwin) since its RPATH works in a different way, +# doesn't apply to libraries loaded via dlopen and most importantly, it is not transitive. +if (NOT CLR_CMAKE_TARGET_OSX) + set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) + set(CMAKE_INSTALL_RPATH "\$ORIGIN/netcoredeps") +endif() + +set(SKIP_VERSIONING 1) + +include_directories(..) + +set(SOURCES + ../bundle_marker.cpp + ./hostfxr_resolver_t.cpp +) + +set(HEADERS + ../bundle_marker.h + ../../../hostfxr_resolver_t.h +) + +if(CLR_CMAKE_TARGET_WIN32) + list(APPEND SOURCES + ../apphost.windows.cpp) + + list(APPEND HEADERS + ../apphost.windows.h) +endif() + +include(../../exe.cmake) + +add_definitions(-DFEATURE_APPHOST=1) + +# Disable manifest generation into the file .exe on Windows +if(CLR_CMAKE_TARGET_WIN32) + set_property(TARGET ${PROJECT_NAME} PROPERTY + LINK_FLAGS "/MANIFEST:NO" + ) +endif() + +# Specify non-default Windows libs to be used for Arm/Arm64 builds +if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64)) + target_link_libraries(apphost Advapi32.lib shell32.lib) +endif() diff --git a/src/installer/corehost/cli/apphost/standalone/hostfxr_resolver_t.cpp b/src/installer/corehost/cli/apphost/standalone/hostfxr_resolver_t.cpp new file mode 100644 index 0000000000000..4f3c3888428c5 --- /dev/null +++ b/src/installer/corehost/cli/apphost/standalone/hostfxr_resolver_t.cpp @@ -0,0 +1,61 @@ +// 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. + +#include + +#include "pal.h" +#include "fxr_resolver.h" +#include "trace.h" +#include "hostfxr_resolver_t.h" + +hostfxr_main_bundle_startupinfo_fn hostfxr_resolver_t::resolve_main_bundle_startupinfo() +{ + assert(m_hostfxr_dll != nullptr); + return reinterpret_cast(pal::get_symbol(m_hostfxr_dll, "hostfxr_main_bundle_startupinfo")); +} + +hostfxr_set_error_writer_fn hostfxr_resolver_t::resolve_set_error_writer() +{ + assert(m_hostfxr_dll != nullptr); + return reinterpret_cast(pal::get_symbol(m_hostfxr_dll, "hostfxr_set_error_writer")); +} + +hostfxr_main_startupinfo_fn hostfxr_resolver_t::resolve_main_startupinfo() +{ + assert(m_hostfxr_dll != nullptr); + return reinterpret_cast(pal::get_symbol(m_hostfxr_dll, "hostfxr_main_startupinfo")); +} + +hostfxr_main_fn hostfxr_resolver_t::resolve_main_v1() +{ + assert(m_hostfxr_dll != nullptr); + return reinterpret_cast(pal::get_symbol(m_hostfxr_dll, "hostfxr_main")); +} + +hostfxr_resolver_t::hostfxr_resolver_t(const pal::string_t& app_root) +{ + if (!fxr_resolver::try_get_path(app_root, &m_dotnet_root, &m_fxr_path)) + { + m_status_code = StatusCode::CoreHostLibMissingFailure; + } + else if (pal::load_library(&m_fxr_path, &m_hostfxr_dll)) + { + m_status_code = StatusCode::Success; + } + else + { + trace::error(_X("The library %s was found, but loading it from %s failed"), LIBFXR_NAME, m_fxr_path.c_str()); + trace::error(_X(" - Installing .NET prerequisites might help resolve this problem.")); + trace::error(_X(" %s"), DOTNET_CORE_INSTALL_PREREQUISITES_URL); + m_status_code = StatusCode::CoreHostLibLoadFailure; + } +} + +hostfxr_resolver_t::~hostfxr_resolver_t() +{ + if (m_hostfxr_dll != nullptr) + { + pal::unload_library(m_hostfxr_dll); + } +} diff --git a/src/installer/corehost/cli/apphost/static/CMakeLists.txt b/src/installer/corehost/cli/apphost/static/CMakeLists.txt new file mode 100644 index 0000000000000..967aebb24133a --- /dev/null +++ b/src/installer/corehost/cli/apphost/static/CMakeLists.txt @@ -0,0 +1,63 @@ +# 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. + +project(singlefilehost) +set(DOTNET_PROJECT_NAME "singlefilehost") + +# Add RPATH to the apphost binary that allows using local copies of shared libraries +# dotnet core depends on for special scenarios when system wide installation of such +# dependencies is not possible for some reason. +# This cannot be enabled for MacOS (Darwin) since its RPATH works in a different way, +# doesn't apply to libraries loaded via dlopen and most importantly, it is not transitive. +if (NOT CLR_CMAKE_TARGET_OSX) + set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) + set(CMAKE_INSTALL_RPATH "\$ORIGIN/netcoredeps") +endif() + +set(SKIP_VERSIONING 1) + +include_directories(..) +include_directories(../../json) + +set(SOURCES + ../bundle_marker.cpp + ./hostfxr_resolver_t.cpp + ./hostpolicy_resolver.cpp +) + +set(HEADERS + ../bundle_marker.h + ../../../hostfxr_resolver_t.h +) + +if(CLR_CMAKE_TARGET_WIN32) + list(APPEND SOURCES + ../apphost.windows.cpp) + + list(APPEND HEADERS + ../apphost.windows.h) +endif() + +include(../../exe.cmake) + +add_definitions(-DFEATURE_APPHOST=1) +add_definitions(-DFEATURE_STATIC_HOST=1) + +# Disable manifest generation into the file .exe on Windows +if(CLR_CMAKE_TARGET_WIN32) + set_property(TARGET ${PROJECT_NAME} PROPERTY + LINK_FLAGS "/MANIFEST:NO" + ) +endif() + +# Specify non-default Windows libs to be used for Arm/Arm64 builds +if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64)) + target_link_libraries(singlefilehost Advapi32.lib shell32.lib) +endif() + +target_link_libraries(singlefilehost + libhostfxr_static + libhostpolicy_static + libhostcommon +) diff --git a/src/installer/corehost/cli/apphost/static/hostfxr_resolver_t.cpp b/src/installer/corehost/cli/apphost/static/hostfxr_resolver_t.cpp new file mode 100644 index 0000000000000..2c7e2b87a5f6d --- /dev/null +++ b/src/installer/corehost/cli/apphost/static/hostfxr_resolver_t.cpp @@ -0,0 +1,63 @@ +// 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. + +#include +#include "trace.h" +#include "hostfxr.h" +#include "hostfxr_resolver_t.h" + +extern "C" +{ + int HOSTFXR_CALLTYPE hostfxr_main_bundle_startupinfo(const int argc, const pal::char_t* argv[], const pal::char_t* host_path, const pal::char_t* dotnet_root, const pal::char_t* app_path, int64_t bundle_header_offset); + int HOSTFXR_CALLTYPE hostfxr_main_startupinfo(const int argc, const pal::char_t* argv[], const pal::char_t* host_path, const pal::char_t* dotnet_root, const pal::char_t* app_path); + int HOSTFXR_CALLTYPE hostfxr_main(const int argc, const pal::char_t* argv[]); + hostfxr_error_writer_fn HOSTFXR_CALLTYPE hostfxr_set_error_writer(hostfxr_error_writer_fn error_writer); +} + +hostfxr_main_bundle_startupinfo_fn hostfxr_resolver_t::resolve_main_bundle_startupinfo() +{ + assert(m_hostfxr_dll == nullptr); + return hostfxr_main_bundle_startupinfo; +} + +hostfxr_set_error_writer_fn hostfxr_resolver_t::resolve_set_error_writer() +{ + assert(m_hostfxr_dll == nullptr); + return hostfxr_set_error_writer; +} + +hostfxr_main_startupinfo_fn hostfxr_resolver_t::resolve_main_startupinfo() +{ + assert(m_hostfxr_dll == nullptr); + return hostfxr_main_startupinfo; +} + +hostfxr_main_fn hostfxr_resolver_t::resolve_main_v1() +{ + assert(m_hostfxr_dll == nullptr); + assert(!"This function should not be called in a static host"); + return nullptr; +} + +hostfxr_resolver_t::hostfxr_resolver_t(const pal::string_t& app_root) +{ + if (app_root.length() == 0) + { + trace::info(_X("Application root path is empty. This shouldn't happen")); + m_status_code = StatusCode::CoreHostLibMissingFailure; + } + else + { + trace::info(_X("Using internal fxr")); + + m_dotnet_root.assign(app_root); + m_fxr_path.assign(app_root); + + m_status_code = StatusCode::Success; + } +} + +hostfxr_resolver_t::~hostfxr_resolver_t() +{ +} diff --git a/src/installer/corehost/cli/apphost/static/hostpolicy_resolver.cpp b/src/installer/corehost/cli/apphost/static/hostpolicy_resolver.cpp new file mode 100644 index 0000000000000..0b2a35639a2e1 --- /dev/null +++ b/src/installer/corehost/cli/apphost/static/hostpolicy_resolver.cpp @@ -0,0 +1,59 @@ +// 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. + +#include +#include +#include +#include "hostpolicy_resolver.h" +#include +#include + +extern "C" +{ + int HOSTPOLICY_CALLTYPE corehost_load(const host_interface_t* init); + int HOSTPOLICY_CALLTYPE corehost_unload(); + corehost_error_writer_fn HOSTPOLICY_CALLTYPE corehost_set_error_writer(corehost_error_writer_fn error_writer); + int HOSTPOLICY_CALLTYPE corehost_initialize(const corehost_initialize_request_t *init_request, int32_t options, /*out*/ corehost_context_contract *context_contract); + int HOSTPOLICY_CALLTYPE corehost_main(const int argc, const pal::char_t* argv[]); + int HOSTPOLICY_CALLTYPE corehost_main_with_output_buffer(const int argc, const pal::char_t* argv[], pal::char_t buffer[], int32_t buffer_size, int32_t* required_buffer_size); +} + +int hostpolicy_resolver::load( + const pal::string_t& lib_dir, + pal::dll_t* dll, + hostpolicy_contract_t &hostpolicy_contract) +{ + static hostpolicy_contract_t contract; + + trace::info(_X("Using internal hostpolicy")); + + contract.load = corehost_load; + contract.unload = corehost_unload; + contract.set_error_writer = corehost_set_error_writer; + contract.initialize = corehost_initialize; + contract.corehost_main = corehost_main; + contract.corehost_main_with_output_buffer = corehost_main_with_output_buffer; + + hostpolicy_contract = contract; + *dll = nullptr; + + return StatusCode::Success; +} + +bool hostpolicy_resolver::try_get_dir( + host_mode_t mode, + const pal::string_t& dotnet_root, + const fx_definition_vector_t& fx_definitions, + const pal::string_t& app_candidate, + const pal::string_t& specified_deps_file, + const std::vector& probe_realpaths, + pal::string_t* impl_dir) +{ + // static apphost is not supposed to be used in a framework-dependent app + assert(!get_app(fx_definitions).get_runtime_config().get_is_framework_dependent()); + assert(mode == host_mode_t::apphost); + + impl_dir->assign(dotnet_root); + return true; +} diff --git a/src/installer/corehost/cli/dotnet/CMakeLists.txt b/src/installer/corehost/cli/dotnet/CMakeLists.txt index 4527986acfe3c..798ae4030ea0a 100644 --- a/src/installer/corehost/cli/dotnet/CMakeLists.txt +++ b/src/installer/corehost/cli/dotnet/CMakeLists.txt @@ -10,4 +10,8 @@ if(CLR_CMAKE_TARGET_WIN32) dotnet.manifest) endif() +list(APPEND SOURCES + ../apphost/standalone/hostfxr_resolver_t.cpp +) + include(../exe.cmake) diff --git a/src/installer/corehost/cli/exe.cmake b/src/installer/corehost/cli/exe.cmake index c9295d5c65f77..3acc130174aa3 100644 --- a/src/installer/corehost/cli/exe.cmake +++ b/src/installer/corehost/cli/exe.cmake @@ -18,6 +18,9 @@ list(APPEND SOURCES ${CMAKE_CURRENT_LIST_DIR}/fxr_resolver.cpp ${CMAKE_CURRENT_LIST_DIR}/../corehost.cpp ) +list(APPEND HEADERS + ${CMAKE_CURRENT_LIST_DIR}/../hostfxr_resolver_t.h +) add_executable(${DOTNET_PROJECT_NAME} ${SOURCES} ${RESOURCES}) diff --git a/src/installer/corehost/cli/fxr/CMakeLists.txt b/src/installer/corehost/cli/fxr/CMakeLists.txt index 216ecbf076bb7..ec7e8e3e2ce4b 100644 --- a/src/installer/corehost/cli/fxr/CMakeLists.txt +++ b/src/installer/corehost/cli/fxr/CMakeLists.txt @@ -2,46 +2,5 @@ # The .NET Foundation licenses this file to you under the MIT license. # See the LICENSE file in the project root for more information. -project(hostfxr) - -set(DOTNET_PROJECT_NAME "hostfxr") - -# Include directories -include_directories(../json) - -# CMake does not recommend using globbing since it messes with the freshness checks -set(SOURCES - ./command_line.cpp - ./corehost_init.cpp - ./hostfxr.cpp - ./fx_muxer.cpp - ./fx_resolver.cpp - ./fx_resolver.messages.cpp - ./framework_info.cpp - ./host_context.cpp - ./hostpolicy_resolver.cpp - ./sdk_info.cpp - ./sdk_resolver.cpp -) - -set(HEADERS - ../corehost_context_contract.h - ../hostpolicy.h - ../fx_definition.h - ../fx_reference.h - ../roll_fwd_on_no_candidate_fx_option.h - ./command_line.h - ./corehost_init.h - ./fx_muxer.h - ./fx_resolver.h - ./framework_info.h - ./host_context.h - ./hostpolicy_resolver.h - ./sdk_info.h - ./sdk_resolver.h -) - -include(../lib.cmake) - -install_with_stripped_symbols(hostfxr TARGETS corehost) -target_link_libraries(hostfxr libhostcommon) +add_subdirectory(static) +add_subdirectory(standalone) diff --git a/src/installer/corehost/cli/fxr/fx_muxer.cpp b/src/installer/corehost/cli/fxr/fx_muxer.cpp index 31c8c17797807..f41e9095ef064 100644 --- a/src/installer/corehost/cli/fxr/fx_muxer.cpp +++ b/src/installer/corehost/cli/fxr/fx_muxer.cpp @@ -66,16 +66,11 @@ namespace } } -template int load_hostpolicy( const pal::string_t& lib_dir, pal::dll_t* h_host, - hostpolicy_contract_t &hostpolicy_contract, - const char *main_entry_symbol, - T* main_fn) + hostpolicy_contract_t& hostpolicy_contract) { - assert(main_entry_symbol != nullptr && main_fn != nullptr); - int rc = hostpolicy_resolver::load(lib_dir, h_host, hostpolicy_contract); if (rc != StatusCode::Success) { @@ -83,11 +78,6 @@ int load_hostpolicy( return rc; } - // Obtain entrypoint symbol - *main_fn = reinterpret_cast(pal::get_symbol(*h_host, main_entry_symbol)); - if (*main_fn == nullptr) - return StatusCode::CoreHostEntryPointFailure; - return StatusCode::Success; } @@ -114,7 +104,18 @@ static int execute_app( hostpolicy_contract_t hostpolicy_contract{}; corehost_main_fn host_main = nullptr; - int code = load_hostpolicy(impl_dll_dir, &hostpolicy_dll, hostpolicy_contract, "corehost_main", &host_main); + int code = load_hostpolicy(impl_dll_dir, &hostpolicy_dll, hostpolicy_contract); + + // Obtain entrypoint symbol + if (code == StatusCode::Success) + { + host_main = hostpolicy_contract.corehost_main; + if (host_main == nullptr) + { + code = StatusCode::CoreHostEntryPointFailure; + } + } + if (code != StatusCode::Success) { handle_initialize_failure_or_abort(); @@ -164,7 +165,18 @@ static int execute_host_command( hostpolicy_contract_t hostpolicy_contract{}; corehost_main_with_output_buffer_fn host_main = nullptr; - int code = load_hostpolicy(impl_dll_dir, &hostpolicy_dll, hostpolicy_contract, "corehost_main_with_output_buffer", &host_main); + int code = load_hostpolicy(impl_dll_dir, &hostpolicy_dll, hostpolicy_contract); + + // Obtain entrypoint symbol + if (code == StatusCode::Success) + { + host_main = hostpolicy_contract.corehost_main_with_output_buffer; + if (host_main == nullptr) + { + code = StatusCode::CoreHostEntryPointFailure; + } + } + if (code != StatusCode::Success) return code; @@ -471,7 +483,7 @@ namespace if (!hostpolicy_resolver::try_get_dir(mode, host_info.dotnet_root, fx_definitions, app_candidate, deps_file, probe_realpaths, &hostpolicy_dir)) { - return CoreHostLibMissingFailure; + return StatusCode::CoreHostLibMissingFailure; } init.reset(new corehost_init_t(host_command, host_info, deps_file, additional_deps_serialized, probe_realpaths, mode, fx_definitions)); diff --git a/src/installer/corehost/cli/fxr/hostfxr.cpp b/src/installer/corehost/cli/fxr/hostfxr.cpp index 1fdfa21048935..23418b03da032 100644 --- a/src/installer/corehost/cli/fxr/hostfxr.cpp +++ b/src/installer/corehost/cli/fxr/hostfxr.cpp @@ -438,7 +438,7 @@ namespace if (startup_info.dotnet_root.empty()) { pal::string_t mod_path; - if (!pal::get_own_module_path(&mod_path)) + if (!pal::get_method_module_path(&mod_path, (void*)&hostfxr_set_error_writer)) return StatusCode::CoreHostCurHostFindFailure; startup_info.dotnet_root = get_dotnet_root_from_fxr_path(mod_path); diff --git a/src/installer/corehost/cli/fxr/hostpolicy_resolver.h b/src/installer/corehost/cli/fxr/hostpolicy_resolver.h index 4348a53c778e0..35128327b7bca 100644 --- a/src/installer/corehost/cli/fxr/hostpolicy_resolver.h +++ b/src/installer/corehost/cli/fxr/hostpolicy_resolver.h @@ -20,6 +20,10 @@ struct hostpolicy_contract_t // 3.0+ contracts corehost_set_error_writer_fn set_error_writer; corehost_initialize_fn initialize; + + // 5.0+ contracts + corehost_main_fn corehost_main; + corehost_main_with_output_buffer_fn corehost_main_with_output_buffer; }; namespace hostpolicy_resolver @@ -38,4 +42,4 @@ namespace hostpolicy_resolver pal::string_t* impl_dir); }; -#endif // __HOSTPOLICY_RESOLVER_H__ \ No newline at end of file +#endif // __HOSTPOLICY_RESOLVER_H__ diff --git a/src/installer/corehost/cli/fxr/standalone/CMakeLists.txt b/src/installer/corehost/cli/fxr/standalone/CMakeLists.txt new file mode 100644 index 0000000000000..0a2ea92174b6f --- /dev/null +++ b/src/installer/corehost/cli/fxr/standalone/CMakeLists.txt @@ -0,0 +1,65 @@ +# 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. + +project(hostfxr) + +set(DOTNET_PROJECT_NAME "hostfxr") + +# Include directories +include_directories(../../json) +include_directories(../../fxr) + +# CMake does not recommend using globbing since it messes with the freshness checks +set(SOURCES + ./hostpolicy_resolver.cpp +) + +set(HEADERS + ../command_line.h + ../corehost_init.h + ../fx_muxer.h + ../fx_resolver.h + ../framework_info.h + ../host_context.h + ../sdk_info.h + ../sdk_resolver.h + ../hostpolicy_resolver.h +) + +if(CLR_CMAKE_TARGET_WIN32) + list(APPEND SOURCES + hostfxr.def) +else(CLR_CMAKE_TARGET_WIN32) + set(DEF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/hostfxr_unixexports.src) + set(EXPORTS_FILE ${CMAKE_CURRENT_BINARY_DIR}/hostfxr.exports) + generate_exports_file(${DEF_SOURCES} ${EXPORTS_FILE}) + + if(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) + # Add linker exports file option + set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE}) + endif(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) + + if(CLR_CMAKE_HOST_OSX) + # Add linker exports file option + set(EXPORTS_LINKER_OPTION -Wl,-exported_symbols_list,${EXPORTS_FILE}) + endif(CLR_CMAKE_HOST_OSX) + + if(CLR_CMAKE_HOST_SUNOS) + # Add linker exports file option + set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) + endif(CLR_CMAKE_HOST_SUNOS) +endif(CLR_CMAKE_TARGET_WIN32) + +include(../../lib.cmake) + +if(CLR_CMAKE_HOST_UNIX) + add_custom_target(hostfxr_exports DEPENDS ${EXPORTS_FILE}) + add_dependencies(hostfxr hostfxr_exports) + + set_property(TARGET hostfxr APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION}) + set_property(TARGET hostfxr APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE}) +endif(CLR_CMAKE_HOST_UNIX) + +install_with_stripped_symbols(hostfxr TARGETS corehost) +target_link_libraries(hostfxr libhostcommon libhostfxr_static) diff --git a/src/installer/corehost/cli/fxr/standalone/hostfxr.def b/src/installer/corehost/cli/fxr/standalone/hostfxr.def new file mode 100644 index 0000000000000..c86139a7fb58b --- /dev/null +++ b/src/installer/corehost/cli/fxr/standalone/hostfxr.def @@ -0,0 +1,21 @@ +; 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. + +EXPORTS + hostfxr_main_bundle_startupinfo + hostfxr_main_startupinfo + hostfxr_main + hostfxr_resolve_sdk + hostfxr_resolve_sdk2 + hostfxr_get_available_sdks + hostfxr_get_native_search_directories + hostfxr_set_error_writer + hostfxr_initialize_for_dotnet_command_line + hostfxr_initialize_for_runtime_config + hostfxr_run_app + hostfxr_get_runtime_delegate + hostfxr_get_runtime_property_value + hostfxr_set_runtime_property_value + hostfxr_get_runtime_properties + hostfxr_close diff --git a/src/installer/corehost/cli/fxr/standalone/hostfxr_unixexports.src b/src/installer/corehost/cli/fxr/standalone/hostfxr_unixexports.src new file mode 100644 index 0000000000000..fcf85d027fa64 --- /dev/null +++ b/src/installer/corehost/cli/fxr/standalone/hostfxr_unixexports.src @@ -0,0 +1,20 @@ +; 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. + +hostfxr_main_bundle_startupinfo +hostfxr_main_startupinfo +hostfxr_main +hostfxr_resolve_sdk +hostfxr_resolve_sdk2 +hostfxr_get_available_sdks +hostfxr_get_native_search_directories +hostfxr_set_error_writer +hostfxr_initialize_for_dotnet_command_line +hostfxr_initialize_for_runtime_config +hostfxr_run_app +hostfxr_get_runtime_delegate +hostfxr_get_runtime_property_value +hostfxr_set_runtime_property_value +hostfxr_get_runtime_properties +hostfxr_close diff --git a/src/installer/corehost/cli/fxr/hostpolicy_resolver.cpp b/src/installer/corehost/cli/fxr/standalone/hostpolicy_resolver.cpp similarity index 97% rename from src/installer/corehost/cli/fxr/hostpolicy_resolver.cpp rename to src/installer/corehost/cli/fxr/standalone/hostpolicy_resolver.cpp index de3291fecc5b5..67881d207944f 100644 --- a/src/installer/corehost/cli/fxr/hostpolicy_resolver.cpp +++ b/src/installer/corehost/cli/fxr/standalone/hostpolicy_resolver.cpp @@ -198,6 +198,9 @@ int hostpolicy_resolver::load( g_hostpolicy_contract.set_error_writer = reinterpret_cast(pal::get_symbol(g_hostpolicy, "corehost_set_error_writer")); g_hostpolicy_contract.initialize = reinterpret_cast(pal::get_symbol(g_hostpolicy, "corehost_initialize")); + g_hostpolicy_contract.corehost_main = reinterpret_cast(pal::get_symbol(g_hostpolicy, "corehost_main")); + g_hostpolicy_contract.corehost_main_with_output_buffer = reinterpret_cast(pal::get_symbol(g_hostpolicy, "corehost_main_with_output_buffer")); + // It's possible to not have corehost_set_error_writer and corehost_initialize. These were // introduced in 3.0, so 2.0 hostpolicy would not have the exports. In this case, we will // not propagate the error writer and errors will still be reported to stderr. Callers are diff --git a/src/installer/corehost/cli/fxr/static/CMakeLists.txt b/src/installer/corehost/cli/fxr/static/CMakeLists.txt new file mode 100644 index 0000000000000..16c0951c5b21b --- /dev/null +++ b/src/installer/corehost/cli/fxr/static/CMakeLists.txt @@ -0,0 +1,45 @@ +# 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. + +project(hostfxr_static) + +set(DOTNET_PROJECT_NAME "hostfxr_static") + +# Include directories +include_directories(../../json) +include_directories(../../fxr) + +# CMake does not recommend using globbing since it messes with the freshness checks +set(SOURCES + ../command_line.cpp + ../corehost_init.cpp + ../hostfxr.cpp + ../fx_muxer.cpp + ../fx_resolver.cpp + ../fx_resolver.messages.cpp + ../framework_info.cpp + ../host_context.cpp + ../sdk_info.cpp + ../sdk_resolver.cpp +) + +set(HEADERS + ../../corehost_context_contract.h + ../../hostpolicy.h + ../../fx_definition.h + ../../fx_reference.h + ../../roll_fwd_on_no_candidate_fx_option.h + ../command_line.h + ../corehost_init.h + ../fx_muxer.h + ../fx_resolver.h + ../framework_info.h + ../host_context.h + ../sdk_info.h + ../sdk_resolver.h +) + +set(SKIP_VERSIONING 1) +set(BUILD_OBJECT_LIBRARY 1) +include(../../lib_static.cmake) diff --git a/src/installer/corehost/cli/hostmisc/pal.h b/src/installer/corehost/cli/hostmisc/pal.h index 5c8fa68a27881..743687546ad07 100644 --- a/src/installer/corehost/cli/hostmisc/pal.h +++ b/src/installer/corehost/cli/hostmisc/pal.h @@ -272,6 +272,7 @@ namespace pal bool get_own_executable_path(string_t* recv); bool get_own_module_path(string_t* recv); + bool get_method_module_path(string_t* recv, void* method); bool get_module_path(dll_t mod, string_t* recv); bool get_current_module(dll_t *mod); bool getenv(const char_t* name, string_t* recv); diff --git a/src/installer/corehost/cli/hostmisc/pal.unix.cpp b/src/installer/corehost/cli/hostmisc/pal.unix.cpp index b09721677da7b..a17487636d60b 100644 --- a/src/installer/corehost/cli/hostmisc/pal.unix.cpp +++ b/src/installer/corehost/cli/hostmisc/pal.unix.cpp @@ -821,6 +821,16 @@ bool pal::get_own_module_path(string_t* recv) return true; } +bool pal::get_method_module_path(string_t* recv, void* method) +{ + Dl_info info; + if (dladdr(method, &info) == 0) + return false; + + recv->assign(info.dli_fname); + return true; +} + bool pal::get_module_path(dll_t module, string_t* recv) { return false; diff --git a/src/installer/corehost/cli/hostmisc/pal.windows.cpp b/src/installer/corehost/cli/hostmisc/pal.windows.cpp index 81f538bed4414..1c724611d72c6 100644 --- a/src/installer/corehost/cli/hostmisc/pal.windows.cpp +++ b/src/installer/corehost/cli/hostmisc/pal.windows.cpp @@ -553,6 +553,16 @@ bool pal::get_own_module_path(string_t* recv) return GetModuleFileNameWrapper(hmod, recv); } +bool pal::get_method_module_path(string_t* recv, void* method) +{ + HMODULE hmod; + if (!GetModuleHandleFromAddress(method, &hmod)) + return false; + + return GetModuleFileNameWrapper(hmod, recv); +} + + bool pal::get_module_path(dll_t mod, string_t* recv) { return GetModuleFileNameWrapper(mod, recv); diff --git a/src/installer/corehost/cli/hostpolicy/CMakeLists.txt b/src/installer/corehost/cli/hostpolicy/CMakeLists.txt index ca2c78fa27951..ec7e8e3e2ce4b 100644 --- a/src/installer/corehost/cli/hostpolicy/CMakeLists.txt +++ b/src/installer/corehost/cli/hostpolicy/CMakeLists.txt @@ -2,47 +2,5 @@ # The .NET Foundation licenses this file to you under the MIT license. # See the LICENSE file in the project root for more information. -project(hostpolicy) - -set(DOTNET_PROJECT_NAME "hostpolicy") - -# Include directories -include_directories(../fxr) -include_directories(../json) - -# CMake does not recommend using globbing since it messes with the freshness checks -set(SOURCES - ./args.cpp - ./breadcrumbs.cpp - ./coreclr.cpp - ./deps_resolver.cpp - ./hostpolicy_context.cpp - ./hostpolicy.cpp - ./hostpolicy_init.cpp - ../bundle/dir_utils.cpp - ../bundle/extractor.cpp - ../bundle/file_entry.cpp - ../bundle/manifest.cpp - ../bundle/runner.cpp -) - -set(HEADERS - ./args.h - ./breadcrumbs.h - ./coreclr.h - ../corehost_context_contract.h - ./deps_resolver.h - ./hostpolicy_context.h - ../hostpolicy.h - ./hostpolicy_init.h - ../bundle/dir_utils.h - ../bundle/extractor.h - ../bundle/file_entry.h - ../bundle/manifest.h - ../bundle/runner.h -) - -include(../lib.cmake) - -install_with_stripped_symbols(hostpolicy TARGETS corehost) -target_link_libraries(hostpolicy libhostcommon) +add_subdirectory(static) +add_subdirectory(standalone) diff --git a/src/installer/corehost/cli/hostpolicy/standalone/CMakeLists.txt b/src/installer/corehost/cli/hostpolicy/standalone/CMakeLists.txt new file mode 100644 index 0000000000000..d6631543f81b5 --- /dev/null +++ b/src/installer/corehost/cli/hostpolicy/standalone/CMakeLists.txt @@ -0,0 +1,59 @@ +# 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. + +project(hostpolicy) + +set(DOTNET_PROJECT_NAME "hostpolicy") + +# CMake does not recommend using globbing since it messes with the freshness checks + +# Can't call add_library() without source files. Create an empty .c file, +# then link with the static library just recently built. +if (NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/empty.cpp") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/empty.cpp" "") +endif () + +set(SOURCES + ${CMAKE_CURRENT_BINARY_DIR}/empty.cpp +) + +set(HEADERS +) + +if(CLR_CMAKE_TARGET_WIN32) + list(APPEND SOURCES + hostpolicy.def) +else(CLR_CMAKE_TARGET_WIN32) + set(DEF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/hostpolicy_unixexports.src) + set(EXPORTS_FILE ${CMAKE_CURRENT_BINARY_DIR}/hostpolicy.exports) + generate_exports_file(${DEF_SOURCES} ${EXPORTS_FILE}) + + if(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) + # Add linker exports file option + set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE}) + endif(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) + + if(CLR_CMAKE_HOST_OSX) + # Add linker exports file option + set(EXPORTS_LINKER_OPTION -Wl,-exported_symbols_list,${EXPORTS_FILE}) + endif(CLR_CMAKE_HOST_OSX) + + if(CLR_CMAKE_HOST_SUNOS) + # Add linker exports file option + set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) + endif(CLR_CMAKE_HOST_SUNOS) +endif(CLR_CMAKE_TARGET_WIN32) + +include(../../lib.cmake) + +if(CLR_CMAKE_HOST_UNIX) + add_custom_target(hostpolicy_exports DEPENDS ${EXPORTS_FILE}) + add_dependencies(hostpolicy hostpolicy_exports) + + set_property(TARGET hostpolicy APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION}) + set_property(TARGET hostpolicy APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE}) +endif(CLR_CMAKE_HOST_UNIX) + +install_with_stripped_symbols(hostpolicy TARGETS corehost) +target_link_libraries(hostpolicy libhostcommon libhostpolicy_static) diff --git a/src/installer/corehost/cli/hostpolicy/standalone/hostpolicy.def b/src/installer/corehost/cli/hostpolicy/standalone/hostpolicy.def new file mode 100644 index 0000000000000..af03ab9dca68d --- /dev/null +++ b/src/installer/corehost/cli/hostpolicy/standalone/hostpolicy.def @@ -0,0 +1,12 @@ +; 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. + +EXPORTS + corehost_initialize + corehost_load + corehost_main + corehost_main_with_output_buffer + corehost_resolve_component_dependencies + corehost_set_error_writer + corehost_unload diff --git a/src/installer/corehost/cli/hostpolicy/standalone/hostpolicy_unixexports.src b/src/installer/corehost/cli/hostpolicy/standalone/hostpolicy_unixexports.src new file mode 100644 index 0000000000000..98f3e616e9499 --- /dev/null +++ b/src/installer/corehost/cli/hostpolicy/standalone/hostpolicy_unixexports.src @@ -0,0 +1,11 @@ +; 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. + +corehost_initialize +corehost_load +corehost_main +corehost_main_with_output_buffer +corehost_resolve_component_dependencies +corehost_set_error_writer +corehost_unload diff --git a/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt b/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt new file mode 100644 index 0000000000000..6845e369bdac3 --- /dev/null +++ b/src/installer/corehost/cli/hostpolicy/static/CMakeLists.txt @@ -0,0 +1,47 @@ +# 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. + +project(hostpolicy_static) + +set(DOTNET_PROJECT_NAME "hostpolicy_static") + +# Include directories +include_directories(../../fxr) +include_directories(../../json) + +# CMake does not recommend using globbing since it messes with the freshness checks +set(SOURCES + ../args.cpp + ../breadcrumbs.cpp + ../coreclr.cpp + ../deps_resolver.cpp + ../hostpolicy_context.cpp + ../hostpolicy.cpp + ../hostpolicy_init.cpp + ../../bundle/dir_utils.cpp + ../../bundle/extractor.cpp + ../../bundle/file_entry.cpp + ../../bundle/manifest.cpp + ../../bundle/runner.cpp +) + +set(HEADERS + ../args.h + ../breadcrumbs.h + ../coreclr.h + ../deps_resolver.h + ../hostpolicy_context.h + ../hostpolicy_init.h + ../../hostpolicy.h + ../../corehost_context_contract.h + ../../bundle/dir_utils.h + ../../bundle/extractor.h + ../../bundle/file_entry.h + ../../bundle/manifest.h + ../../bundle/runner.h +) + +set(SKIP_VERSIONING 1) +set(BUILD_OBJECT_LIBRARY 1) +include(../../lib_static.cmake) diff --git a/src/installer/corehost/cli/lib_static.cmake b/src/installer/corehost/cli/lib_static.cmake index 8135e9c19e0e0..00204df3ce9f4 100644 --- a/src/installer/corehost/cli/lib_static.cmake +++ b/src/installer/corehost/cli/lib_static.cmake @@ -10,7 +10,11 @@ add_definitions(-D_NO_ASYNCRTIMP) add_definitions(-D_NO_PPLXIMP) add_definitions(-DEXPORT_SHARED_API=1) -add_library(lib${DOTNET_PROJECT_NAME} STATIC ${SOURCES} ${RESOURCES}) +if (BUILD_OBJECT_LIBRARY) + add_library(lib${DOTNET_PROJECT_NAME} OBJECT ${SOURCES} ${RESOURCES}) +else () + add_library(lib${DOTNET_PROJECT_NAME} STATIC ${SOURCES} ${RESOURCES}) +endif () set_target_properties(lib${DOTNET_PROJECT_NAME} PROPERTIES MACOSX_RPATH TRUE) set_target_properties(lib${DOTNET_PROJECT_NAME} PROPERTIES PREFIX "") diff --git a/src/installer/corehost/corehost.cpp b/src/installer/corehost/corehost.cpp index 55b8ed629827c..65cfb61f3ac64 100644 --- a/src/installer/corehost/corehost.cpp +++ b/src/installer/corehost/corehost.cpp @@ -9,6 +9,7 @@ #include "fx_ver.h" #include "trace.h" #include "utils.h" +#include "hostfxr_resolver_t.h" #if defined(FEATURE_APPHOST) #include "bundle_marker.h" @@ -176,51 +177,41 @@ int exe_start(const int argc, const pal::char_t* argv[]) app_path.append(_X(".dll")); #endif - pal::string_t dotnet_root; - pal::string_t fxr_path; - if (!fxr_resolver::try_get_path(app_root, &dotnet_root, &fxr_path)) - { - return StatusCode::CoreHostLibMissingFailure; - } + hostfxr_resolver_t fxr{app_root}; - // Load library - pal::dll_t fxr; - if (!pal::load_library(&fxr_path, &fxr)) + // Obtain the entrypoints. + int rc = fxr.status_code(); + if (rc != StatusCode::Success) { - trace::error(_X("The library %s was found, but loading it from %s failed"), LIBFXR_NAME, fxr_path.c_str()); - trace::error(_X(" - Installing .NET prerequisites might help resolve this problem.")); - trace::error(_X(" %s"), DOTNET_CORE_INSTALL_PREREQUISITES_URL); - return StatusCode::CoreHostLibLoadFailure; + return rc; } - // Obtain the entrypoints. - int rc; #if defined(FEATURE_APPHOST) if (bundle_marker_t::is_bundle()) { - hostfxr_main_bundle_startupinfo_fn hostfxr_main_bundle_startupinfo = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_main_bundle_startupinfo")); + auto hostfxr_main_bundle_startupinfo = fxr.resolve_main_bundle_startupinfo(); if (hostfxr_main_bundle_startupinfo != nullptr) { const pal::char_t* host_path_cstr = host_path.c_str(); - const pal::char_t* dotnet_root_cstr = dotnet_root.empty() ? nullptr : dotnet_root.c_str(); + const pal::char_t* dotnet_root_cstr = fxr.dotnet_root().empty() ? nullptr : fxr.dotnet_root().c_str(); const pal::char_t* app_path_cstr = app_path.empty() ? nullptr : app_path.c_str(); int64_t bundle_header_offset = bundle_marker_t::header_offset(); - trace::info(_X("Invoking fx resolver [%s] hostfxr_main_bundle_startupinfo"), fxr_path.c_str()); + trace::info(_X("Invoking fx resolver [%s] hostfxr_main_bundle_startupinfo"), fxr.fxr_path().c_str()); trace::info(_X("Host path: [%s]"), host_path.c_str()); - trace::info(_X("Dotnet path: [%s]"), dotnet_root.c_str()); + trace::info(_X("Dotnet path: [%s]"), fxr.dotnet_root().c_str()); trace::info(_X("App path: [%s]"), app_path.c_str()); trace::info(_X("Bundle Header Offset: [%lx]"), bundle_header_offset); - hostfxr_set_error_writer_fn set_error_writer_fn = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_set_error_writer")); - propagate_error_writer_t propagate_error_writer_to_hostfxr(set_error_writer_fn); + auto set_error_writer = fxr.resolve_set_error_writer(); + propagate_error_writer_t propagate_error_writer_to_hostfxr(set_error_writer); rc = hostfxr_main_bundle_startupinfo(argc, argv, host_path_cstr, dotnet_root_cstr, app_path_cstr, bundle_header_offset); } else { // The host components will be statically linked with the app-host: https://github.com/dotnet/runtime/issues/32823 // Once this work is completed, an outdated hostfxr can only be found for framework-related apps. - trace::error(_X("The required library %s does not support single-file apps."), fxr_path.c_str()); + trace::error(_X("The required library %s does not support single-file apps."), fxr.fxr_path().c_str()); need_newer_framework_error(); rc = StatusCode::FrameworkMissingFailure; } @@ -228,60 +219,61 @@ int exe_start(const int argc, const pal::char_t* argv[]) else #endif // defined(FEATURE_APPHOST) { - hostfxr_main_startupinfo_fn hostfxr_main_startupinfo = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_main_startupinfo")); + auto hostfxr_main_startupinfo = fxr.resolve_main_startupinfo(); if (hostfxr_main_startupinfo != nullptr) { const pal::char_t* host_path_cstr = host_path.c_str(); - const pal::char_t* dotnet_root_cstr = dotnet_root.empty() ? nullptr : dotnet_root.c_str(); + const pal::char_t* dotnet_root_cstr = fxr.dotnet_root().empty() ? nullptr : fxr.dotnet_root().c_str(); const pal::char_t* app_path_cstr = app_path.empty() ? nullptr : app_path.c_str(); - trace::info(_X("Invoking fx resolver [%s] hostfxr_main_startupinfo"), fxr_path.c_str()); + trace::info(_X("Invoking fx resolver [%s] hostfxr_main_startupinfo"), fxr.fxr_path().c_str()); trace::info(_X("Host path: [%s]"), host_path.c_str()); - trace::info(_X("Dotnet path: [%s]"), dotnet_root.c_str()); + trace::info(_X("Dotnet path: [%s]"), fxr.dotnet_root().c_str()); trace::info(_X("App path: [%s]"), app_path.c_str()); - hostfxr_set_error_writer_fn set_error_writer_fn = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_set_error_writer")); - propagate_error_writer_t propagate_error_writer_to_hostfxr(set_error_writer_fn); + auto set_error_writer = fxr.resolve_set_error_writer(); + propagate_error_writer_t propagate_error_writer_to_hostfxr(set_error_writer); rc = hostfxr_main_startupinfo(argc, argv, host_path_cstr, dotnet_root_cstr, app_path_cstr); // This check exists to provide an error message for UI apps when running 3.0 apps on 2.0 only hostfxr, which doesn't support error writer redirection. - if (trace::get_error_writer() != nullptr && rc == static_cast(StatusCode::FrameworkMissingFailure) && !set_error_writer_fn) + if (trace::get_error_writer() != nullptr && rc == static_cast(StatusCode::FrameworkMissingFailure) && set_error_writer == nullptr) { need_newer_framework_error(); } } +#if !defined(FEATURE_STATIC_HOST) else { if (requires_hostfxr_startupinfo_interface) { - trace::error(_X("The required library %s does not support relative app dll paths."), fxr_path.c_str()); + trace::error(_X("The required library %s does not support relative app dll paths."), fxr.fxr_path().c_str()); rc = StatusCode::CoreHostEntryPointFailure; } else { - trace::info(_X("Invoking fx resolver [%s] v1"), fxr_path.c_str()); + trace::info(_X("Invoking fx resolver [%s] v1"), fxr.fxr_path().c_str()); // Previous corehost trace messages must be printed before calling trace::setup in hostfxr trace::flush(); // For compat, use the v1 interface. This requires additional file I\O to re-parse parameters and // for apphost, does not support DOTNET_ROOT or dll with different name for exe. - hostfxr_main_fn main_fn_v1 = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_main")); + auto main_fn_v1 = fxr.resolve_main_v1(); if (main_fn_v1 != nullptr) { rc = main_fn_v1(argc, argv); } else { - trace::error(_X("The required library %s does not contain the expected entry point."), fxr_path.c_str()); + trace::error(_X("The required library %s does not contain the expected entry point."), fxr.fxr_path().c_str()); rc = StatusCode::CoreHostEntryPointFailure; } } } +#endif // defined(FEATURE_STATIC_HOST) } - pal::unload_library(fxr); return rc; } diff --git a/src/installer/corehost/hostfxr_resolver_t.h b/src/installer/corehost/hostfxr_resolver_t.h new file mode 100644 index 0000000000000..21047b56a3c89 --- /dev/null +++ b/src/installer/corehost/hostfxr_resolver_t.h @@ -0,0 +1,40 @@ +// 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. + +#ifndef __HOSTFXR_RESOLVER_T_H__ +#define __HOSTFXR_RESOLVER_T_H__ + +#include "hostfxr.h" +#include "pal.h" +#include "error_codes.h" + +class hostfxr_resolver_t +{ + public: + hostfxr_resolver_t(const pal::string_t& app_root); + ~hostfxr_resolver_t(); + + StatusCode status_code() const { return m_status_code; } + + const pal::string_t& host_path() const { return m_host_path; } + const pal::string_t& dotnet_root() const { return m_dotnet_root; } + const pal::string_t& fxr_path() const { return m_fxr_path; } + + hostfxr_main_bundle_startupinfo_fn resolve_main_bundle_startupinfo(); + hostfxr_set_error_writer_fn resolve_set_error_writer(); + hostfxr_main_startupinfo_fn resolve_main_startupinfo(); + hostfxr_main_fn resolve_main_v1(); + + private: + pal::dll_t m_hostfxr_dll{nullptr}; + + pal::string_t m_host_path; + pal::string_t m_dotnet_root; + pal::string_t m_fxr_path; + + bool m_requires_startupinfo_iface{false}; + StatusCode m_status_code; +}; + +#endif // __HOSTFXR_RESOLVER_T_H__ diff --git a/src/installer/pkg/projects/Microsoft.NETCore.DotNetAppHost/runtime.Windows_NT.Microsoft.NETCore.DotNetAppHost.props b/src/installer/pkg/projects/Microsoft.NETCore.DotNetAppHost/runtime.Windows_NT.Microsoft.NETCore.DotNetAppHost.props index c74da91a0f25c..6d52e1984f8ce 100644 --- a/src/installer/pkg/projects/Microsoft.NETCore.DotNetAppHost/runtime.Windows_NT.Microsoft.NETCore.DotNetAppHost.props +++ b/src/installer/pkg/projects/Microsoft.NETCore.DotNetAppHost/runtime.Windows_NT.Microsoft.NETCore.DotNetAppHost.props @@ -2,6 +2,7 @@ + diff --git a/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Host.pkgproj b/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Host.pkgproj index 10915e8d504d4..8daa78d3ec711 100644 --- a/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Host.pkgproj +++ b/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Host.pkgproj @@ -15,6 +15,7 @@ --> + @@ -29,4 +30,4 @@ true - \ No newline at end of file + diff --git a/src/installer/test/Assets/TestProjects/StaticHostApp/Program.cs b/src/installer/test/Assets/TestProjects/StaticHostApp/Program.cs new file mode 100644 index 0000000000000..c631d81d54048 --- /dev/null +++ b/src/installer/test/Assets/TestProjects/StaticHostApp/Program.cs @@ -0,0 +1,16 @@ +// 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. + +using System; + +namespace StaticHostApp +{ + public static class Program + { + public static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } +} diff --git a/src/installer/test/Assets/TestProjects/StaticHostApp/StaticHostApp.csproj b/src/installer/test/Assets/TestProjects/StaticHostApp/StaticHostApp.csproj new file mode 100644 index 0000000000000..eff31e8532b40 --- /dev/null +++ b/src/installer/test/Assets/TestProjects/StaticHostApp/StaticHostApp.csproj @@ -0,0 +1,13 @@ + + + + $(NETCoreAppFramework) + Exe + $(TestTargetRid) + $(MNAVersion) + + + + + + diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/StaticHost.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/StaticHost.cs new file mode 100644 index 0000000000000..78b5c9449fe1b --- /dev/null +++ b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/StaticHost.cs @@ -0,0 +1,98 @@ +// 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. + +using BundleTests.Helpers; +using Microsoft.DotNet.Cli.Build.Framework; +using Microsoft.DotNet.CoreSetup.Test; +using Microsoft.NET.HostModel.AppHost; +using Microsoft.NET.HostModel.Bundle; +using System; +using System.IO; +using System.Threading; +using Xunit; + +namespace AppHost.Bundle.Tests +{ + public class StaticHost : IClassFixture + { + private SharedTestState sharedTestState; + + public StaticHost(SharedTestState fixture) + { + sharedTestState = fixture; + } + + // This helper is used in lieu of SDK support for publishing apps using the singlefilehost. + // It replaces the apphost with singlefilehost, and along with appropriate app.dll updates in the host. + // For now, we leave behind the hostpolicy and hostfxr DLLs in the publish directory, because + // removing them requires deps.json update. + void ReplaceApphostWithStaticHost(TestProjectFixture fixture) + { + var staticHost = Path.Combine(fixture.RepoDirProvider.HostArtifacts, + RuntimeInformationExtensions.GetExeFileNameForCurrentPlatform("singlefilehost")); + HostWriter.CreateAppHost(staticHost, + BundleHelper.GetHostPath(fixture), + BundleHelper.GetAppPath(fixture)); + + } + + [Fact] + private void Can_Run_App_With_StatiHost() + { + var fixture = sharedTestState.TestFixture.Copy(); + var appExe = BundleHelper.GetHostPath(fixture); + + ReplaceApphostWithStaticHost(fixture); + + Command.Create(appExe) + .CaptureStdErr() + .CaptureStdOut() + .Execute() + .Should() + .Pass() + .And + .HaveStdOutContaining("Hello World"); + } + + [Fact] + private void Can_Run_SingleFile_App_With_StatiHost() + { + var fixture = sharedTestState.TestFixture.Copy(); + + ReplaceApphostWithStaticHost(fixture); + + string singleFile = BundleHelper.BundleApp(fixture); + + Command.Create(singleFile) + .CaptureStdErr() + .CaptureStdOut() + .Execute() + .Should() + .Pass() + .And + .HaveStdOutContaining("Hello World"); + } + + public class SharedTestState : IDisposable + { + public TestProjectFixture TestFixture { get; set; } + public RepoDirectoriesProvider RepoDirectories { get; set; } + + public SharedTestState() + { + RepoDirectories = new RepoDirectoriesProvider(); + TestFixture = new TestProjectFixture("StaticHostApp", RepoDirectories); + TestFixture + .EnsureRestoredForRid(TestFixture.CurrentRid, RepoDirectories.CorehostPackages) + .PublishProject(runtime: TestFixture.CurrentRid, + outputDirectory: BundleHelper.GetPublishPath(TestFixture)); + } + + public void Dispose() + { + TestFixture.Dispose(); + } + } + } +} From cbef985abad43a4389331ef60ab781e6a7f11444 Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Fri, 15 May 2020 16:01:16 -0700 Subject: [PATCH 236/420] Produce DropFromSingleFile annotations in RuntimeList.xml (#36578) * SingleFileHostInclude * style fixes * PR feedback --- .../pkg/projects/Directory.Build.targets | 11 +++---- .../netcoreapp/pkg/Directory.Build.props | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/installer/pkg/projects/Directory.Build.targets b/src/installer/pkg/projects/Directory.Build.targets index b2450a84266c1..cfce7c8527f4f 100644 --- a/src/installer/pkg/projects/Directory.Build.targets +++ b/src/installer/pkg/projects/Directory.Build.targets @@ -3,8 +3,8 @@ - - + + - + @@ -324,7 +324,8 @@ FileClassifications="@(FrameworkListFileClass)" TargetFile="$(FrameworkListFile)" TargetFilePrefixes="ref/;runtimes/" - RootAttributes="@(FrameworkListRootAttributes)" /> + RootAttributes="@(FrameworkListRootAttributes)" + SingleFileHostIncludeFilenames="@(SingleFileHostIncludeFilename)" /> @@ -371,7 +372,7 @@ + ExcludeAssets="All" /> diff --git a/src/installer/pkg/projects/netcoreapp/pkg/Directory.Build.props b/src/installer/pkg/projects/netcoreapp/pkg/Directory.Build.props index cad6d6838fc09..befd427101bea 100644 --- a/src/installer/pkg/projects/netcoreapp/pkg/Directory.Build.props +++ b/src/installer/pkg/projects/netcoreapp/pkg/Directory.Build.props @@ -12,6 +12,35 @@ $(SharedFrameworkName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index c82088bcb6e98..5330f4309c38e 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -106,7 +106,7 @@ <_runtimeOS Condition="'$(_runtimeOS)' == 'tizen.5.0.0'">linux <_runtimeOS Condition="'$(PortableBuild)' == 'true'">$(_portableOS) $(_runtimeOS)-x64 - $(_runtimeOS)-$(HostArch) + $(_runtimeOS)-$(HostArch) linux-x64 From 5b0bf40aa640dfa551c801303376b25af7129076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20P=C3=ADchov=C3=A1?= <11718369+ManickaP@users.noreply.github.com> Date: Sat, 16 May 2020 11:15:05 +0200 Subject: [PATCH 238/420] SslStream.AuthenticateAs sync overloads with SslOptions made public (#36221) --- .../ref/System.Net.Security.cs | 3 + .../src/System/Net/Security/SslStream.cs | 26 +++- .../SslAuthenticationOptionsTest.cs | 20 ++- .../SslStreamAllowRenegotiationTests.cs | 18 ++- .../FunctionalTests/SslStreamAlpnTests.cs | 42 ++++-- .../FunctionalTests/SslStreamExtensions.cs | 25 ++++ .../SslStreamStreamToStreamTest.cs | 121 +++++++++++++++--- .../System.Net.Security.Tests.csproj | 1 + 8 files changed, 219 insertions(+), 37 deletions(-) create mode 100644 src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamExtensions.cs diff --git a/src/libraries/System.Net.Security/ref/System.Net.Security.cs b/src/libraries/System.Net.Security/ref/System.Net.Security.cs index c022960def9c7..ff6cee15760f3 100644 --- a/src/libraries/System.Net.Security/ref/System.Net.Security.cs +++ b/src/libraries/System.Net.Security/ref/System.Net.Security.cs @@ -182,6 +182,7 @@ public partial class SslStream : System.Net.Security.AuthenticatedStream public virtual System.Security.Authentication.SslProtocols SslProtocol { get { throw null; } } public System.Net.TransportContext TransportContext { get { throw null; } } public override int WriteTimeout { get { throw null; } set { } } + public void AuthenticateAsClient(System.Net.Security.SslClientAuthenticationOptions sslClientAuthenticationOptions) { } public virtual void AuthenticateAsClient(string targetHost) { } public virtual void AuthenticateAsClient(string targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection? clientCertificates, bool checkCertificateRevocation) { } public virtual void AuthenticateAsClient(string targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection? clientCertificates, System.Security.Authentication.SslProtocols enabledSslProtocols, bool checkCertificateRevocation) { } @@ -189,6 +190,7 @@ public partial class SslStream : System.Net.Security.AuthenticatedStream public virtual System.Threading.Tasks.Task AuthenticateAsClientAsync(string targetHost) { throw null; } public virtual System.Threading.Tasks.Task AuthenticateAsClientAsync(string targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection? clientCertificates, bool checkCertificateRevocation) { throw null; } public virtual System.Threading.Tasks.Task AuthenticateAsClientAsync(string targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection? clientCertificates, System.Security.Authentication.SslProtocols enabledSslProtocols, bool checkCertificateRevocation) { throw null; } + public void AuthenticateAsServer(System.Net.Security.SslServerAuthenticationOptions sslServerAuthenticationOptions) { } public virtual void AuthenticateAsServer(System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate) { } public virtual void AuthenticateAsServer(System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, bool clientCertificateRequired, bool checkCertificateRevocation) { } public virtual void AuthenticateAsServer(System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, bool clientCertificateRequired, System.Security.Authentication.SslProtocols enabledSslProtocols, bool checkCertificateRevocation) { } @@ -210,6 +212,7 @@ public partial class SslStream : System.Net.Security.AuthenticatedStream public virtual void EndAuthenticateAsServer(System.IAsyncResult asyncResult) { } public override int EndRead(System.IAsyncResult asyncResult) { throw null; } public override void EndWrite(System.IAsyncResult asyncResult) { } + ~SslStream() { } public override void Flush() { } public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; } public override int Read(byte[] buffer, int offset, int count) { throw null; } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs index 73f4417dacc21..79c16bf043ed4 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs @@ -304,8 +304,13 @@ public virtual void AuthenticateAsClient(string targetHost, X509CertificateColle AuthenticateAsClient(options); } - private void AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions) + public void AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions) { + if (sslClientAuthenticationOptions == null) + { + throw new ArgumentNullException(nameof(sslClientAuthenticationOptions)); + } + SetAndVerifyValidationCallback(sslClientAuthenticationOptions.RemoteCertificateValidationCallback); SetAndVerifySelectionCallback(sslClientAuthenticationOptions.LocalCertificateSelectionCallback); @@ -337,8 +342,13 @@ public virtual void AuthenticateAsServer(X509Certificate serverCertificate, bool AuthenticateAsServer(options); } - private void AuthenticateAsServer(SslServerAuthenticationOptions sslServerAuthenticationOptions) + public void AuthenticateAsServer(SslServerAuthenticationOptions sslServerAuthenticationOptions) { + if (sslServerAuthenticationOptions == null) + { + throw new ArgumentNullException(nameof(sslServerAuthenticationOptions)); + } + SetAndVerifyValidationCallback(sslServerAuthenticationOptions.RemoteCertificateValidationCallback); ValidateCreateContext(CreateAuthenticationOptions(sslServerAuthenticationOptions)); @@ -367,6 +377,11 @@ public virtual Task AuthenticateAsClientAsync(string targetHost, X509Certificate public Task AuthenticateAsClientAsync(SslClientAuthenticationOptions sslClientAuthenticationOptions, CancellationToken cancellationToken = default) { + if (sslClientAuthenticationOptions == null) + { + throw new ArgumentNullException(nameof(sslClientAuthenticationOptions)); + } + SetAndVerifyValidationCallback(sslClientAuthenticationOptions.RemoteCertificateValidationCallback); SetAndVerifySelectionCallback(sslClientAuthenticationOptions.LocalCertificateSelectionCallback); @@ -417,6 +432,11 @@ public virtual Task AuthenticateAsServerAsync(X509Certificate serverCertificate, public Task AuthenticateAsServerAsync(SslServerAuthenticationOptions sslServerAuthenticationOptions, CancellationToken cancellationToken = default) { + if (sslServerAuthenticationOptions == null) + { + throw new ArgumentNullException(nameof(sslServerAuthenticationOptions)); + } + SetAndVerifyValidationCallback(sslServerAuthenticationOptions.RemoteCertificateValidationCallback); ValidateCreateContext(CreateAuthenticationOptions(sslServerAuthenticationOptions)); @@ -792,7 +812,7 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati return WriteAsync(new ReadOnlyMemory(buffer, offset, count), cancellationToken).AsTask(); } - public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken) + public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { ThrowIfExceptionalOrNotAuthenticated(); AsyncSslIOAdapter writeAdapter = new AsyncSslIOAdapter(this, cancellationToken); diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslAuthenticationOptionsTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslAuthenticationOptionsTest.cs index ada4a652b6e77..af9e02ad03ed6 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslAuthenticationOptionsTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslAuthenticationOptionsTest.cs @@ -14,8 +14,10 @@ namespace System.Net.Security.Tests { using Configuration = System.Net.Test.Common.Configuration; - public class SslClientAuthenticationOptionsTest + public abstract class SslClientAuthenticationOptionsTestBase { + protected abstract bool TestAuthenticateAsync { get; } + [Fact] public async Task ClientOptions_ServerOptions_NotMutatedDuringAuthentication() { @@ -74,9 +76,9 @@ public async Task ClientOptions_ServerOptions_NotMutatedDuringAuthentication() }; // Authenticate - Task clientTask = client.AuthenticateAsClientAsync(clientOptions, default); - Task serverTask = server.AuthenticateAsServerAsync(serverOptions, default); - await new[] { clientTask, serverTask }.WhenAllOrAnyFailed(); + Task clientTask = client.AuthenticateAsClientAsync(TestAuthenticateAsync, clientOptions); + Task serverTask = server.AuthenticateAsServerAsync(TestAuthenticateAsync, serverOptions); + await new[] {clientTask, serverTask}.WhenAllOrAnyFailed(); // Validate that client options are unchanged Assert.Equal(clientAllowRenegotiation, clientOptions.AllowRenegotiation); @@ -105,4 +107,14 @@ public async Task ClientOptions_ServerOptions_NotMutatedDuringAuthentication() } } } + + public sealed class SslClientAuthenticationOptionsTestBase_Sync : SslClientAuthenticationOptionsTestBase + { + protected override bool TestAuthenticateAsync => false; + } + + public sealed class SslClientAuthenticationOptionsTestBase_Async : SslClientAuthenticationOptionsTestBase + { + protected override bool TestAuthenticateAsync => true; + } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamAllowRenegotiationTests.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamAllowRenegotiationTests.cs index 1895d118ea6f2..b4147844b9060 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamAllowRenegotiationTests.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamAllowRenegotiationTests.cs @@ -17,8 +17,10 @@ namespace System.Net.Security.Tests { using Configuration = System.Net.Test.Common.Configuration; - public class SslStreamAllowRenegotiationTests + public abstract class SslStreamAllowRenegotiationTestsBase { + protected abstract bool TestAuthenticateAsync { get; } + [Fact] [OuterLoop] // Test hits external azure server. public async Task SslStream_AllowRenegotiation_True_Succeeds() @@ -49,7 +51,7 @@ public async Task SslStream_AllowRenegotiation_True_Succeeds() }; // Perform handshake to establish secure connection. - await ssl.AuthenticateAsClientAsync(options, CancellationToken.None); + await ssl.AuthenticateAsClientAsync(TestAuthenticateAsync, options); Assert.True(ssl.IsAuthenticated); Assert.True(ssl.IsEncrypted); @@ -89,7 +91,7 @@ public async Task SslStream_AllowRenegotiation_False_Throws() }; // Perform handshake to establish secure connection. - await ssl.AuthenticateAsClientAsync(options, CancellationToken.None); + await ssl.AuthenticateAsClientAsync(TestAuthenticateAsync, options); Assert.True(ssl.IsAuthenticated); Assert.True(ssl.IsEncrypted); @@ -103,4 +105,14 @@ public async Task SslStream_AllowRenegotiation_False_Throws() } } } + + public sealed class SslStreamAllowRenegotiationTests_Sync : SslStreamAllowRenegotiationTestsBase + { + protected override bool TestAuthenticateAsync => false; + } + + public sealed class SslStreamAllowRenegotiationTests_Async : SslStreamAllowRenegotiationTestsBase + { + protected override bool TestAuthenticateAsync => true; + } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamAlpnTests.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamAlpnTests.cs index de5212a93fc4c..c5284653585b7 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamAlpnTests.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamAlpnTests.cs @@ -21,19 +21,21 @@ namespace System.Net.Security.Tests { using Configuration = System.Net.Test.Common.Configuration; - public class SslStreamAlpnTests + public abstract class SslStreamAlpnTestBase { private static bool BackendSupportsAlpn => PlatformDetection.SupportsAlpn; private static bool ClientSupportsAlpn => PlatformDetection.SupportsClientAlpn; readonly ITestOutputHelper _output; public static readonly object[][] Http2Servers = Configuration.Http.Http2Servers; - public SslStreamAlpnTests(ITestOutputHelper output) + // Whether AuthenticateAs(Client/Server) or AuthenticateAs(Client/Server)Async will be called + public abstract bool TestAuthenticateAsync { get; } + + protected SslStreamAlpnTestBase(ITestOutputHelper output) { _output = output; } - private async Task DoHandshakeWithOptions(SslStream clientSslStream, SslStream serverSslStream, SslClientAuthenticationOptions clientOptions, SslServerAuthenticationOptions serverOptions) { using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate()) @@ -42,8 +44,8 @@ private async Task DoHandshakeWithOptions(SslStream clientSslStream, SslStream s clientOptions.TargetHost = certificate.GetNameInfo(X509NameType.SimpleName, false); serverOptions.ServerCertificate = certificate; - Task t1 = clientSslStream.AuthenticateAsClientAsync(clientOptions, CancellationToken.None); - Task t2 = serverSslStream.AuthenticateAsServerAsync(serverOptions, CancellationToken.None); + Task t1 = clientSslStream.AuthenticateAsClientAsync(TestAuthenticateAsync, clientOptions); + Task t2 = serverSslStream.AuthenticateAsServerAsync(TestAuthenticateAsync, serverOptions); await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2); } @@ -95,8 +97,8 @@ public async Task SslStream_StreamToStream_DuplicateOptions_Throws() serverOptions.ServerCertificate = certificate; serverOptions.RemoteCertificateValidationCallback = AllowAnyServerCertificate; - Task t1 = Assert.ThrowsAsync(() => client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None)); - Task t2 = Assert.ThrowsAsync(() => server.AuthenticateAsServerAsync(serverOptions, CancellationToken.None)); + Task t1 = Assert.ThrowsAsync(() => client.AuthenticateAsClientAsync(TestAuthenticateAsync, clientOptions)); + Task t2 = Assert.ThrowsAsync(() => server.AuthenticateAsServerAsync(TestAuthenticateAsync, serverOptions)); await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2); } @@ -163,11 +165,11 @@ public async Task SslStream_StreamToStream_Alpn_NonMatchingProtocols_Fail() { // schannel sends alert on ALPN failure, openssl does not. Task t1 = Assert.ThrowsAsync(TestConfiguration.SupportsAlpnAlerts ? typeof(AuthenticationException) : typeof(IOException), () => - clientStream.AuthenticateAsClientAsync(clientOptions, CancellationToken.None)); + clientStream.AuthenticateAsClientAsync(TestAuthenticateAsync, clientOptions)); try { - await serverStream.AuthenticateAsServerAsync(serverOptions, CancellationToken.None); + await serverStream.AuthenticateAsServerAsync(TestAuthenticateAsync, serverOptions); Assert.True(false, "AuthenticationException was not thrown."); } catch (AuthenticationException) { server.Dispose(); } @@ -176,8 +178,8 @@ public async Task SslStream_StreamToStream_Alpn_NonMatchingProtocols_Fail() } else { - Task t1 = clientStream.AuthenticateAsClientAsync(clientOptions, CancellationToken.None); - Task t2 = serverStream.AuthenticateAsServerAsync(serverOptions, CancellationToken.None); + Task t1 = clientStream.AuthenticateAsClientAsync(TestAuthenticateAsync, clientOptions); + Task t2 = serverStream.AuthenticateAsServerAsync(TestAuthenticateAsync, serverOptions); await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2); @@ -211,7 +213,7 @@ public async Task SslStream_Http2_Alpn_Success(Uri server) TargetHost = server.Host }; - await clientStream.AuthenticateAsClientAsync(clientOptions, CancellationToken.None); + await clientStream.AuthenticateAsClientAsync(TestAuthenticateAsync, clientOptions); Assert.Equal("h2", clientStream.NegotiatedApplicationProtocol.ToString()); } } @@ -246,4 +248,20 @@ public static IEnumerable Alpn_TestData() } } } + + public sealed class SslStreamAlpnTest_Async : SslStreamAlpnTestBase + { + public override bool TestAuthenticateAsync => true; + + public SslStreamAlpnTest_Async(ITestOutputHelper output) + : base (output) { } + } + + public sealed class SslStreamAlpnTest_Sync : SslStreamAlpnTestBase + { + public override bool TestAuthenticateAsync => false; + + public SslStreamAlpnTest_Sync(ITestOutputHelper output) + : base(output) { } + } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamExtensions.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamExtensions.cs new file mode 100644 index 0000000000000..e7e423ee89580 --- /dev/null +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamExtensions.cs @@ -0,0 +1,25 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Security.Tests +{ + internal static class SslStreamExtensions + { + public static Task AuthenticateAsClientAsync(this SslStream stream, + bool async, SslClientAuthenticationOptions clientOptions, + CancellationToken cancellationToken = default) + { + return async + ? stream.AuthenticateAsClientAsync(clientOptions, cancellationToken) + : Task.Run(() => stream.AuthenticateAsClient(clientOptions)); + } + public static Task AuthenticateAsServerAsync(this SslStream stream, + bool async, SslServerAuthenticationOptions serverOptions, + CancellationToken cancellationToken = default) + { + return async + ? stream.AuthenticateAsServerAsync(serverOptions, cancellationToken) + : Task.Run(() => stream.AuthenticateAsServer(serverOptions)); + } + } +} diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs index 93baf83fd156f..9fb2ac9fefbd6 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs @@ -395,7 +395,7 @@ public async Task SslStream_StreamToStream_WriteAsync_ReadByte_Success() [Fact] public async Task SslStream_StreamToStream_WriteAsync_ReadAsync_Pending_Success() { - if (this is SslStreamStreamToStreamTest_Sync) + if (this is SslStreamStreamToStreamTest_SyncBase) { // This test assumes operations complete asynchronously. return; @@ -488,7 +488,7 @@ public async Task SslStream_ConcurrentBidirectionalReadsWrites_Success() [Fact] public async Task SslStream_StreamToStream_Dispose_Throws() { - if (this is SslStreamStreamToStreamTest_Sync) + if (this is SslStreamStreamToStreamTest_SyncBase) { // This test assumes operations complete asynchronously. return; @@ -511,7 +511,7 @@ public async Task SslStream_StreamToStream_Dispose_Throws() await WriteAsync(serverSslStream, new byte[] { 1 }, 0, 1) .TimeoutAfter(TestConfiguration.PassingTestTimeoutMilliseconds); - // Shouldn't throw, the context is diposed now. + // Shouldn't throw, the context is disposed now. // Since the server read task is in progress, the read buffer is not returned to ArrayPool. serverSslStream.Dispose(); @@ -821,19 +821,8 @@ protected override async Task DoHandshake(SslStream clientSslStream, SslStream s Task.Factory.FromAsync(stream.BeginWrite, stream.EndWrite, buffer, offset, count, null); } - public sealed class SslStreamStreamToStreamTest_Sync : SslStreamStreamToStreamTest + public abstract class SslStreamStreamToStreamTest_SyncBase : SslStreamStreamToStreamTest { - protected override async Task DoHandshake(SslStream clientSslStream, SslStream serverSslStream, X509Certificate serverCertificate = null, X509Certificate clientCertificate = null) - { - X509CertificateCollection clientCerts = clientCertificate != null ? new X509CertificateCollection() { clientCertificate } : null; - await WithServerCertificate(serverCertificate, async (certificate, name) => - { - Task t1 = Task.Run(() => clientSslStream.AuthenticateAsClient(name, clientCerts, SslProtocols.None, checkCertificateRevocation: false)); - Task t2 = Task.Run(() => serverSslStream.AuthenticateAsServer(certificate, clientCertificateRequired: clientCertificate != null, checkCertificateRevocation: false)); - await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2); - }); - } - protected override Task ReadAsync(Stream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) @@ -868,6 +857,108 @@ protected override Task WriteAsync(Stream stream, byte[] buffer, int offset, int return Task.FromException(e); } } + + [Fact] + public async Task SslStream_StreamToStream_Handshake_DisposeClient_Throws() + { + VirtualNetwork network = new VirtualNetwork(); + + var clientStream = new VirtualNetworkStream(network, isServer: false); + using (var serverStream = new VirtualNetworkStream(network, isServer: true)) + using (var clientSslStream = new SslStream(clientStream, false, AllowAnyServerCertificate)) + using (var serverSslStream = new SslStream(serverStream)) + { + clientStream.Dispose(); + + await Assert.ThrowsAsync(() => DoHandshake(clientSslStream, serverSslStream)); + } + } + + [Fact] + public async Task SslStream_StreamToStream_Handshake_DisposeServer_Throws() + { + VirtualNetwork network = new VirtualNetwork(); + + var serverStream = new VirtualNetworkStream(network, isServer: true); + using (var clientStream = new VirtualNetworkStream(network, isServer: false)) + using (var clientSslStream = new SslStream(clientStream, false, AllowAnyServerCertificate)) + using (var serverSslStream = new SslStream(serverStream)) + { + serverStream.Dispose(); + + await Assert.ThrowsAsync(() => DoHandshake(clientSslStream, serverSslStream)); + } + } + + [Fact] + public async Task SslStream_StreamToStream_Handshake_DisposeClientSsl_Throws() + { + VirtualNetwork network = new VirtualNetwork() { DisableConnectionBreaking = true }; + + using (var clientStream = new VirtualNetworkStream(network, isServer: false)) + using (var serverStream = new VirtualNetworkStream(network, isServer: true)) + using (var serverSslStream = new SslStream(serverStream)) + { + var clientSslStream = new SslStream(clientStream, false, AllowAnyServerCertificate); + clientSslStream.Dispose(); + + await Assert.ThrowsAsync(() => DoHandshake(clientSslStream, serverSslStream)); + } + } + + [Fact] + public async Task SslStream_StreamToStream_Handshake_DisposeServerSsl_Throws() + { + VirtualNetwork network = new VirtualNetwork() {DisableConnectionBreaking = true}; + + using (var clientStream = new VirtualNetworkStream(network, isServer: false)) + using (var serverStream = new VirtualNetworkStream(network, isServer: true)) + using (var clientSslStream = new SslStream(clientStream, false, AllowAnyServerCertificate)) + { + var serverSslStream = new SslStream(serverStream); + serverSslStream.Dispose(); + + await Assert.ThrowsAsync(() => DoHandshake(clientSslStream, serverSslStream)); + } + } + } + + public sealed class SslStreamStreamToStreamTest_SyncParameters : SslStreamStreamToStreamTest_SyncBase + { + protected override async Task DoHandshake(SslStream clientSslStream, SslStream serverSslStream, X509Certificate serverCertificate = null, X509Certificate clientCertificate = null) + { + X509CertificateCollection clientCerts = clientCertificate != null ? new X509CertificateCollection() { clientCertificate } : null; + await WithServerCertificate(serverCertificate, async (certificate, name) => + { + Task t1 = Task.Run(() => clientSslStream.AuthenticateAsClient(name, clientCerts, SslProtocols.None, checkCertificateRevocation: false)); + Task t2 = Task.Run(() => serverSslStream.AuthenticateAsServer(certificate, clientCertificateRequired: clientCertificate != null, checkCertificateRevocation: false)); + await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2); + }); + } + } + + public sealed class SslStreamStreamToStreamTest_SyncSslOptions : SslStreamStreamToStreamTest_SyncBase + { + protected override async Task DoHandshake(SslStream clientSslStream, SslStream serverSslStream, X509Certificate serverCertificate = null, X509Certificate clientCertificate = null) + { + X509CertificateCollection clientCerts = clientCertificate != null ? new X509CertificateCollection() { clientCertificate } : null; + await WithServerCertificate(serverCertificate, async (certificate, name) => + { + SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions + { + TargetHost = name, + ClientCertificates = clientCerts, + EnabledSslProtocols = SslProtocols.None, + }; + SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions() + { + ServerCertificate = certificate, ClientCertificateRequired = clientCertificate != null, + }; + Task t1 = Task.Run(() => clientSslStream.AuthenticateAsClient(clientOptions)); + Task t2 = Task.Run(() => serverSslStream.AuthenticateAsServer(serverOptions)); + await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2); + }); + } } public sealed class SslStreamStreamToStreamTest_MemoryAsync : SslStreamStreamToStreamTest_CancelableReadWriteAsync diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj b/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj index 4ad947504b2c1..94026f1078c10 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj @@ -9,6 +9,7 @@ + From 00acdc1514ed73bbb802307e6f5029a53c7a3335 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Sat, 16 May 2020 16:15:56 +0300 Subject: [PATCH 239/420] [mono] Use "dotnet publish" for Android sample with ILLink (#36593) --- .../testing/libraries/testing-android.md | 8 +- src/mono/mono.proj | 7 +- src/mono/netcore/sample/Android/Makefile | 18 ++--- .../netcore/sample/Android/Program.csproj | 80 +++++++++---------- .../AndroidAppBuilder/AndroidAppBuilder.cs | 2 +- .../AndroidAppBuilder/ApkBuilder.cs | 2 +- .../Templates/CMakeLists.txt.template | 2 +- 7 files changed, 57 insertions(+), 62 deletions(-) diff --git a/docs/workflow/testing/libraries/testing-android.md b/docs/workflow/testing/libraries/testing-android.md index 4c32cd49279ff..7ac22f84062fa 100644 --- a/docs/workflow/testing/libraries/testing-android.md +++ b/docs/workflow/testing/libraries/testing-android.md @@ -36,13 +36,13 @@ fi # download Android NDK export ANDROID_NDK_ROOT=~/android-ndk-${NDK_VER} curl https://dl.google.com/android/repository/android-ndk-${NDK_VER}-${HOST_OS}-x86_64.zip -L --output ~/andk.zip -unzip ~/andk.zip -o -d $(dirname ${ANDROID_NDK_ROOT}) && rm -rf ~/andk.zip +unzip ~/andk.zip -d $(dirname ${ANDROID_NDK_ROOT}) && rm -rf ~/andk.zip # download Android SDK, accept licenses and download additional packages such as # platform-tools, platforms and build-tools export ANDROID_SDK_ROOT=~/android-sdk curl https://dl.google.com/android/repository/commandlinetools-${HOST_OS_SHORT}-${SDK_VER}.zip -L --output ~/asdk.zip -unzip ~/asdk.zip -o -d ${ANDROID_SDK_ROOT} && rm -rf ~/asdk.zip +unzip ~/asdk.zip -d ${ANDROID_SDK_ROOT} && rm -rf ~/asdk.zip yes | ${ANDROID_SDK_ROOT}/tools/bin/./sdkmanager --sdk_root=${ANDROID_SDK_ROOT} --licenses ${ANDROID_SDK_ROOT}/tools/bin/./sdkmanager --sdk_root=${ANDROID_SDK_ROOT} "platform-tools" "platforms;android-${SDK_API_LEVEL}" "build-tools;${SDK_BUILD_TOOLS}" @@ -50,10 +50,10 @@ ${ANDROID_SDK_ROOT}/tools/bin/./sdkmanager --sdk_root=${ANDROID_SDK_ROOT} "platf # and will be removed once we figure out how to integrate OpenSSL properly as a dependency export ANDROID_OPENSSL_AAR=~/openssl-android curl https://maven.google.com/com/android/ndk/thirdparty/openssl/${OPENSSL_VER}/openssl-${OPENSSL_VER}.aar -L --output ~/openssl.zip -unzip ~/openssl.zip -o -d ${ANDROID_OPENSSL_AAR} && rm -rf ~/openssl.zip +unzip ~/openssl.zip -d ${ANDROID_OPENSSL_AAR} && rm -rf ~/openssl.zip printf "\n\nexport ANDROID_NDK_ROOT=${ANDROID_NDK_ROOT}\nexport ANDROID_SDK_ROOT=${ANDROID_SDK_ROOT}\nexport ANDROID_OPENSSL_AAR=${ANDROID_OPENSSL_AAR}\n" >> ${BASHRC} ``` -Make sure `ANDROID_NDK_ROOT`, `ANDROID_SDK_ROOT` and `ANDROID_OPENSSL_AAR` environment variables are accessible and point to correct locations. +Save it to a file (e.g. `deps.sh`) and execute using `source` (e.g. `chmod +x deps.sh && source ./deps.sh`) in order to propogate the `ANDROID_NDK_ROOT`, `ANDROID_SDK_ROOT` and `ANDROID_OPENSSL_AAR` environment variables to the current process. ## Building Libs and Tests for Android diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 83ddd98916415..3951191cc1d7b 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -70,10 +70,13 @@ - <_MonoCFLAGS Include="-O2" /> + <_MonoCFLAGS Include="-O2" Condition="'$(TargetsMobile)' != 'true'" /> + <_MonoCFLAGS Include="-Os" Condition="'$(TargetsMobile)' == 'true'" /> <_MonoCFLAGS Include="-g" /> + <_MonoCFLAGS Include="-Wl,-s" Condition="'$(TargetsAndroid)' == 'true'" /> - <_MonoCXXFLAGS Include="-O2" /> + <_MonoCXXFLAGS Include="-O2" Condition="'$(TargetsMobile)' != 'true'" /> + <_MonoCXXFLAGS Include="-Os" Condition="'$(TargetsMobile)' == 'true'" /> <_MonoCXXFLAGS Include="-g" /> diff --git a/src/mono/netcore/sample/Android/Makefile b/src/mono/netcore/sample/Android/Makefile index 898c8cf1bea57..32d038d5a2ed0 100644 --- a/src/mono/netcore/sample/Android/Makefile +++ b/src/mono/netcore/sample/Android/Makefile @@ -1,18 +1,18 @@ -MONO_CONFIG=Debug +MONO_CONFIG=Release MONO_ARCH=arm64 DOTNET := ../../../../.././dotnet.sh -#export ANDROID_NDK_ROOT=/path/to/android/ndk -#export ANDROID_SDK_ROOT=/path/to/android/sdk +all: runtimepack apk -all: bundle +appbuilder: + $(DOTNET) build -c Release ../../../../../tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.csproj -bundle: clean - $(DOTNET) build -c $(MONO_CONFIG) Program.csproj - $(DOTNET) msbuild /t:BuildAppBundle /p:Configuration=$(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH) +runtimepack: + ../../../../.././build.sh Mono+Libs -os Android -arch $(MONO_ARCH) -c $(MONO_CONFIG) -deploy-launch: bundle - $(DOTNET) msbuild /t:ReinstallAndLaunch +apk: clean appbuilder + $(DOTNET) publish -c Release -r android-$(MONO_ARCH) \ + /p:Platform=$(MONO_ARCH) /p:DeployAndRun=true clean: rm -rf bin diff --git a/src/mono/netcore/sample/Android/Program.csproj b/src/mono/netcore/sample/Android/Program.csproj index 600ac6dd74727..d7516dc186290 100644 --- a/src/mono/netcore/sample/Android/Program.csproj +++ b/src/mono/netcore/sample/Android/Program.csproj @@ -4,71 +4,63 @@ bin Portable $(NetCoreAppCurrent) - x64 $(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-Android-$(Configuration)-$(TargetArchitecture)\runtimes\android-$(TargetArchitecture) - $(MSBuildThisFileDirectory)\bin\bundle $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', 'Debug', '$(NetCoreAppCurrent)')) - + false + true + <_TrimmerDefaultAction>link - - + + + + + $(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-Android-$(Configuration)-$(Platform) + + + - + + - arm64-v8a - armeabi-v7a - x86_64 - $(TargetArchitecture) + arm64-v8a + armeabi-v7a + x86_64 + $(Platform) + $(MSBuildThisFileDirectory)$(PublishDir)\apk + False + True + $(ANDROID_SDK_ROOT)\platform-tools\adb - - - - - - - - - - - - - + - + + + + + StripDebugSymbols="$(StripDebugSymbols)" + SourceDir="$(MSBuildThisFileDirectory)$(PublishDir)" + OutputDir="$(ApkDir)"> - - - - - $(ANDROID_SDK_ROOT)\platform-tools\adb - - - - - - + + + + diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.cs index cc915aeaf69ef..baaa1c7f18e2f 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.cs @@ -22,7 +22,7 @@ public class AndroidAppBuilderTask : Task public string MainLibraryFileName { get; set; } = ""!; /// - /// Target arch, can be 'x86', 'x86_64', 'armeabi', 'armeabi-v7a' or 'arm64-v8a' + /// Target arch, can be 'x86', 'x86_64', 'armeabi-v7a' or 'arm64-v8a' /// [Required] public string Abi { get; set; } = ""!; diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs index 4330c7451f027..b252a46530af4 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs @@ -23,7 +23,7 @@ public class ApkBuilder throw new ArgumentException($"sourceDir='{sourceDir}' is empty or doesn't exist"); if (string.IsNullOrEmpty(abi)) - throw new ArgumentException("abi shoudln't be empty (e.g. x86, x86_64, armeabi, armeabi-v7a or arm64-v8a"); + throw new ArgumentException("abi shoudln't be empty (e.g. x86, x86_64, armeabi-v7a or arm64-v8a"); if (string.IsNullOrEmpty(entryPointLib)) throw new ArgumentException("entryPointLib shouldn't be empty"); diff --git a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/CMakeLists.txt.template b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/CMakeLists.txt.template index 8ba0e854c063e..11c5631a6d9fe 100644 --- a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/CMakeLists.txt.template +++ b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/CMakeLists.txt.template @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14.5) +cmake_minimum_required(VERSION 3.16) project(%ProjectName%) enable_language(OBJC ASM) From 0a87dfeb4d471f954d439dddefa1f922332d1b26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Sat, 16 May 2020 16:09:54 +0200 Subject: [PATCH 240/420] Port changes to shared files Nullable.cs, Enum.cs (#36597) --- src/libraries/System.Private.CoreLib/src/System/Enum.cs | 1 - src/libraries/System.Private.CoreLib/src/System/Nullable.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Enum.cs b/src/libraries/System.Private.CoreLib/src/System/Enum.cs index 9d80c82f1a4fe..33e294a7862c1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Enum.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Enum.cs @@ -10,7 +10,6 @@ using Internal.Runtime.CompilerServices; #if CORERT -using CorElementType = System.Runtime.RuntimeImports.RhCorElementType; using RuntimeType = System.Type; using EnumInfo = Internal.Runtime.Augments.EnumInfo; #endif diff --git a/src/libraries/System.Private.CoreLib/src/System/Nullable.cs b/src/libraries/System.Private.CoreLib/src/System/Nullable.cs index 223a446ae8eb6..8a5416d728656 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Nullable.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Nullable.cs @@ -111,7 +111,7 @@ public static class Nullable { if (nullableEEType.IsNullable) { - return Internal.Reflection.Core.NonPortable.RuntimeTypeUnifier.GetRuntimeTypeForEEType(nullableEEType.NullableType); + return Type.GetTypeFromEETypePtr(nullableEEType.NullableType); } } return null; From 4e94c33f9fe41b9cbb2b3c0321a99a3abfceaeb8 Mon Sep 17 00:00:00 2001 From: Manish Godse <61718172+mangod9@users.noreply.github.com> Date: Sat, 16 May 2020 08:53:28 -0700 Subject: [PATCH 241/420] updating area owners (#36467) * updating area owners * adding cross-gen contrib as owner --- docs/area-owners.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/area-owners.md b/docs/area-owners.md index ca92b6fadc6c3..ed99186090f57 100644 --- a/docs/area-owners.md +++ b/docs/area-owners.md @@ -4,8 +4,8 @@ Below table shows the combined area owners on this repository: |-------------|------------------|------------------| | area-AssemblyLoader-coreclr | @jeffschwMSFT @vitek-karas | | | area-CodeGen-coreclr | @BruceForstall @dotnet/jit-contrib | | -| area-CrossGen/NGEN-coreclr | @fadimounir | | -| area-crossgen2-coreclr | @nattress @MichalStrehovsky @trylek @fadimounir | | +| area-CrossGen/NGEN-coreclr | @nattress | | +| area-crossgen2-coreclr | @nattress @trylek @dotnet/crossgen-contrib | | | area-DependencyModel | @eerhardt | Microsoft.Extensions.DependencyModel | | area-Diagnostics-coreclr | @tommcdon | | | area-ExceptionHandling-coreclr | @janvorli | | @@ -30,9 +30,9 @@ Below table shows the combined area owners on this repository: | area-TieredCompilation-coreclr | @kouvel | | | area-Tizen | @alpencolt @gbalykov | | | area-Tracing-coreclr | @sywhang @josalem | | -| area-TypeSystem-coreclr | @davidwrighton @MichalStrehovsky @fadimounir | | +| area-TypeSystem-coreclr | @davidwrighton @MichalStrehovsky @janvorli @mangod9 | | | area-UWP | @nattress | UWP-specific issues including Microsoft.NETCore.UniversalWindowsPlatform and Microsoft.Net.UWPCoreRuntimeSdk | -| area-VM-coreclr | @jeffschwMSFT | | +| area-VM-coreclr | @mangod9 | | | area-AssemblyLoader-mono | @CoffeeFlux | | | area-Codegen-meta-mono | @vargaz | | | area-Codegen-JIT-mono | @SamMonoRT | | From b01de3ef9f27c27d592c7e25d8cf964461db9d0c Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Sat, 16 May 2020 10:01:15 -0700 Subject: [PATCH 242/420] Fix StackTraceTests to work with JIT optimization (#36596) Disable optimization/inlining on methods that are expected to remain on the stack. --- .../System.Diagnostics.StackTrace/tests/StackTraceTests.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceTests.cs b/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceTests.cs index 900f6dbbb26d7..0a614bbe9e4d5 100644 --- a/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceTests.cs +++ b/src/libraries/System.Diagnostics.StackTrace/tests/StackTraceTests.cs @@ -313,7 +313,9 @@ public void ToString_NullFrame_ThrowsNullReferenceException() [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)] private static StackTrace Generic() => new StackTrace(); + [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)] private static StackTrace InvokeIgnoredMethod() => Ignored.Method(); + [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)] private static StackTrace InvokeIgnoredMethodWithException() => Ignored.MethodWithException(); [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)] @@ -335,6 +337,8 @@ private static Exception InvokeException() private class ClassWithConstructor { public StackTrace StackTrace { get; } + + [MethodImpl(MethodImplOptions.NoInlining)] public ClassWithConstructor() => StackTrace = new StackTrace(); } From 0aa560bba9c4f477867a9187370763ba198e860e Mon Sep 17 00:00:00 2001 From: Alexis Christoforides Date: Sat, 16 May 2020 13:38:41 -0400 Subject: [PATCH 243/420] [mono] Enable some System.Reflection.Emit tests (#35872) --- .../tests/ConstructorBuilder/ConstructorBuilderToString.cs | 1 - .../tests/ModuleBuilder/ModuleBuilderDefineEnum.cs | 1 - .../tests/ModuleBuilder/ModuleBuilderDefineType.cs | 1 - .../src/System/Reflection/Emit/ConstructorBuilder.Mono.cs | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libraries/System.Reflection.Emit/tests/ConstructorBuilder/ConstructorBuilderToString.cs b/src/libraries/System.Reflection.Emit/tests/ConstructorBuilder/ConstructorBuilderToString.cs index a00d42e12c25f..22ef09f782522 100644 --- a/src/libraries/System.Reflection.Emit/tests/ConstructorBuilder/ConstructorBuilderToString.cs +++ b/src/libraries/System.Reflection.Emit/tests/ConstructorBuilder/ConstructorBuilderToString.cs @@ -9,7 +9,6 @@ namespace System.Reflection.Emit.Tests public class ConstructorBuilderToString { [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] public void ToString_NullRequiredOptionalCustomModifiers() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Public); diff --git a/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineEnum.cs b/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineEnum.cs index 920dc871b5867..5e2b570c2bbc7 100644 --- a/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineEnum.cs +++ b/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineEnum.cs @@ -161,7 +161,6 @@ public void DefineEnum_VoidUnderlyingType_ThrowsArgumentException() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] public void DefineEnum_ByRefUnderlyingType_ThrowsCOMExceptionOnCreation() { ModuleBuilder module = Helpers.DynamicModule(); diff --git a/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineType.cs b/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineType.cs index fe52f133e5b5c..844dcb8d18119 100644 --- a/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineType.cs +++ b/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineType.cs @@ -33,7 +33,6 @@ public static IEnumerable TestData() } [Theory] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] [MemberData(nameof(TestData))] public void DefineType(string name, TypeAttributes attributes, Type parent, PackingSize packingSize, int typesize, Type[] implementedInterfaces) { diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.Mono.cs index 8f40153db0f3d..53faf4ad11b76 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.Mono.cs @@ -325,7 +325,7 @@ public override Module Module public override string ToString() { - return "ConstructorBuilder ['" + type.Name + "']"; + return "Name: " + Name; } internal void fixup() From ce1123f166944422b3d1171fed86a402149c17e8 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Sat, 16 May 2020 16:47:39 -0400 Subject: [PATCH 244/420] [interp] Don't share interp_in signatures for different valuetypes (#36520) We share interp_in wrappers for different types of signatures if the corresponding params are equivalent. This was added in https://github.com/mono/mono/commit/5cbe93884798684efbb81abd79e0e2a170544b75. This was reusing some sharing mechanism used by gsharedvt. Those wrappers are shared with regard to managed->managed transitions so it takes additional freedoms, converting all valuetypes to ValueTuples instances. These can end up being marshalled differently from the initial struct so we can't use this valuetype sharing infrastructure in the interp_in_wrappers which can operate on native structs. Fixes test_0_marshal_struct_delegate from pinvoke3.cs Co-authored-by: BrzVlad --- src/mono/mono/mini/mini-generic-sharing.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index 9bf9c2cf528e8..23a702868a81e 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -1335,8 +1335,10 @@ get_wrapper_shared_type (MonoType *t) /* Returns the intptr type for types that are passed in a single register */ static MonoType* -get_wrapper_shared_type_reg (MonoType *t) +get_wrapper_shared_type_reg (MonoType *t, gboolean pinvoke) { + MonoType *orig_t = t; + t = get_wrapper_shared_type (t); if (t->byref) return t; @@ -1364,6 +1366,15 @@ get_wrapper_shared_type_reg (MonoType *t) case MONO_TYPE_ARRAY: case MONO_TYPE_PTR: return mono_get_int_type (); + case MONO_TYPE_GENERICINST: + if (orig_t->type == MONO_TYPE_VALUETYPE && pinvoke) + /* + * These are translated to instances of Mono.ValueTuple, but generic types + * cannot be passed in pinvoke. + */ + return orig_t; + else + return t; default: return t; } @@ -1375,9 +1386,9 @@ mini_get_underlying_reg_signature (MonoMethodSignature *sig) MonoMethodSignature *res = mono_metadata_signature_dup (sig); int i; - res->ret = get_wrapper_shared_type_reg (sig->ret); + res->ret = get_wrapper_shared_type_reg (sig->ret, sig->pinvoke); for (i = 0; i < sig->param_count; ++i) - res->params [i] = get_wrapper_shared_type_reg (sig->params [i]); + res->params [i] = get_wrapper_shared_type_reg (sig->params [i], sig->pinvoke); res->generic_param_count = 0; res->is_inflated = 0; From 9c0ba553815d9355236f6226f45b100fc360c3d5 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sun, 17 May 2020 14:18:20 +0000 Subject: [PATCH 245/420] [master] Update dependencies from mono/linker Microsoft/vstest dotnet/xharness (#36598) * Update dependencies from https://github.com/mono/linker build 20200515.2 Microsoft.NET.ILLink.Tasks From Version 5.0.0-preview.3.20265.1 -> To Version 5.0.0-preview.3.20265.2 * Update dependencies from https://github.com/microsoft/vstest build 20200515-03 Microsoft.NET.Test.Sdk From Version 16.7.0-preview-20200515-01 -> To Version 16.7.0-preview-20200515-03 * Update dependencies from https://github.com/dotnet/xharness build 20200515.8 Microsoft.DotNet.XHarness.Tests.Runners From Version 1.0.0-prerelease.20265.1 -> To Version 1.0.0-prerelease.20265.8 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 54a3d03935e2a..a8e0f383c42a6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -82,9 +82,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization d0bb63d2ec7060714e63ee4082fac48f2e57f3e2 - + https://github.com/microsoft/vstest - cffe1860c1e821db78bf18ba0b829c73ae1e3944 + 59354e1f9c366b40d06ecf62372fc455d7f1ba18 https://github.com/dotnet/runtime-assets @@ -170,13 +170,13 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - d94ab76abdc1cb87349ed9fe4c2f0ed34cab5b1e + 06751af55b1e0b34b8081617728dace17543724b - + https://github.com/dotnet/xharness - 7c4562725b1c313e617393017f4903bde02d53e5 + 7f79598da0ffe62781affb5bab1fc477e479d767 diff --git a/eng/Versions.props b/eng/Versions.props index 8eb5078211a2c..302659f0ea787 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -108,8 +108,8 @@ 4.8.0 - 16.7.0-preview-20200515-01 - 1.0.0-prerelease.20265.1 + 16.7.0-preview-20200515-03 + 1.0.0-prerelease.20265.8 2.4.1 1.2.1 2.0.5 @@ -118,7 +118,7 @@ 3.1.0-preview-20200129.1 - 5.0.0-preview.3.20265.1 + 5.0.0-preview.3.20265.2 9.0.1-alpha.1.20262.1 9.0.1-alpha.1.20262.1 From 4224c4c16274b99791fbcc4e8fc987e64c4aaead Mon Sep 17 00:00:00 2001 From: Alfred Myers Date: Sun, 17 May 2020 12:37:47 -0300 Subject: [PATCH 246/420] Removed left-over NUnit references from comments (#36606) --- .../tests/Mono/KeyValueConfigurationElementTest.cs | 1 - .../tests/Functional/AlternateViewCollectionTest.cs | 2 +- .../System.Net.Mail/tests/Functional/AlternateViewTest.cs | 2 +- .../tests/Functional/AttachmentCollectionTest.cs | 2 +- .../System.Net.Mail/tests/Functional/AttachmentTest.cs | 2 +- .../tests/Functional/LinkedResourceCollectionTest.cs | 2 +- .../System.Net.Mail/tests/Functional/LinkedResourceTest.cs | 2 +- .../tests/Functional/MailAddressCollectionTest.cs | 2 +- .../System.Net.Mail/tests/Functional/MailMessageTest.cs | 2 +- .../System.Net.Mail/tests/Functional/SmtpClientTest.cs | 2 +- .../System.Net.Mail/tests/Functional/SmtpExceptionTest.cs | 2 +- .../System.Private.Xml.Linq/tests/Schema/ExtensionTests.cs | 2 +- src/libraries/System.Runtime/tests/System/Attributes.cs | 2 +- 13 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/Mono/KeyValueConfigurationElementTest.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/Mono/KeyValueConfigurationElementTest.cs index 703e3180c974e..7055f2f73c363 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/Mono/KeyValueConfigurationElementTest.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/Mono/KeyValueConfigurationElementTest.cs @@ -57,7 +57,6 @@ public ConfigurationPropertyCollection GetProperties() } [Fact] - // [NUnit.Framework.Category("NotWorking")] public void Properties() { Poker p = new Poker("name", "value"); diff --git a/src/libraries/System.Net.Mail/tests/Functional/AlternateViewCollectionTest.cs b/src/libraries/System.Net.Mail/tests/Functional/AlternateViewCollectionTest.cs index 6540a168b5b92..ed20522d401c0 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/AlternateViewCollectionTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/AlternateViewCollectionTest.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // See the LICENSE file in the project root for more information. // -// AlternateViewCollectionTest.cs - NUnit Test Cases for System.Net.MailAddress.AlternateViewCollection +// AlternateViewCollectionTest.cs - Unit Test Cases for System.Net.MailAddress.AlternateViewCollection // // Authors: // John Luke (john.luke@gmail.com) diff --git a/src/libraries/System.Net.Mail/tests/Functional/AlternateViewTest.cs b/src/libraries/System.Net.Mail/tests/Functional/AlternateViewTest.cs index 302dd3e156b82..59320cbb1d54e 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/AlternateViewTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/AlternateViewTest.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // See the LICENSE file in the project root for more information. // -// AlternateViewTest.cs - NUnit Test Cases for System.Net.MailAddress.AlternateView +// AlternateViewTest.cs - Unit Test Cases for System.Net.MailAddress.AlternateView // // Authors: // John Luke (john.luke@gmail.com) diff --git a/src/libraries/System.Net.Mail/tests/Functional/AttachmentCollectionTest.cs b/src/libraries/System.Net.Mail/tests/Functional/AttachmentCollectionTest.cs index 2237a9838d30c..68e4c1ef78f1c 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/AttachmentCollectionTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/AttachmentCollectionTest.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // See the LICENSE file in the project root for more information. // -// AttachmentCollectionTest.cs - NUnit Test Cases for System.Net.MailAddress.AttachmentCollection +// AttachmentCollectionTest.cs - Unit Test Cases for System.Net.MailAddress.AttachmentCollection // // Authors: // John Luke (john.luke@gmail.com) diff --git a/src/libraries/System.Net.Mail/tests/Functional/AttachmentTest.cs b/src/libraries/System.Net.Mail/tests/Functional/AttachmentTest.cs index a3264ea162a2d..9a0b9f41e966a 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/AttachmentTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/AttachmentTest.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // See the LICENSE file in the project root for more information. // -// AttachmentTest.cs - NUnit Test Cases for System.Net.MailAddress.Attachment +// AttachmentTest.cs - Unit Test Cases for System.Net.MailAddress.Attachment // // Authors: // John Luke (john.luke@gmail.com) diff --git a/src/libraries/System.Net.Mail/tests/Functional/LinkedResourceCollectionTest.cs b/src/libraries/System.Net.Mail/tests/Functional/LinkedResourceCollectionTest.cs index 8bed530fbbc9d..68ef77002980e 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/LinkedResourceCollectionTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/LinkedResourceCollectionTest.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // See the LICENSE file in the project root for more information. // -// LinkedResourceCollectionTest.cs - NUnit Test Cases for System.Net.MailAddress.LinkedResourceCollection +// LinkedResourceCollectionTest.cs - Unit Test Cases for System.Net.MailAddress.LinkedResourceCollection // // Authors: // John Luke (john.luke@gmail.com) diff --git a/src/libraries/System.Net.Mail/tests/Functional/LinkedResourceTest.cs b/src/libraries/System.Net.Mail/tests/Functional/LinkedResourceTest.cs index c64a92ed08efd..00b6a62f64d0b 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/LinkedResourceTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/LinkedResourceTest.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // See the LICENSE file in the project root for more information. // -// LinkedResourceTest.cs - NUnit Test Cases for System.Net.MailAddress.LinkedResource +// LinkedResourceTest.cs - Unit Test Cases for System.Net.MailAddress.LinkedResource // // Authors: // John Luke (john.luke@gmail.com) diff --git a/src/libraries/System.Net.Mail/tests/Functional/MailAddressCollectionTest.cs b/src/libraries/System.Net.Mail/tests/Functional/MailAddressCollectionTest.cs index 8d1a2156b7ac4..5aa41b4a26b73 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/MailAddressCollectionTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/MailAddressCollectionTest.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // See the LICENSE file in the project root for more information. // -// MailAddressCollectionTest.cs - NUnit Test Cases for System.Net.MailAddress.MailAddressCollection +// MailAddressCollectionTest.cs - Unit Test Cases for System.Net.MailAddress.MailAddressCollection // // Authors: // John Luke (john.luke@gmail.com) diff --git a/src/libraries/System.Net.Mail/tests/Functional/MailMessageTest.cs b/src/libraries/System.Net.Mail/tests/Functional/MailMessageTest.cs index f8be941b6c750..bdd41aa31cb60 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/MailMessageTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/MailMessageTest.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // See the LICENSE file in the project root for more information. // -// MailMessageTest.cs - NUnit Test Cases for System.Net.MailAddress.MailMessage +// MailMessageTest.cs - Unit Test Cases for System.Net.MailAddress.MailMessage // // Authors: // John Luke (john.luke@gmail.com) diff --git a/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs b/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs index 7e1c86d2fadef..ddcb811b8b5c6 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // See the LICENSE file in the project root for more information. // -// SmtpClientTest.cs - NUnit Test Cases for System.Net.Mail.SmtpClient +// SmtpClientTest.cs - Unit Test Cases for System.Net.Mail.SmtpClient // // Authors: // John Luke (john.luke@gmail.com) diff --git a/src/libraries/System.Net.Mail/tests/Functional/SmtpExceptionTest.cs b/src/libraries/System.Net.Mail/tests/Functional/SmtpExceptionTest.cs index 2846746446e71..443a32ebd4d66 100644 --- a/src/libraries/System.Net.Mail/tests/Functional/SmtpExceptionTest.cs +++ b/src/libraries/System.Net.Mail/tests/Functional/SmtpExceptionTest.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // See the LICENSE file in the project root for more information. // -// SmtpExceptionTest.cs - NUnit Test Cases for System.Net.Mail.SmtpException +// SmtpExceptionTest.cs - Unit Test Cases for System.Net.Mail.SmtpException // // Authors: // Gert Driesen (drieseng@users.sourceforge.net) diff --git a/src/libraries/System.Private.Xml.Linq/tests/Schema/ExtensionTests.cs b/src/libraries/System.Private.Xml.Linq/tests/Schema/ExtensionTests.cs index a5d88ddcf1f32..2005c66ae2acb 100644 --- a/src/libraries/System.Private.Xml.Linq/tests/Schema/ExtensionTests.cs +++ b/src/libraries/System.Private.Xml.Linq/tests/Schema/ExtensionTests.cs @@ -2,7 +2,7 @@ // See the LICENSE file in the project root for more information. // -// ExtensionsTest.cs - NUnit Test Cases for Extensions.cs class under +// ExtensionsTest.cs - Unit Test Cases for Extensions.cs class under // System.Xml.Schema namespace found in System.Xml.Linq assembly // (System.Xml.Linq.dll) // diff --git a/src/libraries/System.Runtime/tests/System/Attributes.cs b/src/libraries/System.Runtime/tests/System/Attributes.cs index 92926dab8c377..f30464ca65ae6 100644 --- a/src/libraries/System.Runtime/tests/System/Attributes.cs +++ b/src/libraries/System.Runtime/tests/System/Attributes.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. // -// AttributeTest.cs - NUnit Test Cases for the System.Attribute class +// AttributeTest.cs - Unit Test Cases for the System.Attribute class // // Authors: // Duco Fijma (duco@lorentz.xs4all.nl) From 7d6a355059bf46994c921bdc1dbcfb162cddc713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Sun, 17 May 2020 21:35:32 +0200 Subject: [PATCH 247/420] Sync crossgen2 shared files (#36610) --- .../src/tools/Common/Compiler/HardwareIntrinsicHelpers.cs | 2 +- .../tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs | 7 +++++++ .../src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/tools/Common/Compiler/HardwareIntrinsicHelpers.cs b/src/coreclr/src/tools/Common/Compiler/HardwareIntrinsicHelpers.cs index fbf7b61a618e0..1481a74e77b90 100644 --- a/src/coreclr/src/tools/Common/Compiler/HardwareIntrinsicHelpers.cs +++ b/src/coreclr/src/tools/Common/Compiler/HardwareIntrinsicHelpers.cs @@ -11,7 +11,7 @@ namespace ILCompiler { - public static class HardwareIntrinsicHelpers + public static partial class HardwareIntrinsicHelpers { /// /// Gets a value indicating whether this is a hardware intrinsic on the platform that we're compiling for. diff --git a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs index 8635957e67085..ac307a8b2c74f 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs @@ -158,6 +158,9 @@ public static partial class MarshalHelpers case MarshallerKind.AsAnyW: return context.GetWellKnownType(WellKnownType.IntPtr); + case MarshallerKind.ComInterface: + return context.GetWellKnownType(WellKnownType.IntPtr); + case MarshallerKind.Unknown: default: throw new NotSupportedException(); @@ -563,6 +566,10 @@ public static partial class MarshalHelpers else return MarshallerKind.Invalid; } + else if (type.IsInterface) + { + return MarshallerKind.ComInterface; + } else return MarshallerKind.Invalid; } diff --git a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs index 17931e448fcff..50f9254171ea9 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs @@ -50,6 +50,7 @@ enum MarshallerKind LayoutClassPtr, AsAnyA, AsAnyW, + ComInterface, Invalid } public enum MarshalDirection From 4700cf4e755c2cffefc3d993d647fc75e76c3e4e Mon Sep 17 00:00:00 2001 From: Nick Craver Date: Sun, 17 May 2020 19:27:13 -0400 Subject: [PATCH 248/420] CMake: Point download URLs directly to https:// (#36615) --- docs/workflow/requirements/windows-requirements.md | 2 +- eng/native/build-commons.sh | 2 +- src/coreclr/src/pal/tools/set-cmake-path.ps1 | 4 ++-- src/installer/corehost/Windows/probe-win.ps1 | 2 +- src/libraries/Native/Windows/probe-win.ps1 | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/workflow/requirements/windows-requirements.md b/docs/workflow/requirements/windows-requirements.md index 0035887b2d6cb..d623f0bcaa07e 100644 --- a/docs/workflow/requirements/windows-requirements.md +++ b/docs/workflow/requirements/windows-requirements.md @@ -38,7 +38,7 @@ The dotnet/runtime repository requires at least Visual Studio 2019 16.6 Preview ## CMake -- Install [CMake](http://www.cmake.org/download) for Windows. +- Install [CMake](https://cmake.org/download) for Windows. - Add its location (e.g. C:\Program Files (x86)\CMake\bin) to the PATH environment variable. The installation script has a check box to do this, but you can do it yourself after the fact following the instructions at [Adding to the Default PATH variable](#adding-to-the-default-path-variable). diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh index 309244b9671cc..c231a01d42957 100755 --- a/eng/native/build-commons.sh +++ b/eng/native/build-commons.sh @@ -56,7 +56,7 @@ check_prereqs() local cmake_version="$(cmake --version | awk '/^cmake.* version [0-9]+\.[0-9]+\.[0-9]+$/ {print $3}')" if [[ "$(version "$cmake_version")" -lt "$(version 3.14.2)" ]]; then - echo "Please install CMake 3.14.2 or newer from http://www.cmake.org/download/ or https://apt.kitware.com and ensure it is on your path."; exit 1; + echo "Please install CMake 3.14.2 or newer from https://cmake.org/download/ or https://apt.kitware.com and ensure it is on your path."; exit 1; fi if [[ "$__HostOS" == "OSX" ]]; then diff --git a/src/coreclr/src/pal/tools/set-cmake-path.ps1 b/src/coreclr/src/pal/tools/set-cmake-path.ps1 index f367ad127c3ff..689c8c5596a55 100644 --- a/src/coreclr/src/pal/tools/set-cmake-path.ps1 +++ b/src/coreclr/src/pal/tools/set-cmake-path.ps1 @@ -33,7 +33,7 @@ function GetCMakeInfo($regKey) function LocateCMake { - $errorMsg = "CMake is a pre-requisite to build this repository but it was not found on the path. Please install CMake from http://www.cmake.org/download/ and ensure it is on your path." + $errorMsg = "CMake is a pre-requisite to build this repository but it was not found on the path. Please install CMake from https://cmake.org/download/ and ensure it is on your path." $inPathPath = (get-command cmake.exe -ErrorAction SilentlyContinue) if ($inPathPath -ne $null) { # Resolve the first version of CMake if multiple commands are found @@ -64,7 +64,7 @@ try { $version = [Version]$(& $cmakePath --version | Select-String -Pattern '\d+\.\d+\.\d+' | %{$_.Matches.Value}) if ($version -lt [Version]"3.14.0") { - Throw "This repository requires CMake 3.14. The newest version of CMake installed is $version. Please install CMake 3.14 or newer from http://www.cmake.org/download/ and ensure it is on your path." + Throw "This repository requires CMake 3.14. The newest version of CMake installed is $version. Please install CMake 3.14 or newer from https://cmake.org/download/ and ensure it is on your path." } [System.Console]::WriteLine("set CMakePath=" + $cmakePath) diff --git a/src/installer/corehost/Windows/probe-win.ps1 b/src/installer/corehost/Windows/probe-win.ps1 index 353db37bfc63b..8641741c6c79e 100644 --- a/src/installer/corehost/Windows/probe-win.ps1 +++ b/src/installer/corehost/Windows/probe-win.ps1 @@ -34,7 +34,7 @@ function GetCMakeInfo($regKey) function LocateCMake { - $errorMsg = "CMake is a pre-requisite to build this repository but it was not found on the path. Please install CMake from http://www.cmake.org/download/ and ensure it is on your path." + $errorMsg = "CMake is a pre-requisite to build this repository but it was not found on the path. Please install CMake from https://cmake.org/download/ and ensure it is on your path." $inPathPath = (get-command cmake.exe -ErrorAction SilentlyContinue) if ($inPathPath -ne $null) { # Resolve the first version of CMake if multiple commands are found diff --git a/src/libraries/Native/Windows/probe-win.ps1 b/src/libraries/Native/Windows/probe-win.ps1 index 353db37bfc63b..8641741c6c79e 100644 --- a/src/libraries/Native/Windows/probe-win.ps1 +++ b/src/libraries/Native/Windows/probe-win.ps1 @@ -34,7 +34,7 @@ function GetCMakeInfo($regKey) function LocateCMake { - $errorMsg = "CMake is a pre-requisite to build this repository but it was not found on the path. Please install CMake from http://www.cmake.org/download/ and ensure it is on your path." + $errorMsg = "CMake is a pre-requisite to build this repository but it was not found on the path. Please install CMake from https://cmake.org/download/ and ensure it is on your path." $inPathPath = (get-command cmake.exe -ErrorAction SilentlyContinue) if ($inPathPath -ne $null) { # Resolve the first version of CMake if multiple commands are found From bacef403fbfce0d9e3d49368bfd36dec6dea01fc Mon Sep 17 00:00:00 2001 From: Nathan Ricci Date: Sun, 17 May 2020 19:51:37 -0400 Subject: [PATCH 249/420] Naricc/ci interpreter arm64 (#36258) Change mono interpreter runs to be a scenario instead of a seperate leg. Also enable arm64 interpreter runs, and add test exclusions. --- .../templates/runtimes/run-test-job.yml | 9 +- eng/pipelines/runtime.yml | 23 - src/coreclr/tests/helixpublishwitharcade.proj | 3 - src/coreclr/tests/issues.targets | 578 +++++++++++++++++- src/coreclr/tests/testenvironment.proj | 2 + 5 files changed, 583 insertions(+), 32 deletions(-) diff --git a/eng/pipelines/common/templates/runtimes/run-test-job.yml b/eng/pipelines/common/templates/runtimes/run-test-job.yml index cdc2b96129429..a57e18183ea64 100644 --- a/eng/pipelines/common/templates/runtimes/run-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/run-test-job.yml @@ -107,10 +107,6 @@ jobs: - name: crossgenArg value: 'composite' - - ${{ if eq(parameters.runtimeMode, 'interpreter') }}: - - name: RuntimeModeDisplayName - value: 'Interpreter' - # Set job timeouts # # "timeoutPerTestCollectionInMinutes" is the time needed for the "biggest" xUnit test collection to complete. @@ -335,7 +331,10 @@ jobs: ${{ if in(parameters.testGroup, 'innerloop', 'outerloop') }}: scenarios: - normal - - no_tiered_compilation + - ${{ if eq(parameters.runtimeFlavor, 'coreclr') }}: + - no_tiered_compilation + - ${{ if eq(parameters.runtimeFlavor, 'mono') }}: + - interpreter ${{ if in(parameters.testGroup, 'jitstress') }}: scenarios: - jitminopts diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 0a9e05f94a6cb..2ee5255fee8c1 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -729,29 +729,6 @@ jobs: eq(dependencies.checkout.outputs['SetPathVars_runtimetests.containsChange'], true), eq(variables['isFullMatrix'], true)) -# -# Mono CoreCLR runtime Test executions using live libraries -# Only when Mono is changed -- template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml - buildConfig: release - runtimeFlavor: mono - platforms: - - OSX_x64 - helixQueueGroup: pr - helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml - jobParameters: - testGroup: innerloop - liveLibrariesBuildConfig: ${{ variables.debugOnPrReleaseOnRolling }} - liveRuntimeBuildConfig: release - runtimeMode: 'interpreter' - runtimeModeDisplayName: 'Interpreter' - condition: >- - or( - eq(dependencies.checkout.outputs['SetPathVars_mono.containsChange'], true), - eq(variables['isFullMatrix'], true)) - # # Libraries Release Test Execution against a release mono runtime. # Only when libraries or mono changed diff --git a/src/coreclr/tests/helixpublishwitharcade.proj b/src/coreclr/tests/helixpublishwitharcade.proj index 6d46021c28e83..561fc7e1af721 100644 --- a/src/coreclr/tests/helixpublishwitharcade.proj +++ b/src/coreclr/tests/helixpublishwitharcade.proj @@ -197,7 +197,6 @@ R2R-CG2 $(TestRunNamePrefix)$(TargetOS) $(TargetArchitecture) $(Configuration) @ $(TestRunNamePrefix)$(TargetOS) $(TargetArchitecture) $(Configuration) $(Scenario) @ - $(TestRunNamePrefix) Interpreter $([System.TimeSpan]::FromMinutes($(TimeoutPerTestInMinutes)).TotalMilliseconds) true <_XUnitParallelMode>collections @@ -224,7 +223,6 @@ - @@ -244,7 +242,6 @@ - diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index 16851f03a2797..a29dda03c8ec6 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -1558,7 +1558,6 @@ needs triage - needs triage needs triage @@ -1871,6 +1870,577 @@ needs triage + + + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + + needs triage + + @@ -2057,5 +2627,11 @@ needs triage + + + + needs triage + + diff --git a/src/coreclr/tests/testenvironment.proj b/src/coreclr/tests/testenvironment.proj index caed6ae7e1ee8..6bb7dda56ddbb 100644 --- a/src/coreclr/tests/testenvironment.proj +++ b/src/coreclr/tests/testenvironment.proj @@ -174,11 +174,13 @@ <_TestEnvFileLine Include="@(_COMPlusVariable->'set %(Identity)=%(Value)')" /> + <_TestEnvFileLine Include="set MONO_ENV_OPTIONS=--interpreter" Condition="'$(Scenario)' == 'interpreter'" /> <_TestEnvFileLine Include="#!/usr/bin/env bash" /> <_TestEnvFileLine Include="@(_COMPlusVariable->'export %(Identity)=%(Value)')" /> + <_TestEnvFileLine Include="export MONO_ENV_OPTIONS=--interpreter" Condition="'$(Scenario)' == 'interpreter'" /> From 0541e4bdaa3c4b979088adc637ffc9f39b903bf3 Mon Sep 17 00:00:00 2001 From: Swaroop Sridhar Date: Mon, 20 Apr 2020 22:04:13 -0700 Subject: [PATCH 250/420] Single-File: Run from Bundle This change implements: * Runtime changes necessary to load assemblies directly from the bundle: * Design notes about [Load from Bundle](https://github.com/dotnet/designs/blob/master/accepted/2020/single-file/design.md#peimage-loader) * Most of these changes are directly from https://github.com/dotnet/coreclr/pull/26504 and https://github.com/dotnet/coreclr/pull/26904 * Hostpolicy change to not add bundled assemblies to TPA list: * Design notes about [Dependency Resolution](https://github.com/dotnet/designs/blob/master/accepted/2020/single-file/design.md#dependency-resolution) * TBD (separately) items: Fix for hammer servicing #36031 Fixes #32822 --- src/coreclr/src/binder/assemblybinder.cpp | 114 ++++++++++++++---- .../src/binder/coreclrbindercommon.cpp | 1 + src/coreclr/src/binder/inc/assembly.hpp | 21 ++-- src/coreclr/src/binder/inc/assemblybinder.hpp | 4 +- .../src/dlls/mscoree/unixinterface.cpp | 22 +++- src/coreclr/src/inc/bundle.h | 62 ++++++++++ src/coreclr/src/pal/inc/pal.h | 6 +- src/coreclr/src/pal/src/include/pal/map.hpp | 3 +- src/coreclr/src/pal/src/include/pal/module.h | 3 +- src/coreclr/src/pal/src/loader/module.cpp | 12 +- src/coreclr/src/pal/src/map/map.cpp | 25 ++-- src/coreclr/src/vm/CMakeLists.txt | 1 + src/coreclr/src/vm/appdomain.cpp | 10 +- src/coreclr/src/vm/appdomain.hpp | 1 + src/coreclr/src/vm/assemblynative.cpp | 8 +- src/coreclr/src/vm/bundle.cpp | 93 ++++++++++++++ src/coreclr/src/vm/coreassemblyspec.cpp | 16 +-- src/coreclr/src/vm/crossgen/CMakeLists.txt | 1 + src/coreclr/src/vm/pefile.cpp | 7 +- src/coreclr/src/vm/peimage.cpp | 47 ++++---- src/coreclr/src/vm/peimage.h | 15 ++- src/coreclr/src/vm/peimage.inl | 39 +++++- src/coreclr/src/vm/peimagelayout.cpp | 64 +++++++--- src/coreclr/src/vm/peimagelayout.h | 1 + .../corehost/cli/bundle/file_entry.cpp | 3 +- src/installer/corehost/cli/bundle/runner.cpp | 9 +- src/installer/corehost/cli/bundle/runner.h | 15 ++- src/installer/corehost/cli/deps_entry.cpp | 18 ++- src/installer/corehost/cli/deps_entry.h | 4 +- .../corehost/cli/hostpolicy/deps_resolver.cpp | 59 ++++++--- .../corehost/cli/hostpolicy/deps_resolver.h | 3 +- .../cli/hostpolicy/hostpolicy_context.cpp | 23 ++-- .../BundleExtractToSpecificPath.cs | 3 +- .../BundledAppWithSubDirs.cs | 6 +- .../Helpers/BundleHelper.cs | 11 +- .../BundleAndRun.cs | 17 +-- .../BundleLegacy.cs | 4 +- 37 files changed, 558 insertions(+), 193 deletions(-) create mode 100644 src/coreclr/src/inc/bundle.h create mode 100644 src/coreclr/src/vm/bundle.cpp diff --git a/src/coreclr/src/binder/assemblybinder.cpp b/src/coreclr/src/binder/assemblybinder.cpp index 784b91260ee75..18d66a8b198f5 100644 --- a/src/coreclr/src/binder/assemblybinder.cpp +++ b/src/coreclr/src/binder/assemblybinder.cpp @@ -14,7 +14,6 @@ #include "assemblybinder.hpp" #include "assemblyname.hpp" - #include "assembly.hpp" #include "applicationcontext.hpp" #include "bindertracing.h" @@ -380,23 +379,29 @@ namespace BINDER_SPACE _ASSERTE(ppSystemAssembly != NULL); - StackSString sCoreLibDir(systemDirectory); ReleaseHolder pSystemAssembly; + StackSString sCoreLibDir(systemDirectory); if (!sCoreLibDir.EndsWith(DIRECTORY_SEPARATOR_CHAR_W)) { sCoreLibDir.Append(DIRECTORY_SEPARATOR_CHAR_W); } - StackSString sCoreLib; + StackSString sCoreLib(sCoreLibDir); + StackSString coreLibName(CoreLibName_IL_W); + sCoreLib.Append(coreLibName); // At run-time, System.Private.CoreLib.dll is expected to be the NI image. - sCoreLib = sCoreLibDir; - sCoreLib.Append(CoreLibName_IL_W); + // System.Private.CoreLib.dll is expected to be found at one of the following locations: + // * Non-single-file app: In systemDirectory, beside coreclr.dll + // * Framework-dependent single-file app: In system directory, beside coreclr.dll + // * Self-contained single-file app: Within the single-file bundle. IF_FAIL_GO(AssemblyBinder::GetAssembly(sCoreLib, - TRUE /* fIsInGAC */, - fBindToNativeImage, - &pSystemAssembly)); + TRUE /* fIsInGAC */, + fBindToNativeImage, + &pSystemAssembly, + NULL /* szMDAssemblyPath */, + Bundle::ProbeAppBundle(coreLibName, /*pathIsBundleRelative */ true))); *ppSystemAssembly = pSystemAssembly.Extract(); @@ -418,25 +423,32 @@ namespace BINDER_SPACE _ASSERTE(ppSystemAssembly != NULL); - StackSString sMscorlibSatellite(systemDirectory); - ReleaseHolder pSystemAssembly; + // Satellite assembly's relative path + StackSString relativePath; // append culture name if (!cultureName.IsEmpty()) { - CombinePath(sMscorlibSatellite, cultureName, sMscorlibSatellite); + CombinePath(relativePath, cultureName, relativePath); } // append satellite assembly's simple name - CombinePath(sMscorlibSatellite, simpleName, sMscorlibSatellite); + CombinePath(relativePath, simpleName, relativePath); // append extension - sMscorlibSatellite.Append(W(".dll")); + relativePath.Append(W(".dll")); + + // Satellite assembly's absolute path + StackSString sMscorlibSatellite(systemDirectory); + CombinePath(sMscorlibSatellite, relativePath, sMscorlibSatellite); + ReleaseHolder pSystemAssembly; IF_FAIL_GO(AssemblyBinder::GetAssembly(sMscorlibSatellite, TRUE /* fIsInGAC */, FALSE /* fExplicitBindToNativeImage */, - &pSystemAssembly)); + &pSystemAssembly, + NULL /* szMDAssemblyPath */, + Bundle::ProbeAppBundle(relativePath, /*pathIsBundleRelative */ true))); *ppSystemAssembly = pSystemAssembly.Extract(); @@ -553,7 +565,9 @@ namespace BINDER_SPACE // specified. Generally only NGEN PDB generation has // this TRUE. fExplicitBindToNativeImage, - &pAssembly)); + &pAssembly, + NULL /* szMDAssemblyPath */, + Bundle::ProbeAppBundle(assemblyPath))); AssemblyName *pAssemblyName; pAssemblyName = pAssembly->GetAssemblyName(); @@ -850,6 +864,13 @@ namespace BINDER_SPACE /* * BindByTpaList is the entry-point for the custom binding algorithm in CoreCLR. + * + * The search for assemblies will proceed in the following order: + * + * If this application is a single-file bundle, the meta-data contained in the bundle + * will be probed to find the requested assembly. If the assembly is not found, + * The list of platform assemblies (TPAs) are considered next. + * * Platform assemblies are specified as a list of files. This list is the only set of * assemblies that we will load as platform. They can be specified as IL or NIs. * @@ -903,11 +924,53 @@ namespace BINDER_SPACE } else { + ReleaseHolder pTPAAssembly; + SString& simpleName = pRequestedAssemblyName->GetSimpleName(); + + // Is assembly in the bundle? + // Single-file bundle contents take precedence over TPA. + // The list of bundled assemblies is contained in the bundle manifest, and NOT in the TPA. + // Therefore the bundle is first probed using the assembly's simple name. + // If found, the assembly is loaded from the bundle. + if (Bundle::AppIsBundle()) + { + SString candidates[] = { W(".dll"), W(".ni.dll") }; + + // Loop through the binding paths looking for a matching assembly + for (int i = 0; i < 2; i++) + { + SString assemblyFileName(simpleName); + assemblyFileName.Append(candidates[i]); + + SString assemblyFilePath(Bundle::AppBundle->BasePath()); + assemblyFilePath.Append(assemblyFileName); + + hr = GetAssembly(assemblyFilePath, + TRUE, // fIsInGAC + FALSE, // fExplicitBindToNativeImage + &pTPAAssembly, + NULL, // szMDAssemblyPath + Bundle::ProbeAppBundle(assemblyFileName, /* pathIsBundleRelative */ true)); + + if (hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) + { + // Any other error is fatal + IF_FAIL_GO(hr); + + if (TestCandidateRefMatchesDef(pRequestedAssemblyName, pTPAAssembly->GetAssemblyName(), true /*tpaListAssembly*/)) + { + // We have found the requested assembly match in the bundle with validation of the full-qualified name. + // Bind to it. + pBindResult->SetResult(pTPAAssembly); + GO_WITH_HRESULT(S_OK); + } + } + } + } + // Is assembly on TPA list? - SString &simpleName = pRequestedAssemblyName->GetSimpleName(); SimpleNameToFileNameMap * tpaMap = pApplicationContext->GetTpaList(); const SimpleNameToFileNameMapEntry *pTpaEntry = tpaMap->LookupPtr(simpleName.GetUnicode()); - ReleaseHolder pTPAAssembly; if (pTpaEntry != nullptr) { if (pTpaEntry->m_wszNIFileName != nullptr) @@ -1020,20 +1083,21 @@ namespace BINDER_SPACE } /* static */ - HRESULT AssemblyBinder::GetAssembly(SString &assemblyPath, - BOOL fIsInGAC, + HRESULT AssemblyBinder::GetAssembly(SString &assemblyPath, + BOOL fIsInGAC, // When binding to the native image, should we // assume assemblyPath explicitly specifies that // NI? (If not, infer the path to the NI // implicitly.) - BOOL fExplicitBindToNativeImage, + BOOL fExplicitBindToNativeImage, - Assembly **ppAssembly, + Assembly **ppAssembly, // If assemblyPath refers to a native image without metadata, // szMDAssemblyPath gives the alternative file to get metadata. - LPCTSTR szMDAssemblyPath) + LPCTSTR szMDAssemblyPath, + BundleFileLocation bundleFileLocation) { HRESULT hr = S_OK; @@ -1053,7 +1117,7 @@ namespace BINDER_SPACE { LPCTSTR szAssemblyPath = const_cast(assemblyPath.GetUnicode()); - hr = BinderAcquirePEImage(szAssemblyPath, &pPEImage, &pNativePEImage, fExplicitBindToNativeImage); + hr = BinderAcquirePEImage(szAssemblyPath, &pPEImage, &pNativePEImage, fExplicitBindToNativeImage, bundleFileLocation); IF_FAIL_GO(hr); // If we found a native image, it might be an MSIL assembly masquerading as an native image @@ -1068,7 +1132,7 @@ namespace BINDER_SPACE BinderReleasePEImage(pPEImage); BinderReleasePEImage(pNativePEImage); - hr = BinderAcquirePEImage(szAssemblyPath, &pPEImage, &pNativePEImage, false); + hr = BinderAcquirePEImage(szAssemblyPath, &pPEImage, &pNativePEImage, false, bundleFileLocation); IF_FAIL_GO(hr); } } @@ -1094,7 +1158,7 @@ namespace BINDER_SPACE } else { - hr = BinderAcquirePEImage(szMDAssemblyPath, &pPEImage, NULL, FALSE); + hr = BinderAcquirePEImage(szMDAssemblyPath, &pPEImage, NULL, FALSE, bundleFileLocation); IF_FAIL_GO(hr); hr = BinderAcquireImport(pPEImage, &pIMetaDataAssemblyImport, dwPAFlags, FALSE); diff --git a/src/coreclr/src/binder/coreclrbindercommon.cpp b/src/coreclr/src/binder/coreclrbindercommon.cpp index afd64cfc4dc58..e415b9067bb34 100644 --- a/src/coreclr/src/binder/coreclrbindercommon.cpp +++ b/src/coreclr/src/binder/coreclrbindercommon.cpp @@ -7,6 +7,7 @@ #include "assemblybinder.hpp" #include "coreclrbindercommon.h" #include "clrprivbindercoreclr.h" +#include "bundle.h" using namespace BINDER_SPACE; diff --git a/src/coreclr/src/binder/inc/assembly.hpp b/src/coreclr/src/binder/inc/assembly.hpp index 0d5500afb8203..f42cee4e62268 100644 --- a/src/coreclr/src/binder/inc/assembly.hpp +++ b/src/coreclr/src/binder/inc/assembly.hpp @@ -27,15 +27,18 @@ #include "clrprivbinderassemblyloadcontext.h" #endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) -STDAPI BinderAcquirePEImage(LPCTSTR szAssemblyPath, - PEImage **ppPEImage, - PEImage **ppNativeImage, - BOOL fExplicitBindToNativeImage); - -STDAPI BinderAcquireImport(PEImage *pPEImage, - IMDInternalImport **pIMetaDataAssemblyImport, - DWORD *pdwPAFlags, - BOOL bNativeImage); +#include "bundle.h" + +STDAPI BinderAcquirePEImage(LPCTSTR szAssemblyPath, + PEImage **ppPEImage, + PEImage **ppNativeImage, + BOOL fExplicitBindToNativeImage, + BundleFileLocation bundleFileLocation); + +STDAPI BinderAcquireImport(PEImage *pPEImage, + IMDInternalImport **pIMetaDataAssemblyImport, + DWORD *pdwPAFlags, + BOOL bNativeImage); STDAPI BinderHasNativeHeader(PEImage *pPEImage, BOOL *result); diff --git a/src/coreclr/src/binder/inc/assemblybinder.hpp b/src/coreclr/src/binder/inc/assemblybinder.hpp index 1332b671edc2d..5246676b1a47f 100644 --- a/src/coreclr/src/binder/inc/assemblybinder.hpp +++ b/src/coreclr/src/binder/inc/assemblybinder.hpp @@ -18,6 +18,7 @@ #include "bindertypes.hpp" #include "bindresult.hpp" #include "coreclrbindercommon.h" +#include "bundle.h" class CLRPrivBinderAssemblyLoadContext; class CLRPrivBinderCoreCLR; @@ -54,7 +55,8 @@ namespace BINDER_SPACE /* in */ BOOL fIsInGAC, /* in */ BOOL fExplicitBindToNativeImage, /* out */ Assembly **ppAssembly, - /* in */ LPCTSTR szMDAssemblyPath = NULL); + /* in */ LPCTSTR szMDAssemblyPath = NULL, + /* in */ BundleFileLocation bundleFileLocation = BundleFileLocation::Invalid()); #if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) static HRESULT BindUsingHostAssemblyResolver (/* in */ INT_PTR pManagedAssemblyLoadContextToBindWithin, diff --git a/src/coreclr/src/dlls/mscoree/unixinterface.cpp b/src/coreclr/src/dlls/mscoree/unixinterface.cpp index f54e7c7be0604..ca4d452a8edae 100644 --- a/src/coreclr/src/dlls/mscoree/unixinterface.cpp +++ b/src/coreclr/src/dlls/mscoree/unixinterface.cpp @@ -18,6 +18,7 @@ #ifdef FEATURE_GDBJIT #include "../../vm/gdbjithelpers.h" #endif // FEATURE_GDBJIT +#include "bundle.h" #define ASSERTE_ALL_BUILDS(expr) _ASSERTE_ALL_BUILDS(__FILE__, (expr)) @@ -112,7 +113,8 @@ static void ConvertConfigPropertiesToUnicode( const char** propertyValues, int propertyCount, LPCWSTR** propertyKeysWRef, - LPCWSTR** propertyValuesWRef) + LPCWSTR** propertyValuesWRef, + BundleProbe** bundleProbe) { LPCWSTR* propertyKeysW = new (nothrow) LPCWSTR[propertyCount]; ASSERTE_ALL_BUILDS(propertyKeysW != nullptr); @@ -124,6 +126,13 @@ static void ConvertConfigPropertiesToUnicode( { propertyKeysW[propertyIndex] = StringToUnicode(propertyKeys[propertyIndex]); propertyValuesW[propertyIndex] = StringToUnicode(propertyValues[propertyIndex]); + + if (strcmp(propertyKeys[propertyIndex], "BUNDLE_PROBE") == 0) + { + // If this application is a single-file bundle, the bundle-probe callback + // is passed in as the value of "BUNDLE_PROBE" property (encoded as a string). + *bundleProbe = (BundleProbe*)_wcstoui64(propertyValuesW[propertyIndex], nullptr, 0); + } } *propertyKeysWRef = propertyKeysW; @@ -183,12 +192,21 @@ int coreclr_initialize( LPCWSTR* propertyKeysW; LPCWSTR* propertyValuesW; + BundleProbe* bundleProbe = nullptr; + ConvertConfigPropertiesToUnicode( propertyKeys, propertyValues, propertyCount, &propertyKeysW, - &propertyValuesW); + &propertyValuesW, + &bundleProbe); + + if (bundleProbe != nullptr) + { + static Bundle bundle(StringToUnicode(exePath), bundleProbe); + Bundle::AppBundle = &bundle; + } // This will take ownership of propertyKeysWTemp and propertyValuesWTemp Configuration::InitializeConfigurationKnobs(propertyCount, propertyKeysW, propertyValuesW); diff --git a/src/coreclr/src/inc/bundle.h b/src/coreclr/src/inc/bundle.h new file mode 100644 index 0000000000000..00fc186ab9ff0 --- /dev/null +++ b/src/coreclr/src/inc/bundle.h @@ -0,0 +1,62 @@ +// 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. + +/***************************************************************************** + ** ** + ** bundle.h - Information about applications bundled as a single-file ** + ** ** + *****************************************************************************/ + +#ifndef _BUNDLE_H_ +#define _BUNDLE_H_ + +#include + +class Bundle; + +struct BundleFileLocation +{ + INT64 Size; + INT64 Offset; + + BundleFileLocation() + { + LIMITED_METHOD_CONTRACT; + + Size = 0; + Offset = 0; + } + + static BundleFileLocation Invalid() { LIMITED_METHOD_CONTRACT; return BundleFileLocation(); } + + const SString &Path() const; + + bool IsValid() const { LIMITED_METHOD_CONTRACT; return Offset != 0; } +}; + +typedef bool(__stdcall BundleProbe)(LPCWSTR, INT64*, INT64*); + +class Bundle +{ +public: + Bundle(LPCWSTR bundlePath, BundleProbe *probe); + BundleFileLocation Probe(LPCWSTR path, bool pathIsBundleRelative = false) const; + + const SString &Path() const { LIMITED_METHOD_CONTRACT; return m_path; } + const SString &BasePath() const { LIMITED_METHOD_CONTRACT; return m_basePath; } + + static Bundle* AppBundle; // The BundleInfo for the current app, initialized by coreclr_initialize. + static bool AppIsBundle() { LIMITED_METHOD_CONTRACT; return AppBundle != nullptr; } + static BundleFileLocation ProbeAppBundle(LPCWSTR path, bool pathIsBundleRelative = false); + +private: + + SString m_path; // The path to single-file executable + BundleProbe *m_probe; + + SString m_basePath; // The prefix to denote a path within the bundle +}; + +#endif // _BUNDLE_H_ +// EOF ======================================================================= diff --git a/src/coreclr/src/pal/inc/pal.h b/src/coreclr/src/pal/inc/pal.h index 861a10f842da7..7ffdc2b7ec320 100644 --- a/src/coreclr/src/pal/inc/pal.h +++ b/src/coreclr/src/pal/inc/pal.h @@ -47,6 +47,9 @@ Module Name: #include #include #include +#include +#include +#include #endif #ifdef __cplusplus @@ -2543,6 +2546,7 @@ Abstract Parameters: IN hFile - The file to load + IN offset - offset within hFile where the PE "file" is located Return value: A valid base address if successful. @@ -2551,7 +2555,7 @@ Return value: PALIMPORT PVOID PALAPI -PAL_LOADLoadPEFile(HANDLE hFile); +PAL_LOADLoadPEFile(HANDLE hFile, size_t offset); /*++ PAL_LOADUnloadPEFile diff --git a/src/coreclr/src/pal/src/include/pal/map.hpp b/src/coreclr/src/pal/src/include/pal/map.hpp index eba0d8844bb27..b8c584f83c526 100644 --- a/src/coreclr/src/pal/src/include/pal/map.hpp +++ b/src/coreclr/src/pal/src/include/pal/map.hpp @@ -79,13 +79,14 @@ extern "C" Parameters: IN hFile - file to map + IN offset - offset within hFile where the PE "file" is located Return value: non-NULL - the base address of the mapped image NULL - error, with last error set. --*/ - void * MAPMapPEFile(HANDLE hFile); + void* MAPMapPEFile(HANDLE hFile, off_t offset); /*++ Function : diff --git a/src/coreclr/src/pal/src/include/pal/module.h b/src/coreclr/src/pal/src/include/pal/module.h index bb409b8fcd449..6a5e080d499d2 100644 --- a/src/coreclr/src/pal/src/include/pal/module.h +++ b/src/coreclr/src/pal/src/include/pal/module.h @@ -145,12 +145,13 @@ Abstract Parameters: IN hFile - The file to load + IN offset - offset within hFile where the PE "file" is located Return value: A valid base address if successful. 0 if failure --*/ -void * PAL_LOADLoadPEFile(HANDLE hFile); +void* PAL_LOADLoadPEFile(HANDLE hFile, size_t offset); /*++ PAL_LOADUnloadPEFile diff --git a/src/coreclr/src/pal/src/loader/module.cpp b/src/coreclr/src/pal/src/loader/module.cpp index 8418ef776d4be..65168978ba743 100644 --- a/src/coreclr/src/pal/src/loader/module.cpp +++ b/src/coreclr/src/pal/src/loader/module.cpp @@ -752,6 +752,7 @@ PAL_UnregisterModule( Parameters: IN hFile - file to map + IN offset - offset within hFile where the PE "file" is located Return value: non-NULL - the base address of the mapped image @@ -759,11 +760,11 @@ Return value: --*/ PVOID PALAPI -PAL_LOADLoadPEFile(HANDLE hFile) +PAL_LOADLoadPEFile(HANDLE hFile, size_t offset) { - ENTRY("PAL_LOADLoadPEFile (hFile=%p)\n", hFile); + ENTRY("PAL_LOADLoadPEFile (hFile=%p, offset=%zx)\n", hFile, offset); - void * loadedBase = MAPMapPEFile(hFile); + void* loadedBase = MAPMapPEFile(hFile, offset); #ifdef _DEBUG if (loadedBase != nullptr) @@ -775,7 +776,7 @@ PAL_LOADLoadPEFile(HANDLE hFile) { TRACE("Forcing failure of PE file map, and retry\n"); PAL_LOADUnloadPEFile(loadedBase); // unload it - loadedBase = MAPMapPEFile(hFile); // load it again + loadedBase = MAPMapPEFile(hFile, offset); // load it again } free(envVar); @@ -1547,7 +1548,8 @@ static MODSTRUCT *LOADAddModule(NATIVE_LIBRARY_HANDLE dl_handle, LPCSTR libraryN { /* found the handle. increment the refcount and return the existing module structure */ - TRACE("Found matching module %p for module name %s\n", module, libraryNameOrPath); + TRACE("Found matching module %p for module name %s\n", module, + (libraryNameOrPath != nullptr) ? libraryNameOrPath : "nullptr"); if (module->refcount != -1) { diff --git a/src/coreclr/src/pal/src/map/map.cpp b/src/coreclr/src/pal/src/map/map.cpp index cac736460bb3f..90936b19fd916 100644 --- a/src/coreclr/src/pal/src/map/map.cpp +++ b/src/coreclr/src/pal/src/map/map.cpp @@ -1088,6 +1088,8 @@ CorUnix::InternalMapViewOfFile( CFileMappingImmutableData *pImmutableData = NULL; CFileMappingProcessLocalData *pProcessLocalData = NULL; IDataLock *pProcessLocalDataLock = NULL; + INT64 offset = ((INT64)dwFileOffsetHigh << 32) | (INT64)dwFileOffsetLow; + #if ONE_SHARED_MAPPING_PER_FILEREGION_PER_PROCESS PMAPPED_VIEW_LIST pReusedMapping = NULL; #endif @@ -1102,9 +1104,9 @@ CorUnix::InternalMapViewOfFile( goto InternalMapViewOfFileExit; } - if ( 0 != dwFileOffsetHigh || 0 != dwFileOffsetLow ) + if (offset < 0) { - ASSERT( "dwFileOffsetHigh and dwFileOffsetLow are always 0.\n" ); + ASSERT("dwFileOffsetHigh | dwFileOffsetLow should be non-negative.\n"); palError = ERROR_INVALID_PARAMETER; goto InternalMapViewOfFileExit; } @@ -1182,7 +1184,7 @@ CorUnix::InternalMapViewOfFile( PROT_READ|PROT_WRITE, flags, pProcessLocalData->UnixFd, - 0 + offset ); } else @@ -1205,7 +1207,7 @@ CorUnix::InternalMapViewOfFile( prot, flags, pProcessLocalData->UnixFd, - 0 + offset ); #if ONE_SHARED_MAPPING_PER_FILEREGION_PER_PROCESS @@ -2210,13 +2212,14 @@ MAPmmapAndRecord( Parameters: IN hFile - file to map + IN offset - offset within hFile where the PE "file" is located Return value: non-NULL - the base address of the mapped image NULL - error, with last error set. --*/ -void * MAPMapPEFile(HANDLE hFile) +void * MAPMapPEFile(HANDLE hFile, off_t offset) { PAL_ERROR palError = 0; IPalObject *pFileObject = NULL; @@ -2231,7 +2234,7 @@ void * MAPMapPEFile(HANDLE hFile) char* envVar; #endif - ENTRY("MAPMapPEFile (hFile=%p)\n", hFile); + ENTRY("MAPMapPEFile (hFile=%p offset=%zx)\n", hFile, offset); //Step 0: Verify values, find internal pal data structures. if (INVALID_HANDLE_VALUE == hFile) @@ -2270,13 +2273,13 @@ void * MAPMapPEFile(HANDLE hFile) //Step 1: Read the PE headers and reserve enough space for the whole image somewhere. IMAGE_DOS_HEADER dosHeader; IMAGE_NT_HEADERS ntHeader; - if (sizeof(dosHeader) != pread(fd, &dosHeader, sizeof(dosHeader), 0)) + if (sizeof(dosHeader) != pread(fd, &dosHeader, sizeof(dosHeader), offset)) { palError = FILEGetLastErrorFromErrno(); ERROR_(LOADER)( "reading dos header failed\n" ); goto done; } - if (sizeof(ntHeader) != pread(fd, &ntHeader, sizeof(ntHeader), dosHeader.e_lfanew)) + if (sizeof(ntHeader) != pread(fd, &ntHeader, sizeof(ntHeader), offset + dosHeader.e_lfanew)) { palError = FILEGetLastErrorFromErrno(); goto done; @@ -2418,7 +2421,7 @@ void * MAPMapPEFile(HANDLE hFile) //first, map the PE header to the first page in the image. Get pointers to the section headers palError = MAPmmapAndRecord(pFileObject, loadedBase, - loadedBase, headerSize, PROT_READ, MAP_FILE|MAP_PRIVATE|MAP_FIXED, fd, 0, + loadedBase, headerSize, PROT_READ, MAP_FILE|MAP_PRIVATE|MAP_FIXED, fd, offset, (void**)&loadedHeader); if (NO_ERROR != palError) { @@ -2511,7 +2514,7 @@ void * MAPMapPEFile(HANDLE hFile) prot, MAP_FILE|MAP_PRIVATE|MAP_FIXED, fd, - currentHeader.PointerToRawData, + offset + currentHeader.PointerToRawData, §ionData); if (NO_ERROR != palError) { @@ -2541,7 +2544,7 @@ void * MAPMapPEFile(HANDLE hFile) palError = MAPRecordMapping(pFileObject, loadedBase, prevSectionEnd, - (char*)imageEnd - (char*)prevSectionEnd, + offset + (char*)imageEnd - (char*)prevSectionEnd, PROT_NONE); if (NO_ERROR != palError) { diff --git a/src/coreclr/src/vm/CMakeLists.txt b/src/coreclr/src/vm/CMakeLists.txt index e11e58d777251..c04d5f6219e03 100644 --- a/src/coreclr/src/vm/CMakeLists.txt +++ b/src/coreclr/src/vm/CMakeLists.txt @@ -42,6 +42,7 @@ set(VM_SOURCES_DAC_AND_WKS_COMMON assemblyloadcontext.cpp baseassemblyspec.cpp binder.cpp + bundle.cpp castcache.cpp callcounting.cpp ceeload.cpp diff --git a/src/coreclr/src/vm/appdomain.cpp b/src/coreclr/src/vm/appdomain.cpp index 95cd9174b9db2..7681e64a99cef 100644 --- a/src/coreclr/src/vm/appdomain.cpp +++ b/src/coreclr/src/vm/appdomain.cpp @@ -1761,7 +1761,7 @@ void SystemDomain::Init() sizeof(MethodDesc), sizeof(FieldDesc), sizeof(Module) - )); + )); #endif // _DEBUG // The base domain is initialized in SystemDomain::Attach() @@ -1775,7 +1775,7 @@ void SystemDomain::Init() m_pSystemAssembly = NULL; DWORD size = 0; - + AppDomain* pAppDomain = ::GetAppDomain(); // Get the install directory so we can find mscorlib hr = GetInternalSystemDirectory(NULL, &size); @@ -1783,19 +1783,19 @@ void SystemDomain::Init() ThrowHR(hr); // GetInternalSystemDirectory returns a size, including the null! - WCHAR *buffer = m_SystemDirectory.OpenUnicodeBuffer(size-1); + WCHAR* buffer = m_SystemDirectory.OpenUnicodeBuffer(size - 1); IfFailThrow(GetInternalSystemDirectory(buffer, &size)); m_SystemDirectory.CloseBuffer(); m_SystemDirectory.Normalize(); // At this point m_SystemDirectory should already be canonicalized - m_BaseLibrary.Append(m_SystemDirectory); if (!m_BaseLibrary.EndsWith(DIRECTORY_SEPARATOR_CHAR_W)) { m_BaseLibrary.Append(DIRECTORY_SEPARATOR_CHAR_W); } + m_BaseLibrary.Append(g_pwBaseLibrary); m_BaseLibrary.Normalize(); @@ -1825,7 +1825,7 @@ void SystemDomain::Init() #ifdef _DEBUG BOOL fPause = EEConfig::GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_PauseOnLoad, FALSE); - while(fPause) + while (fPause) { ClrSleepEx(20, TRUE); } diff --git a/src/coreclr/src/vm/appdomain.hpp b/src/coreclr/src/vm/appdomain.hpp index f017b42c73a2a..ece967214cc74 100644 --- a/src/coreclr/src/vm/appdomain.hpp +++ b/src/coreclr/src/vm/appdomain.hpp @@ -29,6 +29,7 @@ #include "gchandleutilities.h" #include "../binder/inc/applicationcontext.hpp" #include "rejit.h" +#include "bundle.h" #ifdef FEATURE_MULTICOREJIT #include "multicorejit.h" diff --git a/src/coreclr/src/vm/assemblynative.cpp b/src/coreclr/src/vm/assemblynative.cpp index b9cec28e3c5a2..0cb1dba31c3c4 100644 --- a/src/coreclr/src/vm/assemblynative.cpp +++ b/src/coreclr/src/vm/assemblynative.cpp @@ -239,7 +239,9 @@ void QCALLTYPE AssemblyNative::LoadFromPath(INT_PTR ptrNativeAssemblyLoadContext if (pwzILPath != NULL) { - pILImage = PEImage::OpenImage(pwzILPath); + pILImage = PEImage::OpenImage(pwzILPath, + MDInternalImport_Default, + Bundle::ProbeAppBundle(pwzILPath)); // Need to verify that this is a valid CLR assembly. if (!pILImage->CheckILFormat()) @@ -257,7 +259,9 @@ void QCALLTYPE AssemblyNative::LoadFromPath(INT_PTR ptrNativeAssemblyLoadContext // Form the PEImage for the NI assembly, if specified if (pwzNIPath != NULL) { - pNIImage = PEImage::OpenImage(pwzNIPath, MDInternalImport_TrustedNativeImage); + pNIImage = PEImage::OpenImage(pwzNIPath, + MDInternalImport_TrustedNativeImage, + Bundle::ProbeAppBundle(pwzNIPath)); if (pNIImage->HasReadyToRunHeader()) { diff --git a/src/coreclr/src/vm/bundle.cpp b/src/coreclr/src/vm/bundle.cpp new file mode 100644 index 0000000000000..e0d03155a56a1 --- /dev/null +++ b/src/coreclr/src/vm/bundle.cpp @@ -0,0 +1,93 @@ +// 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. +//***************************************************************************** +// Bundle.cpp +// +// Helpers to access meta-data stored in single-file bundles +// +//***************************************************************************** + +#include "common.h" +#include "bundle.h" +#include +#include +#include + +Bundle *Bundle::AppBundle = nullptr; + +const SString &BundleFileLocation::Path() const +{ + LIMITED_METHOD_CONTRACT; + + // Currently, there is only one bundle -- the bundle for the main App. + // Therefore, obtain the path from the global AppBundle. + // If there is more than one bundle in one application (ex: single file plugins) + // the BundlePath may be stored in the BundleFileLocation structure. + + _ASSERTE(IsValid()); + _ASSERTE(Bundle::AppBundle != nullptr); + + return Bundle::AppBundle->Path(); +} + +Bundle::Bundle(LPCWSTR bundlePath, BundleProbe *probe) +{ + STANDARD_VM_CONTRACT; + + _ASSERTE(probe != nullptr); + + m_path.Set(bundlePath); + m_probe = probe; + + // The bundle-base path is the directory containing the single-file bundle. + // When the Probe() function searches within the bundle, it masks out the basePath from the assembly-path (if found). + + LPCWSTR pos = wcsrchr(bundlePath, DIRECTORY_SEPARATOR_CHAR_W); + _ASSERTE(pos != nullptr); + size_t baseLen = pos - bundlePath + 1; // Include DIRECTORY_SEPARATOR_CHAR_W in m_basePath + m_basePath.Set(bundlePath, (COUNT_T)baseLen); +} + +BundleFileLocation Bundle::Probe(LPCWSTR path, bool pathIsBundleRelative) const +{ + STANDARD_VM_CONTRACT; + + BundleFileLocation loc; + + // Skip over m_base_path, if any. For example: + // Bundle.Probe("lib.dll") => m_probe("lib.dll") + // Bundle.Probe("path/to/exe/lib.dll") => m_probe("lib.dll") + // Bundle.Probe("path/to/exe/and/some/more/lib.dll") => m_probe("and/some/more/lib.dll") + + if (!pathIsBundleRelative) + { + size_t baseLen = m_basePath.GetCount(); + +#ifdef TARGET_UNIX + if (wcsncmp(m_basePath, path, baseLen) == 0) +#else + if (_wcsnicmp(m_basePath, path, baseLen) == 0) +#endif // TARGET_UNIX + { + path += baseLen; // m_basePath includes count for DIRECTORY_SEPARATOR_CHAR_W + } + else + { + // This is not a file within the bundle + return loc; + } + } + + m_probe(path, &loc.Offset, &loc.Size); + + return loc; +} + +BundleFileLocation Bundle::ProbeAppBundle(LPCWSTR path, bool pathIsBundleRelative) +{ + STANDARD_VM_CONTRACT; + + return AppIsBundle() ? AppBundle->Probe(path, pathIsBundleRelative) : BundleFileLocation::Invalid(); +} + diff --git a/src/coreclr/src/vm/coreassemblyspec.cpp b/src/coreclr/src/vm/coreassemblyspec.cpp index 99ae244064758..d2fc56ad064d9 100644 --- a/src/coreclr/src/vm/coreassemblyspec.cpp +++ b/src/coreclr/src/vm/coreassemblyspec.cpp @@ -19,7 +19,7 @@ #include "domainfile.h" #include "holder.h" #include "../binder/inc/assemblybinder.hpp" - +#include "bundle.h" #include "strongnameinternal.h" #include "strongnameholders.h" @@ -174,10 +174,11 @@ VOID AssemblySpec::Bind(AppDomain *pAppDomain, } -STDAPI BinderAcquirePEImage(LPCWSTR wszAssemblyPath, - PEImage **ppPEImage, - PEImage **ppNativeImage, - BOOL fExplicitBindToNativeImage) +STDAPI BinderAcquirePEImage(LPCWSTR wszAssemblyPath, + PEImage **ppPEImage, + PEImage **ppNativeImage, + BOOL fExplicitBindToNativeImage, + BundleFileLocation bundleFileLocation) { HRESULT hr = S_OK; @@ -187,12 +188,13 @@ STDAPI BinderAcquirePEImage(LPCWSTR wszAssemblyPath, { PEImageHolder pImage = NULL; PEImageHolder pNativeImage = NULL; + AppDomain* pDomain = ::GetAppDomain(); // DEAD ? ? #ifdef FEATURE_PREJIT // fExplicitBindToNativeImage is set on Phone when we bind to a list of native images and have no IL on device for an assembly if (fExplicitBindToNativeImage) { - pNativeImage = PEImage::OpenImage(wszAssemblyPath, MDInternalImport_TrustedNativeImage); + pNativeImage = PEImage::OpenImage(wszAssemblyPath, MDInternalImport_TrustedNativeImage, bundleFileLocation); // Make sure that the IL image can be opened if the native image is not available. hr=pNativeImage->TryOpenFile(); @@ -204,7 +206,7 @@ STDAPI BinderAcquirePEImage(LPCWSTR wszAssemblyPath, else #endif { - pImage = PEImage::OpenImage(wszAssemblyPath, MDInternalImport_Default); + pImage = PEImage::OpenImage(wszAssemblyPath, MDInternalImport_Default, bundleFileLocation); // Make sure that the IL image can be opened if the native image is not available. hr=pImage->TryOpenFile(); diff --git a/src/coreclr/src/vm/crossgen/CMakeLists.txt b/src/coreclr/src/vm/crossgen/CMakeLists.txt index 77f46314b9bed..b532a9ecdc3cb 100644 --- a/src/coreclr/src/vm/crossgen/CMakeLists.txt +++ b/src/coreclr/src/vm/crossgen/CMakeLists.txt @@ -6,6 +6,7 @@ set(VM_CROSSGEN_SOURCES ../assemblyspec.cpp ../baseassemblyspec.cpp ../binder.cpp + ../bundle.cpp ../castcache.cpp ../ceeload.cpp ../ceemain.cpp diff --git a/src/coreclr/src/vm/pefile.cpp b/src/coreclr/src/vm/pefile.cpp index 7da14c95cf3a8..ae9c966cb7983 100644 --- a/src/coreclr/src/vm/pefile.cpp +++ b/src/coreclr/src/vm/pefile.cpp @@ -295,12 +295,15 @@ void PEFile::LoadLibrary(BOOL allowNativeSkip/*=TRUE*/) // if allowNativeSkip==F if (GetILimage()->IsFile()) { #ifdef TARGET_UNIX - if (GetILimage()->IsILOnly()) + bool loadILImage = GetILimage()->IsILOnly(); +#else // TARGET_UNIX + bool loadILImage = GetILimage()->IsILOnly() && GetILimage()->IsInBundle(); +#endif // TARGET_UNIX + if (loadILImage) { GetILimage()->Load(); } else -#endif // TARGET_UNIX { GetILimage()->LoadFromMapped(); } diff --git a/src/coreclr/src/vm/peimage.cpp b/src/coreclr/src/vm/peimage.cpp index 7dc580fe8f8d8..c07facfa37269 100644 --- a/src/coreclr/src/vm/peimage.cpp +++ b/src/coreclr/src/vm/peimage.cpp @@ -973,10 +973,7 @@ PTR_PEImageLayout PEImage::GetLayoutInternal(DWORD imageLayoutMask,DWORD flags) BOOL bIsFlatLayoutSuitable = ((imageLayoutMask & PEImageLayout::LAYOUT_FLAT) != 0); #if !defined(TARGET_UNIX) - if (bIsMappedLayoutSuitable) - { - bIsFlatLayoutSuitable = FALSE; - } + bIsFlatLayoutSuitable = IsInBundle() || !bIsMappedLayoutSuitable; #endif // !TARGET_UNIX _ASSERTE(bIsMappedLayoutSuitable || bIsFlatLayoutSuitable); @@ -1183,7 +1180,14 @@ void PEImage::Load() } #ifdef TARGET_UNIX - if (m_pLayouts[IMAGE_FLAT] != NULL + bool canUseLoadedFlat = true; +#else + bool canUseLoadedFlat = IsInBundle(); +#endif // TARGET_UNIX + + + if (canUseLoadedFlat + && m_pLayouts[IMAGE_FLAT] != NULL && m_pLayouts[IMAGE_FLAT]->CheckILOnlyFormat() && !m_pLayouts[IMAGE_FLAT]->HasWriteableSections()) { @@ -1200,7 +1204,6 @@ void PEImage::Load() SetLayout(IMAGE_LOADED, m_pLayouts[IMAGE_FLAT]); } else -#endif // TARGET_UNIX { if(!IsFile()) { @@ -1328,19 +1331,19 @@ HANDLE PEImage::GetFileHandle() { ErrorModeHolder mode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS); - m_hFile=WszCreateFile((LPCWSTR) m_path, - GENERIC_READ, - FILE_SHARE_READ|FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); + m_hFile=WszCreateFile((LPCWSTR) GetPathToLoad(), + GENERIC_READ, + FILE_SHARE_READ|FILE_SHARE_DELETE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); } if (m_hFile == INVALID_HANDLE_VALUE) { #if !defined(DACCESS_COMPILE) - EEFileLoadException::Throw(m_path, HRESULT_FROM_WIN32(GetLastError())); + EEFileLoadException::Throw(GetPathToLoad(), HRESULT_FROM_WIN32(GetLastError())); #else // defined(DACCESS_COMPILE) ThrowLastError(); #endif // !defined(DACCESS_COMPILE) @@ -1374,14 +1377,14 @@ HRESULT PEImage::TryOpenFile() if (m_hFile!=INVALID_HANDLE_VALUE) return S_OK; { - ErrorModeHolder mode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS); - m_hFile=WszCreateFile((LPCWSTR) m_path, - GENERIC_READ, - FILE_SHARE_READ|FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); + ErrorModeHolder mode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS); + m_hFile=WszCreateFile((LPCWSTR)GetPathToLoad(), + GENERIC_READ, + FILE_SHARE_READ|FILE_SHARE_DELETE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); } if (m_hFile != INVALID_HANDLE_VALUE) return S_OK; diff --git a/src/coreclr/src/vm/peimage.h b/src/coreclr/src/vm/peimage.h index 1edf05d8ec217..2a9b0b76ac10a 100644 --- a/src/coreclr/src/vm/peimage.h +++ b/src/coreclr/src/vm/peimage.h @@ -19,6 +19,7 @@ #include "peimagelayout.h" #include "sstring.h" #include "holder.h" +#include class SimpleRWLock; // -------------------------------------------------------------------------------- @@ -102,7 +103,8 @@ class PEImage #endif // !TARGET_UNIX static PTR_PEImage OpenImage( LPCWSTR pPath, - MDInternalImportFlags flags = MDInternalImport_Default); + MDInternalImportFlags flags = MDInternalImport_Default, + BundleFileLocation bundleFileLocation = BundleFileLocation::Invalid()); // clones the image with new flags (this is pretty much about cached / noncached difference) @@ -146,8 +148,13 @@ class PEImage // Accessors const SString &GetPath(); + const SString& GetPathToLoad(); BOOL IsFile(); + BOOL IsInBundle() const; HANDLE GetFileHandle(); + INT64 GetOffset() const; + INT64 GetSize() const; + void SetFileHandle(HANDLE hFile); HRESULT TryOpenFile(); @@ -237,7 +244,7 @@ class PEImage // Private routines // ------------------------------------------------------------ - void Init(LPCWSTR pPath); + void Init(LPCWSTR pPath, BundleFileLocation bundleFileLocation); void Init(IStream* pStream, UINT64 uStreamAsmId, DWORD dwModuleId, BOOL resourceFile); @@ -273,6 +280,10 @@ class PEImage SString m_path; LONG m_refCount; + BundleFileLocation m_bundleFileLocation; // If this image is located within a single-file bundle, + // the location within the bundle. If m_bundleFileLocation is vaild, + // it takes precedence over m_path for loading. + // This variable will have the data of module name. // It is only used by DAC to remap fusion loaded modules back to // disk IL. This really is a workaround. The real fix is for fusion loader diff --git a/src/coreclr/src/vm/peimage.inl b/src/coreclr/src/vm/peimage.inl index 03d8bc229ce05..eebae16e15f7a 100644 --- a/src/coreclr/src/vm/peimage.inl +++ b/src/coreclr/src/vm/peimage.inl @@ -33,6 +33,33 @@ inline const SString &PEImage::GetPath() return m_path; } +inline const SString& PEImage::GetPathToLoad() +{ + LIMITED_METHOD_DAC_CONTRACT; + + return IsInBundle() ? m_bundleFileLocation.Path() : m_path; +} + +inline INT64 PEImage::GetOffset() const +{ + LIMITED_METHOD_CONTRACT; + + return m_bundleFileLocation.Offset; +} + +inline BOOL PEImage::IsInBundle() const +{ + LIMITED_METHOD_CONTRACT; + + return m_bundleFileLocation.IsValid(); +} + +inline INT64 PEImage::GetSize() const +{ + LIMITED_METHOD_CONTRACT; + return m_bundleFileLocation.Size; +} + inline void PEImage::SetModuleFileNameHintForDAC() { LIMITED_METHOD_DAC_CONTRACT; @@ -71,7 +98,7 @@ inline BOOL PEImage::IsFile() { WRAPPER_NO_CONTRACT; - return !m_path.IsEmpty(); + return !GetPathToLoad().IsEmpty(); } #ifndef DACCESS_COMPILE @@ -433,7 +460,7 @@ inline CHECK PEImage::CheckFormat() CHECK_OK; } -inline void PEImage::Init(LPCWSTR pPath) +inline void PEImage::Init(LPCWSTR pPath, BundleFileLocation bundleFileLocation) { CONTRACTL { @@ -442,8 +469,10 @@ inline void PEImage::Init(LPCWSTR pPath) MODE_ANY; } CONTRACTL_END; + m_path = pPath; m_path.Normalize(); + m_bundleFileLocation = bundleFileLocation; SetModuleFileNameHintForDAC(); } #ifndef DACCESS_COMPILE @@ -475,14 +504,14 @@ inline PTR_PEImage PEImage::FindByPath(LPCWSTR pPath) } /* static */ -inline PTR_PEImage PEImage::OpenImage(LPCWSTR pPath, MDInternalImportFlags flags /* = MDInternalImport_Default */) +inline PTR_PEImage PEImage::OpenImage(LPCWSTR pPath, MDInternalImportFlags flags /* = MDInternalImport_Default */, BundleFileLocation bundleFileLocation) { BOOL fUseCache = !((flags & MDInternalImport_NoCache) == MDInternalImport_NoCache); if (!fUseCache) { PEImageHolder pImage(new PEImage); - pImage->Init(pPath); + pImage->Init(pPath, bundleFileLocation); return dac_cast(pImage.Extract()); } @@ -504,7 +533,7 @@ inline PTR_PEImage PEImage::OpenImage(LPCWSTR pPath, MDInternalImportFlags flags if (flags & MDInternalImport_TrustedNativeImage) pImage->SetIsTrustedNativeImage(); #endif - pImage->Init(pPath); + pImage->Init(pPath, bundleFileLocation); pImage->AddToHashMap(); return dac_cast(pImage.Extract()); diff --git a/src/coreclr/src/vm/peimagelayout.cpp b/src/coreclr/src/vm/peimagelayout.cpp index 79739716da430..33032108e7e3e 100644 --- a/src/coreclr/src/vm/peimagelayout.cpp +++ b/src/coreclr/src/vm/peimagelayout.cpp @@ -40,6 +40,17 @@ PEImageLayout* PEImageLayout::LoadFromFlat(PEImageLayout* pflatimage) return new ConvertedImageLayout(pflatimage); } +PEImageLayout* PEImageLayout::LoadConverted(PEImage* pOwner) +{ + STANDARD_VM_CONTRACT; + + PEImageLayoutHolder pFlat(new FlatImageLayout(pOwner)); + if (!pFlat->CheckFormat()) + ThrowHR(COR_E_BADIMAGEFORMAT); + + return new ConvertedImageLayout(pFlat); +} + PEImageLayout* PEImageLayout::Load(PEImage* pOwner, BOOL bNTSafeLoad, BOOL bThrowOnError) { STANDARD_VM_CONTRACT; @@ -47,6 +58,11 @@ PEImageLayout* PEImageLayout::Load(PEImage* pOwner, BOOL bNTSafeLoad, BOOL bThro #if defined(CROSSGEN_COMPILE) || defined(TARGET_UNIX) return PEImageLayout::Map(pOwner); #else + if (pOwner->IsInBundle()) + { + return PEImageLayout::LoadConverted(pOwner); + } + PEImageLayoutHolder pAlloc(new LoadedImageLayout(pOwner,bNTSafeLoad,bThrowOnError)); if (pAlloc->GetBase()==NULL) return NULL; @@ -83,11 +99,7 @@ PEImageLayout* PEImageLayout::Map(PEImage* pOwner) if (pAlloc->GetBase()==NULL) { //cross-platform or a bad image - PEImageLayoutHolder pFlat(new FlatImageLayout(pOwner)); - if (!pFlat->CheckFormat()) - ThrowHR(COR_E_BADIMAGEFORMAT); - - pAlloc=new ConvertedImageLayout(pFlat); + pAlloc = LoadConverted(pOwner); } else if(!pAlloc->CheckFormat()) @@ -393,8 +405,8 @@ ConvertedImageLayout::ConvertedImageLayout(PEImageLayout* source) m_FileMap.Assign(WszCreateFileMapping(INVALID_HANDLE_VALUE, NULL, - PAGE_READWRITE, 0, - source->GetVirtualSize(), NULL)); + PAGE_READWRITE, 0, + source->GetVirtualSize(), NULL)); if (m_FileMap == NULL) ThrowLastError(); @@ -428,6 +440,8 @@ MappedImageLayout::MappedImageLayout(PEImage* pOwner) m_pOwner=pOwner; HANDLE hFile = pOwner->GetFileHandle(); + INT64 offset = pOwner->GetOffset(); + INT64 size = pOwner->GetSize(); // If mapping was requested, try to do SEC_IMAGE mapping LOG((LF_LOADER, LL_INFO100, "PEImage: Opening OS mapped %S (hFile %p)\n", (LPCWSTR) GetPath(), hFile)); @@ -459,21 +473,24 @@ MappedImageLayout::MappedImageLayout(PEImage* pOwner) ThrowWin32(dwLastError); } -#endif // CROSSGEN_COMPILE +#endif // !CROSSGEN_COMPILE return; } + DWORD offsetLowPart = (DWORD)offset; + DWORD offsetHighPart = (DWORD)(offset >> 32); + #ifdef _DEBUG // Force relocs by occuping the preferred base while the actual mapping is performed CLRMapViewHolder forceRelocs; if (PEDecoder::GetForceRelocs()) { - forceRelocs.Assign(CLRMapViewOfFile(m_FileMap, 0, 0, 0, 0)); + forceRelocs.Assign(CLRMapViewOfFile(m_FileMap, 0, offsetHighPart, offsetLowPart, (SIZE_T)size)); } #endif // _DEBUG - m_FileView.Assign(CLRMapViewOfFile(m_FileMap, 0, 0, 0, 0)); + m_FileView.Assign(CLRMapViewOfFile(m_FileMap, 0, offsetHighPart, offsetLowPart, (SIZE_T)size)); if (m_FileView == NULL) ThrowLastError(); IfFailThrow(Init((void *) m_FileView)); @@ -502,7 +519,7 @@ MappedImageLayout::MappedImageLayout(PEImage* pOwner) } } else -#endif +#endif // CROSSGEN_COMPILE if (!IsNativeMachineFormat() && !IsI386()) { //can't rely on the image @@ -529,7 +546,7 @@ MappedImageLayout::MappedImageLayout(PEImage* pOwner) #else //!TARGET_UNIX #ifndef CROSSGEN_COMPILE - m_LoadedFile = PAL_LOADLoadPEFile(hFile); + m_LoadedFile = PAL_LOADLoadPEFile(hFile, offset); if (m_LoadedFile == NULL) { @@ -612,13 +629,19 @@ FlatImageLayout::FlatImageLayout(PEImage* pOwner) m_pOwner=pOwner; HANDLE hFile = pOwner->GetFileHandle(); + INT64 offset = pOwner->GetOffset(); + INT64 size = pOwner->GetSize(); LOG((LF_LOADER, LL_INFO100, "PEImage: Opening flat %S\n", (LPCWSTR) GetPath())); - COUNT_T size = SafeGetFileSize(hFile, NULL); - if (size == 0xffffffff && GetLastError() != NOERROR) + // If a size is not specified, load the whole file + if (size == 0) { - ThrowLastError(); + size = SafeGetFileSize(hFile, NULL); + if (size == 0xffffffff && GetLastError() != NOERROR) + { + ThrowLastError(); + } } // It's okay if resource files are length zero @@ -628,11 +651,16 @@ FlatImageLayout::FlatImageLayout(PEImage* pOwner) if (m_FileMap == NULL) ThrowLastError(); - m_FileView.Assign(CLRMapViewOfFile(m_FileMap, FILE_MAP_READ, 0, 0, 0)); + //DWORD lowPart = (DWORD)offset; + //DWORD highPart = (DWORD)(offset >> 32); + char *addr = (char*)CLRMapViewOfFile(m_FileMap, FILE_MAP_READ, 0, 0, 0); + addr += offset; + m_FileView.Assign((LPVOID)addr); + if (m_FileView == NULL) ThrowLastError(); } - Init(m_FileView, size); + Init(m_FileView, (COUNT_T)size); } NativeImageLayout::NativeImageLayout(LPCWSTR fullPath) @@ -655,7 +683,7 @@ NativeImageLayout::NativeImageLayout(LPCWSTR fullPath) ThrowLastError(); } - loadedImage = PAL_LOADLoadPEFile(fileHandle); + loadedImage = PAL_LOADLoadPEFile(fileHandle, 0); } #else loadedImage = CLRLoadLibraryEx(fullPath, NULL, GetLoadWithAlteredSearchPathFlag()); diff --git a/src/coreclr/src/vm/peimagelayout.h b/src/coreclr/src/vm/peimagelayout.h index 9ae14c4b74e54..bc846c54d6c74 100644 --- a/src/coreclr/src/vm/peimagelayout.h +++ b/src/coreclr/src/vm/peimagelayout.h @@ -54,6 +54,7 @@ class PEImageLayout : public PEDecoder static PEImageLayout* LoadFromFlat(PEImageLayout* pflatimage); static PEImageLayout* Load(PEImage* pOwner, BOOL bNTSafeLoad, BOOL bThrowOnError = TRUE); static PEImageLayout* LoadFlat(PEImage* pOwner); + static PEImageLayout* LoadConverted(PEImage* pOwner); static PEImageLayout* LoadNative(LPCWSTR fullPath); static PEImageLayout* Map(PEImage* pOwner); #endif diff --git a/src/installer/corehost/cli/bundle/file_entry.cpp b/src/installer/corehost/cli/bundle/file_entry.cpp index 775117fb9a1f6..25e2cd01ce3fc 100644 --- a/src/installer/corehost/cli/bundle/file_entry.cpp +++ b/src/installer/corehost/cli/bundle/file_entry.cpp @@ -38,10 +38,9 @@ bool file_entry_t::needs_extraction() const { switch (m_type) { - // Once the runtime can load assemblies from bundle, - // file_type_t::assembly should be in this category case file_type_t::deps_json: case file_type_t::runtime_config_json: + case file_type_t::assembly: return false; default: diff --git a/src/installer/corehost/cli/bundle/runner.cpp b/src/installer/corehost/cli/bundle/runner.cpp index 19fc8bcd47576..dec93009e4683 100644 --- a/src/installer/corehost/cli/bundle/runner.cpp +++ b/src/installer/corehost/cli/bundle/runner.cpp @@ -79,8 +79,7 @@ bool runner_t::probe(const pal::string_t& relative_path, int64_t* offset, int64_ return true; } - -bool runner_t::locate(const pal::string_t& relative_path, pal::string_t& full_path) const +bool runner_t::locate(const pal::string_t& relative_path, pal::string_t& full_path, bool& extracted_to_disk) const { const bundle::file_entry_t* entry = probe(relative_path); @@ -90,11 +89,9 @@ bool runner_t::locate(const pal::string_t& relative_path, pal::string_t& full_pa return false; } - // Currently, all files except deps.json and runtimeconfig.json are extracted to disk. - // The json files are not queried by the host using this method. - assert(entry->needs_extraction()); + extracted_to_disk = entry->needs_extraction(); + full_path.assign(extracted_to_disk ? extraction_path() : base_path()); - full_path.assign(extraction_path()); append_path(&full_path, relative_path.c_str()); return true; diff --git a/src/installer/corehost/cli/bundle/runner.h b/src/installer/corehost/cli/bundle/runner.h index 39c6b6b1190b0..f632814df8f81 100644 --- a/src/installer/corehost/cli/bundle/runner.h +++ b/src/installer/corehost/cli/bundle/runner.h @@ -21,26 +21,31 @@ namespace bundle { public: runner_t(const pal::char_t* bundle_path, - const pal::char_t *app_path, - int64_t header_offset) + const pal::char_t* app_path, + int64_t header_offset) : info_t(bundle_path, app_path, header_offset) {} const pal::string_t& extraction_path() const { return m_extraction_path; } bool probe(const pal::string_t& relative_path, int64_t* offset, int64_t* size) const; - bool locate(const pal::string_t& relative_path, pal::string_t& full_path) const; + const file_entry_t* probe(const pal::string_t& relative_path) const; + bool locate(const pal::string_t& relative_path, pal::string_t& full_path, bool& extracted_to_disk) const; + bool locate(const pal::string_t& relative_path, pal::string_t& full_path) const + { + bool extracted_to_disk; + return locate(relative_path, full_path, extracted_to_disk); + } static StatusCode process_manifest_and_extract() { return ((runner_t*) the_app)->extract(); } - + static const runner_t* app() { return (const runner_t*)the_app; } private: StatusCode extract(); - const file_entry_t* probe(const pal::string_t& relative_path) const; manifest_t m_manifest; pal::string_t m_extraction_path; diff --git a/src/installer/corehost/cli/deps_entry.cpp b/src/installer/corehost/cli/deps_entry.cpp index 449403fa038e2..85c845047da4c 100644 --- a/src/installer/corehost/cli/deps_entry.cpp +++ b/src/installer/corehost/cli/deps_entry.cpp @@ -38,11 +38,12 @@ static pal::string_t normalize_dir_separator(const pal::string_t& path) // Returns: // If the file exists in the path relative to the "base" directory within the // single-file or on disk. -bool deps_entry_t::to_path(const pal::string_t& base, const pal::string_t& ietf_dir, bool look_in_base, bool look_in_bundle, pal::string_t* str) const +bool deps_entry_t::to_path(const pal::string_t& base, const pal::string_t& ietf_dir, bool look_in_base, bool look_in_bundle, pal::string_t* str, bool &loaded_from_bundle) const { pal::string_t& candidate = *str; candidate.clear(); + loaded_from_bundle = false; // Base directory must be present to obtain full path if (base.empty()) @@ -67,9 +68,11 @@ bool deps_entry_t::to_path(const pal::string_t& base, const pal::string_t& ietf_ { // If sub_path is found in the single-file bundle, // app::locate() will set candidate to the full-path to the assembly extracted out to disk. - if (app->locate(sub_path, candidate)) + bool extracted_to_disk = false; + if (app->locate(sub_path, candidate, extracted_to_disk)) { - trace::verbose(_X(" %s found in bundle [%s]"), sub_path.c_str(), candidate.c_str()); + loaded_from_bundle = !extracted_to_disk; + trace::verbose(_X(" %s found in bundle [%s] %s"), sub_path.c_str(), candidate.c_str(), extracted_to_disk ? _X("(extracted)") : _X("")); return true; } else @@ -112,7 +115,7 @@ bool deps_entry_t::to_path(const pal::string_t& base, const pal::string_t& ietf_ // Returns: // If the file exists in the path relative to the "base" directory. // -bool deps_entry_t::to_dir_path(const pal::string_t& base, bool look_in_bundle, pal::string_t* str) const +bool deps_entry_t::to_dir_path(const pal::string_t& base, bool look_in_bundle, pal::string_t* str, bool& loaded_from_bundle) const { pal::string_t ietf_dir; @@ -134,7 +137,7 @@ bool deps_entry_t::to_dir_path(const pal::string_t& base, bool look_in_bundle, p base.c_str(), ietf_dir.c_str(), asset.name.c_str()); } - return to_path(base, ietf_dir, true, look_in_bundle, str); + return to_path(base, ietf_dir, true, look_in_bundle, str, loaded_from_bundle); } // ----------------------------------------------------------------------------- @@ -150,7 +153,10 @@ bool deps_entry_t::to_dir_path(const pal::string_t& base, bool look_in_bundle, p // bool deps_entry_t::to_rel_path(const pal::string_t& base, bool look_in_bundle, pal::string_t* str) const { - return to_path(base, _X(""), false, look_in_bundle, str); + bool loaded_from_bundle; + bool result = to_path(base, _X(""), false, look_in_bundle, str, loaded_from_bundle); + assert(!loaded_from_bundle); + return result; } // ----------------------------------------------------------------------------- diff --git a/src/installer/corehost/cli/deps_entry.h b/src/installer/corehost/cli/deps_entry.h index 2c66b1f055273..a8e994bef5b21 100644 --- a/src/installer/corehost/cli/deps_entry.h +++ b/src/installer/corehost/cli/deps_entry.h @@ -53,7 +53,7 @@ struct deps_entry_t bool is_rid_specific; // Given a "base" dir, yield the file path within this directory or single-file bundle. - bool to_dir_path(const pal::string_t& base, bool look_in_bundle, pal::string_t* str) const; + bool to_dir_path(const pal::string_t& base, bool look_in_bundle, pal::string_t* str, bool& loaded_from_bundle) const; // Given a "base" dir, yield the relative path in the package layout. bool to_rel_path(const pal::string_t& base, bool look_in_bundle, pal::string_t* str) const; @@ -64,7 +64,7 @@ struct deps_entry_t private: // Given a "base" dir, yield the filepath within this directory or relative to this directory based on "look_in_base" // Returns a path within the single-file bundle, or a file on disk, - bool to_path(const pal::string_t& base, const pal::string_t& ietf_code, bool look_in_base, bool look_in_bundle, pal::string_t* str) const; + bool to_path(const pal::string_t& base, const pal::string_t& ietf_code, bool look_in_base, bool look_in_bundle, pal::string_t* str, bool & loaded_from_bundle) const; }; #endif // __DEPS_ENTRY_H_ diff --git a/src/installer/corehost/cli/hostpolicy/deps_resolver.cpp b/src/installer/corehost/cli/hostpolicy/deps_resolver.cpp index 21060eab4bdfb..5a3d5a0fc612d 100644 --- a/src/installer/corehost/cli/hostpolicy/deps_resolver.cpp +++ b/src/installer/corehost/cli/hostpolicy/deps_resolver.cpp @@ -281,10 +281,13 @@ void deps_resolver_t::setup_additional_probes(const std::vector& * -- When servicing directories are looked up, look up only if the deps file marks the entry as serviceable. * -- When a deps json based probe is performed, the deps entry's package name and version must match. * -- When looking into a published dir, for rid specific assets lookup rid split folders; for non-rid assets lookup the layout dir. + * The path to the resolved file is returned in candidate out parameter + * If the candidate is embedded within the single-file bundle (rather than an actual file on disk), found_in_bundle will be set to true. */ -bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::string_t& deps_dir, int fx_level, pal::string_t* candidate) +bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::string_t& deps_dir, int fx_level, pal::string_t* candidate, bool & loaded_from_bundle) { candidate->clear(); + loaded_from_bundle = false; for (const auto& config : m_probes) { @@ -316,8 +319,9 @@ bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::str // If the deps json has the package name and version, then someone has already done rid selection and // put the right asset in the dir. So checking just package name and version would suffice. // No need to check further for the exact asset relative sub path. - if (config.probe_deps_json->has_package(entry.library_name, entry.library_version) && entry.to_dir_path(probe_dir, false, candidate)) + if (config.probe_deps_json->has_package(entry.library_name, entry.library_version) && entry.to_dir_path(probe_dir, false, candidate, loaded_from_bundle)) { + assert(!loaded_from_bundle); trace::verbose(_X(" Probed deps json and matched '%s'"), candidate->c_str()); return true; } @@ -343,7 +347,7 @@ bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::str else { // Non-rid assets, lookup in the published dir. - if (entry.to_dir_path(deps_dir, true, candidate)) + if (entry.to_dir_path(deps_dir, true, candidate, loaded_from_bundle)) { trace::verbose(_X(" Probed deps dir and matched '%s'"), candidate->c_str()); return true; @@ -437,10 +441,17 @@ bool deps_resolver_t::resolve_tpa_list( name_to_resolved_asset_map_t::iterator existing = items.find(entry.asset.name); if (existing == items.end()) { - if (probe_deps_entry(entry, deps_dir, fx_level, &resolved_path)) + bool loaded_from_bundle = false; + if (probe_deps_entry(entry, deps_dir, fx_level, &resolved_path, loaded_from_bundle)) { - deps_resolved_asset_t resolved_asset(entry.asset, resolved_path); - add_tpa_asset(resolved_asset, &items); + // Assemblies loaded directly from the bundle are not added to the TPA list. + // The runtime directly probes the bundle-manifest using a host-callback. + if (!loaded_from_bundle) + { + deps_resolved_asset_t resolved_asset(entry.asset, resolved_path); + add_tpa_asset(resolved_asset, &items); + } + return true; } @@ -468,7 +479,8 @@ bool deps_resolver_t::resolve_tpa_list( if (entry.asset.assembly_version > existing_entry->asset.assembly_version || (entry.asset.assembly_version == existing_entry->asset.assembly_version && entry.asset.file_version >= existing_entry->asset.file_version)) { - if (probe_deps_entry(entry, deps_dir, fx_level, &resolved_path)) + bool loaded_from_bundle = false; + if (probe_deps_entry(entry, deps_dir, fx_level, &resolved_path, loaded_from_bundle)) { // If the path is the same, then no need to replace if (resolved_path != existing_entry->resolved_path) @@ -480,9 +492,12 @@ bool deps_resolver_t::resolve_tpa_list( existing_entry = nullptr; items.erase(existing); - deps_asset_t asset(entry.asset.name, entry.asset.relative_path, entry.asset.assembly_version, entry.asset.file_version); - deps_resolved_asset_t resolved_asset(asset, resolved_path); - add_tpa_asset(resolved_asset, &items); + if (!loaded_from_bundle) + { + deps_asset_t asset(entry.asset.name, entry.asset.relative_path, entry.asset.assembly_version, entry.asset.file_version); + deps_resolved_asset_t resolved_asset(asset, resolved_path); + add_tpa_asset(resolved_asset, &items); + } } } else if (fx_level != 0) @@ -505,9 +520,17 @@ bool deps_resolver_t::resolve_tpa_list( // First add managed assembly to the TPA. // TODO: Remove: the deps should contain the managed DLL. // Workaround for: csc.deps.json doesn't have the csc.dll - deps_asset_t asset(get_filename_without_ext(m_managed_app), get_filename(m_managed_app), version_t(), version_t()); - deps_resolved_asset_t resolved_asset(asset, m_managed_app); - add_tpa_asset(resolved_asset, &items); + + // If this is a single-file bundle, app.dll is expected to be within the bundle, unless it is explicitly excluded from the bundle. + // In all other cases, add its path to the TPA list. + pal::string_t managed_app_name = get_filename(m_managed_app); + if (!bundle::info_t::is_single_file_bundle() || + bundle::runner_t::app()->probe(managed_app_name) == nullptr) + { + deps_asset_t asset(get_filename_without_ext(m_managed_app), managed_app_name, version_t(), version_t()); + deps_resolved_asset_t resolved_asset(asset, m_managed_app); + add_tpa_asset(resolved_asset, &items); + } // Add the app's entries const auto& deps_entries = get_deps().get_entries(deps_entry_t::asset_types::runtime); @@ -783,10 +806,14 @@ bool deps_resolver_t::resolve_probe_dirs( trace::verbose(_X("Processing native/culture for deps entry [%s, %s, %s]"), entry.library_name.c_str(), entry.library_version.c_str(), entry.asset.relative_path.c_str()); - if (probe_deps_entry(entry, deps_dir, fx_level, &candidate)) + bool loaded_from_bundle = false; + if (probe_deps_entry(entry, deps_dir, fx_level, &candidate, loaded_from_bundle)) { - init_known_entry_path(entry, candidate); - add_unique_path(asset_type, action(candidate), &items, output, &non_serviced, core_servicing); + if (!loaded_from_bundle) + { + init_known_entry_path(entry, candidate); + add_unique_path(asset_type, action(candidate), &items, output, &non_serviced, core_servicing); + } } else { diff --git a/src/installer/corehost/cli/hostpolicy/deps_resolver.h b/src/installer/corehost/cli/hostpolicy/deps_resolver.h index cb033f5c6d698..8471d94b44c12 100644 --- a/src/installer/corehost/cli/hostpolicy/deps_resolver.h +++ b/src/installer/corehost/cli/hostpolicy/deps_resolver.h @@ -228,7 +228,8 @@ class deps_resolver_t const deps_entry_t& entry, const pal::string_t& deps_dir, int fx_level, - pal::string_t* candidate); + pal::string_t* candidate, + bool &loaded_from_bundle); fx_definition_vector_t& m_fx_definitions; diff --git a/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp b/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp index 5a0a32394e9a1..ed6801342c465 100644 --- a/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp +++ b/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp @@ -113,17 +113,24 @@ int hostpolicy_context_t::initialize(hostpolicy_init_t &hostpolicy_init, const a // Get path in which CoreCLR is present. clr_dir = get_directory(clr_path); + // If this is a self-contained single-file bundle, + // System.Private.CoreLib.dll is expected to be within the bundle, unless it is explicitly excluded from the bundle. + // In all other cases, // System.Private.CoreLib.dll is expected to be next to CoreCLR.dll - add its path to the TPA list. - pal::string_t corelib_path = clr_dir; - append_path(&corelib_path, CORELIB_NAME); - - // Append CoreLib path - if (!probe_paths.tpa.empty() && probe_paths.tpa.back() != PATH_SEPARATOR) + if (!bundle::info_t::is_single_file_bundle() || + bundle::runner_t::app()->probe(CORELIB_NAME) == nullptr) { - probe_paths.tpa.push_back(PATH_SEPARATOR); - } + pal::string_t corelib_path = clr_dir; + append_path(&corelib_path, CORELIB_NAME); + + // Append CoreLib path + if (!probe_paths.tpa.empty() && probe_paths.tpa.back() != PATH_SEPARATOR) + { + probe_paths.tpa.push_back(PATH_SEPARATOR); + } - probe_paths.tpa.append(corelib_path); + probe_paths.tpa.append(corelib_path); + } const fx_definition_vector_t &fx_definitions = resolver.get_fx_definitions(); diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs index 26dbc3a00ef83..8f9e97415285b 100644 --- a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs +++ b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs @@ -30,7 +30,7 @@ private void Bundle_Extraction_To_Specific_Path_Succeeds() // Publish the bundle string singleFile; - Bundler bundler = BundleHelper.BundleApp(fixture, out singleFile); + Bundler bundler = BundleHelper.BundleApp(fixture, out singleFile, options: BundleOptions.BundleNativeBinaries); // Verify expected files in the bundle directory var bundleDir = BundleHelper.GetBundleDir(fixture); @@ -157,7 +157,6 @@ private void Bundle_extraction_can_recover_missing_files() extractDir.Should().HaveFiles(extractedFiles); } - public class SharedTestState : IDisposable { public TestProjectFixture TestFixture { get; set; } diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs index 33e05b5c0504d..ff15ee6fb80f1 100644 --- a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs +++ b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundledAppWithSubDirs.cs @@ -32,9 +32,7 @@ private void RunTheApp(string path) .HaveStdOutContaining("Wow! We now say hello to the big world and you."); } - // BundleOptions.BundleNativeBinaries: Test when the payload data files are unbundled, and beside the single-file app. - // BundleOptions.BundleAllContent: Test when the payload data files are bundled and extracted to temporary directory. - // Once the runtime can load assemblies from the bundle, BundleOptions.None can be used in place of BundleOptions.BundleNativeBinaries. + [InlineData(BundleOptions.None)] [InlineData(BundleOptions.BundleNativeBinaries)] [InlineData(BundleOptions.BundleAllContent)] [Theory] @@ -50,6 +48,7 @@ public void Bundled_Framework_dependent_App_Run_Succeeds(BundleOptions options) RunTheApp(singleFile); } + [InlineData(BundleOptions.None)] [InlineData(BundleOptions.BundleNativeBinaries)] [InlineData(BundleOptions.BundleAllContent)] [Theory] @@ -65,6 +64,7 @@ public void Bundled_Self_Contained_App_Run_Succeeds(BundleOptions options) RunTheApp(singleFile); } + [InlineData(BundleOptions.None)] [InlineData(BundleOptions.BundleNativeBinaries)] [InlineData(BundleOptions.BundleAllContent)] [Theory] diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/Helpers/BundleHelper.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/Helpers/BundleHelper.cs index c5f7717943676..def3a46956399 100644 --- a/src/installer/test/Microsoft.NET.HostModel.Tests/Helpers/BundleHelper.cs +++ b/src/installer/test/Microsoft.NET.HostModel.Tests/Helpers/BundleHelper.cs @@ -53,8 +53,7 @@ public static string[] GetBundledFiles(TestProjectFixture fixture) public static string[] GetExtractedFiles(TestProjectFixture fixture) { - string appBaseName = GetAppBaseName(fixture); - return new string[] { $"{appBaseName}.dll" }; + return new string[] { Path.GetFileName(fixture.TestProject.CoreClrDll) }; } public static string[] GetFilesNeverExtracted(TestProjectFixture fixture) @@ -62,6 +61,7 @@ public static string[] GetFilesNeverExtracted(TestProjectFixture fixture) string appBaseName = GetAppBaseName(fixture); return new string[] { $"{appBaseName}.deps.json", $"{appBaseName}.runtimeconfig.json", + $"{appBaseName}.dll", Path.GetFileName(fixture.TestProject.HostFxrDll), Path.GetFileName(fixture.TestProject.HostPolicyDll) }; } @@ -139,7 +139,7 @@ public static string GenerateBundle(Bundler bundler, string sourceDir, string ou // which may not (yet) be available in the SDK. public static Bundler BundleApp(TestProjectFixture fixture, out string singleFile, - BundleOptions options = BundleOptions.BundleNativeBinaries, + BundleOptions options = BundleOptions.None, Version targetFrameworkVersion = null, bool copyExcludedFiles = true) { @@ -153,11 +153,8 @@ public static string GenerateBundle(Bundler bundler, string sourceDir, string ou return bundler; } - // The defaut option for Bundling apps is BundleOptions.BundleNativeBinaries - // Until CoreCLR runtime can learn how to process assemblies from the bundle. - // This is because CoreCLR expects System.Private.Corelib.dll to be beside CoreCLR.dll public static string BundleApp(TestProjectFixture fixture, - BundleOptions options = BundleOptions.BundleNativeBinaries, + BundleOptions options = BundleOptions.None, Version targetFrameworkVersion = null) { string singleFile; diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleAndRun.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleAndRun.cs index e4949b47750da..bf9ff14cf5b0f 100644 --- a/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleAndRun.cs +++ b/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleAndRun.cs @@ -32,7 +32,7 @@ private void RunTheApp(string path) .HaveStdOutContaining("Wow! We now say hello to the big world and you."); } - private void BundleRun(TestProjectFixture fixture, string publishPath, string singleFileDir) + private void BundleRun(TestProjectFixture fixture, string publishPath) { var hostName = BundleHelper.GetHostName(fixture); @@ -56,33 +56,24 @@ private string RelativePath(string path) public void TestWithAbsolutePaths() { var fixture = sharedTestState.TestFixture.Copy(); - string publishDir = BundleHelper.GetPublishPath(fixture); - string outputDir = BundleHelper.GetBundleDir(fixture).FullName; - - BundleRun(fixture, publishDir, outputDir); + BundleRun(fixture, publishDir); } [Fact] public void TestWithRelativePaths() { var fixture = sharedTestState.TestFixture.Copy(); - string publishDir = RelativePath(BundleHelper.GetPublishPath(fixture)); - string outputDir = RelativePath(BundleHelper.GetBundleDir(fixture).FullName); - - BundleRun(fixture, publishDir, outputDir); + BundleRun(fixture, publishDir); } [Fact] public void TestWithRelativePathsDirSeparator() { var fixture = sharedTestState.TestFixture.Copy(); - string publishDir = RelativePath(BundleHelper.GetPublishPath(fixture)) + Path.DirectorySeparatorChar; - string outputDir = RelativePath(BundleHelper.GetBundleDir(fixture).FullName) + Path.DirectorySeparatorChar; - - BundleRun(fixture, publishDir, outputDir); + BundleRun(fixture, publishDir); } public class SharedTestState : IDisposable diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleLegacy.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleLegacy.cs index 7b9d6863607d2..1690be766e33a 100644 --- a/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleLegacy.cs +++ b/src/installer/test/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleLegacy.cs @@ -27,8 +27,7 @@ public void TestNetCoreApp3xApp(int minorVersion) { var fixture = (minorVersion == 0) ? sharedTestState.TestFixture30.Copy() : sharedTestState.TestFixture31.Copy(); - // Targetting netcoreap3.x implies BundleOption.BundleAllContent - var singleFile = BundleHelper.BundleApp(fixture, BundleOptions.None, new Version(3, minorVersion)); + var singleFile = BundleHelper.BundleApp(fixture, targetFrameworkVersion: new Version(3, minorVersion)); Command.Create(singleFile) .CaptureStdErr() @@ -50,7 +49,6 @@ private static TestProjectFixture CreatePublishedFixture(string netCoreAppFramew return fixture; } - public class SharedTestState : IDisposable { public TestProjectFixture TestFixture30 { get; set; } From 10732fee1a74fbc7c08dff46db3dcec43cd03bfe Mon Sep 17 00:00:00 2001 From: Swaroop Sridhar Date: Wed, 13 May 2020 01:46:37 -0700 Subject: [PATCH 251/420] Address some code review feedback --- src/coreclr/src/binder/assemblybinder.cpp | 2 +- src/coreclr/src/vm/appdomain.cpp | 3 --- src/coreclr/src/vm/appdomain.hpp | 1 - src/coreclr/src/vm/peimage.cpp | 5 ++++- src/installer/corehost/cli/hostpolicy/deps_resolver.cpp | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/coreclr/src/binder/assemblybinder.cpp b/src/coreclr/src/binder/assemblybinder.cpp index 18d66a8b198f5..0f8c782867107 100644 --- a/src/coreclr/src/binder/assemblybinder.cpp +++ b/src/coreclr/src/binder/assemblybinder.cpp @@ -394,7 +394,7 @@ namespace BINDER_SPACE // At run-time, System.Private.CoreLib.dll is expected to be the NI image. // System.Private.CoreLib.dll is expected to be found at one of the following locations: // * Non-single-file app: In systemDirectory, beside coreclr.dll - // * Framework-dependent single-file app: In system directory, beside coreclr.dll + // * Framework-dependent single-file app: In systemDirectory, beside coreclr.dll // * Self-contained single-file app: Within the single-file bundle. IF_FAIL_GO(AssemblyBinder::GetAssembly(sCoreLib, TRUE /* fIsInGAC */, diff --git a/src/coreclr/src/vm/appdomain.cpp b/src/coreclr/src/vm/appdomain.cpp index 7681e64a99cef..2e39d011b49d8 100644 --- a/src/coreclr/src/vm/appdomain.cpp +++ b/src/coreclr/src/vm/appdomain.cpp @@ -1775,7 +1775,6 @@ void SystemDomain::Init() m_pSystemAssembly = NULL; DWORD size = 0; - AppDomain* pAppDomain = ::GetAppDomain(); // Get the install directory so we can find mscorlib hr = GetInternalSystemDirectory(NULL, &size); @@ -1789,13 +1788,11 @@ void SystemDomain::Init() m_SystemDirectory.Normalize(); // At this point m_SystemDirectory should already be canonicalized - m_BaseLibrary.Append(m_SystemDirectory); if (!m_BaseLibrary.EndsWith(DIRECTORY_SEPARATOR_CHAR_W)) { m_BaseLibrary.Append(DIRECTORY_SEPARATOR_CHAR_W); } - m_BaseLibrary.Append(g_pwBaseLibrary); m_BaseLibrary.Normalize(); diff --git a/src/coreclr/src/vm/appdomain.hpp b/src/coreclr/src/vm/appdomain.hpp index ece967214cc74..f017b42c73a2a 100644 --- a/src/coreclr/src/vm/appdomain.hpp +++ b/src/coreclr/src/vm/appdomain.hpp @@ -29,7 +29,6 @@ #include "gchandleutilities.h" #include "../binder/inc/applicationcontext.hpp" #include "rejit.h" -#include "bundle.h" #ifdef FEATURE_MULTICOREJIT #include "multicorejit.h" diff --git a/src/coreclr/src/vm/peimage.cpp b/src/coreclr/src/vm/peimage.cpp index c07facfa37269..be06ebc837a14 100644 --- a/src/coreclr/src/vm/peimage.cpp +++ b/src/coreclr/src/vm/peimage.cpp @@ -973,7 +973,10 @@ PTR_PEImageLayout PEImage::GetLayoutInternal(DWORD imageLayoutMask,DWORD flags) BOOL bIsFlatLayoutSuitable = ((imageLayoutMask & PEImageLayout::LAYOUT_FLAT) != 0); #if !defined(TARGET_UNIX) - bIsFlatLayoutSuitable = IsInBundle() || !bIsMappedLayoutSuitable; + if (!IsInBundle() && bIsMappedLayoutSuitable) + { + bIsFlatLayoutSuitable = FALSE; + } #endif // !TARGET_UNIX _ASSERTE(bIsMappedLayoutSuitable || bIsFlatLayoutSuitable); diff --git a/src/installer/corehost/cli/hostpolicy/deps_resolver.cpp b/src/installer/corehost/cli/hostpolicy/deps_resolver.cpp index 5a3d5a0fc612d..de3762cb13098 100644 --- a/src/installer/corehost/cli/hostpolicy/deps_resolver.cpp +++ b/src/installer/corehost/cli/hostpolicy/deps_resolver.cpp @@ -282,7 +282,7 @@ void deps_resolver_t::setup_additional_probes(const std::vector& * -- When a deps json based probe is performed, the deps entry's package name and version must match. * -- When looking into a published dir, for rid specific assets lookup rid split folders; for non-rid assets lookup the layout dir. * The path to the resolved file is returned in candidate out parameter - * If the candidate is embedded within the single-file bundle (rather than an actual file on disk), found_in_bundle will be set to true. + * If the candidate is embedded within the single-file bundle (rather than an actual file on disk), loaded_from_bundle will be set to true. */ bool deps_resolver_t::probe_deps_entry(const deps_entry_t& entry, const pal::string_t& deps_dir, int fx_level, pal::string_t* candidate, bool & loaded_from_bundle) { From 54e08b663fd4343e194d9162d7792566b23d380d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Mon, 18 May 2020 11:27:21 +0200 Subject: [PATCH 252/420] Add iOS x86 build (#36602) Needed for the iOS Simulator for 32bit iOS devices. --- eng/native/configureplatform.cmake | 2 + eng/pipelines/common/platform-matrix.yml | 20 ++++++ eng/pipelines/runtime-official.yml | 3 + eng/pipelines/runtime.yml | 4 ++ src/libraries/Native/build-native.sh | 4 ++ .../runtime.compatibility.json | 44 ++++++++++++ .../Microsoft.NETCore.Platforms/runtime.json | 24 +++++++ .../runtimeGroups.props | 2 +- src/mono/Directory.Build.props | 2 +- src/mono/mono.proj | 71 ++++++++++--------- .../mono/tools/offsets-tool/offsets-tool.py | 5 ++ 11 files changed, 144 insertions(+), 37 deletions(-) diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index 1c5254d84965a..9dfd3cff36ac4 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -88,6 +88,8 @@ if(CLR_CMAKE_HOST_OS STREQUAL iOS) set(CLR_CMAKE_HOST_IOS 1) if(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64") set(CLR_CMAKE_HOST_UNIX_AMD64 1) + elseif(CMAKE_OSX_ARCHITECTURES MATCHES "i386") + set(CLR_CMAKE_HOST_UNIX_X86 1) elseif(CMAKE_OSX_ARCHITECTURES MATCHES "armv7") set(CLR_CMAKE_HOST_UNIX_ARM 1) elseif(CMAKE_OSX_ARCHITECTURES MATCHES "arm64") diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index 21e0b2a1c20f0..2979349d8beca 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -348,6 +348,26 @@ jobs: managedTestBuildOsGroup: OSX ${{ insert }}: ${{ parameters.jobParameters }} +# iOS x86 + +- ${{ if containsValue(parameters.platforms, 'iOS_x86') }}: + - template: xplat-setup.yml + parameters: + jobTemplate: ${{ parameters.jobTemplate }} + helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }} + osGroup: iOS + archType: x86 + platform: iOS_x86 + jobParameters: + runtimeFlavor: mono + stagedBuild: ${{ parameters.stagedBuild }} + buildConfig: ${{ parameters.buildConfig }} + ${{ if eq(parameters.passPlatforms, true) }}: + platforms: ${{ parameters.platforms }} + helixQueueGroup: ${{ parameters.helixQueueGroup }} + managedTestBuildOsGroup: OSX + ${{ insert }}: ${{ parameters.jobParameters }} + # iOS arm - ${{ if containsValue(parameters.platforms, 'iOS_arm') }}: diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index cb8388d654679..22b4e8c186b9f 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -77,6 +77,7 @@ stages: - tvOS_x64 - tvOS_arm64 - iOS_x64 + - iOS_x86 - iOS_arm - iOS_arm64 - OSX_x64 @@ -131,6 +132,7 @@ stages: - tvOS_x64 - tvOS_arm64 - iOS_x64 + - iOS_x86 - iOS_arm - iOS_arm64 - Browser_wasm @@ -196,6 +198,7 @@ stages: - iOS_arm - iOS_arm64 - iOS_x64 + - iOS_x86 - Android_arm - Android_arm64 - Android_x64 diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 2ee5255fee8c1..97fc69361b167 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -247,6 +247,7 @@ jobs: - tvOS_x64 - tvOS_arm64 - iOS_x64 + - iOS_x86 - iOS_arm - iOS_arm64 - OSX_x64 @@ -284,6 +285,7 @@ jobs: - tvOS_x64 - tvOS_arm64 - iOS_x64 + - iOS_x86 - iOS_arm - iOS_arm64 - Linux_x64 @@ -440,6 +442,7 @@ jobs: - Android_arm64 - tvOS_x64 - iOS_arm64 + - iOS_x86 - Browser_wasm jobParameters: liveRuntimeBuildConfig: debug @@ -552,6 +555,7 @@ jobs: - Android_arm64 - tvOS_x64 - iOS_arm64 + - iOS_x86 - OSX_x64 - Linux_x64 - Browser_wasm diff --git a/src/libraries/Native/build-native.sh b/src/libraries/Native/build-native.sh index 84061ea1b2cef..fb8b183403eb5 100755 --- a/src/libraries/Native/build-native.sh +++ b/src/libraries/Native/build-native.sh @@ -109,6 +109,10 @@ elif [[ "$__TargetOS" == iOS ]]; then # set default iOS simulator deployment target (8.0 is the minimum supported by Xcode 11) # keep in sync with src/mono/Directory.Build.props __CMakeArgs="-DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=8.0 -DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" + elif [[ "$__BuildArch" == x86 ]]; then + # set default iOS simulator deployment target (8.0 is the minimum supported by Xcode 11) + # keep in sync with src/mono/Directory.Build.props + __CMakeArgs="-DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=8.0 -DCMAKE_OSX_ARCHITECTURES=\"i386\" $__CMakeArgs" elif [[ "$__BuildArch" == arm64 ]]; then # set default iOS device deployment target (7.0 is the minimum supported by Xcode 11) # keep in sync with src/mono/Directory.Build.props diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json index 79a50fab018df..8612ca4647164 100644 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json +++ b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json @@ -2052,6 +2052,14 @@ "any", "base" ], + "ios-x86": [ + "ios-x86", + "ios", + "unix-x86", + "unix", + "any", + "base" + ], "ios.10": [ "ios.10", "ios.9", @@ -2103,6 +2111,20 @@ "any", "base" ], + "ios.10-x86": [ + "ios.10-x86", + "ios.10", + "ios.9-x86", + "ios.9", + "ios.8-x86", + "ios.8", + "ios-x86", + "ios", + "unix-x86", + "unix", + "any", + "base" + ], "ios.11": [ "ios.11", "ios.10", @@ -2281,6 +2303,16 @@ "any", "base" ], + "ios.8-x86": [ + "ios.8-x86", + "ios.8", + "ios-x86", + "ios", + "unix-x86", + "unix", + "any", + "base" + ], "ios.9": [ "ios.9", "ios.8", @@ -2325,6 +2357,18 @@ "any", "base" ], + "ios.9-x86": [ + "ios.9-x86", + "ios.9", + "ios.8-x86", + "ios.8", + "ios-x86", + "ios", + "unix-x86", + "unix", + "any", + "base" + ], "linux": [ "linux", "unix", diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json index dd502f4ca3138..ff9a224f0c471 100644 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json +++ b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json @@ -910,6 +910,12 @@ "unix-x64" ] }, + "ios-x86": { + "#import": [ + "ios", + "unix-x86" + ] + }, "ios.10": { "#import": [ "ios.9" @@ -933,6 +939,12 @@ "ios.9-x64" ] }, + "ios.10-x86": { + "#import": [ + "ios.10", + "ios.9-x86" + ] + }, "ios.11": { "#import": [ "ios.10" @@ -1007,6 +1019,12 @@ "ios-x64" ] }, + "ios.8-x86": { + "#import": [ + "ios.8", + "ios-x86" + ] + }, "ios.9": { "#import": [ "ios.8" @@ -1030,6 +1048,12 @@ "ios.8-x64" ] }, + "ios.9-x86": { + "#import": [ + "ios.9", + "ios.8-x86" + ] + }, "linux": { "#import": [ "unix" diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props index cd8358675fc13..5ee96996906b8 100644 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props +++ b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props @@ -71,7 +71,7 @@ unix - arm + arm;x86 8;9;10 diff --git a/src/mono/Directory.Build.props b/src/mono/Directory.Build.props index a17c7ae918729..baa3cfc4c5dd1 100644 --- a/src/mono/Directory.Build.props +++ b/src/mono/Directory.Build.props @@ -39,7 +39,7 @@ true true true - true + true true true true diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 3951191cc1d7b..0007880a01daf 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -40,7 +40,7 @@ - + @@ -167,15 +167,6 @@ <_MonoLDFLAGS Include="-framework CoreFoundation" /> <_MonoLDFLAGS Include="-lobjc" /> <_MonoLDFLAGS Include="-lc++" /> - - - <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' == 'arm64'" Include="--abi=aarch64-apple-darwin10" /> - <_MonoAotCrossOffsetsToolParams Include="--netcore" /> - <_MonoAotCrossOffsetsToolParams Include="--targetdir="$(MonoObjDir)"" /> - <_MonoAotCrossOffsetsToolParams Include="--monodir="$(MonoProjectRoot)"" /> - <_MonoAotCrossOffsetsToolParams Include="--outfile="$(MonoObjDir)cross/offsets-$(Platform)-darwin.h"" /> - <_MonoAotCrossOffsetsToolParams Include="--libclang="$(XcodeDir)/Toolchains/XcodeDefault.xctoolchain/usr/lib/libclang.dylib"" /> - <_MonoAotCrossOffsetsToolParams Include="--sysroot="$(XcodeDir)/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS$(tvOSVersion).sdk"" /> @@ -312,21 +303,12 @@ <_MonoLDFLAGS Include="-framework CoreFoundation" /> <_MonoLDFLAGS Include="-lobjc" /> <_MonoLDFLAGS Include="-lc++" /> - - - <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' == 'arm64'" Include="--abi=aarch64-apple-darwin10" /> - <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' == 'arm'" Include="--abi=arm-apple-darwin10" /> - <_MonoAotCrossOffsetsToolParams Include="--netcore" /> - <_MonoAotCrossOffsetsToolParams Include="--targetdir="$(MonoObjDir)"" /> - <_MonoAotCrossOffsetsToolParams Include="--monodir="$(MonoProjectRoot)"" /> - <_MonoAotCrossOffsetsToolParams Include="--outfile="$(MonoObjDir)cross/offsets-$(Platform)-darwin.h"" /> - <_MonoAotCrossOffsetsToolParams Include="--libclang="$(XcodeDir)/Toolchains/XcodeDefault.xctoolchain/usr/lib/libclang.dylib"" /> - <_MonoAotCrossOffsetsToolParams Include="--sysroot="$(XcodeDir)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS$(iOSVersion).sdk"" /> - <_MonoConfigureParams Include="--host=x86_64-apple-darwin10" /> + <_MonoConfigureParams Condition="'$(Platform)' == 'x64'" Include="--host=x86_64-apple-darwin10" /> + <_MonoConfigureParams Condition="'$(Platform)' == 'x86'" Include="--host=i386-apple-darwin10" /> <_MonoConfigureParams Include="--disable-boehm" /> <_MonoConfigureParams Include="--disable-btls" /> <_MonoConfigureParams Include="--disable-executables" /> @@ -353,20 +335,26 @@ <_MonoAC_VARS Include="ac_cv_func_shm_open_working_with_mmap=no" /> <_MonoAC_VARS Include="mono_cv_uscore=yes" /> - <_MonoCFLAGS Include="-arch x86_64" /> - <_MonoCFLAGS Include="-m64" /> + <_MonoCFLAGS Condition="'$(Platform)' == 'x64'" Include="-arch x86_64" /> + <_MonoCFLAGS Condition="'$(Platform)' == 'x64'" Include="-m64" /> + <_MonoCFLAGS Condition="'$(Platform)' == 'x86'" Include="-arch i386" /> + <_MonoCFLAGS Condition="'$(Platform)' == 'x86'" Include="-m32" /> <_MonoCFLAGS Include="-isysroot $(XcodeDir)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator$(iOSVersion).sdk" /> <_MonoCFLAGS Include="-mios-simulator-version-min=$(iOSVersionMin)" /> <_MonoCFLAGS Include="-Wl,-application_extension" /> - <_MonoCXXFLAGS Include="-arch x86_64" /> - <_MonoCXXFLAGS Include="-m64" /> + <_MonoCXXFLAGS Condition="'$(Platform)' == 'x64'" Include="-arch x86_64" /> + <_MonoCXXFLAGS Condition="'$(Platform)' == 'x64'" Include="-m64" /> + <_MonoCXXFLAGS Condition="'$(Platform)' == 'x86'" Include="-arch i386" /> + <_MonoCXXFLAGS Condition="'$(Platform)' == 'x86'" Include="-m32" /> <_MonoCXXFLAGS Include="-isysroot $(XcodeDir)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator$(iOSVersion).sdk" /> <_MonoCXXFLAGS Include="-mios-simulator-version-min=$(iOSVersionMin)" /> <_MonoCXXFLAGS Include="-Wl,-application_extension" /> - <_MonoCPPFLAGS Include="-arch x86_64" /> - <_MonoCPPFLAGS Include="-m64" /> + <_MonoCPPFLAGS Condition="'$(Platform)' == 'x64'" Include="-arch x86_64" /> + <_MonoCPPFLAGS Condition="'$(Platform)' == 'x64'" Include="-m64" /> + <_MonoCPPFLAGS Condition="'$(Platform)' == 'x86'" Include="-arch i386" /> + <_MonoCPPFLAGS Condition="'$(Platform)' == 'x86'" Include="-m32" /> <_MonoCPPFLAGS Include="-isysroot $(XcodeDir)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator$(iOSVersion).sdk" /> <_MonoCPPFLAGS Include="-mios-simulator-version-min=$(iOSVersionMin)" /> <_MonoCPPFLAGS Include="-Wl,-application_extension" /> @@ -379,10 +367,10 @@ <_MonoAotCrossConfigureParams Include="--host=x86_64-apple-darwin10" /> - <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'arm64'" Include="--target=aarch64-darwin" /> - <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'arm'" Include="--target=arm-darwin" /> - <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'x86'" Include="--target=i386-apple-darwin" /> - <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'arm'" Include="--with-cross-offsets=$(MonoObjDir)cross/offsets-$(Platform)-darwin.h" /> + <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'arm64'" Include="--target=aarch64-apple-darwin10" /> + <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'arm'" Include="--target=arm-apple-darwin10" /> + <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'x86'" Include="--target=i386-apple-darwin10" /> + <_MonoAotCrossConfigureParams Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'arm' or '$(Platform)' == 'x86'" Include="--with-cross-offsets=$(MonoObjDir)cross/offsets-$(Platform)-darwin.h" /> <_MonoAotCrossConfigureParams Include="--with-core=only" /> <_MonoAotCrossConfigureParams Include="--enable-maintainer-mode" /> <_MonoAotCrossConfigureParams Include="--enable-compile-warnings" /> @@ -427,6 +415,19 @@ <_MonoAotCrossCXXPPFLAGS Include="-m64" /> <_MonoAotCrossLDFLAGS Include="-stdlib=libc++" /> + + + <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' == 'arm64'" Include="--abi=aarch64-apple-darwin10" /> + <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' == 'arm'" Include="--abi=arm-apple-darwin10" /> + <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' == 'x86'" Include="--abi=i386-apple-darwin10" /> + <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' != 'x64'" Include="--netcore" /> + <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' != 'x64'" Include="--targetdir="$(MonoObjDir)"" /> + <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' != 'x64'" Include="--monodir="$(MonoProjectRoot)"" /> + <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' != 'x64'" Include="--outfile="$(MonoObjDir)cross/offsets-$(Platform)-darwin.h"" /> + <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' != 'x64'" Include="--libclang="$(XcodeDir)/Toolchains/XcodeDefault.xctoolchain/usr/lib/libclang.dylib"" /> + <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' != 'x64' and '$(TargetsiOS)' == 'true' and '$(TargetsiOSSimulator)' != 'true'" Include="--sysroot="$(XcodeDir)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS$(iOSVersion).sdk"" /> + <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' != 'x64' and '$(TargetsiOS)' == 'true' and '$(TargetsiOSSimulator)' == 'true'" Include="--sysroot="$(XcodeDir)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator$(iOSVersion).sdk"" /> + <_MonoAotCrossOffsetsToolParams Condition="'$(Platform)' != 'x64' and '$(TargetstvOS)' == 'true'" Include="--sysroot="$(XcodeDir)/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS$(tvOSVersion).sdk"" /> @@ -908,11 +909,11 @@ <_MonoRuntimeFilePath Condition="'$(TargetsBrowser)' == 'true'">$(MonoObjDir)mono\mini\.libs\libmonosgen-2.0.a <_MonoRuntimeFilePath Condition="'$(_MonoRuntimeFilePath)' == ''">$(MonoObjDir)mono\mini\.libs\libmonosgen-2.0.so <_MonoRuntimeStaticFilePath Condition="'$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true' or '$(TargetsAndroid)' == 'true'">$(MonoObjDir)out\lib\libmonosgen-2.0.a - <_MonoAotCrossFilePath Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'arm64'">$(MonoObjDir)cross\out\bin\aarch64-darwin-mono-sgen - <_MonoAotCrossFilePath Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'arm'">$(MonoObjDir)cross\out\bin\arm-darwin-mono-sgen + <_MonoAotCrossFilePath Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'arm64'">$(MonoObjDir)cross\out\bin\aarch64-apple-darwin10-mono-sgen + <_MonoAotCrossFilePath Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'arm'">$(MonoObjDir)cross\out\bin\arm-apple-darwin10-mono-sgen + <_MonoAotCrossFilePath Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'x86'">$(MonoObjDir)cross\out\bin\i386-apple-darwin10-mono-sgen <_MonoAotCrossFilePath Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'x64'">$(MonoObjDir)cross\out\bin\mono-sgen - <_MonoAotCrossFilePath Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'x86'">$(MonoObjDir)cross\out\bin\mono-sgen - <_MonoAotCrossFilePath Condition="'$(TargetstvOS)' == 'true' and '$(Platform)' == 'arm64'">$(MonoObjDir)cross\out\bin\aarch64-darwin-mono-sgen + <_MonoAotCrossFilePath Condition="'$(TargetstvOS)' == 'true' and '$(Platform)' == 'arm64'">$(MonoObjDir)cross\out\bin\aarch64-apple-darwin10-mono-sgen <_MonoAotCrossFilePath Condition="'$(TargetstvOS)' == 'true' and '$(Platform)' == 'x64'">$(MonoObjDir)cross\out\bin\mono-sgen <_MonoAotCrossFilePath Condition="'$(TargetsBrowser)' == 'true'">$(MonoObjDir)cross\out\bin\wasm32-unknown-none-mono-sgen diff --git a/src/mono/mono/tools/offsets-tool/offsets-tool.py b/src/mono/mono/tools/offsets-tool/offsets-tool.py index d44e436e22985..f9f7170aac319 100644 --- a/src/mono/mono/tools/offsets-tool/offsets-tool.py +++ b/src/mono/mono/tools/offsets-tool/offsets-tool.py @@ -125,6 +125,11 @@ def require_emscipten_path (args): self.target = Target ("TARGET_ARM64", "TARGET_IOS", IOS_DEFINES) self.target_args += ["-arch", "arm64"] self.target_args += ["-isysroot", args.sysroot] + elif "i386-apple-darwin10" == args.abi: + require_sysroot (args) + self.target = Target ("TARGET_X86", "", IOS_DEFINES) + self.target_args += ["-arch", "i386"] + self.target_args += ["-isysroot", args.sysroot] # watchOS elif "armv7k-apple-darwin" == args.abi: From d9b006ba9a27dce2f19217c00f843337a4428805 Mon Sep 17 00:00:00 2001 From: Alexis Christoforides Date: Mon, 18 May 2020 08:46:49 -0400 Subject: [PATCH 253/420] [mono] Fix AssemblyLoadContext.GetRuntimeAssembly() for AssemblyBuilders (#36367) --- .../src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs index 0fea7764808c2..5e58b1b3cf47d 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs @@ -7,6 +7,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; +using Internal.Runtime.CompilerServices; namespace System.Runtime.Loader { @@ -155,15 +156,13 @@ private static void MonoResolveUnmanagedDllUsingEvent(string unmanagedDllName, A dll = context.GetResolvedUnmanagedDll(assembly, unmanagedDllName); } - #region Copied from AssemblyLoadContext.CoreCLR.cs, modified until our AssemblyBuilder implementation is functional private static RuntimeAssembly? GetRuntimeAssembly(Assembly? asm) { return asm == null ? null : asm is RuntimeAssembly rtAssembly ? rtAssembly : - //asm is System.Reflection.Emit.AssemblyBuilder ab ? ab.InternalAssembly : + asm is System.Reflection.Emit.AssemblyBuilder ab ? Unsafe.As(ab) : // Mono AssemblyBuilder is also a RuntimeAssembly, see AssemblyBuilder.Mono.cs null; } - #endregion } } From 2962ded0845db263393b4c853bd4d6e497cd6e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Mon, 18 May 2020 15:49:35 +0200 Subject: [PATCH 254/420] Fix mono file name on iOS/Browser (#36646) We initially intended to just use libmono.so/dylib as the name to simplify and follow the libcoreclr.dylib pattern and we did that by just copying to a different name after the build. However that didn't work on Android since the name gets embedded inside the binary and Android checks that these match, so we'd either have to change the (auto)make to use the correct library name (and possibly creates complex conditionals in the Makefile for netcore) or go back to using `libmonosgen-2.0` on iOS. We decided to do the latter. --- src/mono/mono.proj | 10 +++------- src/mono/netcore/sample/iOS/Program.csproj | 2 +- src/mono/wasm/Makefile | 2 +- .../tasks/mobile.tasks/AppleAppBuilder/Xcode.cs | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 0007880a01daf..2b7d2ed316373 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -14,15 +14,11 @@ coreclr.dll libcoreclr.dylib libcoreclr.so - libmono.dylib - libmono.dylib + libmonosgen-2.0.dylib libmonosgen-2.0.so - libmono.a - libmono.a - libmonosgen-2.0.a - libmono.a - libmono.a + libmonosgen-2.0.a $(CoreClrFileName) + libmonosgen-2.0.a $(Configuration) $(Configuration) $(ArtifactsDir)tests\coreclr\$(TargetOS).$(Platform).$(CoreClrTestConfig)\Tests\Core_Root diff --git a/src/mono/netcore/sample/iOS/Program.csproj b/src/mono/netcore/sample/iOS/Program.csproj index 6105c1f58fbb4..d30d644fd90f2 100644 --- a/src/mono/netcore/sample/iOS/Program.csproj +++ b/src/mono/netcore/sample/iOS/Program.csproj @@ -35,7 +35,7 @@ - + diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile index 78e6a049d843e..9cd0b9ba169fe 100644 --- a/src/mono/wasm/Makefile +++ b/src/mono/wasm/Makefile @@ -43,7 +43,7 @@ emsdk_env.sh: | provision-wasm cd $(EMSDK_PATH) && ./emsdk construct_env $(CURDIR)/emsdk_env.sh MONO_OBJ_DIR=$(OBJDIR)/mono/Browser.wasm.$(CONFIG) -MONO_LIBS = $(MONO_BIN_DIR)/{libmono-ee-interp.a,libmono.a,libmono-ilgen.a,libmono-icall-table.a} ${SYS_NATIVE_DIR}/libSystem.Native.a +MONO_LIBS = $(MONO_BIN_DIR)/{libmono-ee-interp.a,libmonosgen-2.0.a,libmono-ilgen.a,libmono-icall-table.a} ${SYS_NATIVE_DIR}/libSystem.Native.a MONO_INCLUDE_DIR=$(MONO_BIN_DIR)/include/mono-2.0 BUILDS_BIN_DIR=$(MONO_BIN_DIR)/wasm/runtimes BUILDS_OBJ_DIR=$(MONO_OBJ_DIR)/wasm/runtimes diff --git a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs index 5c51e245135f2..c0db9d1d2837e 100644 --- a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs +++ b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs @@ -59,7 +59,7 @@ internal class Xcode { string libName = Path.GetFileNameWithoutExtension(lib); // libmono must always be statically linked, for other librarires we can use dylibs - bool dylibExists = libName != "libmono" && dylibs.Any(dylib => Path.GetFileName(dylib) == libName + ".dylib"); + bool dylibExists = libName != "libmonosgen-2.0" && dylibs.Any(dylib => Path.GetFileName(dylib) == libName + ".dylib"); if (!preferDylibs || !dylibExists) { From 0ac06661636ea7f1a3cc2a6ee9245d6df5b47f24 Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Mon, 18 May 2020 11:02:32 -0300 Subject: [PATCH 255/420] [mono] Linking statically ICU shim on mono (#35790) Linking statically ICU shim on mono for windows, linux, macOs and android. --- .../Loader/AssemblyLoadContext.CoreCLR.cs | 10 +++ .../Common/src/Interop/Interop.Libraries.cs | 4 + .../System.Globalization.Native/pal_icushim.c | 5 +- .../System.Globalization/tests/IcuTests.cs | 3 +- .../Runtime/Loader/AssemblyLoadContext.cs | 10 --- src/mono/configure.ac | 40 +++++++++ src/mono/mono/metadata/Makefile.am | 26 +++++- src/mono/mono/metadata/native-library.c | 20 ++++- src/mono/mono/mini/monovm.c | 3 + src/mono/mono/utils/mono-dl-posix.c | 6 +- src/mono/mono/utils/mono-dl.c | 34 ++++++++ src/mono/mono/utils/mono-dl.h | 2 + src/mono/msvc/libmono-dynamic.vcxproj | 16 ++-- src/mono/msvc/libmonoruntime.targets | 1 + src/mono/msvc/libmonoruntime.targets.filters | 1 + src/mono/msvc/libmonoruntime.vcxproj | 16 ++-- src/mono/msvc/mono.props | 4 + src/mono/msvc/shimglobalization.targets | 51 +++++++++++ .../msvc/shimglobalization.targets.filters | 87 +++++++++++++++++++ .../Globalization/GlobalizationMode.Mono.cs | 16 ++-- .../GlobalizationMode.Unix.Mono.cs | 1 + .../GlobalizationMode.Windows.Mono.cs | 10 +-- .../Loader/AssemblyLoadContext.Mono.cs | 8 +- 23 files changed, 324 insertions(+), 50 deletions(-) create mode 100644 src/mono/msvc/shimglobalization.targets create mode 100644 src/mono/msvc/shimglobalization.targets.filters diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs index 7b494115f72d6..997fa49107dce 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs @@ -95,6 +95,16 @@ internal Assembly LoadFromInMemoryModule(IntPtr moduleHandle) } #endif + // This method is invoked by the VM to resolve a satellite assembly reference + // after trying assembly resolution via Load override without success. + private static Assembly? ResolveSatelliteAssembly(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName) + { + AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target)!; + + // Invoke the ResolveSatelliteAssembly method + return context.ResolveSatelliteAssembly(assemblyName); + } + // This method is invoked by the VM when using the host-provided assembly load context // implementation. private static IntPtr ResolveUnmanagedDll(string unmanagedDllName, IntPtr gchManagedAssemblyLoadContext) diff --git a/src/libraries/Common/src/Interop/Interop.Libraries.cs b/src/libraries/Common/src/Interop/Interop.Libraries.cs index 4fee38ad35bd2..9a64a909e35ca 100644 --- a/src/libraries/Common/src/Interop/Interop.Libraries.cs +++ b/src/libraries/Common/src/Interop/Interop.Libraries.cs @@ -6,6 +6,10 @@ internal static partial class Interop { internal static partial class Libraries { +#if MONO + internal const string GlobalizationNative = "__Internal"; +#else internal const string GlobalizationNative = "libSystem.Globalization.Native"; +#endif } } diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim.c b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim.c index 1a594c461c0ed..093188b964a0e 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim.c +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim.c @@ -3,6 +3,9 @@ // See the LICENSE file in the project root for more information. // +#include +#include "pal_icushim_internal.h" + #if defined(TARGET_UNIX) #include #elif defined(TARGET_WINDOWS) @@ -10,12 +13,10 @@ #include #include #endif -#include #include #include #include -#include "pal_icushim_internal.h" #include "pal_icushim.h" // Define pointers to all the used ICU functions diff --git a/src/libraries/System.Globalization/tests/IcuTests.cs b/src/libraries/System.Globalization/tests/IcuTests.cs index 8e862c910195f..80533da8fb7d1 100644 --- a/src/libraries/System.Globalization/tests/IcuTests.cs +++ b/src/libraries/System.Globalization/tests/IcuTests.cs @@ -11,8 +11,7 @@ namespace System.Globalization.Tests public class IcuTests { private static bool IsIcuCompatiblePlatform => PlatformDetection.IsNotWindows || - (!PlatformDetection.IsMonoRuntime && - PlatformDetection.IsWindows10Version1903OrGreater); + PlatformDetection.IsWindows10Version1903OrGreater; [ConditionalFact(nameof(IsIcuCompatiblePlatform))] public static void IcuShouldBeUsedByDefault() diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs index c958169fe579d..80d7c00ea8d54 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs @@ -564,16 +564,6 @@ public void Dispose() return context.ResolveUsingLoad(assemblyName); } - // This method is invoked by the VM to resolve a satellite assembly reference - // after trying assembly resolution via Load override without success. - private static Assembly? ResolveSatelliteAssembly(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName) - { - AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target)!; - - // Invoke the ResolveSatelliteAssembly method - return context.ResolveSatelliteAssembly(assemblyName); - } - private Assembly? GetFirstResolvedAssemblyFromResolvingEvent(AssemblyName assemblyName) { Assembly? resolvedAssembly = null; diff --git a/src/mono/configure.ac b/src/mono/configure.ac index 42ceddb528e27..94c228bd8049f 100644 --- a/src/mono/configure.ac +++ b/src/mono/configure.ac @@ -6795,6 +6795,46 @@ AC_COMPILE_IFELSE( AC_MSG_RESULT(no) ]) +# for icu shim +ICU_SHIM_PATH=. +if test x$with_core = xonly; then + if test x$cross_compiling = xno; then + AC_CHECK_FILE($srcdir/../libraries/Native/Unix/System.Globalization.Native/pal_icushim.h, [have_shim_globalization=yes], [have_shim_globalization=no]) + fi + if test x$have_shim_globalization = xyes || test x$cross_compiling = xyes; then + ICU_SHIM_PATH=../../../libraries/Native/Unix/System.Globalization.Native + if test x$target_osx = xyes; then + ORIG_CPPFLAGS=$CPPFLAGS + # adding icu path to pkg_config_path + PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig + export PKG_CONFIG_PATH + CPPFLAGS="`pkg-config --cflags-only-I icu-uc`" + AC_CHECK_LIB(icucore, ucol_open, LIBS=$LIBS, + [AC_MSG_ERROR([Cannot find libicucore, skipping build for System.Globalization.Native. .NET globalization is not expected to function.])]) + AC_CHECK_HEADER(unicode/utypes.h, [have_sys_icu=yes], [have_sys_icu=no]) + if test x$have_sys_icu = xyes; then + ICU_CFLAGS="$CPPFLAGS -DOSX_ICU_LIBRARY_PATH=AS_ESCAPE(\"/usr/lib/libicucore.dylib\", '\"') -DTARGET_UNIX -DU_DISABLE_RENAMING -Wno-reserved-id-macro -Wno-documentation -Wno-documentation-unknown-command -Wno-switch-enum -Wno-covered-switch-default -Wno-covered-switch-default -Wno-extra-semi-stmt -Wno-unknown-warning-option -Wno-deprecated-declarations" + fi + CPPFLAGS=$ORIG_CPPFLAGS + elif test x$platform_android = xyes; then + ICU_CFLAGS="-DHAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS -DHAVE_SET_MAX_VARIABLE -DTARGET_UNIX -DTARGET_ANDROID -Wno-reserved-id-macro -Wno-documentation -Wno-documentation-unknown-command -Wno-switch-enum -Wno-covered-switch-default -Wno-covered-switch-default -Wno-extra-semi-stmt -Wno-unknown-warning-option" + have_sys_icu=yes + elif test x$host_linux = xyes; then + AC_CHECK_LIB(icuuc, main, LIBS=$LIBS, + [AC_MSG_ERROR([Cannot find libicuuc, try installing libicu-dev (or the appropriate package for your platform).])]) + AC_CHECK_LIB(icui18n, main, LIBS=$LIBS, + [AC_MSG_ERROR([Cannot find libicui18n, try installing libicu-dev (or the appropriate package for your platform).])]) + AC_CHECK_HEADER(unicode/utypes.h, [have_sys_icu=yes], [have_sys_icu=no]) + if test x$have_sys_icu = xyes; then + ICU_CFLAGS="-DTARGET_UNIX -Wno-reserved-id-macro -Wno-documentation -Wno-documentation-unknown-command -Wno-switch-enum -Wno-covered-switch-default -Wno-covered-switch-default -Wno-extra-semi-stmt -Wno-unknown-warning-option" + fi + fi + AC_SUBST(ICU_CFLAGS) + fi +fi +AC_SUBST(ICU_SHIM_PATH) +AM_CONDITIONAL(HAVE_SYS_ICU, test x$have_sys_icu = xyes) + AC_SUBST(CFLAGS) AC_SUBST(CPPFLAGS) AC_SUBST(LDFLAGS) diff --git a/src/mono/mono/metadata/Makefile.am b/src/mono/mono/metadata/Makefile.am index 0415d87bee410..6a4bf4e7238eb 100644 --- a/src/mono/mono/metadata/Makefile.am +++ b/src/mono/mono/metadata/Makefile.am @@ -103,7 +103,7 @@ Z_LIBS=$(BUNDLE_ZLIB_PATH) endif endif -noinst_LTLIBRARIES = libmonoruntime-config.la $(support_libraries) $(boehm_libraries) $(sgen_libraries) +noinst_LTLIBRARIES = libmonoruntime-config.la $(support_libraries) $(boehm_libraries) $(sgen_libraries) $(shim_libraries) lib_LTLIBRARIES = $(icall_table_libraries) $(ilgen_libraries) @@ -136,6 +136,26 @@ libmonoruntime_support_la_SOURCES = support.c libmonoruntime_support_la_LDFLAGS = $(Z_LIBS) libmonoruntime_support_la_CFLAGS = $(filter-out @CXX_REMOVE_CFLAGS@, @CFLAGS@) @ZLIB_CFLAGS@ +if ENABLE_NETCORE +if HAVE_SYS_ICU +shim_libraries = libmonoruntime-shimglobalization.la + +libmonoruntime_shimglobalization_la_SOURCES = \ + @ICU_SHIM_PATH@/pal_calendarData.c \ + @ICU_SHIM_PATH@/pal_casing.c \ + @ICU_SHIM_PATH@/pal_collation.c \ + @ICU_SHIM_PATH@/pal_idna.c \ + @ICU_SHIM_PATH@/pal_locale.c \ + @ICU_SHIM_PATH@/pal_localeNumberData.c \ + @ICU_SHIM_PATH@/pal_localeStringData.c \ + @ICU_SHIM_PATH@/pal_normalization.c \ + @ICU_SHIM_PATH@/pal_timeZoneInfo.c \ + @ICU_SHIM_PATH@/pal_icushim.c + +libmonoruntime_shimglobalization_la_CFLAGS = @ICU_CFLAGS@ -I$(top_srcdir)/../libraries/Native/Unix/Common/ +endif +endif + # # This library contains the icall tables if the runtime was configured with --disable-icall-tables # @@ -424,12 +444,12 @@ if !ENABLE_MSVC_ONLY libmonoruntime_la_SOURCES = $(common_sources) $(icall_tables_sources) $(ilgen_sources) $(gc_dependent_sources) $(null_gc_sources) $(boehm_sources) # Add CXX_ADD_CFLAGS per-library until/unless https://github.com/dotnet/corefx/pull/31342. libmonoruntime_la_CFLAGS = $(BOEHM_DEFINES) @CXX_ADD_CFLAGS@ -libmonoruntime_la_LIBADD = libmonoruntime-config.la $(support_libraries) +libmonoruntime_la_LIBADD = libmonoruntime-config.la $(support_libraries) $(shim_libraries) libmonoruntimesgen_la_SOURCES = $(common_sources) $(icall_tables_sources) $(ilgen_sources) $(gc_dependent_sources) $(sgen_sources) # Add CXX_ADD_CFLAGS per-library until/unless https://github.com/dotnet/corefx/pull/31342. libmonoruntimesgen_la_CFLAGS = $(SGEN_DEFINES) @CXX_ADD_CFLAGS@ -libmonoruntimesgen_la_LIBADD = libmonoruntime-config.la $(support_libraries) +libmonoruntimesgen_la_LIBADD = libmonoruntime-config.la $(support_libraries) $(shim_libraries) endif # !ENABLE_MSVC_ONLY diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c index 91b88a79f8b32..2b04f0d6d83c1 100644 --- a/src/mono/mono/metadata/native-library.c +++ b/src/mono/mono/metadata/native-library.c @@ -758,7 +758,7 @@ netcore_lookup_native_library (MonoAssemblyLoadContext *alc, MonoImage *image, c // We allow a special name to dlopen from the running process namespace, which is not present in CoreCLR if (strcmp (scope, "__Internal") == 0) { if (!internal_module) - internal_module = mono_dl_open (NULL, MONO_DL_LAZY, &error_msg); + internal_module = mono_dl_open_self (&error_msg); module = internal_module; if (!module) { @@ -1240,6 +1240,9 @@ lookup_pinvoke_call_impl (MonoMethod *method, MonoLookupPInvokeStatus *status_ou #endif #ifdef ENABLE_NETCORE +#ifndef HOST_WIN32 +retry_with_libcoreclr: +#endif // FIXME: these flags are not getting passed correctly module = netcore_lookup_native_library (alc, image, new_scope, 0); #else @@ -1262,6 +1265,21 @@ lookup_pinvoke_call_impl (MonoMethod *method, MonoLookupPInvokeStatus *status_ou addr = pinvoke_probe_for_symbol (module, piinfo, new_import, &error_msg); if (!addr) { +#if defined(ENABLE_NETCORE) && !defined(HOST_WIN32) + if (strcmp (new_scope, "__Internal") == 0) { + g_free ((char *)new_scope); +#if defined(TARGET_OSX) + new_scope = g_strdup ("libcoreclr.dylib"); +#else +#if defined(TARGET_ANDROID) + new_scope = g_strdup ("libmonosgen-2.0.so"); +#else + new_scope = g_strdup ("libcoreclr.so"); +#endif +#endif + goto retry_with_libcoreclr; + } +#endif status_out->err_code = LOOKUP_PINVOKE_ERR_NO_SYM; status_out->err_arg = g_strdup (new_import); goto exit; diff --git a/src/mono/mono/mini/monovm.c b/src/mono/mono/mini/monovm.c index d1aff44ed68f6..32185645d985f 100644 --- a/src/mono/mono/mini/monovm.c +++ b/src/mono/mono/mini/monovm.c @@ -181,6 +181,9 @@ parse_properties (int propertyCount, const char **propertyKeys, const char **pro } else if (prop_len == 30 && !strncmp (propertyKeys [i], "System.Globalization.Invariant", 30)) { // TODO: Ideally we should propagate this through AppContext options g_setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", propertyValues [i], TRUE); + } else if (prop_len == 27 && !strncmp (propertyKeys [i], "System.Globalization.UseNls", 27)) { + // TODO: Ideally we should propagate this through AppContext options + g_setenv ("DOTNET_SYSTEM_GLOBALIZATION_USENLS", propertyValues [i], TRUE); } else { #if 0 // can't use mono logger, it's not initialized yet. diff --git a/src/mono/mono/utils/mono-dl-posix.c b/src/mono/mono/utils/mono-dl-posix.c index 1900a1acf5621..a6c767c8285db 100644 --- a/src/mono/mono/utils/mono-dl-posix.c +++ b/src/mono/mono/utils/mono-dl-posix.c @@ -136,10 +136,10 @@ mono_dl_convert_flags (int flags) #ifdef ENABLE_NETCORE // Specifying both will default to LOCAL - if (flags & MONO_DL_LOCAL) - lflags |= RTLD_LOCAL; - else if (flags & MONO_DL_GLOBAL) + if (flags & MONO_DL_GLOBAL && !(flags & MONO_DL_LOCAL)) lflags |= RTLD_GLOBAL; + else + lflags |= RTLD_LOCAL; #else lflags = flags & MONO_DL_LOCAL ? RTLD_LOCAL : RTLD_GLOBAL; #endif diff --git a/src/mono/mono/utils/mono-dl.c b/src/mono/mono/utils/mono-dl.c index 8b4aedd179ac9..32fc1daed7dbc 100644 --- a/src/mono/mono/utils/mono-dl.c +++ b/src/mono/mono/utils/mono-dl.c @@ -21,6 +21,9 @@ #include #include #include +#if defined(ENABLE_NETCORE) && defined(TARGET_ANDROID) +#include +#endif // Contains LIBC_SO definition #ifdef HAVE_GNU_LIB_NAMES_H @@ -168,6 +171,37 @@ fix_libc_name (const char *name) } #endif +/** + * mono_dl_open_self: + * \param error_msg pointer for error message on failure + * + * Returns a handle to the main program, on android x86 it's not possible to + * call dl_open(null), it returns a null handle, so this function returns RTLD_DEFAULT + * handle in this platform. + */ +MonoDl* +mono_dl_open_self (char **error_msg) +{ +#if defined(ENABLE_NETCORE) && defined(TARGET_ANDROID) + MonoDl *module; + if (error_msg) + *error_msg = NULL; + module = (MonoDl *) g_malloc (sizeof (MonoDl)); + if (!module) { + if (error_msg) + *error_msg = g_strdup ("Out of memory"); + return NULL; + } + mono_refcount_init (module, NULL); + module->handle = RTLD_DEFAULT; + module->dl_fallback = NULL; + module->full_name = NULL; + return module; +#else + return mono_dl_open (NULL, MONO_DL_LAZY, error_msg); +#endif +} + /** * mono_dl_open: * \param name name of file containing shared module diff --git a/src/mono/mono/utils/mono-dl.h b/src/mono/mono/utils/mono-dl.h index 6236d98b1e59b..6efee6feabfd5 100644 --- a/src/mono/mono/utils/mono-dl.h +++ b/src/mono/mono/utils/mono-dl.h @@ -43,6 +43,8 @@ char* mono_dl_build_path (const char *directory, const char *name, void ** MonoDl* mono_dl_open_runtime_lib (const char *lib_name, int flags, char **error_msg); +MonoDl* mono_dl_open_self (char **error_msg); + //Platform API for mono_dl const char* mono_dl_get_so_prefix (void); diff --git a/src/mono/msvc/libmono-dynamic.vcxproj b/src/mono/msvc/libmono-dynamic.vcxproj index 3b1fab1c678a2..c63be2c85ad72 100644 --- a/src/mono/msvc/libmono-dynamic.vcxproj +++ b/src/mono/msvc/libmono-dynamic.vcxproj @@ -96,8 +96,8 @@ /D /NODEFAULTLIB:LIBCD" " %(AdditionalOptions) Disabled - $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);%(AdditionalIncludeDirectories) - WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);_DEBUG;%(PreprocessorDefinitions) + $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories) + WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);$(SHIM_GLOBALIZATION_DEFINES);_DEBUG;%(PreprocessorDefinitions) 4996;4018;4244;%(DisableSpecificWarnings) Level3 @@ -123,8 +123,8 @@ /D /NODEFAULTLIB:LIBCD" " %(AdditionalOptions) Disabled - $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);%(AdditionalIncludeDirectories) - WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);WIN64;_DEBUG;%(PreprocessorDefinitions) + $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories) + WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);$(SHIM_GLOBALIZATION_DEFINES);WIN64;_DEBUG;%(PreprocessorDefinitions) 4996;4018;4244;%(DisableSpecificWarnings) Level3 @@ -147,8 +147,8 @@ /D /NODEFAULTLIB:LIBCD" " %(AdditionalOptions) true - $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);%(AdditionalIncludeDirectories) - WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);NDEBUG;%(PreprocessorDefinitions) + $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories) + WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);$(SHIM_GLOBALIZATION_DEFINES);NDEBUG;%(PreprocessorDefinitions) true Level3 true @@ -176,8 +176,8 @@ /D /NODEFAULTLIB:LIBCD" " %(AdditionalOptions) true - $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);%(AdditionalIncludeDirectories) - WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);WIN64;NDEBUG;%(PreprocessorDefinitions) + $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories) + WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);$(SHIM_GLOBALIZATION_DEFINES);WIN64;NDEBUG;%(PreprocessorDefinitions) true Level3 true diff --git a/src/mono/msvc/libmonoruntime.targets b/src/mono/msvc/libmonoruntime.targets index ba371e200fef9..7b797ee766ddc 100644 --- a/src/mono/msvc/libmonoruntime.targets +++ b/src/mono/msvc/libmonoruntime.targets @@ -1,6 +1,7 @@ + diff --git a/src/mono/msvc/libmonoruntime.targets.filters b/src/mono/msvc/libmonoruntime.targets.filters index 870a2b19f6e21..d59ba5b295cee 100644 --- a/src/mono/msvc/libmonoruntime.targets.filters +++ b/src/mono/msvc/libmonoruntime.targets.filters @@ -1,6 +1,7 @@  + diff --git a/src/mono/msvc/libmonoruntime.vcxproj b/src/mono/msvc/libmonoruntime.vcxproj index 4c009edd82391..2541712d4817e 100644 --- a/src/mono/msvc/libmonoruntime.vcxproj +++ b/src/mono/msvc/libmonoruntime.vcxproj @@ -97,8 +97,8 @@ Level3 Disabled - WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);_DEBUG;%(PreprocessorDefinitions) - $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);%(AdditionalIncludeDirectories) + WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);$(SHIM_GLOBALIZATION_DEFINES);_DEBUG;%(PreprocessorDefinitions) + $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories) $(IntDir)$(TargetName).pdb ProgramDatabase @@ -111,8 +111,8 @@ Level3 Disabled - WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);WIN64;_DEBUG;%(PreprocessorDefinitions) - $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);%(AdditionalIncludeDirectories) + WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);$(SHIM_GLOBALIZATION_DEFINES);WIN64;_DEBUG;%(PreprocessorDefinitions) + $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories) $(IntDir)$(TargetName).pdb ProgramDatabase @@ -125,8 +125,8 @@ Level3 true - WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);NDEBUG;%(PreprocessorDefinitions) - $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);%(AdditionalIncludeDirectories) + WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);$(SHIM_GLOBALIZATION_DEFINES);NDEBUG;%(PreprocessorDefinitions) + $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories) $(IntDir)$(TargetName).pdb true @@ -141,8 +141,8 @@ Level3 true - WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);WIN64;NDEBUG;%(PreprocessorDefinitions) - $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);%(AdditionalIncludeDirectories) + WIN32;WIN32_LEAN_AND_MEAN;_LIB;$(GC_DEFINES);$(SHIM_GLOBALIZATION_DEFINES);WIN64;NDEBUG;%(PreprocessorDefinitions) + $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories) $(IntDir)$(TargetName).pdb true diff --git a/src/mono/msvc/mono.props b/src/mono/msvc/mono.props index e71f2cc330d6d..502c5398527d2 100644 --- a/src/mono/msvc/mono.props +++ b/src/mono/msvc/mono.props @@ -45,6 +45,9 @@ $(MONO_LIBGC_INCLUDE_DIR) $(MONO_EGLIB_SOURCE_DIR) 610 + $(top_srcdir)/../libraries/Native/Unix/System.Globalization.Native + $(top_srcdir)/../libraries/Native/Unix/Common + $(SHIM_GLOBALIZATION_COMMON);$(SHIM_GLOBALIZATION) $(MONO_DIR)/external/llvm-project/llvm/include @@ -58,6 +61,7 @@ HAVE_SGEN_GC;HAVE_MOVING_COLLECTOR;HAVE_WRITE_BARRIERS;HAVE_CONC_GC_AS_DEFAULT $(SGEN_DEFINES) + TARGET_WINDOWS;PALEXPORT=extern "C" __declspec(dllexport) libgcmonosgen.lib -sgen $(MONO_BUILD_DIR_PREFIX)sgen/ diff --git a/src/mono/msvc/shimglobalization.targets b/src/mono/msvc/shimglobalization.targets new file mode 100644 index 0000000000000..19bc337ba6c28 --- /dev/null +++ b/src/mono/msvc/shimglobalization.targets @@ -0,0 +1,51 @@ + + + + + CompileAsCpp + + + CompileAsCpp + + + CompileAsCpp + + + CompileAsCpp + + + CompileAsCpp + + + CompileAsCpp + + + CompileAsCpp + + + CompileAsCpp + + + CompileAsCpp + + + CompileAsCpp + + + + + + + + + + + + + + + + + + + diff --git a/src/mono/msvc/shimglobalization.targets.filters b/src/mono/msvc/shimglobalization.targets.filters new file mode 100644 index 0000000000000..106d7b8717996 --- /dev/null +++ b/src/mono/msvc/shimglobalization.targets.filters @@ -0,0 +1,87 @@ + + + + + Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Source Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + Header Files$(MonoRuntimeFilterSubFolder)\shimglobalization + + + + + + + diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Mono.cs index 911499ea842e3..3d7b5ca4866f2 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Mono.cs @@ -6,14 +6,18 @@ namespace System.Globalization { internal static partial class GlobalizationMode { - internal static bool Invariant { get; } = GetGlobalizationInvariantMode(); + private static bool GetInvariantSwitchValue() => + GetSwitchValue("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"); - private static bool GetInvariantSwitchValue() + private static bool GetSwitchValue(string envVariable) { - string? val = Environment.GetEnvironmentVariable("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"); - if (val != null) - return bool.IsTrueStringIgnoreCase(val) || val.Equals("1"); - return false; + bool ret = false; + string? switchValue = Environment.GetEnvironmentVariable(envVariable); + if (switchValue != null) + { + ret = bool.IsTrueStringIgnoreCase(switchValue) || switchValue.Equals("1"); + } + return ret; } } } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.Mono.cs index e3ca7ce617366..70d7e7e3dc41f 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Unix.Mono.cs @@ -8,6 +8,7 @@ namespace System.Globalization { internal partial class GlobalizationMode { + internal static bool Invariant { get; } = GetGlobalizationInvariantMode(); internal static bool UseNls => false; private static bool GetGlobalizationInvariantMode() diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.Mono.cs index 5aaa143170376..abf2a603c2126 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.Windows.Mono.cs @@ -6,11 +6,9 @@ namespace System.Globalization { internal partial class GlobalizationMode { - internal static bool UseNls => true; - - private static bool GetGlobalizationInvariantMode() - { - return GetInvariantSwitchValue(); - } + internal static bool Invariant { get; } = GetInvariantSwitchValue(); + internal static bool UseNls { get; } = !Invariant && + (GetSwitchValue("DOTNET_SYSTEM_GLOBALIZATION_USENLS") || + Interop.Globalization.LoadICU() == 0); } } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs index 5e58b1b3cf47d..4a35247b1c137 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs @@ -130,7 +130,13 @@ public void StartProfileOptimization(string? profile) // Invoked by Mono to resolve requests to load satellite assemblies. private static Assembly? MonoResolveUsingResolveSatelliteAssembly(IntPtr gchALC, string assemblyName) { - return ResolveSatelliteAssembly(gchALC, new AssemblyName(assemblyName)); + AssemblyLoadContext context; + // This check exists because the function can be called early in startup, before the default ALC is initialized + if (gchALC == IntPtr.Zero) + context = Default; + else + context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchALC).Target)!; + return context.ResolveSatelliteAssembly(new AssemblyName(assemblyName)); } private static AssemblyLoadContext GetAssemblyLoadContext(IntPtr gchManagedAssemblyLoadContext) From 6d25c29b133cc8da6c626a72b0c6bf2af88d9847 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 18 May 2020 14:18:48 +0000 Subject: [PATCH 256/420] Update dependencies from https://github.com/mono/linker build 20200518.2 (#36647) Microsoft.NET.ILLink.Tasks From Version 5.0.0-preview.3.20265.2 -> To Version 5.0.0-preview.3.20268.2 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a8e0f383c42a6..510009e4b4833 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -170,9 +170,9 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - 06751af55b1e0b34b8081617728dace17543724b + 0f1b1a569fcd16bd9e7c180d3c8bef1080348d9d https://github.com/dotnet/xharness diff --git a/eng/Versions.props b/eng/Versions.props index 302659f0ea787..2ef1900170fd3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -118,7 +118,7 @@ 3.1.0-preview-20200129.1 - 5.0.0-preview.3.20265.2 + 5.0.0-preview.3.20268.2 9.0.1-alpha.1.20262.1 9.0.1-alpha.1.20262.1 From 6a0570fe5bed49b7705571f817386a2dc6d4c8ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 18 May 2020 17:38:04 +0200 Subject: [PATCH 257/420] Sync one more shared crossgen2 file (#36638) --- .../Common/Compiler/DependencyAnalysis/ObjectNodeSection.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/ObjectNodeSection.cs b/src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/ObjectNodeSection.cs index b89b9482403b7..5a672f953c96b 100644 --- a/src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/ObjectNodeSection.cs +++ b/src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/ObjectNodeSection.cs @@ -39,16 +39,17 @@ public bool IsStandardSection { get { - return this == DataSection || this == ReadOnlyDataSection || this == FoldableReadOnlyDataSection || this == TextSection || this == XDataSection; + return this == DataSection || this == ReadOnlyDataSection || this == FoldableReadOnlyDataSection || this == TextSection || this == XDataSection || this == BssSection; } } public static readonly ObjectNodeSection XDataSection = new ObjectNodeSection("xdata", SectionType.ReadOnly); public static readonly ObjectNodeSection DataSection = new ObjectNodeSection("data", SectionType.Writeable); public static readonly ObjectNodeSection ReadOnlyDataSection = new ObjectNodeSection("rdata", SectionType.ReadOnly); - public static readonly ObjectNodeSection FoldableReadOnlyDataSection = new ObjectNodeSection("rdata$F", SectionType.ReadOnly); + public static readonly ObjectNodeSection FoldableReadOnlyDataSection = new ObjectNodeSection("rdata", SectionType.ReadOnly); public static readonly ObjectNodeSection TextSection = new ObjectNodeSection("text", SectionType.Executable); public static readonly ObjectNodeSection TLSSection = new ObjectNodeSection("TLS", SectionType.Writeable); + public static readonly ObjectNodeSection BssSection = new ObjectNodeSection("bss", SectionType.Writeable); public static readonly ObjectNodeSection ManagedCodeWindowsContentSection = new ObjectNodeSection(".managedcode$I", SectionType.Executable); public static readonly ObjectNodeSection FoldableManagedCodeWindowsContentSection = new ObjectNodeSection(".managedcode$I", SectionType.Executable); public static readonly ObjectNodeSection ManagedCodeUnixContentSection = new ObjectNodeSection("__managedcode", SectionType.Executable); From e102b34b8415234e41defe7391161ca967f74725 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Mon, 18 May 2020 11:58:11 -0400 Subject: [PATCH 258/420] Delete OrderBy(...).First{OrDefault}(...) optimization (#36643) The optimization removes the O(n log n) cost of the OrderBy. But it can result in executing the predicate passed to First{OrDefault} more than in .NET Framework; it would always execute it n times, whereas previously it would execute it <= n times. Developers have expressed concern about the change, in particular when using a relatively expensive predicate on a relatively short list, or when unadvisedly relying on side-effecting predicates. --- .../System.Linq/src/System/Linq/First.cs | 5 -- .../src/System/Linq/OrderedEnumerable.cs | 34 ---------- .../System.Linq/tests/OrderByTests.cs | 64 +++++++++++++++++++ 3 files changed, 64 insertions(+), 39 deletions(-) diff --git a/src/libraries/System.Linq/src/System/Linq/First.cs b/src/libraries/System.Linq/src/System/Linq/First.cs index 95ada9a81cf4e..8763d207c133d 100644 --- a/src/libraries/System.Linq/src/System/Linq/First.cs +++ b/src/libraries/System.Linq/src/System/Linq/First.cs @@ -89,11 +89,6 @@ private static TSource TryGetFirst(this IEnumerable source, Fu ThrowHelper.ThrowArgumentNullException(ExceptionArgument.predicate); } - if (source is OrderedEnumerable ordered) - { - return ordered.TryGetFirst(predicate, out found); - } - foreach (TSource element in source) { if (predicate(element)) diff --git a/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.cs b/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.cs index da0ed0c7c4769..f28f7efa672de 100644 --- a/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.cs +++ b/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.cs @@ -73,40 +73,6 @@ internal IEnumerator GetEnumerator(int minIdx, int maxIdx) IOrderedEnumerable IOrderedEnumerable.CreateOrderedEnumerable(Func keySelector, IComparer? comparer, bool descending) => new OrderedEnumerable(_source, keySelector, comparer, @descending, this); - [return: MaybeNull] - public TElement TryGetFirst(Func predicate, out bool found) - { - CachingComparer comparer = GetComparer(); - using (IEnumerator e = _source.GetEnumerator()) - { - TElement value; - do - { - if (!e.MoveNext()) - { - found = false; - return default!; - } - - value = e.Current; - } - while (!predicate(value)); - - comparer.SetElement(value); - while (e.MoveNext()) - { - TElement x = e.Current; - if (predicate(x) && comparer.Compare(x, true) < 0) - { - value = x; - } - } - - found = true; - return value; - } - } - [return: MaybeNull] public TElement TryGetLast(Func predicate, out bool found) { diff --git a/src/libraries/System.Linq/tests/OrderByTests.cs b/src/libraries/System.Linq/tests/OrderByTests.cs index 8c99b5668c763..627becd98800b 100644 --- a/src/libraries/System.Linq/tests/OrderByTests.cs +++ b/src/libraries/System.Linq/tests/OrderByTests.cs @@ -291,6 +291,38 @@ public void FirstOnEmptyOrderedThrows() Assert.Throws(() => Enumerable.Empty().OrderBy(i => i).First()); } + [Fact] + public void FirstWithPredicateOnOrdered() + { + IEnumerable orderBy = Enumerable.Range(0, 10).Shuffle().OrderBy(i => i); + IEnumerable orderByDescending = Enumerable.Range(0, 10).Shuffle().OrderByDescending(i => i); + int counter; + + counter = 0; + Assert.Equal(0, orderBy.First(i => { counter++; return true; })); + Assert.Equal(1, counter); + + counter = 0; + Assert.Equal(9, orderBy.First(i => { counter++; return i == 9; })); + Assert.Equal(10, counter); + + counter = 0; + Assert.Throws(() => orderBy.First(i => { counter++; return false; })); + Assert.Equal(10, counter); + + counter = 0; + Assert.Equal(9, orderByDescending.First(i => { counter++; return true; })); + Assert.Equal(1, counter); + + counter = 0; + Assert.Equal(0, orderByDescending.First(i => { counter++; return i == 0; })); + Assert.Equal(10, counter); + + counter = 0; + Assert.Throws(() => orderByDescending.First(i => { counter++; return false; })); + Assert.Equal(10, counter); + } + [Fact] public void FirstOrDefaultOnOrdered() { @@ -300,6 +332,38 @@ public void FirstOrDefaultOnOrdered() Assert.Equal(0, Enumerable.Empty().OrderBy(i => i).FirstOrDefault()); } + [Fact] + public void FirstOrDefaultWithPredicateOnOrdered() + { + IEnumerable orderBy = Enumerable.Range(0, 10).Shuffle().OrderBy(i => i); + IEnumerable orderByDescending = Enumerable.Range(0, 10).Shuffle().OrderByDescending(i => i); + int counter; + + counter = 0; + Assert.Equal(0, orderBy.FirstOrDefault(i => { counter++; return true; })); + Assert.Equal(1, counter); + + counter = 0; + Assert.Equal(9, orderBy.FirstOrDefault(i => { counter++; return i == 9; })); + Assert.Equal(10, counter); + + counter = 0; + Assert.Equal(0, orderBy.FirstOrDefault(i => { counter++; return false; })); + Assert.Equal(10, counter); + + counter = 0; + Assert.Equal(9, orderByDescending.FirstOrDefault(i => { counter++; return true; })); + Assert.Equal(1, counter); + + counter = 0; + Assert.Equal(0, orderByDescending.FirstOrDefault(i => { counter++; return i == 0; })); + Assert.Equal(10, counter); + + counter = 0; + Assert.Equal(0, orderByDescending.FirstOrDefault(i => { counter++; return false; })); + Assert.Equal(10, counter); + } + [Fact] public void LastOnOrdered() { From 07a8ca34b0804ee024fa18a94d265c14bdec6db3 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Mon, 18 May 2020 11:58:41 -0400 Subject: [PATCH 259/420] Fix failing Sockets tests after argument exception changes (#36645) --- .../tests/FunctionalTests/DualModeSocketTest.cs | 4 ++-- .../tests/FunctionalTests/LingerStateTest.cs | 2 +- .../tests/FunctionalTests/SendPacketsAsync.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs index bb88d9a93806d..e53c90d949f0a 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs @@ -1649,7 +1649,7 @@ public void Socket_ReceiveFromAsyncV4IPEndPointFromV4Client_Throws() args.RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, UnusedPort); args.SetBuffer(new byte[1], 0, 1); - AssertExtensions.Throws("RemoteEndPoint", () => + AssertExtensions.Throws("e", () => { socket.ReceiveFromAsync(args); }); @@ -2188,7 +2188,7 @@ public void Socket_ReceiveMessageFromAsyncV4IPEndPointFromV4Client_Throws() args.RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, UnusedPort); args.SetBuffer(new byte[1], 0, 1); - AssertExtensions.Throws("RemoteEndPoint", () => + AssertExtensions.Throws("e", () => { socket.ReceiveMessageFromAsync(args); }); diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/LingerStateTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/LingerStateTest.cs index c2d98010766af..80c9c54e8d428 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/LingerStateTest.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/LingerStateTest.cs @@ -19,7 +19,7 @@ private void TestLingerState_Success(Socket sock, bool enabled, int lingerTime) private void TestLingerState_ArgumentException(Socket sock, bool enabled, int lingerTime) { - AssertExtensions.Throws("optionValue.LingerTime", () => + AssertExtensions.Throws("optionValue", () => { sock.LingerState = new LingerOption(enabled, lingerTime); }); diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs index 8c81909054b74..3406be9532737 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs @@ -111,7 +111,7 @@ public void NotConnected_Throw() [InlineData(SocketImplementationType.Async)] public void NullList_Throws(SocketImplementationType type) { - AssertExtensions.Throws("e.SendPacketsElements", () => SendPackets(type, (SendPacketsElement[])null, SocketError.Success, 0)); + AssertExtensions.Throws("e", () => SendPackets(type, (SendPacketsElement[])null, SocketError.Success, 0)); } [OuterLoop] From 0955d7f38597ea80856bd5f6b0cdb915ad90a1a8 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Mon, 18 May 2020 19:16:23 +0300 Subject: [PATCH 260/420] Removed redundant visibility check (#36648) --- .../Text/Json/Serialization/JsonClassInfo.cs | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs index f0adf7412981f..b97b6117923d4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs @@ -111,17 +111,6 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) continue; } - if (IsNonPublicProperty(propertyInfo)) - { - if (JsonPropertyInfo.GetAttribute(propertyInfo) != null) - { - ThrowHelper.ThrowInvalidOperationException_JsonIncludeOnNonPublicInvalid(propertyInfo, currentType); - } - - // Non-public properties should not be included for (de)serialization. - continue; - } - // For now we only support public getters\setters if (propertyInfo.GetMethod?.IsPublic == true || propertyInfo.SetMethod?.IsPublic == true) @@ -149,6 +138,15 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) // else ignore jsonPropertyInfo since it has [JsonIgnore] or it's hidden by a new slot. } } + else + { + if (JsonPropertyInfo.GetAttribute(propertyInfo) != null) + { + ThrowHelper.ThrowInvalidOperationException_JsonIncludeOnNonPublicInvalid(propertyInfo, currentType); + } + + // Non-public properties should not be included for (de)serialization. + } } } @@ -211,13 +209,6 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) } } - private static bool IsNonPublicProperty(PropertyInfo propertyInfo) - { - MethodInfo? getMethod = propertyInfo.GetMethod; - MethodInfo? setMethod = propertyInfo.SetMethod; - return !((getMethod != null && getMethod.IsPublic) || (setMethod != null && setMethod.IsPublic)); - } - private void InitializeConstructorParameters(Dictionary propertyCache, ConstructorInfo constructorInfo) { ParameterInfo[] parameters = constructorInfo!.GetParameters(); From 6ce2c39f4df40c9acaae4318ee4a61adab86e0ba Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Mon, 18 May 2020 13:47:04 -0400 Subject: [PATCH 261/420] Remove unnecessary initialization from Utf8JsonWriter ctors (#36651) --- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 39 +------------------ 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 9ba41e024b4b3..16c00a80f8f21 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -78,13 +78,7 @@ public sealed partial class Utf8JsonWriter : IDisposable, IAsyncDisposable /// the which indicates whether to format the output /// while writing and whether to skip structural JSON validation or not. /// - public JsonWriterOptions Options - { - get - { - return _options; - } - } + public JsonWriterOptions Options => _options; private int Indentation => CurrentDepth * JsonConstants.SpacesPerIndent; @@ -107,21 +101,7 @@ public JsonWriterOptions Options public Utf8JsonWriter(IBufferWriter bufferWriter, JsonWriterOptions options = default) { _output = bufferWriter ?? throw new ArgumentNullException(nameof(bufferWriter)); - _stream = default; - _arrayBufferWriter = default; - - BytesPending = default; - BytesCommitted = default; - _memory = default; - - _inObject = default; - _tokenType = default; - _currentDepth = default; _options = options; - - // Only allocate if the user writes a JSON payload beyond the depth that the _allocationFreeContainer can handle. - // This way we avoid allocations in the common, default cases, and allocate lazily. - _bitStack = default; } /// @@ -142,21 +122,8 @@ public Utf8JsonWriter(Stream utf8Json, JsonWriterOptions options = default) throw new ArgumentException(SR.StreamNotWritable); _stream = utf8Json; - _arrayBufferWriter = new ArrayBufferWriter(); - _output = default; - - BytesPending = default; - BytesCommitted = default; - _memory = default; - - _inObject = default; - _tokenType = default; - _currentDepth = default; _options = options; - - // Only allocate if the user writes a JSON payload beyond the depth that the _allocationFreeContainer can handle. - // This way we avoid allocations in the common, default cases, and allocate lazily. - _bitStack = default; + _arrayBufferWriter = new ArrayBufferWriter(); } /// @@ -249,8 +216,6 @@ private void ResetHelper() _tokenType = default; _currentDepth = default; - // Only allocate if the user writes a JSON payload beyond the depth that the _allocationFreeContainer can handle. - // This way we avoid allocations in the common, default cases, and allocate lazily. _bitStack = default; } From b9275463428b6eebb16531aa20e36cfd9d20797f Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 18 May 2020 14:33:42 -0500 Subject: [PATCH 262/420] Remove PreserveDependency on non-existing type (#36657) The DefaultArrayConverter type was been refactored away causing the linker to warn about it. --- .../Converters/Collection/IEnumerableConverterFactory.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactory.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactory.cs index 27214b3c10a2b..1a58ed83cda94 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactory.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactory.cs @@ -28,7 +28,6 @@ public override bool CanConvert(Type typeToConvert) [PreserveDependency(".ctor", "System.Text.Json.Serialization.Converters.ArrayConverter`2")] [PreserveDependency(".ctor", "System.Text.Json.Serialization.Converters.ConcurrentQueueOfTConverter`2")] [PreserveDependency(".ctor", "System.Text.Json.Serialization.Converters.ConcurrentStackOfTConverter`2")] - [PreserveDependency(".ctor", "System.Text.Json.Serialization.Converters.DefaultArrayConverter`2")] [PreserveDependency(".ctor", "System.Text.Json.Serialization.Converters.DictionaryOfStringTValueConverter`2")] [PreserveDependency(".ctor", "System.Text.Json.Serialization.Converters.ICollectionOfTConverter`2")] [PreserveDependency(".ctor", "System.Text.Json.Serialization.Converters.IDictionaryOfStringTValueConverter`2")] From f0ddc9a0e329533d36e8894011a830f965a29055 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 18 May 2020 17:35:38 -0400 Subject: [PATCH 263/420] Produce Mono+LLVM runtime packs on desktop platforms (#35841) * Add LLVM Mono runtime build * Switch from 'llvm' boolean to 'runtimeVariant' freeform string in yaml This makes it easier to add oddball variant builds, without a big pile of booleans for every possible variant * Add an LLVM suffix to installer nupkgs * Add runtimeVariant to CoreCLR artifact names * Add installer run for LLVM JIT Mono * Actually specify LLVM or not to installer build * Unique name for LLVM installer run * Ensure log uploads are disambiguated * Fix dependency in full matrix * Add LLVMAOT variant, which bundles llc/opt for current arch * Make sure we don't use Mono.LLVM package names on CoreCLR or Mobile * Fix perf runs to deal with runtimeVariant * Try to reconcile perf test artifact names * Make bundling llc/opt the default when LLVM enabled on Mono --- .../templates/runtimes/build-test-job.yml | 4 +- .../templates/runtimes/run-test-job.yml | 14 ++-- .../templates/runtimes/send-to-helix-step.yml | 6 +- eng/pipelines/coreclr/templates/build-job.yml | 6 +- .../templates/crossgen-comparison-job.yml | 4 +- eng/pipelines/coreclr/templates/perf-job.yml | 10 ++- .../coreclr/templates/xplat-pipeline-job.yml | 4 +- eng/pipelines/installer/installer-matrix.yml | 2 + eng/pipelines/installer/jobs/base-job.yml | 25 ++++-- .../jobs/steps/upload-job-artifacts.yml | 4 +- eng/pipelines/libraries/base-job.yml | 2 +- eng/pipelines/libraries/build-job.yml | 4 +- eng/pipelines/libraries/build-test-job.yml | 4 +- eng/pipelines/libraries/run-test-job.yml | 4 +- eng/pipelines/mono/templates/build-job.yml | 40 +++++----- .../mono/templates/xplat-pipeline-job.yml | 11 +-- eng/pipelines/runtime-official.yml | 74 ++++++++++++++++++ eng/pipelines/runtime.yml | 76 ++++++++++++++++++- src/coreclr/tests/helixpublishwitharcade.proj | 2 +- .../pkg/projects/Directory.Build.targets | 7 ++ src/mono/mono.proj | 7 ++ 21 files changed, 247 insertions(+), 63 deletions(-) diff --git a/eng/pipelines/common/templates/runtimes/build-test-job.yml b/eng/pipelines/common/templates/runtimes/build-test-job.yml index a1831664868a8..a4f94efcc56b4 100644 --- a/eng/pipelines/common/templates/runtimes/build-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/build-test-job.yml @@ -21,6 +21,7 @@ parameters: pool: '' runtimeFlavor: 'coreclr' runtimeFlavorDisplayName: 'CoreCLR' + runtimeVariant: '' ### Build managed test components (native components are getting built as part ### of the the product build job). @@ -41,6 +42,7 @@ jobs: managedTestBuildOsGroup: ${{ parameters.osGroup }} managedTestBuildOsSubgroup: ${{ parameters.osSubgroup }} container: ${{ parameters.container }} + runtimeVariant: ${{ parameters.runtimeVariant }} testGroup: ${{ parameters.testGroup }} stagedBuild: ${{ parameters.stagedBuild }} liveLibrariesBuildConfig: ${{ parameters.liveLibrariesBuildConfig }} @@ -68,7 +70,7 @@ jobs: # by switching over to using reference assembly. ${{ if ne(parameters.stagedBuild, true) }}: dependsOn: - - ${{ format('coreclr_product_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, coalesce(parameters.liveRuntimeBuildConfig, parameters.buildConfig)) }} + - ${{ format('coreclr_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, coalesce(parameters.liveRuntimeBuildConfig, parameters.buildConfig)) }} - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}: - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveLibrariesBuildConfig) }} diff --git a/eng/pipelines/common/templates/runtimes/run-test-job.yml b/eng/pipelines/common/templates/runtimes/run-test-job.yml index a57e18183ea64..760dad39c85d8 100644 --- a/eng/pipelines/common/templates/runtimes/run-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/run-test-job.yml @@ -19,12 +19,11 @@ parameters: stagedBuild: false displayNameArgs: '' runInUnloadableContext: false + runtimeVariant: '' variables: {} pool: '' runtimeFlavor: 'coreclr' runtimeFlavorDisplayName: 'CoreCLR' - runtimeMode: '' - runtimeModeDisplayName: '' ### Test run job @@ -47,6 +46,7 @@ jobs: stagedBuild: ${{ parameters.stagedBuild }} liveLibrariesBuildConfig: ${{ parameters.liveLibrariesBuildConfig }} helixType: 'build/tests/' + runtimeVariant: ${{ parameters.runtimeVariant }} pool: ${{ parameters.pool }} condition: ${{ parameters.condition }} @@ -61,18 +61,18 @@ jobs: - ${{ if ne(parameters.testGroup, 'innerloop') }}: - '${{ parameters.runtimeFlavor }}_common_test_build_p1_${{ parameters.managedTestBuildOsGroup }}${{ parameters.managedTestBuildOsSubgroup }}_${{ parameters.archType }}_${{parameters.buildConfig }}' - ${{ if ne(parameters.stagedBuild, true) }}: - - ${{ format('{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeFlavor, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}: - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveLibrariesBuildConfig) }} # Compute job name from template parameters ${{ if eq(parameters.testGroup, 'innerloop') }}: - name: 'run_test_p0_${{ parameters.runtimeFlavor }}${{ parameters.runtimeMode }}_${{ parameters.displayNameArgs }}_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}' - displayName: '${{ parameters.runtimeFlavorDisplayName }} ${{ parameters.runtimeModeDisplayName}} Pri0 Runtime Tests Run ${{ parameters.displayNameArgs }} ${{ parameters.osGroup }}${{ parameters.osSubgroup }} ${{ parameters.archType }} ${{ parameters.buildConfig }}' + name: 'run_test_p0_${{ parameters.runtimeFlavor }}${{ parameters.runtimeVariant }}_${{ parameters.displayNameArgs }}_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}' + displayName: '${{ parameters.runtimeFlavorDisplayName }} ${{ parameters.runtimeVariant}} Pri0 Runtime Tests Run ${{ parameters.displayNameArgs }} ${{ parameters.osGroup }}${{ parameters.osSubgroup }} ${{ parameters.archType }} ${{ parameters.buildConfig }}' ${{ if ne(parameters.testGroup, 'innerloop') }}: name: 'run_test_p1_${{ parameters.displayNameArgs }}_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}' - displayName: '${{ parameters.runtimeFlavorDisplayName }} ${{ parameters.runtimeModeDisplayName }} Pri1 Runtime Tests Run ${{ parameters.displayNameArgs }} ${{ parameters.osGroup }}${{ parameters.osSubgroup }} ${{ parameters.archType }} ${{ parameters.buildConfig }}' + displayName: '${{ parameters.runtimeFlavorDisplayName }} ${{ parameters.runtimeVariant }} Pri1 Runtime Tests Run ${{ parameters.displayNameArgs }} ${{ parameters.osGroup }}${{ parameters.osSubgroup }} ${{ parameters.archType }} ${{ parameters.buildConfig }}' variables: - name: testhostArg @@ -458,6 +458,6 @@ jobs: displayName: Publish Logs inputs: targetPath: $(Build.SourcesDirectory)/artifacts/log - artifactName: '${{ parameters.runtimeFlavor }}_${{ parameters.runtimeMode }}_$(LogNamePrefix)_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)_${{ parameters.testGroup }}' + artifactName: '${{ parameters.runtimeFlavor }}_${{ parameters.runtimeVariant }}_$(LogNamePrefix)_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)_${{ parameters.testGroup }}' continueOnError: true condition: always() diff --git a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml index 2fc09a15ecd6b..ca58a7eff3165 100644 --- a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml +++ b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml @@ -23,7 +23,7 @@ parameters: gcSimulatorTests: '' coreClrRepoRoot: '' runtimeFlavorDisplayName: 'CoreCLR' - runtimeMode: '' + runtimeVariant: '' steps: - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: @@ -58,7 +58,7 @@ steps: _TimeoutPerTestCollectionInMinutes: ${{ parameters.timeoutPerTestCollectionInMinutes }} _TimeoutPerTestInMinutes: ${{ parameters.timeoutPerTestInMinutes }} runtimeFlavorDisplayName: ${{ parameters.runtimeFlavorDisplayName }} - _RuntimeMode: ${{ parameters.runtimeMode }} + _RuntimeVariant: ${{ parameters.runtimeVariant }} ${{ if eq(parameters.publishTestResults, 'true') }}: SYSTEM_ACCESSTOKEN: $(System.AccessToken) # TODO: remove NUGET_PACKAGES once https://github.com/dotnet/arcade/issues/1578 is fixed @@ -100,7 +100,7 @@ steps: _TimeoutPerTestCollectionInMinutes: ${{ parameters.timeoutPerTestCollectionInMinutes }} _TimeoutPerTestInMinutes: ${{ parameters.timeoutPerTestInMinutes }} runtimeFlavorDisplayName: ${{ parameters.runtimeFlavorDisplayName }} - _RuntimeMode: ${{ parameters.runtimeMode }} + _RuntimeVariant: ${{ parameters.runtimeVariant }} ${{ if eq(parameters.publishTestResults, 'true') }}: SYSTEM_ACCESSTOKEN: $(System.AccessToken) # TODO: remove NUGET_PACKAGES once https://github.com/dotnet/arcade/issues/1578 is fixed diff --git a/eng/pipelines/coreclr/templates/build-job.yml b/eng/pipelines/coreclr/templates/build-job.yml index f14883ba46d6c..870cdc6c0822a 100644 --- a/eng/pipelines/coreclr/templates/build-job.yml +++ b/eng/pipelines/coreclr/templates/build-job.yml @@ -10,6 +10,7 @@ parameters: osSubgroup: '' platform: '' pool: '' + runtimeVariant: '' signBinaries: false stagedBuild: false testGroup: '' @@ -25,6 +26,7 @@ jobs: archType: ${{ parameters.archType }} osGroup: ${{ parameters.osGroup }} osSubgroup: ${{ parameters.osSubgroup }} + runtimeVariant: ${{ parameters.runtimeVariant }} testGroup: ${{ parameters.testGroup }} helixType: 'build/product/' enableMicrobuild: true @@ -37,8 +39,8 @@ jobs: name: ${{ format('coreclr_{0}_product_build_{1}{1}_{3}_{4}', parameters.compilerName, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} displayName: ${{ format('CoreCLR GCC Product Build {0}{1} {2} {3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} ${{ if eq(parameters.compilerName, 'clang') }}: - name: ${{ format('coreclr_product_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - displayName: ${{ format('CoreCLR Product Build {0}{1} {2} {3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + name: ${{ format('coreclr_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + displayName: ${{ format('CoreCLR {0} Product Build {1}{2} {3} {4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} # Run all steps in the container. # Note that the containers are defined in platform-matrix.yml diff --git a/eng/pipelines/coreclr/templates/crossgen-comparison-job.yml b/eng/pipelines/coreclr/templates/crossgen-comparison-job.yml index cfecf9bbd5c06..0e537cb6c7e17 100644 --- a/eng/pipelines/coreclr/templates/crossgen-comparison-job.yml +++ b/eng/pipelines/coreclr/templates/crossgen-comparison-job.yml @@ -5,6 +5,7 @@ parameters: osSubgroup: '' container: '' helixQueues: '' + runtimeVariant: '' crossrootfsDir: '' stagedBuild: false variables: {} @@ -30,6 +31,7 @@ jobs: osGroup: ${{ parameters.osGroup }} osSubgroup: ${{ parameters.osSubgroup }} stagedBuild: ${{ parameters.stagedBuild }} + runtimeVariant: ${{ parameters.runtimeVariant }} liveLibrariesBuildConfig: ${{ parameters.liveLibrariesBuildConfig }} helixType: 'test/crossgen-comparison/' pool: ${{ parameters.pool }} @@ -72,7 +74,7 @@ jobs: # Test job depends on the corresponding build job dependsOn: - - ${{ format('coreclr_product_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + - ${{ format('coreclr_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}: - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveLibrariesBuildConfig) }} diff --git a/eng/pipelines/coreclr/templates/perf-job.yml b/eng/pipelines/coreclr/templates/perf-job.yml index 8bfd67fb7024a..003e58f276146 100644 --- a/eng/pipelines/coreclr/templates/perf-job.yml +++ b/eng/pipelines/coreclr/templates/perf-job.yml @@ -4,6 +4,7 @@ parameters: osGroup: '' osSubgroup: '' container: '' + runtimeVariant: '' framework: net5.0 # Specify the appropriate framework when running release branches (ie netcoreapp3.0 for release/3.0) liveLibrariesBuildConfig: '' variables: {} @@ -26,15 +27,16 @@ jobs: archType: ${{ parameters.archType }} osGroup: ${{ parameters.osGroup }} osSubgroup: ${{ parameters.osSubgroup }} + runtimeVariant: ${{ parameters.runtimeVariant }} liveLibrariesBuildConfig: ${{ parameters.liveLibrariesBuildConfig }} runtimeType: ${{ parameters.runtimeType }} # Test job depends on the corresponding build job dependsOn: - - ${{ format('coreclr_product_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + - ${{ format('coreclr_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}: - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveLibrariesBuildConfig) }} - ${{ if eq(parameters.runtimeType, 'mono') }}: - - ${{ format('mono_product_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + - ${{ format('mono_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} ${{ if eq(parameters.osGroup, 'Windows_NT') }}: ${{ if eq(parameters.runtimeType, 'mono') }}: @@ -78,8 +80,8 @@ jobs: parameters: unpackFolder: $(librariesDownloadDir)/bin/mono/$(osGroup).$(archType).$(buildConfigUpper) cleanUnpackFolder: false - artifactFileName: 'MonoProduct_$(osGroup)_$(archType)_$(buildConfig)$(archiveExtension)' - artifactName: 'MonoProduct_$(osGroup)_$(archType)_$(buildConfig)' + artifactFileName: 'MonoProduct_${{ parameters.runtimeVariant }}_$(osGroup)_$(archType)_$(buildConfig)$(archiveExtension)' + artifactName: 'MonoProduct_${{ parameters.runtimeVariant }}_$(osGroup)_$(archType)_$(buildConfig)' displayName: 'Mono runtime' # Create Core_Root diff --git a/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml b/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml index dad7bf689dea1..daa189d88d6da 100644 --- a/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml +++ b/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml @@ -71,14 +71,14 @@ jobs: # Build product defines what we are trying to build, either coreclr or mono - name: buildProductArtifactName - value: 'CoreCLRProduct_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + value: 'CoreCLRProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' - name: buildProductRootFolderPath value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(buildConfigUpper)' # We need this because both mono and coreclr build currently depends on CoreClr - name: coreClrProductArtifactName - value: 'CoreCLRProduct_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + value: 'CoreCLRProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' - name: coreClrProductRootFolderPath value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(buildConfigUpper)' diff --git a/eng/pipelines/installer/installer-matrix.yml b/eng/pipelines/installer/installer-matrix.yml index bb5e6e46f96c4..e9ae06bf26769 100644 --- a/eng/pipelines/installer/installer-matrix.yml +++ b/eng/pipelines/installer/installer-matrix.yml @@ -3,6 +3,7 @@ parameters: platforms: [] jobParameters: [] buildConfig: Release + runtimeVariant: '' jobs: @@ -16,5 +17,6 @@ jobs: platforms: ${{ parameters.platforms }} passPlatforms: true runtimeFlavor: ${{ parameters.runtimeFlavor }} + runtimeVariant: ${{ parameters.runtimeVariant }} jobParameters: ${{ insert }}: ${{ parameters.jobParameters }} diff --git a/eng/pipelines/installer/jobs/base-job.yml b/eng/pipelines/installer/jobs/base-job.yml index 413f9c7c70807..2c309c03892a7 100644 --- a/eng/pipelines/installer/jobs/base-job.yml +++ b/eng/pipelines/installer/jobs/base-job.yml @@ -13,6 +13,7 @@ parameters: variables: [] name: '' displayName: '' + runtimeVariant: '' pool: '' packageDistroList: @@ -38,8 +39,8 @@ parameters: platforms: [] jobs: -- job: ${{ format('installer_{0}_{1}_{2}', parameters.runtimeFlavor, coalesce(parameters.name, parameters.platform), parameters.buildConfig) }} - displayName: ${{ format('Installer Build and Test {0} {1} {2}', parameters.runtimeFlavor, coalesce(parameters.name, parameters.platform), parameters.buildConfig) }} +- job: ${{ format('installer_{0}_{1}_{2}_{3}', parameters.runtimeFlavor, parameters.runtimeVariant, coalesce(parameters.name, parameters.platform), parameters.buildConfig) }} + displayName: ${{ format('Installer Build and Test {0} {1} {2} {3}', parameters.runtimeFlavor, parameters.runtimeVariant, coalesce(parameters.name, parameters.platform), parameters.buildConfig) }} condition: and(succeeded(), ${{ parameters.condition }}) pool: ${{ parameters.pool }} @@ -79,6 +80,14 @@ jobs: - name: SignType value: test + - ${{ if eq(parameters.runtimeVariant, 'llvmjit') }}: + - name: llvmParameter + value: /p:MonoEnableLLVM=true + + - ${{ if eq(parameters.runtimeVariant, 'llvmaot') }}: + - name: llvmParameter + value: /p:MonoEnableLLVM=true /p:MonoBundleLLVMOptimizer=true + # Set up non-PR build from internal project - ${{ if eq(parameters.isOfficialBuild, true) }}: - name: SignType @@ -105,6 +114,7 @@ jobs: /p:PortableBuild=true /p:SkipTests=$(SkipTests) /p:RuntimeFlavor=${{ parameters.runtimeFlavor }} + $(llvmParameter) $(OfficialBuildArg) - name: MsbuildSigningArguments value: >- @@ -129,6 +139,7 @@ jobs: /p:PortableBuild=true /p:SkipTests=$(SkipTests) /p:RuntimeFlavor=${{ parameters.runtimeFlavor }} + $(llvmParameter) - name: BaseJobBuildCommand value: >- @@ -145,6 +156,7 @@ jobs: value: >- /p:PortableBuild=true /p:SkipTests=$(SkipTests) + $(llvmParameter) - name: BaseJobBuildCommand value: >- @@ -195,6 +207,7 @@ jobs: /p:TargetArchitecture=${{ parameters.archType }} /p:RuntimeFlavor=${{ parameters.runtimeFlavor }} $(OfficialBuildArg) + $(llvmParameter) - name: _PortableBuild value: ${{ eq(parameters.osSubgroup, '') }} @@ -292,7 +305,7 @@ jobs: /p:RuntimeArtifactsPath=$(buildCommandSourcesDirectory)$(RuntimeDownloadPath) /p:RuntimeConfiguration=${{ parameters.liveRuntimeBuildConfig }} - name: RuntimeArtifactName - value: $(runtimeFlavorName)Product_$(liveRuntimeLegName) + value: $(runtimeFlavorName)Product_${{ parameters.runtimeVariant }}_$(liveRuntimeLegName) - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}: - name: liveLibrariesLegName @@ -331,8 +344,9 @@ jobs: - checkout - ${{ parameters.dependsOn }} - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}: - - ${{ format('{0}_product_build_{1}{2}_{3}_{4}', + - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, + parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, @@ -347,7 +361,7 @@ jobs: - libraries_build_allconfigurations_Windows_NT_x64_Release - ${{ if eq(parameters.buildFullPlatformManifest, true) }}: - ${{ each platform in parameters.platforms }}: - - ${{ parameters.runtimeFlavor }}_product_build_${{ platform }}_${{ parameters.liveRuntimeBuildConfig }} + - ${{ parameters.runtimeFlavor }}_${{ parameters.runtimeVariant }}_product_build_${{ platform }}_${{ parameters.liveRuntimeBuildConfig }} - libraries_build_${{ platform }}_${{ parameters.liveLibrariesBuildConfig }} steps: @@ -522,6 +536,7 @@ jobs: parameters: name: ${{ coalesce(parameters.name, parameters.platform) }} runtimeFlavor: ${{ parameters.runtimeFlavor }} + runtimeVariant: ${{ parameters.runtimeVariant }} skipTests: $(SkipTests) isOfficialBuild: ${{ eq(parameters.isOfficialBuild, true) }} diff --git a/eng/pipelines/installer/jobs/steps/upload-job-artifacts.yml b/eng/pipelines/installer/jobs/steps/upload-job-artifacts.yml index 672a12aa61be7..884ca0177e7f8 100644 --- a/eng/pipelines/installer/jobs/steps/upload-job-artifacts.yml +++ b/eng/pipelines/installer/jobs/steps/upload-job-artifacts.yml @@ -1,7 +1,7 @@ parameters: name: '' runtimeFlavor: 'coreclr' - + runtimeVariant: '' isOfficialBuild: false steps: @@ -38,6 +38,6 @@ steps: displayName: Publish BuildLogs inputs: targetPath: '$(Build.StagingDirectory)/BuildLogs' - artifactName: Installer-Logs-${{ parameters.runtimeFlavor }}-${{ parameters.name }}-$(_BuildConfig) + artifactName: Installer-Logs-${{ parameters.runtimeFlavor }}-${{ parameters.runtimeVariant }}-${{ parameters.name }}-$(_BuildConfig) continueOnError: true condition: succeededOrFailed() diff --git a/eng/pipelines/libraries/base-job.yml b/eng/pipelines/libraries/base-job.yml index 2793183d99ae6..53305711a23b5 100644 --- a/eng/pipelines/libraries/base-job.yml +++ b/eng/pipelines/libraries/base-job.yml @@ -91,7 +91,7 @@ jobs: - _runtimeConfigurationArg: -rc ${{ parameters.liveRuntimeBuildConfig }} # Download full product dependencies for mono or test - ${{ if or(ne(parameters.runtimeFlavor, 'coreclr'), ne(parameters.testScope, '')) }}: - - _runtimeArtifactName: '$(runtimeFlavorName)Product_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.liveRuntimeBuildConfig }}' + - _runtimeArtifactName: '$(runtimeFlavorName)Product_${{ parameters.runtimeVariant}}_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.liveRuntimeBuildConfig }}' - _runtimeArtifactsPathArg: ' /p:RuntimeArtifactsPath=$(_runtimeDownloadPath)' - _testRunNamePrefixSuffix: $(runtimeFlavorName)_${{ parameters.liveRuntimeBuildConfig }} diff --git a/eng/pipelines/libraries/build-job.yml b/eng/pipelines/libraries/build-job.yml index f3de87e46401f..2b4e3dd097ac1 100644 --- a/eng/pipelines/libraries/build-job.yml +++ b/eng/pipelines/libraries/build-job.yml @@ -7,6 +7,7 @@ parameters: framework: '' isOfficialBuild: false isOfficialAllConfigurations: false + runtimeVariant: '' # When set to a non-empty value (Debug / Release), it determines the runtime's # build configuration to use for building libraries and tests. Setting this @@ -43,6 +44,7 @@ jobs: container: ${{ parameters.container }} condition: ${{ parameters.condition }} pool: ${{ parameters.pool }} + runtimeVariant: ${{ parameters.runtimeVariant }} testScope: ${{ parameters.testScope }} name: build displayName: 'Build' @@ -51,7 +53,7 @@ jobs: dependsOn: # Use full product dependency for non-coreclr and test builds - ${{ if or(ne(parameters.runtimeFlavor, 'coreclr'), ne(parameters.testScope, '')) }}: - - ${{ format('{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeFlavor, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }} + - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }} variables: - _subset: libs diff --git a/eng/pipelines/libraries/build-test-job.yml b/eng/pipelines/libraries/build-test-job.yml index c58de839dbdaf..0ce715add47c9 100644 --- a/eng/pipelines/libraries/build-test-job.yml +++ b/eng/pipelines/libraries/build-test-job.yml @@ -7,6 +7,7 @@ parameters: isOfficialBuild: false liveRuntimeBuildConfig: '' runtimeFlavor: 'coreclr' + runtimeVariant: '' timeoutInMinutes: 150 container: '' publishTestArtifacs: true @@ -29,6 +30,7 @@ jobs: liveRuntimeBuildConfig: ${{ parameters.liveRuntimeBuildConfig }} timeoutInMinutes: ${{ parameters.timeoutInMinutes }} container: ${{ parameters.container }} + runtimeVariant: ${{ parameters.runtimeVariant }} pool: ${{ parameters.pool }} testScope: ${{ parameters.testScope }} name: test_build @@ -38,7 +40,7 @@ jobs: - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} # Libraries Test also depends on Product, now that the libraries build only depends on corelib - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}: - - ${{ format('{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeFlavor, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }} + - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }} variables: - librariesTestsArtifactName: ${{ format('libraries_test_assets_{0}_{1}_{2}', parameters.osGroup, parameters.archType, parameters.buildConfig) }} diff --git a/eng/pipelines/libraries/run-test-job.yml b/eng/pipelines/libraries/run-test-job.yml index 7d982c09e7202..053d7f90044ae 100644 --- a/eng/pipelines/libraries/run-test-job.yml +++ b/eng/pipelines/libraries/run-test-job.yml @@ -9,6 +9,7 @@ parameters: runtimeFlavor: 'coreclr' timeoutInMinutes: 150 pool: '' + runtimeVariant: '' testScope: '' helixQueues: [] dependsOnTestBuildConfiguration: Debug @@ -27,6 +28,7 @@ jobs: isOfficialBuild: ${{ parameters.isOfficialBuild }} liveRuntimeBuildConfig: ${{ parameters.liveRuntimeBuildConfig }} runtimeFlavor: ${{ parameters.runtimeFlavor }} + runtimeVariant: ${{ parameters.runtimeVariant }} timeoutInMinutes: ${{ parameters.timeoutInMinutes }} container: '' # we just send to helix, no need to use a container. condition: ${{ parameters.condition }} @@ -47,7 +49,7 @@ jobs: - ${{ format('libraries_build_{0}_{1}{2}_{3}_{4}', parameters.framework, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - ${{ format('libraries_test_build_{0}_{1}_{2}_{3}', parameters.framework, parameters.osGroup, parameters.dependsOnTestArchitecture, parameters.dependsOnTestBuildConfiguration) }} - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}: - - ${{ format('{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeFlavor, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }} + - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }} variables: - librariesTestsArtifactName: ${{ format('libraries_test_assets_{0}_{1}_{2}', parameters.osGroup, parameters.dependsOnTestArchitecture, parameters.dependsOnTestBuildConfiguration) }} diff --git a/eng/pipelines/mono/templates/build-job.yml b/eng/pipelines/mono/templates/build-job.yml index 136c83cf522d2..8593d86481033 100644 --- a/eng/pipelines/mono/templates/build-job.yml +++ b/eng/pipelines/mono/templates/build-job.yml @@ -9,7 +9,7 @@ parameters: variables: {} pool: '' condition: true - llvm: false + runtimeVariant: '' isOfficialBuild: false crossrootfsDir: '' @@ -24,20 +24,13 @@ jobs: helixType: 'build/product/' enableMicrobuild: true pool: ${{ parameters.pool }} - llvm: ${{ parameters.llvm }} + runtimeVariant: ${{ parameters.runtimeVariant }} crossrootfsDir: ${{ parameters.crossroofsDir }} condition: ${{ parameters.condition }} # Compute job name from template parameters - ${{ if ne(parameters.llvm, true) }}: - name: ${{ format('mono_product_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - displayName: ${{ format('Mono Product Build {0}{1} {2} {3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - - # if LLVM enabled, set a variable we can consume - ${{ if eq(parameters.llvm, true) }}: - name: ${{ format('mono_llvm_product_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - displayName: ${{ format('Mono LLVM Product Build {0}{1} {2} {3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - + name: ${{ format('mono_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + displayName: ${{ format('Mono {0} Product Build {1}{2} {3} {4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} # Run all steps in the container. # Note that the containers are defined in platform-matrix.yml @@ -81,6 +74,12 @@ jobs: value: wasm - name: osOverride value: '-os Browser' + - ${{ if eq(parameters.runtimeVariant, 'llvmjit') }}: + - name: llvmParameter + value: /p:MonoEnableLLVM=true /p:MonoBundleLLVMOptimizer=false + - ${{ if eq(parameters.runtimeVariant, 'llvmaot') }}: + - name: llvmParameter + value: /p:MonoEnableLLVM=true /p:MonoBundleLLVMOptimizer=true - ${{ parameters.variables }} steps: @@ -105,10 +104,10 @@ jobs: # Build - ${{ if ne(parameters.osGroup, 'Windows_NT') }}: - - script: ./build$(scriptExt) -subset mono -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) /p:MonoEnableLLVM=${{ parameters.llvm }} + - script: ./build$(scriptExt) -subset mono -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(llvmParameter) displayName: Build product - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: - - script: build$(scriptExt) -subset mono -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) /p:MonoEnableLLVM=${{ parameters.llvm }} + - script: build$(scriptExt) -subset mono -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(llvmParameter) displayName: Build product - ${{ if in(parameters.osGroup, 'OSX', 'iOS','tvOS') }}: @@ -129,15 +128,15 @@ jobs: displayName: 'product build' # Build packages - - ${{ if and(ne(parameters.llvm, true), ne(parameters.osGroup, 'Windows_NT')) }}: - - script: ./build$(scriptExt) -subset mono -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) /p:MonoEnableLLVM=${{ parameters.llvm }} -pack $(OutputRidArg) + - ${{ if ne(parameters.osGroup, 'Windows_NT') }}: + - script: ./build$(scriptExt) -subset mono -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(llvmParameter) -pack $(OutputRidArg) displayName: Build nupkg - - ${{ if and(ne(parameters.llvm, true), eq(parameters.osGroup, 'Windows_NT')) }}: - - script: build$(scriptExt) -subset mono -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) /p:MonoEnableLLVM=${{ parameters.llvm }} -pack $(OutputRidArg) + - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: + - script: build$(scriptExt) -subset mono -c $(buildConfig) -arch $(archType) $(osOverride) -ci $(officialBuildIdArg) $(llvmParameter) -pack $(OutputRidArg) displayName: Build nupkg # Publish official build - - ${{ if and(ne(parameters.llvm, true), eq(parameters.publishToBlobFeed, 'true')) }}: + - ${{ if eq(parameters.publishToBlobFeed, 'true') }}: - ${{ if ne(parameters.osGroup, 'Windows_NT') }}: - script: $(Build.SourcesDirectory)/eng/common/build.sh --ci --restore --publish --configuration $(_BuildConfig) /p:DotNetPublishUsingPipelines=true /p:DotNetPublishToBlobFeed=true /p:DotNetPublishBlobFeedUrl=$(dotnetfeedUrl) /p:DotNetPublishBlobFeedKey=$(dotnetfeedPAT) /p:Configuration=$(_BuildConfig) /p:TargetArchitecture=$(archType) /p:TargetOS=$(osGroup) /p:OSIdentifier=$(osGroup)$(osSubgroup) /bl:"$(Build.SourcesDirectory)/artifacts/log/publish-pkgs.binlog" --projects $(Build.SourcesDirectory)/eng/empty.csproj displayName: Publish packages to blob feed @@ -160,9 +159,6 @@ jobs: displayName: Publish Logs inputs: targetPath: $(Build.SourcesDirectory)/artifacts/log - ${{ if ne(parameters.llvm, true) }}: - artifactName: 'BuildLogs_Mono_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' - ${{ if eq(parameters.llvm, true) }}: - artifactName: 'BuildLogs_Mono_LLVM_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + artifactName: 'BuildLogs_Mono_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' continueOnError: true condition: always() diff --git a/eng/pipelines/mono/templates/xplat-pipeline-job.yml b/eng/pipelines/mono/templates/xplat-pipeline-job.yml index f6f4d26ab73cb..0701073c669c6 100644 --- a/eng/pipelines/mono/templates/xplat-pipeline-job.yml +++ b/eng/pipelines/mono/templates/xplat-pipeline-job.yml @@ -9,7 +9,7 @@ parameters: liveLibrariesBuildConfig: '' strategy: '' pool: '' - llvm: false + runtimeVariant: '' liveRuntimeBuildConfig: 'release' # arcade-specific parameters @@ -35,7 +35,7 @@ jobs: container: ${{ parameters.container }} strategy: ${{ parameters.strategy }} pool: ${{ parameters.pool }} - llvm: ${{ parameters.llvm }} + runtimeVariant: ${{ parameters.runtimeVariant }} # arcade-specific parameters condition: and(succeeded(), ${{ parameters.condition }}) @@ -48,16 +48,13 @@ jobs: variables: - name: coreClrProductArtifactName - value: 'CoreCLRProduct_$(osGroup)$(osSubgroup)_$(archType)_${{ parameters.liveRuntimeBuildConfig }}' + value: 'CoreCLRProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_${{ parameters.liveRuntimeBuildConfig }}' - name: coreClrProductRootFolderPath value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(liveRuntimeBuildConfigUpper)' - name: buildProductArtifactName - ${{ if ne(parameters.llvm, true) }}: - value: 'MonoProduct_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' - ${{ if eq(parameters.llvm, true) }}: - value: 'MonoProduct_LLVM_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' + value: 'MonoProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' - name: binTestsPath value: '$(Build.SourcesDirectory)/artifacts/tests/coreclr' diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index 22b4e8c186b9f..45715a7bf1183 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -94,6 +94,49 @@ stages: jobParameters: isOfficialBuild: ${{ variables.isOfficialBuild }} + # + # Build Mono LLVM release + # + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/mono/templates/build-job.yml + runtimeFlavor: mono + buildConfig: release + platforms: + - OSX_x64 + - Linux_x64 + # - Linux_arm + # - Linux_arm64 + # - Linux_musl_x64 + # - Linux_musl_arm64 + # - Windows_NT_x64 + # - Windows_NT_x86 + # - Windows_NT_arm + # - Windows_NT_arm64 + jobParameters: + runtimeVariant: LLVMJIT + isOfficialBuild: ${{ variables.isOfficialBuild }} + + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/mono/templates/build-job.yml + runtimeFlavor: mono + buildConfig: release + platforms: + - OSX_x64 + - Linux_x64 + # - Linux_arm + # - Linux_arm64 + # - Linux_musl_x64 + # - Linux_musl_arm64 + # - Windows_NT_x64 + # - Windows_NT_x86 + # - Windows_NT_arm + # - Windows_NT_arm64 + jobParameters: + runtimeVariant: LLVMAOT + isOfficialBuild: ${{ variables.isOfficialBuild }} + # # Build libraries using live CoreLib from CoreCLR # @@ -205,6 +248,37 @@ stages: - Android_x86 - Browser_wasm + # + # Installer Build for platforms using Mono + # + - template: /eng/pipelines/installer/installer-matrix.yml + parameters: + jobParameters: + liveRuntimeBuildConfig: release + liveLibrariesBuildConfig: Release + isOfficialBuild: ${{ variables.isOfficialBuild }} + useOfficialAllConfigurations: false + buildFullPlatformManifest: false + runtimeVariant: LLVMJIT + runtimeFlavor: mono + platforms: + - OSX_x64 + - Linux_x64 + + - template: /eng/pipelines/installer/installer-matrix.yml + parameters: + jobParameters: + liveRuntimeBuildConfig: release + liveLibrariesBuildConfig: Release + isOfficialBuild: ${{ variables.isOfficialBuild }} + useOfficialAllConfigurations: false + buildFullPlatformManifest: false + runtimeVariant: LLVMAOT + runtimeFlavor: mono + platforms: + - OSX_x64 + - Linux_x64 + - ${{ if eq(variables.isOfficialBuild, true) }}: - template: /eng/pipelines/official/stages/publish.yml parameters: diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 97fc69361b167..d73ebcdee2594 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -347,7 +347,31 @@ jobs: # - Windows_NT_arm # - Windows_NT_arm64 jobParameters: - llvm: true + runtimeVariant: LLVMJIT + condition: >- + or( + eq(dependencies.checkout.outputs['SetPathVars_libraries.containsChange'], true), + eq(dependencies.checkout.outputs['SetPathVars_mono.containsChange'], true), + eq(variables['isFullMatrix'], true)) + +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/mono/templates/build-job.yml + runtimeFlavor: mono + buildConfig: debug + platforms: + - OSX_x64 + - Linux_x64 + # - Linux_arm + # - Linux_arm64 + # - Linux_musl_x64 + # - Linux_musl_arm64 + # - Windows_NT_x64 + # - Windows_NT_x86 + # - Windows_NT_arm + # - Windows_NT_arm64 + jobParameters: + runtimeVariant: LLVMAOT condition: >- or( eq(dependencies.checkout.outputs['SetPathVars_libraries.containsChange'], true), @@ -375,7 +399,31 @@ jobs: # - Windows_NT_arm # - Windows_NT_arm64 jobParameters: - llvm: true + runtimeVariant: LLVMJIT + condition: >- + or( + eq(dependencies.checkout.outputs['SetPathVars_libraries.containsChange'], true), + eq(dependencies.checkout.outputs['SetPathVars_mono.containsChange'], true), + eq(variables['isFullMatrix'], true)) + +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/mono/templates/build-job.yml + runtimeFlavor: mono + buildConfig: release + platforms: + - OSX_x64 + - Linux_x64 + # - Linux_arm + # - Linux_arm64 + # - Linux_musl_x64 + # - Linux_musl_arm64 + # - Windows_NT_x64 + # - Windows_NT_x86 + # - Windows_NT_arm + # - Windows_NT_arm64 + jobParameters: + runtimeVariant: LLVMAOT condition: >- or( eq(dependencies.checkout.outputs['SetPathVars_libraries.containsChange'], true), @@ -563,6 +611,30 @@ jobs: liveRuntimeBuildConfig: release liveLibrariesBuildConfig: ${{ variables.debugOnPrReleaseOnRolling }} +- template: /eng/pipelines/installer/installer-matrix.yml + parameters: + buildConfig: ${{ variables.debugOnPrReleaseOnRolling }} + runtimeFlavor: mono + platforms: + - OSX_x64 + - Linux_x64 + jobParameters: + runtimeVariant: LLVMJIT + liveRuntimeBuildConfig: release + liveLibrariesBuildConfig: ${{ variables.debugOnPrReleaseOnRolling }} + +- template: /eng/pipelines/installer/installer-matrix.yml + parameters: + buildConfig: ${{ variables.debugOnPrReleaseOnRolling }} + runtimeFlavor: mono + platforms: + - OSX_x64 + - Linux_x64 + jobParameters: + runtimeVariant: LLVMAOT + liveRuntimeBuildConfig: release + liveLibrariesBuildConfig: ${{ variables.debugOnPrReleaseOnRolling }} + # # Libraries Test Build # Only when CoreCLR, Mono or Libraries is changed diff --git a/src/coreclr/tests/helixpublishwitharcade.proj b/src/coreclr/tests/helixpublishwitharcade.proj index 561fc7e1af721..c1d2de4f8b713 100644 --- a/src/coreclr/tests/helixpublishwitharcade.proj +++ b/src/coreclr/tests/helixpublishwitharcade.proj @@ -33,7 +33,7 @@ RunInUnloadableContext=$(_RunInUnloadableContext); TimeoutPerTestCollectionInMinutes=$(_TimeoutPerTestCollectionInMinutes); TimeoutPerTestInMinutes=$(_TimeoutPerTestInMinutes); - RuntimeMode=$(_RuntimeMode); + RuntimeVariant=$(_RuntimeVariant); BundledNETCoreAppPackageVersion=$(BundledNETCoreAppPackageVersion) diff --git a/src/installer/pkg/projects/Directory.Build.targets b/src/installer/pkg/projects/Directory.Build.targets index cfce7c8527f4f..cfe8c6400779c 100644 --- a/src/installer/pkg/projects/Directory.Build.targets +++ b/src/installer/pkg/projects/Directory.Build.targets @@ -12,6 +12,7 @@ Needs to happen in Directory.Build.targets to allow all the pkgproj's to set Version property first. --> $(Version) + true @@ -925,6 +926,12 @@ <_MonoRuntimeArtifacts Include="$(_MonoAotCrossFilePath)"> $(BinDir)cross\mono-aot-cross + <_MonoRuntimeArtifacts Condition="'$(MonoBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\bin\llc"> + $(BinDir)\llc + + <_MonoRuntimeArtifacts Condition="'$(MonoBundleLLVMOptimizer)' == 'true'" Include="$(MonoLLVMDir)\bin\opt"> + $(BinDir)\opt + <_MonoRuntimeArtifacts Condition="'$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'tvOS'" Include="$(MonoLLVMDir)\bin\llc"> $(BinDir)cross\llc From 21abb926c47fce972071c673472c84495b25a0f9 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Mon, 18 May 2020 23:37:29 +0200 Subject: [PATCH 264/420] Fix R2RTest parsing of the issues.targets (#36650) The format of the file has changed a bit some time ago, but the R2RTest wasn't updated accordingly, so test exclusion stopped working. This change fixes it. --- src/coreclr/src/tools/r2rtest/TestExclusion.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/tools/r2rtest/TestExclusion.cs b/src/coreclr/src/tools/r2rtest/TestExclusion.cs index 133df0677c5de..5fefaee6d90fc 100644 --- a/src/coreclr/src/tools/r2rtest/TestExclusion.cs +++ b/src/coreclr/src/tools/r2rtest/TestExclusion.cs @@ -163,7 +163,8 @@ public static TestExclusionMap Create(BuildOptions options) Project project = new Project(); project.SetGlobalProperty("XunitTestBinBase", "*"); - project.SetGlobalProperty("BuildArch", "x64"); + project.SetGlobalProperty("TargetArchitecture", "x64"); + project.SetGlobalProperty("RuntimeFlavor", "coreclr"); // TODO: cross-OS CPAOT project.SetGlobalProperty("TargetsWindows", (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "true" : "false")); project.SetGlobalProperty("AltJitArch", "x64"); From 184f49b20ee9fc6c2e6649e22750cb6c54ffdc53 Mon Sep 17 00:00:00 2001 From: Anirudh Agnihotry Date: Mon, 18 May 2020 14:49:44 -0700 Subject: [PATCH 265/420] Remove BuildOS (#36667) --- src/libraries/Directory.Build.props | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props index 5330f4309c38e..fca7201e832da 100644 --- a/src/libraries/Directory.Build.props +++ b/src/libraries/Directory.Build.props @@ -20,8 +20,6 @@ $(LibrariesProjectRoot)OSGroups.json $(NetCoreAppCurrent) false - - $(TargetOS) $(AdditionalBuildTargetFrameworks);$(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-NetBSD;$(NetCoreAppCurrent)-FreeBSD $(RepositoryEngineeringDir)LicenseHeader.txt From e5badd7a351a04b8b14cb5ec2c7e1e8853991ad7 Mon Sep 17 00:00:00 2001 From: Roman Marusyk Date: Tue, 19 May 2020 02:52:45 +0300 Subject: [PATCH 266/420] Prefix protected fields with underscore for the internal XmlRawWriter (#35759) * Prefix protected fields with underscore for the internal XmlRawWriter and its descendant classes --- .../Xml/Core/HtmlEncodedRawTextWriter.cs | 216 +++--- .../Core/HtmlRawTextWriterGenerator.ttinclude | 60 +- .../System/Xml/Core/HtmlUtf8RawTextWriter.cs | 194 ++--- .../src/System/Xml/Core/QueryOutputWriter.cs | 4 +- .../Xml/Core/RawTextWriterEncoded.ttinclude | 2 +- .../Xml/Core/TextEncodedRawTextWriter.cs | 14 +- .../System/Xml/Core/TextUtf8RawTextWriter.cs | 14 +- .../System/Xml/Core/XmlAutoDetectWriter.cs | 4 +- .../Xml/Core/XmlEncodedRawTextWriter.cs | 690 +++++++++--------- .../Xml/Core/XmlEncodedRawTextWriterAsync.cs | 502 ++++++------- .../src/System/Xml/Core/XmlEventCache.cs | 2 +- .../Core/XmlRawTextWriterGenerator.ttinclude | 670 ++++++++--------- .../XmlRawTextWriterGeneratorAsync.ttinclude | 474 ++++++------ .../src/System/Xml/Core/XmlRawWriter.cs | 20 +- .../src/System/Xml/Core/XmlRawWriterAsync.cs | 10 +- .../System/Xml/Core/XmlUtf8RawTextWriter.cs | 572 +++++++-------- .../Xml/Core/XmlUtf8RawTextWriterAsync.cs | 424 +++++------ 17 files changed, 1936 insertions(+), 1936 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlEncodedRawTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlEncodedRawTextWriter.cs index 87b9c26e81273..f7ae5f5c286b4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlEncodedRawTextWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlEncodedRawTextWriter.cs @@ -17,8 +17,8 @@ namespace System.Xml { internal class HtmlEncodedRawTextWriter : XmlEncodedRawTextWriter { - protected ByteStack elementScope; - protected ElementProperties currentElementProperties; + protected ByteStack _elementScope; + protected ElementProperties _currentElementProperties; private AttributeProperties _currentAttributeProperties; private bool _endsWithAmpersand; @@ -27,8 +27,8 @@ internal class HtmlEncodedRawTextWriter : XmlEncodedRawTextWriter private string _mediaType; private bool _doNotEscapeUriAttributes; - protected static TernaryTreeReadOnly elementPropertySearch; - protected static TernaryTreeReadOnly attributePropertySearch; + protected static TernaryTreeReadOnly _elementPropertySearch; + protected static TernaryTreeReadOnly _attributePropertySearch; private const int StackIncrement = 10; @@ -57,7 +57,7 @@ public override void WriteDocType(string name, string pubid, string sysid, strin { Debug.Assert(name != null && name.Length > 0); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } RawText("'; + _bufChars[_bufPos++] = (char)'>'; } // For the HTML element, it should call this method with ns and prefix as String.Empty @@ -104,24 +104,24 @@ public override void WriteStartElement(string prefix, string localName, string n { Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null); - elementScope.Push((byte)currentElementProperties); + _elementScope.Push((byte)_currentElementProperties); if (ns.Length == 0) { Debug.Assert(prefix.Length == 0); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - currentElementProperties = (ElementProperties)elementPropertySearch.FindCaseInsensitiveString(localName); - base.bufChars[bufPos++] = (char)'<'; + _currentElementProperties = (ElementProperties)_elementPropertySearch.FindCaseInsensitiveString(localName); + base._bufChars[_bufPos++] = (char)'<'; base.RawText(localName); - base.attrEndPos = bufPos; + base._attrEndPos = _bufPos; } else { // Since the HAS_NS has no impact to the ElementTextBlock behavior, // we don't need to push it into the stack. - currentElementProperties = ElementProperties.HAS_NS; + _currentElementProperties = ElementProperties.HAS_NS; base.WriteStartElement(prefix, localName, ns); } } @@ -129,12 +129,12 @@ public override void WriteStartElement(string prefix, string localName, string n // Output >. For HTML needs to output META info internal override void StartElementContent() { - base.bufChars[base.bufPos++] = (char)'>'; + base._bufChars[base._bufPos++] = (char)'>'; // Detect whether content is output - contentPos = bufPos; + _contentPos = _bufPos; - if ((currentElementProperties & ElementProperties.HEAD) != 0) + if ((_currentElementProperties & ElementProperties.HEAD) != 0) { WriteMetaElement(); } @@ -150,14 +150,14 @@ internal override void WriteEndElement(string prefix, string localName, string n { Debug.Assert(prefix.Length == 0); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - if ((currentElementProperties & ElementProperties.EMPTY) == 0) + if ((_currentElementProperties & ElementProperties.EMPTY) == 0) { - bufChars[base.bufPos++] = (char)'<'; - bufChars[base.bufPos++] = (char)'/'; + _bufChars[base._bufPos++] = (char)'<'; + _bufChars[base._bufPos++] = (char)'/'; base.RawText(localName); - bufChars[base.bufPos++] = (char)'>'; + _bufChars[base._bufPos++] = (char)'>'; } } else @@ -166,7 +166,7 @@ internal override void WriteEndElement(string prefix, string localName, string n base.WriteEndElement(prefix, localName, ns); } - currentElementProperties = (ElementProperties)elementScope.Pop(); + _currentElementProperties = (ElementProperties)_elementScope.Pop(); } internal override void WriteFullEndElement(string prefix, string localName, string ns) @@ -175,14 +175,14 @@ internal override void WriteFullEndElement(string prefix, string localName, stri { Debug.Assert(prefix.Length == 0); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - if ((currentElementProperties & ElementProperties.EMPTY) == 0) + if ((_currentElementProperties & ElementProperties.EMPTY) == 0) { - bufChars[base.bufPos++] = (char)'<'; - bufChars[base.bufPos++] = (char)'/'; + _bufChars[base._bufPos++] = (char)'<'; + _bufChars[base._bufPos++] = (char)'/'; base.RawText(localName); - bufChars[base.bufPos++] = (char)'>'; + _bufChars[base._bufPos++] = (char)'>'; } } else @@ -191,7 +191,7 @@ internal override void WriteFullEndElement(string prefix, string localName, stri base.WriteFullEndElement(prefix, localName, ns); } - currentElementProperties = (ElementProperties)elementScope.Pop(); + _currentElementProperties = (ElementProperties)_elementScope.Pop(); } // 1. How the outputBooleanAttribute(fBOOL) and outputHtmlUriText(fURI) being set? @@ -299,22 +299,22 @@ public override void WriteStartAttribute(string prefix, string localName, string { Debug.Assert(prefix.Length == 0); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - if (base.attrEndPos == bufPos) + if (base._attrEndPos == _bufPos) { - base.bufChars[bufPos++] = (char)' '; + base._bufChars[_bufPos++] = (char)' '; } base.RawText(localName); - if ((currentElementProperties & (ElementProperties.BOOL_PARENT | ElementProperties.URI_PARENT | ElementProperties.NAME_PARENT)) != 0) + if ((_currentElementProperties & (ElementProperties.BOOL_PARENT | ElementProperties.URI_PARENT | ElementProperties.NAME_PARENT)) != 0) { - _currentAttributeProperties = (AttributeProperties)attributePropertySearch.FindCaseInsensitiveString(localName) & - (AttributeProperties)currentElementProperties; + _currentAttributeProperties = (AttributeProperties)_attributePropertySearch.FindCaseInsensitiveString(localName) & + (AttributeProperties)_currentElementProperties; if ((_currentAttributeProperties & AttributeProperties.BOOLEAN) != 0) { - base.inAttributeValue = true; + base._inAttributeValue = true; return; } } @@ -323,8 +323,8 @@ public override void WriteStartAttribute(string prefix, string localName, string _currentAttributeProperties = AttributeProperties.DEFAULT; } - base.bufChars[bufPos++] = (char)'='; - base.bufChars[bufPos++] = (char)'"'; + base._bufChars[_bufPos++] = (char)'='; + base._bufChars[_bufPos++] = (char)'"'; } else { @@ -332,7 +332,7 @@ public override void WriteStartAttribute(string prefix, string localName, string _currentAttributeProperties = AttributeProperties.DEFAULT; } - base.inAttributeValue = true; + base._inAttributeValue = true; } // Output the amp; at end of EndAttribute @@ -340,7 +340,7 @@ public override void WriteEndAttribute() { if ((_currentAttributeProperties & AttributeProperties.BOOLEAN) != 0) { - base.attrEndPos = bufPos; + base._attrEndPos = _bufPos; } else { @@ -350,12 +350,12 @@ public override void WriteEndAttribute() _endsWithAmpersand = false; } - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - base.bufChars[bufPos++] = (char)'"'; + base._bufChars[_bufPos++] = (char)'"'; } - base.inAttributeValue = false; - base.attrEndPos = bufPos; + base._inAttributeValue = false; + base._attrEndPos = _bufPos; } // HTML PI's use ">" to terminate rather than "?>". @@ -363,18 +363,18 @@ public override void WriteProcessingInstruction(string target, string text) { Debug.Assert(target != null && target.Length != 0 && text != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[base.bufPos++] = (char)'<'; - bufChars[base.bufPos++] = (char)'?'; + _bufChars[base._bufPos++] = (char)'<'; + _bufChars[base._bufPos++] = (char)'?'; base.RawText(target); - bufChars[base.bufPos++] = (char)' '; + _bufChars[base._bufPos++] = (char)' '; base.WriteCommentOrPi(text, '?'); - base.bufChars[base.bufPos++] = (char)'>'; + base._bufChars[base._bufPos++] = (char)'>'; - if (base.bufPos > base.bufLen) + if (base._bufPos > base._bufLen) { FlushBuffer(); } @@ -385,12 +385,12 @@ public override unsafe void WriteString(string text) { Debug.Assert(text != null); - if (trackTextContent && inTextContent != true) { ChangeTextContentMark(true); } + if (_trackTextContent && _inTextContent != true) { ChangeTextContentMark(true); } fixed (char* pSrc = text) { char* pSrcEnd = pSrc + text.Length; - if (base.inAttributeValue) + if (base._inAttributeValue) { WriteHtmlAttributeTextBlock(pSrc, pSrcEnd); } @@ -422,11 +422,11 @@ public override unsafe void WriteChars(char[] buffer, int index, int count) Debug.Assert(index >= 0); Debug.Assert(count >= 0 && index + count <= buffer.Length); - if (trackTextContent && inTextContent != true) { ChangeTextContentMark(true); } + if (_trackTextContent && _inTextContent != true) { ChangeTextContentMark(true); } fixed (char* pSrcBegin = &buffer[index]) { - if (inAttributeValue) + if (_inAttributeValue) { WriteAttributeTextBlock(pSrcBegin, pSrcBegin + count); } @@ -447,16 +447,16 @@ private void Init(XmlWriterSettings settings) Debug.Assert((int)ElementProperties.BOOL_PARENT == (int)AttributeProperties.BOOLEAN); Debug.Assert((int)ElementProperties.NAME_PARENT == (int)AttributeProperties.NAME); - if (elementPropertySearch == null) + if (_elementPropertySearch == null) { - //elementPropertySearch should be init last for the mutli thread safe situation. - attributePropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlAttributes); - elementPropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlElements); + //_elementPropertySearch should be init last for the mutli thread safe situation. + _attributePropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlAttributes); + _elementPropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlElements); } - elementScope = new ByteStack(StackIncrement); + _elementScope = new ByteStack(StackIncrement); _uriEscapingBuffer = new byte[5]; - currentElementProperties = ElementProperties.DEFAULT; + _currentElementProperties = ElementProperties.DEFAULT; _mediaType = settings.MediaType; _doNotEscapeUriAttributes = settings.DoNotEscapeUriAttributes; @@ -474,7 +474,7 @@ protected void WriteMetaElement() base.RawText(" content=\""); base.RawText(_mediaType); base.RawText("; charset="); - base.RawText(base.encoding.WebName); + base.RawText(base._encoding.WebName); base.RawText("\">"); } @@ -489,7 +489,7 @@ protected void WriteMetaElement() // only the top of the stack is the real E1 element properties. protected unsafe void WriteHtmlElementTextBlock(char* pSrc, char* pSrcEnd) { - if ((currentElementProperties & ElementProperties.NO_ENTITIES) != 0) + if ((_currentElementProperties & ElementProperties.NO_ENTITIES) != 0) { base.RawText(pSrc, pSrcEnd); } @@ -518,7 +518,7 @@ protected unsafe void WriteHtmlAttributeTextBlock(char* pSrc, char* pSrcEnd) WriteHtmlAttributeText(pSrc, pSrcEnd); } } - else if ((currentElementProperties & ElementProperties.HAS_NS) != 0) + else if ((_currentElementProperties & ElementProperties.HAS_NS) != 0) { base.WriteAttributeTextBlock(pSrc, pSrcEnd); } @@ -559,20 +559,20 @@ private unsafe void WriteHtmlAttributeText(char* pSrc, char* pSrcEnd) _endsWithAmpersand = false; } - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; char ch = (char)0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) + while (pDst < pDstEnd && _xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) { *pDst++ = (char)ch; pSrc++; @@ -588,7 +588,7 @@ private unsafe void WriteHtmlAttributeText(char* pSrc, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -632,7 +632,7 @@ private unsafe void WriteHtmlAttributeText(char* pSrc, char* pSrcEnd) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -647,20 +647,20 @@ private unsafe void WriteUriAttributeText(char* pSrc, char* pSrcEnd) _endsWithAmpersand = false; } - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; char ch = (char)0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch < 0x80)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch < 0x80)) { *pDst++ = (char)ch; pSrc++; @@ -676,7 +676,7 @@ private unsafe void WriteUriAttributeText(char* pSrc, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -735,17 +735,17 @@ private unsafe void WriteUriAttributeText(char* pSrc, char* pSrcEnd) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } // For handling &{ in Html text field. If & is not followed by {, it still needs to be escaped. private void OutputRestAmps() { - base.bufChars[bufPos++] = (char)'a'; - base.bufChars[bufPos++] = (char)'m'; - base.bufChars[bufPos++] = (char)'p'; - base.bufChars[bufPos++] = (char)';'; + base._bufChars[_bufPos++] = (char)'a'; + base._bufChars[_bufPos++] = (char)'m'; + base._bufChars[_bufPos++] = (char)'p'; + base._bufChars[_bufPos++] = (char)';'; } } @@ -825,69 +825,69 @@ public override void WriteDocType(string name, string pubid, string sysid, strin base.WriteDocType(name, pubid, sysid, subset); // Allow indentation after DocTypeDecl - _endBlockPos = base.bufPos; + _endBlockPos = base._bufPos; } public override void WriteStartElement(string prefix, string localName, string ns) { Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - base.elementScope.Push((byte)base.currentElementProperties); + base._elementScope.Push((byte)base._currentElementProperties); if (ns.Length == 0) { Debug.Assert(prefix.Length == 0); - base.currentElementProperties = (ElementProperties)elementPropertySearch.FindCaseInsensitiveString(localName); + base._currentElementProperties = (ElementProperties)_elementPropertySearch.FindCaseInsensitiveString(localName); - if (_endBlockPos == base.bufPos && (base.currentElementProperties & ElementProperties.BLOCK_WS) != 0) + if (_endBlockPos == base._bufPos && (base._currentElementProperties & ElementProperties.BLOCK_WS) != 0) { WriteIndent(); } _indentLevel++; - base.bufChars[bufPos++] = (char)'<'; + base._bufChars[_bufPos++] = (char)'<'; } else { - base.currentElementProperties = ElementProperties.HAS_NS | ElementProperties.BLOCK_WS; + base._currentElementProperties = ElementProperties.HAS_NS | ElementProperties.BLOCK_WS; - if (_endBlockPos == base.bufPos) + if (_endBlockPos == base._bufPos) { WriteIndent(); } _indentLevel++; - base.bufChars[base.bufPos++] = (char)'<'; + base._bufChars[base._bufPos++] = (char)'<'; if (prefix.Length != 0) { base.RawText(prefix); - base.bufChars[base.bufPos++] = (char)':'; + base._bufChars[base._bufPos++] = (char)':'; } } base.RawText(localName); - base.attrEndPos = bufPos; + base._attrEndPos = _bufPos; } internal override void StartElementContent() { - base.bufChars[base.bufPos++] = (char)'>'; + base._bufChars[base._bufPos++] = (char)'>'; // Detect whether content is output - base.contentPos = base.bufPos; + base._contentPos = base._bufPos; - if ((currentElementProperties & ElementProperties.HEAD) != 0) + if ((_currentElementProperties & ElementProperties.HEAD) != 0) { WriteIndent(); WriteMetaElement(); - _endBlockPos = base.bufPos; + _endBlockPos = base._bufPos; } - else if ((base.currentElementProperties & ElementProperties.BLOCK_WS) != 0) + else if ((base._currentElementProperties & ElementProperties.BLOCK_WS) != 0) { // store the element block position - _endBlockPos = base.bufPos; + _endBlockPos = base._bufPos; } } @@ -899,12 +899,12 @@ internal override void WriteEndElement(string prefix, string localName, string n _indentLevel--; // If this element has block whitespace properties, - isBlockWs = (base.currentElementProperties & ElementProperties.BLOCK_WS) != 0; + isBlockWs = (base._currentElementProperties & ElementProperties.BLOCK_WS) != 0; if (isBlockWs) { // And if the last node to be output had block whitespace properties, // And if content was output within this element, - if (_endBlockPos == base.bufPos && base.contentPos != base.bufPos) + if (_endBlockPos == base._bufPos && base._contentPos != base._bufPos) { // Then indent WriteIndent(); @@ -914,12 +914,12 @@ internal override void WriteEndElement(string prefix, string localName, string n base.WriteEndElement(prefix, localName, ns); // Reset contentPos in case of empty elements - base.contentPos = 0; + base._contentPos = 0; // Mark end of element in buffer for element's with block whitespace properties if (isBlockWs) { - _endBlockPos = base.bufPos; + _endBlockPos = base._bufPos; } } @@ -927,7 +927,7 @@ public override void WriteStartAttribute(string prefix, string localName, string { if (_newLineOnAttributes) { - RawText(base.newLineChars); + RawText(base._newLineChars); _indentLevel++; WriteIndent(); _indentLevel--; @@ -938,7 +938,7 @@ public override void WriteStartAttribute(string prefix, string localName, string protected override void FlushBuffer() { // Make sure the buffer will reset the block position - _endBlockPos = (_endBlockPos == base.bufPos) ? 1 : 0; + _endBlockPos = (_endBlockPos == base._bufPos) ? 1 : 0; base.FlushBuffer(); } @@ -966,7 +966,7 @@ private void WriteIndent() // -- suppress ws betw and PI // -- suppress ws betw and comment - RawText(base.newLineChars); + RawText(base._newLineChars); for (int i = _indentLevel; i > 0; i--) { RawText(_indentChars); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlRawTextWriterGenerator.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlRawTextWriterGenerator.ttinclude index f8101cbe653ae..09cc00e36c08b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlRawTextWriterGenerator.ttinclude +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlRawTextWriterGenerator.ttinclude @@ -19,8 +19,8 @@ namespace System.Xml { internal class <#= ClassName #> : <#= BaseClassName #> { - protected ByteStack elementScope; - protected ElementProperties currentElementProperties; + protected ByteStack _elementScope; + protected ElementProperties _currentElementProperties; private AttributeProperties _currentAttributeProperties; private bool _endsWithAmpersand; @@ -29,8 +29,8 @@ namespace System.Xml private string _mediaType; private bool _doNotEscapeUriAttributes; - protected static TernaryTreeReadOnly elementPropertySearch; - protected static TernaryTreeReadOnly attributePropertySearch; + protected static TernaryTreeReadOnly _elementPropertySearch; + protected static TernaryTreeReadOnly _attributePropertySearch; private const int StackIncrement = 10; <# if (WriterType == RawTextWriterType.Encoded) { #> @@ -108,7 +108,7 @@ namespace System.Xml { Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null); - elementScope.Push((byte)currentElementProperties); + _elementScope.Push((byte)_currentElementProperties); if (ns.Length == 0) { @@ -116,7 +116,7 @@ namespace System.Xml #><#= SetTextContentMark(4, false) #> - currentElementProperties = (ElementProperties)elementPropertySearch.FindCaseInsensitiveString(localName); + _currentElementProperties = (ElementProperties)_elementPropertySearch.FindCaseInsensitiveString(localName); base.<#= BufferName #>[bufPos++] = (<#= BufferType #>)'<'; base.RawText(localName); base.attrEndPos = bufPos; @@ -125,7 +125,7 @@ namespace System.Xml { // Since the HAS_NS has no impact to the ElementTextBlock behavior, // we don't need to push it into the stack. - currentElementProperties = ElementProperties.HAS_NS; + _currentElementProperties = ElementProperties.HAS_NS; base.WriteStartElement(prefix, localName, ns); } } @@ -138,7 +138,7 @@ namespace System.Xml // Detect whether content is output contentPos = bufPos; - if ((currentElementProperties & ElementProperties.HEAD) != 0) + if ((_currentElementProperties & ElementProperties.HEAD) != 0) { WriteMetaElement(); } @@ -156,7 +156,7 @@ namespace System.Xml #><#= SetTextContentMark(4, false) #> - if ((currentElementProperties & ElementProperties.EMPTY) == 0) + if ((_currentElementProperties & ElementProperties.EMPTY) == 0) { <#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'<'; <#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'/'; @@ -170,7 +170,7 @@ namespace System.Xml base.WriteEndElement(prefix, localName, ns); } - currentElementProperties = (ElementProperties)elementScope.Pop(); + _currentElementProperties = (ElementProperties)_elementScope.Pop(); } internal override void WriteFullEndElement(string prefix, string localName, string ns) @@ -181,7 +181,7 @@ namespace System.Xml #><#= SetTextContentMark(4, false) #> - if ((currentElementProperties & ElementProperties.EMPTY) == 0) + if ((_currentElementProperties & ElementProperties.EMPTY) == 0) { <#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'<'; <#= BufferName #>[base.bufPos++] = (<#= BufferType #>)'/'; @@ -195,7 +195,7 @@ namespace System.Xml base.WriteFullEndElement(prefix, localName, ns); } - currentElementProperties = (ElementProperties)elementScope.Pop(); + _currentElementProperties = (ElementProperties)_elementScope.Pop(); } // 1. How the outputBooleanAttribute(fBOOL) and outputHtmlUriText(fURI) being set? @@ -311,10 +311,10 @@ namespace System.Xml } base.RawText(localName); - if ((currentElementProperties & (ElementProperties.BOOL_PARENT | ElementProperties.URI_PARENT | ElementProperties.NAME_PARENT)) != 0) + if ((_currentElementProperties & (ElementProperties.BOOL_PARENT | ElementProperties.URI_PARENT | ElementProperties.NAME_PARENT)) != 0) { - _currentAttributeProperties = (AttributeProperties)attributePropertySearch.FindCaseInsensitiveString(localName) & - (AttributeProperties)currentElementProperties; + _currentAttributeProperties = (AttributeProperties)_attributePropertySearch.FindCaseInsensitiveString(localName) & + (AttributeProperties)_currentElementProperties; if ((_currentAttributeProperties & AttributeProperties.BOOLEAN) != 0) { @@ -451,16 +451,16 @@ namespace System.Xml Debug.Assert((int)ElementProperties.BOOL_PARENT == (int)AttributeProperties.BOOLEAN); Debug.Assert((int)ElementProperties.NAME_PARENT == (int)AttributeProperties.NAME); - if (elementPropertySearch == null) + if (_elementPropertySearch == null) { - //elementPropertySearch should be init last for the mutli thread safe situation. - attributePropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlAttributes); - elementPropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlElements); + //_elementPropertySearch should be init last for the mutli thread safe situation. + _attributePropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlAttributes); + _elementPropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlElements); } - elementScope = new ByteStack(StackIncrement); + _elementScope = new ByteStack(StackIncrement); _uriEscapingBuffer = new byte[5]; - currentElementProperties = ElementProperties.DEFAULT; + _currentElementProperties = ElementProperties.DEFAULT; _mediaType = settings.MediaType; _doNotEscapeUriAttributes = settings.DoNotEscapeUriAttributes; @@ -493,7 +493,7 @@ namespace System.Xml // only the top of the stack is the real E1 element properties. protected unsafe void WriteHtmlElementTextBlock(char* pSrc, char* pSrcEnd) { - if ((currentElementProperties & ElementProperties.NO_ENTITIES) != 0) + if ((_currentElementProperties & ElementProperties.NO_ENTITIES) != 0) { base.RawText(pSrc, pSrcEnd); } @@ -522,7 +522,7 @@ namespace System.Xml WriteHtmlAttributeText(pSrc, pSrcEnd); } } - else if ((currentElementProperties & ElementProperties.HAS_NS) != 0) + else if ((_currentElementProperties & ElementProperties.HAS_NS) != 0) { base.WriteAttributeTextBlock(pSrc, pSrcEnd); } @@ -844,15 +844,15 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - base.elementScope.Push((byte)base.currentElementProperties); + base._elementScope.Push((byte)base._currentElementProperties); if (ns.Length == 0) { Debug.Assert(prefix.Length == 0); - base.currentElementProperties = (ElementProperties)elementPropertySearch.FindCaseInsensitiveString(localName); + base._currentElementProperties = (ElementProperties)_elementPropertySearch.FindCaseInsensitiveString(localName); - if (_endBlockPos == base.bufPos && (base.currentElementProperties & ElementProperties.BLOCK_WS) != 0) + if (_endBlockPos == base.bufPos && (base._currentElementProperties & ElementProperties.BLOCK_WS) != 0) { WriteIndent(); } @@ -862,7 +862,7 @@ namespace System.Xml } else { - base.currentElementProperties = ElementProperties.HAS_NS | ElementProperties.BLOCK_WS; + base._currentElementProperties = ElementProperties.HAS_NS | ElementProperties.BLOCK_WS; if (_endBlockPos == base.bufPos) { @@ -888,13 +888,13 @@ namespace System.Xml // Detect whether content is output base.contentPos = base.bufPos; - if ((currentElementProperties & ElementProperties.HEAD) != 0) + if ((_currentElementProperties & ElementProperties.HEAD) != 0) { WriteIndent(); WriteMetaElement(); _endBlockPos = base.bufPos; } - else if ((base.currentElementProperties & ElementProperties.BLOCK_WS) != 0) + else if ((base._currentElementProperties & ElementProperties.BLOCK_WS) != 0) { // store the element block position _endBlockPos = base.bufPos; @@ -909,7 +909,7 @@ namespace System.Xml _indentLevel--; // If this element has block whitespace properties, - isBlockWs = (base.currentElementProperties & ElementProperties.BLOCK_WS) != 0; + isBlockWs = (base._currentElementProperties & ElementProperties.BLOCK_WS) != 0; if (isBlockWs) { // And if the last node to be output had block whitespace properties, diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlUtf8RawTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlUtf8RawTextWriter.cs index f9934ec9548d1..375a10747e6b0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlUtf8RawTextWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/HtmlUtf8RawTextWriter.cs @@ -17,8 +17,8 @@ namespace System.Xml { internal class HtmlUtf8RawTextWriter : XmlUtf8RawTextWriter { - protected ByteStack elementScope; - protected ElementProperties currentElementProperties; + protected ByteStack _elementScope; + protected ElementProperties _currentElementProperties; private AttributeProperties _currentAttributeProperties; private bool _endsWithAmpersand; @@ -27,8 +27,8 @@ internal class HtmlUtf8RawTextWriter : XmlUtf8RawTextWriter private string _mediaType; private bool _doNotEscapeUriAttributes; - protected static TernaryTreeReadOnly elementPropertySearch; - protected static TernaryTreeReadOnly attributePropertySearch; + protected static TernaryTreeReadOnly _elementPropertySearch; + protected static TernaryTreeReadOnly _attributePropertySearch; private const int StackIncrement = 10; @@ -69,27 +69,27 @@ public override void WriteDocType(string name, string pubid, string sysid, strin RawText("\" \""); RawText(sysid); } - bufBytes[bufPos++] = (byte)'"'; + _bufBytes[_bufPos++] = (byte)'"'; } else if (sysid != null) { RawText(" SYSTEM \""); RawText(sysid); - bufBytes[bufPos++] = (byte)'"'; + _bufBytes[_bufPos++] = (byte)'"'; } else { - bufBytes[bufPos++] = (byte)' '; + _bufBytes[_bufPos++] = (byte)' '; } if (subset != null) { - bufBytes[bufPos++] = (byte)'['; + _bufBytes[_bufPos++] = (byte)'['; RawText(subset); - bufBytes[bufPos++] = (byte)']'; + _bufBytes[_bufPos++] = (byte)']'; } - bufBytes[bufPos++] = (byte)'>'; + _bufBytes[_bufPos++] = (byte)'>'; } // For the HTML element, it should call this method with ns and prefix as String.Empty @@ -97,22 +97,22 @@ public override void WriteStartElement(string prefix, string localName, string n { Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null); - elementScope.Push((byte)currentElementProperties); + _elementScope.Push((byte)_currentElementProperties); if (ns.Length == 0) { Debug.Assert(prefix.Length == 0); - currentElementProperties = (ElementProperties)elementPropertySearch.FindCaseInsensitiveString(localName); - base.bufBytes[bufPos++] = (byte)'<'; + _currentElementProperties = (ElementProperties)_elementPropertySearch.FindCaseInsensitiveString(localName); + base._bufBytes[_bufPos++] = (byte)'<'; base.RawText(localName); - base.attrEndPos = bufPos; + base._attrEndPos = _bufPos; } else { // Since the HAS_NS has no impact to the ElementTextBlock behavior, // we don't need to push it into the stack. - currentElementProperties = ElementProperties.HAS_NS; + _currentElementProperties = ElementProperties.HAS_NS; base.WriteStartElement(prefix, localName, ns); } } @@ -120,12 +120,12 @@ public override void WriteStartElement(string prefix, string localName, string n // Output >. For HTML needs to output META info internal override void StartElementContent() { - base.bufBytes[base.bufPos++] = (byte)'>'; + base._bufBytes[base._bufPos++] = (byte)'>'; // Detect whether content is output - contentPos = bufPos; + _contentPos = _bufPos; - if ((currentElementProperties & ElementProperties.HEAD) != 0) + if ((_currentElementProperties & ElementProperties.HEAD) != 0) { WriteMetaElement(); } @@ -141,12 +141,12 @@ internal override void WriteEndElement(string prefix, string localName, string n { Debug.Assert(prefix.Length == 0); - if ((currentElementProperties & ElementProperties.EMPTY) == 0) + if ((_currentElementProperties & ElementProperties.EMPTY) == 0) { - bufBytes[base.bufPos++] = (byte)'<'; - bufBytes[base.bufPos++] = (byte)'/'; + _bufBytes[base._bufPos++] = (byte)'<'; + _bufBytes[base._bufPos++] = (byte)'/'; base.RawText(localName); - bufBytes[base.bufPos++] = (byte)'>'; + _bufBytes[base._bufPos++] = (byte)'>'; } } else @@ -155,7 +155,7 @@ internal override void WriteEndElement(string prefix, string localName, string n base.WriteEndElement(prefix, localName, ns); } - currentElementProperties = (ElementProperties)elementScope.Pop(); + _currentElementProperties = (ElementProperties)_elementScope.Pop(); } internal override void WriteFullEndElement(string prefix, string localName, string ns) @@ -164,12 +164,12 @@ internal override void WriteFullEndElement(string prefix, string localName, stri { Debug.Assert(prefix.Length == 0); - if ((currentElementProperties & ElementProperties.EMPTY) == 0) + if ((_currentElementProperties & ElementProperties.EMPTY) == 0) { - bufBytes[base.bufPos++] = (byte)'<'; - bufBytes[base.bufPos++] = (byte)'/'; + _bufBytes[base._bufPos++] = (byte)'<'; + _bufBytes[base._bufPos++] = (byte)'/'; base.RawText(localName); - bufBytes[base.bufPos++] = (byte)'>'; + _bufBytes[base._bufPos++] = (byte)'>'; } } else @@ -178,7 +178,7 @@ internal override void WriteFullEndElement(string prefix, string localName, stri base.WriteFullEndElement(prefix, localName, ns); } - currentElementProperties = (ElementProperties)elementScope.Pop(); + _currentElementProperties = (ElementProperties)_elementScope.Pop(); } // 1. How the outputBooleanAttribute(fBOOL) and outputHtmlUriText(fURI) being set? @@ -286,20 +286,20 @@ public override void WriteStartAttribute(string prefix, string localName, string { Debug.Assert(prefix.Length == 0); - if (base.attrEndPos == bufPos) + if (base._attrEndPos == _bufPos) { - base.bufBytes[bufPos++] = (byte)' '; + base._bufBytes[_bufPos++] = (byte)' '; } base.RawText(localName); - if ((currentElementProperties & (ElementProperties.BOOL_PARENT | ElementProperties.URI_PARENT | ElementProperties.NAME_PARENT)) != 0) + if ((_currentElementProperties & (ElementProperties.BOOL_PARENT | ElementProperties.URI_PARENT | ElementProperties.NAME_PARENT)) != 0) { - _currentAttributeProperties = (AttributeProperties)attributePropertySearch.FindCaseInsensitiveString(localName) & - (AttributeProperties)currentElementProperties; + _currentAttributeProperties = (AttributeProperties)_attributePropertySearch.FindCaseInsensitiveString(localName) & + (AttributeProperties)_currentElementProperties; if ((_currentAttributeProperties & AttributeProperties.BOOLEAN) != 0) { - base.inAttributeValue = true; + base._inAttributeValue = true; return; } } @@ -308,8 +308,8 @@ public override void WriteStartAttribute(string prefix, string localName, string _currentAttributeProperties = AttributeProperties.DEFAULT; } - base.bufBytes[bufPos++] = (byte)'='; - base.bufBytes[bufPos++] = (byte)'"'; + base._bufBytes[_bufPos++] = (byte)'='; + base._bufBytes[_bufPos++] = (byte)'"'; } else { @@ -317,7 +317,7 @@ public override void WriteStartAttribute(string prefix, string localName, string _currentAttributeProperties = AttributeProperties.DEFAULT; } - base.inAttributeValue = true; + base._inAttributeValue = true; } // Output the amp; at end of EndAttribute @@ -325,7 +325,7 @@ public override void WriteEndAttribute() { if ((_currentAttributeProperties & AttributeProperties.BOOLEAN) != 0) { - base.attrEndPos = bufPos; + base._attrEndPos = _bufPos; } else { @@ -335,10 +335,10 @@ public override void WriteEndAttribute() _endsWithAmpersand = false; } - base.bufBytes[bufPos++] = (byte)'"'; + base._bufBytes[_bufPos++] = (byte)'"'; } - base.inAttributeValue = false; - base.attrEndPos = bufPos; + base._inAttributeValue = false; + base._attrEndPos = _bufPos; } // HTML PI's use ">" to terminate rather than "?>". @@ -346,16 +346,16 @@ public override void WriteProcessingInstruction(string target, string text) { Debug.Assert(target != null && target.Length != 0 && text != null); - bufBytes[base.bufPos++] = (byte)'<'; - bufBytes[base.bufPos++] = (byte)'?'; + _bufBytes[base._bufPos++] = (byte)'<'; + _bufBytes[base._bufPos++] = (byte)'?'; base.RawText(target); - bufBytes[base.bufPos++] = (byte)' '; + _bufBytes[base._bufPos++] = (byte)' '; base.WriteCommentOrPi(text, '?'); - base.bufBytes[base.bufPos++] = (byte)'>'; + base._bufBytes[base._bufPos++] = (byte)'>'; - if (base.bufPos > base.bufLen) + if (base._bufPos > base._bufLen) { FlushBuffer(); } @@ -369,7 +369,7 @@ public override unsafe void WriteString(string text) fixed (char* pSrc = text) { char* pSrcEnd = pSrc + text.Length; - if (base.inAttributeValue) + if (base._inAttributeValue) { WriteHtmlAttributeTextBlock(pSrc, pSrcEnd); } @@ -403,7 +403,7 @@ public override unsafe void WriteChars(char[] buffer, int index, int count) fixed (char* pSrcBegin = &buffer[index]) { - if (inAttributeValue) + if (_inAttributeValue) { WriteAttributeTextBlock(pSrcBegin, pSrcBegin + count); } @@ -424,16 +424,16 @@ private void Init(XmlWriterSettings settings) Debug.Assert((int)ElementProperties.BOOL_PARENT == (int)AttributeProperties.BOOLEAN); Debug.Assert((int)ElementProperties.NAME_PARENT == (int)AttributeProperties.NAME); - if (elementPropertySearch == null) + if (_elementPropertySearch == null) { //elementPropertySearch should be init last for the mutli thread safe situation. - attributePropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlAttributes); - elementPropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlElements); + _attributePropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlAttributes); + _elementPropertySearch = new TernaryTreeReadOnly(HtmlTernaryTree.htmlElements); } - elementScope = new ByteStack(StackIncrement); + _elementScope = new ByteStack(StackIncrement); _uriEscapingBuffer = new byte[5]; - currentElementProperties = ElementProperties.DEFAULT; + _currentElementProperties = ElementProperties.DEFAULT; _mediaType = settings.MediaType; _doNotEscapeUriAttributes = settings.DoNotEscapeUriAttributes; @@ -451,7 +451,7 @@ protected void WriteMetaElement() base.RawText(" content=\""); base.RawText(_mediaType); base.RawText("; charset="); - base.RawText(base.encoding.WebName); + base.RawText(base._encoding.WebName); base.RawText("\">"); } @@ -466,7 +466,7 @@ protected void WriteMetaElement() // only the top of the stack is the real E1 element properties. protected unsafe void WriteHtmlElementTextBlock(char* pSrc, char* pSrcEnd) { - if ((currentElementProperties & ElementProperties.NO_ENTITIES) != 0) + if ((_currentElementProperties & ElementProperties.NO_ENTITIES) != 0) { base.RawText(pSrc, pSrcEnd); } @@ -495,7 +495,7 @@ protected unsafe void WriteHtmlAttributeTextBlock(char* pSrc, char* pSrcEnd) WriteHtmlAttributeText(pSrc, pSrcEnd); } } - else if ((currentElementProperties & ElementProperties.HAS_NS) != 0) + else if ((_currentElementProperties & ElementProperties.HAS_NS) != 0) { base.WriteAttributeTextBlock(pSrc, pSrcEnd); } @@ -536,20 +536,20 @@ private unsafe void WriteHtmlAttributeText(char* pSrc, char* pSrcEnd) _endsWithAmpersand = false; } - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; char ch = (char)0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) { *pDst++ = (byte)ch; pSrc++; @@ -565,7 +565,7 @@ private unsafe void WriteHtmlAttributeText(char* pSrc, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -609,7 +609,7 @@ private unsafe void WriteHtmlAttributeText(char* pSrc, char* pSrcEnd) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -624,20 +624,20 @@ private unsafe void WriteUriAttributeText(char* pSrc, char* pSrcEnd) _endsWithAmpersand = false; } - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; char ch = (char)0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch < 0x80)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch < 0x80)) { *pDst++ = (byte)ch; pSrc++; @@ -653,7 +653,7 @@ private unsafe void WriteUriAttributeText(char* pSrc, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -712,17 +712,17 @@ private unsafe void WriteUriAttributeText(char* pSrc, char* pSrcEnd) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } // For handling &{ in Html text field. If & is not followed by {, it still needs to be escaped. private void OutputRestAmps() { - base.bufBytes[bufPos++] = (byte)'a'; - base.bufBytes[bufPos++] = (byte)'m'; - base.bufBytes[bufPos++] = (byte)'p'; - base.bufBytes[bufPos++] = (byte)';'; + base._bufBytes[_bufPos++] = (byte)'a'; + base._bufBytes[_bufPos++] = (byte)'m'; + base._bufBytes[_bufPos++] = (byte)'p'; + base._bufBytes[_bufPos++] = (byte)';'; } } @@ -797,67 +797,67 @@ public override void WriteDocType(string name, string pubid, string sysid, strin base.WriteDocType(name, pubid, sysid, subset); // Allow indentation after DocTypeDecl - _endBlockPos = base.bufPos; + _endBlockPos = base._bufPos; } public override void WriteStartElement(string prefix, string localName, string ns) { Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null); - base.elementScope.Push((byte)base.currentElementProperties); + base._elementScope.Push((byte)base._currentElementProperties); if (ns.Length == 0) { Debug.Assert(prefix.Length == 0); - base.currentElementProperties = (ElementProperties)elementPropertySearch.FindCaseInsensitiveString(localName); + base._currentElementProperties = (ElementProperties)_elementPropertySearch.FindCaseInsensitiveString(localName); - if (_endBlockPos == base.bufPos && (base.currentElementProperties & ElementProperties.BLOCK_WS) != 0) + if (_endBlockPos == base._bufPos && (base._currentElementProperties & ElementProperties.BLOCK_WS) != 0) { WriteIndent(); } _indentLevel++; - base.bufBytes[bufPos++] = (byte)'<'; + base._bufBytes[_bufPos++] = (byte)'<'; } else { - base.currentElementProperties = ElementProperties.HAS_NS | ElementProperties.BLOCK_WS; + base._currentElementProperties = ElementProperties.HAS_NS | ElementProperties.BLOCK_WS; - if (_endBlockPos == base.bufPos) + if (_endBlockPos == base._bufPos) { WriteIndent(); } _indentLevel++; - base.bufBytes[base.bufPos++] = (byte)'<'; + base._bufBytes[base._bufPos++] = (byte)'<'; if (prefix.Length != 0) { base.RawText(prefix); - base.bufBytes[base.bufPos++] = (byte)':'; + base._bufBytes[base._bufPos++] = (byte)':'; } } base.RawText(localName); - base.attrEndPos = bufPos; + base._attrEndPos = _bufPos; } internal override void StartElementContent() { - base.bufBytes[base.bufPos++] = (byte)'>'; + base._bufBytes[base._bufPos++] = (byte)'>'; // Detect whether content is output - base.contentPos = base.bufPos; + base._contentPos = base._bufPos; - if ((currentElementProperties & ElementProperties.HEAD) != 0) + if ((_currentElementProperties & ElementProperties.HEAD) != 0) { WriteIndent(); WriteMetaElement(); - _endBlockPos = base.bufPos; + _endBlockPos = base._bufPos; } - else if ((base.currentElementProperties & ElementProperties.BLOCK_WS) != 0) + else if ((base._currentElementProperties & ElementProperties.BLOCK_WS) != 0) { // store the element block position - _endBlockPos = base.bufPos; + _endBlockPos = base._bufPos; } } @@ -869,12 +869,12 @@ internal override void WriteEndElement(string prefix, string localName, string n _indentLevel--; // If this element has block whitespace properties, - isBlockWs = (base.currentElementProperties & ElementProperties.BLOCK_WS) != 0; + isBlockWs = (base._currentElementProperties & ElementProperties.BLOCK_WS) != 0; if (isBlockWs) { // And if the last node to be output had block whitespace properties, // And if content was output within this element, - if (_endBlockPos == base.bufPos && base.contentPos != base.bufPos) + if (_endBlockPos == base._bufPos && base._contentPos != base._bufPos) { // Then indent WriteIndent(); @@ -884,12 +884,12 @@ internal override void WriteEndElement(string prefix, string localName, string n base.WriteEndElement(prefix, localName, ns); // Reset contentPos in case of empty elements - base.contentPos = 0; + base._contentPos = 0; // Mark end of element in buffer for element's with block whitespace properties if (isBlockWs) { - _endBlockPos = base.bufPos; + _endBlockPos = base._bufPos; } } @@ -897,7 +897,7 @@ public override void WriteStartAttribute(string prefix, string localName, string { if (_newLineOnAttributes) { - RawText(base.newLineChars); + RawText(base._newLineChars); _indentLevel++; WriteIndent(); _indentLevel--; @@ -908,7 +908,7 @@ public override void WriteStartAttribute(string prefix, string localName, string protected override void FlushBuffer() { // Make sure the buffer will reset the block position - _endBlockPos = (_endBlockPos == base.bufPos) ? 1 : 0; + _endBlockPos = (_endBlockPos == base._bufPos) ? 1 : 0; base.FlushBuffer(); } @@ -936,7 +936,7 @@ private void WriteIndent() // -- suppress ws betw and PI // -- suppress ws betw and comment - RawText(base.newLineChars); + RawText(base._newLineChars); for (int i = _indentLevel; i > 0; i--) { RawText(_indentChars); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs index cf7b19cd88a44..9ab4c5b35bcf7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/QueryOutputWriter.cs @@ -91,11 +91,11 @@ public QueryOutputWriter(XmlRawWriter writer, XmlWriterSettings settings) { get { - return this.resolver; + return this._resolver; } set { - this.resolver = value; + this._resolver = value; _wrapped.NamespaceResolver = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/RawTextWriterEncoded.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/RawTextWriterEncoded.ttinclude index a3bd4d0b67053..bfb440689a66e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/RawTextWriterEncoded.ttinclude +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/RawTextWriterEncoded.ttinclude @@ -5,7 +5,7 @@ WriterType = RawTextWriterType.Encoded; ClassName = "XmlEncodedRawTextWriter"; ClassNameIndent = "XmlEncodedRawTextWriterIndent"; - BufferName = "bufChars"; + BufferName = "_bufChars"; BufferType = "char"; EncodeCharBody = @"/* Surrogate character */ if (XmlCharType.IsSurrogate(ch)) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/TextEncodedRawTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/TextEncodedRawTextWriter.cs index 2059fc771e495..bc9cbc38851ef 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/TextEncodedRawTextWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/TextEncodedRawTextWriter.cs @@ -67,12 +67,12 @@ internal override void StartElementContent() // Ignore attributes public override void WriteStartAttribute(string prefix, string localName, string ns) { - base.inAttributeValue = true; + base._inAttributeValue = true; } public override void WriteEndAttribute() { - base.inAttributeValue = false; + base._inAttributeValue = false; } // Ignore namespace declarations @@ -118,7 +118,7 @@ public override void WriteSurrogateCharEntity(char lowChar, char highChar) // Output text content without any escaping; ignore attribute values public override void WriteWhitespace(string ws) { - if (!base.inAttributeValue) + if (!base._inAttributeValue) { base.WriteRaw(ws); } @@ -127,7 +127,7 @@ public override void WriteWhitespace(string ws) // Output text content without any escaping; ignore attribute values public override void WriteString(string textBlock) { - if (!base.inAttributeValue) + if (!base._inAttributeValue) { base.WriteRaw(textBlock); } @@ -136,7 +136,7 @@ public override void WriteString(string textBlock) // Output text content without any escaping; ignore attribute values public override void WriteChars(char[] buffer, int index, int count) { - if (!base.inAttributeValue) + if (!base._inAttributeValue) { base.WriteRaw(buffer, index, count); } @@ -145,7 +145,7 @@ public override void WriteChars(char[] buffer, int index, int count) // Output text content without any escaping; ignore attribute values public override void WriteRaw(char[] buffer, int index, int count) { - if (!base.inAttributeValue) + if (!base._inAttributeValue) { base.WriteRaw(buffer, index, count); } @@ -154,7 +154,7 @@ public override void WriteRaw(char[] buffer, int index, int count) // Output text content without any escaping; ignore attribute values public override void WriteRaw(string data) { - if (!base.inAttributeValue) + if (!base._inAttributeValue) { base.WriteRaw(data); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/TextUtf8RawTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/TextUtf8RawTextWriter.cs index 776f810949d27..b7df1c67074dc 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/TextUtf8RawTextWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/TextUtf8RawTextWriter.cs @@ -62,12 +62,12 @@ internal override void StartElementContent() // Ignore attributes public override void WriteStartAttribute(string prefix, string localName, string ns) { - base.inAttributeValue = true; + base._inAttributeValue = true; } public override void WriteEndAttribute() { - base.inAttributeValue = false; + base._inAttributeValue = false; } // Ignore namespace declarations @@ -113,7 +113,7 @@ public override void WriteSurrogateCharEntity(char lowChar, char highChar) // Output text content without any escaping; ignore attribute values public override void WriteWhitespace(string ws) { - if (!base.inAttributeValue) + if (!base._inAttributeValue) { base.WriteRaw(ws); } @@ -122,7 +122,7 @@ public override void WriteWhitespace(string ws) // Output text content without any escaping; ignore attribute values public override void WriteString(string textBlock) { - if (!base.inAttributeValue) + if (!base._inAttributeValue) { base.WriteRaw(textBlock); } @@ -131,7 +131,7 @@ public override void WriteString(string textBlock) // Output text content without any escaping; ignore attribute values public override void WriteChars(char[] buffer, int index, int count) { - if (!base.inAttributeValue) + if (!base._inAttributeValue) { base.WriteRaw(buffer, index, count); } @@ -140,7 +140,7 @@ public override void WriteChars(char[] buffer, int index, int count) // Output text content without any escaping; ignore attribute values public override void WriteRaw(char[] buffer, int index, int count) { - if (!base.inAttributeValue) + if (!base._inAttributeValue) { base.WriteRaw(buffer, index, count); } @@ -149,7 +149,7 @@ public override void WriteRaw(char[] buffer, int index, int count) // Output text content without any escaping; ignore attribute values public override void WriteRaw(string data) { - if (!base.inAttributeValue) + if (!base._inAttributeValue) { base.WriteRaw(data); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAutoDetectWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAutoDetectWriter.cs index dee8b8e5a6ffb..62355d7b66b5f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAutoDetectWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlAutoDetectWriter.cs @@ -277,11 +277,11 @@ internal override IXmlNamespaceResolver NamespaceResolver { get { - return this.resolver; + return this._resolver; } set { - this.resolver = value; + this._resolver = value; if (_wrapped == null) _eventCache.NamespaceResolver = value; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs index 713f5bcc262af..18d0cc012ba14 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriter.cs @@ -31,60 +31,60 @@ internal partial class XmlEncodedRawTextWriter : XmlRawWriter private readonly bool _useAsync; // main buffer - protected byte[] bufBytes; + protected byte[] _bufBytes; // output stream - protected Stream stream; + protected Stream _stream; // encoding of the stream or text writer - protected Encoding encoding; + protected Encoding _encoding; // char type tables - protected XmlCharType xmlCharType = XmlCharType.Instance; + protected XmlCharType _xmlCharType = XmlCharType.Instance; // buffer positions - protected int bufPos = 1; // buffer position starts at 1, because we need to be able to safely step back -1 in case we need to - // close an empty element or in CDATA section detection of double ]; bufChars[0] will always be 0 - protected int textPos = 1; // text end position; don't indent first element, pi, or comment - protected int contentPos; // element content end position - protected int cdataPos; // cdata end position - protected int attrEndPos; // end of the last attribute - protected int bufLen = BUFSIZE; + protected int _bufPos = 1; // buffer position starts at 1, because we need to be able to safely step back -1 in case we need to + // close an empty element or in CDATA section detection of double ]; bufChars[0] will always be 0 + protected int _textPos = 1; // text end position; don't indent first element, pi, or comment + protected int _contentPos; // element content end position + protected int _cdataPos; // cdata end position + protected int _attrEndPos; // end of the last attribute + protected int _bufLen = BUFSIZE; // flags - protected bool writeToNull; - protected bool hadDoubleBracket; - protected bool inAttributeValue; + protected bool _writeToNull; + protected bool _hadDoubleBracket; + protected bool _inAttributeValue; - protected int bufBytesUsed; - protected char[] bufChars; + protected int _bufBytesUsed; + protected char[] _bufChars; // encoder for encoding chars in specified encoding when writing to stream - protected Encoder encoder; + protected Encoder _encoder; // output text writer - protected TextWriter writer; + protected TextWriter _writer; // escaping of characters invalid in the output encoding - protected bool trackTextContent; - protected bool inTextContent; + protected bool _trackTextContent; + protected bool _inTextContent; private int _lastMarkPos; private int[] _textContentMarks; // even indices contain text content start positions // odd indices contain markup start positions private readonly CharEntityEncoderFallback _charEntityFallback; // writer settings - protected NewLineHandling newLineHandling; - protected bool closeOutput; - protected bool omitXmlDeclaration; - protected string newLineChars; - protected bool checkCharacters; + protected NewLineHandling _newLineHandling; + protected bool _closeOutput; + protected bool _omitXmlDeclaration; + protected string _newLineChars; + protected bool _checkCharacters; - protected XmlStandalone standalone; - protected XmlOutputMethod outputMethod; + protected XmlStandalone _standalone; + protected XmlOutputMethod _outputMethod; - protected bool autoXmlDeclaration; - protected bool mergeCDataSections; + protected bool _autoXmlDeclaration; + protected bool _mergeCDataSections; // // Constants @@ -103,19 +103,19 @@ protected XmlEncodedRawTextWriter(XmlWriterSettings settings) _useAsync = settings.Async; // copy settings - newLineHandling = settings.NewLineHandling; - omitXmlDeclaration = settings.OmitXmlDeclaration; - newLineChars = settings.NewLineChars; - checkCharacters = settings.CheckCharacters; - closeOutput = settings.CloseOutput; + _newLineHandling = settings.NewLineHandling; + _omitXmlDeclaration = settings.OmitXmlDeclaration; + _newLineChars = settings.NewLineChars; + _checkCharacters = settings.CheckCharacters; + _closeOutput = settings.CloseOutput; - standalone = settings.Standalone; - outputMethod = settings.OutputMethod; - mergeCDataSections = settings.MergeCDataSections; + _standalone = settings.Standalone; + _outputMethod = settings.OutputMethod; + _mergeCDataSections = settings.MergeCDataSections; - if (checkCharacters && newLineHandling == NewLineHandling.Replace) + if (_checkCharacters && _newLineHandling == NewLineHandling.Replace) { - ValidateContentChars(newLineChars, "NewLineChars", false); + ValidateContentChars(_newLineChars, "NewLineChars", false); } } @@ -124,20 +124,20 @@ public XmlEncodedRawTextWriter(TextWriter writer, XmlWriterSettings settings) : { Debug.Assert(writer != null && settings != null); - this.writer = writer; - this.encoding = writer.Encoding; + this._writer = writer; + this._encoding = writer.Encoding; // the buffer is allocated will OVERFLOW in order to reduce checks when writing out constant size markup if (settings.Async) { - bufLen = ASYNCBUFSIZE; + _bufLen = ASYNCBUFSIZE; } - this.bufChars = new char[bufLen + OVERFLOW]; + this._bufChars = new char[_bufLen + OVERFLOW]; // Write the xml declaration if (settings.AutoXmlDeclaration) { - WriteXmlDeclaration(standalone); - autoXmlDeclaration = true; + WriteXmlDeclaration(_standalone); + _autoXmlDeclaration = true; } } @@ -146,22 +146,22 @@ public XmlEncodedRawTextWriter(Stream stream, XmlWriterSettings settings) : this { Debug.Assert(stream != null && settings != null); - this.stream = stream; - this.encoding = settings.Encoding; + this._stream = stream; + this._encoding = settings.Encoding; // the buffer is allocated will OVERFLOW in order to reduce checks when writing out constant size markup if (settings.Async) { - bufLen = ASYNCBUFSIZE; + _bufLen = ASYNCBUFSIZE; } - bufChars = new char[bufLen + OVERFLOW]; - bufBytes = new byte[bufChars.Length]; - bufBytesUsed = 0; + _bufChars = new char[_bufLen + OVERFLOW]; + _bufBytes = new byte[_bufChars.Length]; + _bufBytesUsed = 0; // Init escaping of characters not fitting into the target encoding - trackTextContent = true; - inTextContent = false; + _trackTextContent = true; + _inTextContent = false; _lastMarkPos = 0; _textContentMarks = new int[INIT_MARKS_COUNT]; _textContentMarks[0] = 1; @@ -169,29 +169,29 @@ public XmlEncodedRawTextWriter(Stream stream, XmlWriterSettings settings) : this _charEntityFallback = new CharEntityEncoderFallback(); // grab bom before possibly changing encoding settings - ReadOnlySpan bom = encoding.Preamble; + ReadOnlySpan bom = _encoding.Preamble; // the encoding instance this creates can differ from the one passed in - this.encoding = Encoding.GetEncoding( + this._encoding = Encoding.GetEncoding( settings.Encoding.CodePage, _charEntityFallback, settings.Encoding.DecoderFallback); - encoder = encoding.GetEncoder(); + _encoder = _encoding.GetEncoder(); if (!stream.CanSeek || stream.Position == 0) { if (bom.Length != 0) { - this.stream.Write(bom); + this._stream.Write(bom); } } // Write the xml declaration if (settings.AutoXmlDeclaration) { - WriteXmlDeclaration(standalone); - autoXmlDeclaration = true; + WriteXmlDeclaration(_standalone); + _autoXmlDeclaration = true; } } @@ -205,17 +205,17 @@ public override XmlWriterSettings Settings { XmlWriterSettings settings = new XmlWriterSettings(); - settings.Encoding = encoding; - settings.OmitXmlDeclaration = omitXmlDeclaration; - settings.NewLineHandling = newLineHandling; - settings.NewLineChars = newLineChars; - settings.CloseOutput = closeOutput; + settings.Encoding = _encoding; + settings.OmitXmlDeclaration = _omitXmlDeclaration; + settings.NewLineHandling = _newLineHandling; + settings.NewLineChars = _newLineChars; + settings.CloseOutput = _closeOutput; settings.ConformanceLevel = ConformanceLevel.Auto; - settings.CheckCharacters = checkCharacters; + settings.CheckCharacters = _checkCharacters; - settings.AutoXmlDeclaration = autoXmlDeclaration; - settings.Standalone = standalone; - settings.OutputMethod = outputMethod; + settings.AutoXmlDeclaration = _autoXmlDeclaration; + settings.Standalone = _standalone; + settings.OutputMethod = _outputMethod; settings.ReadOnly = true; return settings; @@ -226,9 +226,9 @@ public override XmlWriterSettings Settings internal override void WriteXmlDeclaration(XmlStandalone standalone) { // Output xml declaration only if user allows it and it was not already output - if (!omitXmlDeclaration && !autoXmlDeclaration) + if (!_omitXmlDeclaration && !_autoXmlDeclaration) { - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } RawText(" 0); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } RawText("'; + _bufChars[_bufPos++] = (char)'>'; } // Serialize the beginning of an element start tag: " 0); Debug.Assert(prefix != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[bufPos++] = (char)'<'; + _bufChars[_bufPos++] = (char)'<'; if (prefix != null && prefix.Length != 0) { RawText(prefix); - bufChars[bufPos++] = (char)':'; + _bufChars[_bufPos++] = (char)':'; } RawText(localName); - attrEndPos = bufPos; + _attrEndPos = _bufPos; } // Serialize the end of an element start tag in preparation for content serialization: ">" internal override void StartElementContent() { - bufChars[bufPos++] = (char)'>'; + _bufChars[_bufPos++] = (char)'>'; // StartElementContent is always called; therefore, in order to allow shortcut syntax, we save the // position of the '>' character. If WriteEndElement is called and no other characters have been // output, then the '>' character can be overwritten with the shortcut syntax " />". - contentPos = bufPos; + _contentPos = _bufPos; } // Serialize an element end tag: "", if content was output. Otherwise, serialize @@ -341,29 +341,29 @@ internal override void WriteEndElement(string prefix, string localName, string n Debug.Assert(localName != null && localName.Length > 0); Debug.Assert(prefix != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - if (contentPos != bufPos) + if (_contentPos != _bufPos) { // Content has been output, so can't use shortcut syntax - bufChars[bufPos++] = (char)'<'; - bufChars[bufPos++] = (char)'/'; + _bufChars[_bufPos++] = (char)'<'; + _bufChars[_bufPos++] = (char)'/'; if (prefix != null && prefix.Length != 0) { RawText(prefix); - bufChars[bufPos++] = (char)':'; + _bufChars[_bufPos++] = (char)':'; } RawText(localName); - bufChars[bufPos++] = (char)'>'; + _bufChars[_bufPos++] = (char)'>'; } else { // Use shortcut syntax; overwrite the already output '>' character - bufPos--; - bufChars[bufPos++] = (char)' '; - bufChars[bufPos++] = (char)'/'; - bufChars[bufPos++] = (char)'>'; + _bufPos--; + _bufChars[_bufPos++] = (char)' '; + _bufChars[_bufPos++] = (char)'/'; + _bufChars[_bufPos++] = (char)'>'; } } @@ -373,18 +373,18 @@ internal override void WriteFullEndElement(string prefix, string localName, stri Debug.Assert(localName != null && localName.Length > 0); Debug.Assert(prefix != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[bufPos++] = (char)'<'; - bufChars[bufPos++] = (char)'/'; + _bufChars[_bufPos++] = (char)'<'; + _bufChars[_bufPos++] = (char)'/'; if (prefix != null && prefix.Length != 0) { RawText(prefix); - bufChars[bufPos++] = (char)':'; + _bufChars[_bufPos++] = (char)':'; } RawText(localName); - bufChars[bufPos++] = (char)'>'; + _bufChars[_bufPos++] = (char)'>'; } // Serialize an attribute tag using double quotes around the attribute value: 'prefix:localName="' @@ -393,33 +393,33 @@ public override void WriteStartAttribute(string prefix, string localName, string Debug.Assert(localName != null && localName.Length > 0); Debug.Assert(prefix != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - if (attrEndPos == bufPos) + if (_attrEndPos == _bufPos) { - bufChars[bufPos++] = (char)' '; + _bufChars[_bufPos++] = (char)' '; } if (prefix != null && prefix.Length > 0) { RawText(prefix); - bufChars[bufPos++] = (char)':'; + _bufChars[_bufPos++] = (char)':'; } RawText(localName); - bufChars[bufPos++] = (char)'='; - bufChars[bufPos++] = (char)'"'; + _bufChars[_bufPos++] = (char)'='; + _bufChars[_bufPos++] = (char)'"'; - inAttributeValue = true; + _inAttributeValue = true; } // Serialize the end of an attribute value using double quotes: '"' public override void WriteEndAttribute() { - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[bufPos++] = (char)'"'; - inAttributeValue = false; - attrEndPos = bufPos; + _bufChars[_bufPos++] = (char)'"'; + _inAttributeValue = false; + _attrEndPos = _bufPos; } internal override void WriteNamespaceDeclaration(string prefix, string namespaceName) @@ -443,7 +443,7 @@ internal override void WriteStartNamespaceDeclaration(string prefix) { Debug.Assert(prefix != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } if (prefix.Length == 0) { @@ -453,22 +453,22 @@ internal override void WriteStartNamespaceDeclaration(string prefix) { RawText(" xmlns:"); RawText(prefix); - bufChars[bufPos++] = (char)'='; - bufChars[bufPos++] = (char)'"'; + _bufChars[_bufPos++] = (char)'='; + _bufChars[_bufPos++] = (char)'"'; } - inAttributeValue = true; + _inAttributeValue = true; - if (trackTextContent && inTextContent != true) { ChangeTextContentMark(true); } + if (_trackTextContent && _inTextContent != true) { ChangeTextContentMark(true); } } internal override void WriteEndNamespaceDeclaration() { - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } - inAttributeValue = false; + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } + _inAttributeValue = false; - bufChars[bufPos++] = (char)'"'; - attrEndPos = bufPos; + _bufChars[_bufPos++] = (char)'"'; + _attrEndPos = _bufPos; } // Serialize a CData section. If the "]]>" pattern is found within @@ -477,36 +477,36 @@ public override void WriteCData(string text) { Debug.Assert(text != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - if (mergeCDataSections && bufPos == cdataPos) + if (_mergeCDataSections && _bufPos == _cdataPos) { // Merge adjacent cdata sections - overwrite the "]]>" characters - Debug.Assert(bufPos >= 4); - bufPos -= 3; + Debug.Assert(_bufPos >= 4); + _bufPos -= 3; } else { // Start a new cdata section - bufChars[bufPos++] = (char)'<'; - bufChars[bufPos++] = (char)'!'; - bufChars[bufPos++] = (char)'['; - bufChars[bufPos++] = (char)'C'; - bufChars[bufPos++] = (char)'D'; - bufChars[bufPos++] = (char)'A'; - bufChars[bufPos++] = (char)'T'; - bufChars[bufPos++] = (char)'A'; - bufChars[bufPos++] = (char)'['; + _bufChars[_bufPos++] = (char)'<'; + _bufChars[_bufPos++] = (char)'!'; + _bufChars[_bufPos++] = (char)'['; + _bufChars[_bufPos++] = (char)'C'; + _bufChars[_bufPos++] = (char)'D'; + _bufChars[_bufPos++] = (char)'A'; + _bufChars[_bufPos++] = (char)'T'; + _bufChars[_bufPos++] = (char)'A'; + _bufChars[_bufPos++] = (char)'['; } WriteCDataSection(text); - bufChars[bufPos++] = (char)']'; - bufChars[bufPos++] = (char)']'; - bufChars[bufPos++] = (char)'>'; + _bufChars[_bufPos++] = (char)']'; + _bufChars[_bufPos++] = (char)']'; + _bufChars[_bufPos++] = (char)'>'; - textPos = bufPos; - cdataPos = bufPos; + _textPos = _bufPos; + _cdataPos = _bufPos; } // Serialize a comment. @@ -514,18 +514,18 @@ public override void WriteComment(string text) { Debug.Assert(text != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[bufPos++] = (char)'<'; - bufChars[bufPos++] = (char)'!'; - bufChars[bufPos++] = (char)'-'; - bufChars[bufPos++] = (char)'-'; + _bufChars[_bufPos++] = (char)'<'; + _bufChars[_bufPos++] = (char)'!'; + _bufChars[_bufPos++] = (char)'-'; + _bufChars[_bufPos++] = (char)'-'; WriteCommentOrPi(text, '-'); - bufChars[bufPos++] = (char)'-'; - bufChars[bufPos++] = (char)'-'; - bufChars[bufPos++] = (char)'>'; + _bufChars[_bufPos++] = (char)'-'; + _bufChars[_bufPos++] = (char)'-'; + _bufChars[_bufPos++] = (char)'>'; } // Serialize a processing instruction. @@ -534,20 +534,20 @@ public override void WriteProcessingInstruction(string name, string text) Debug.Assert(name != null && name.Length > 0); Debug.Assert(text != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[bufPos++] = (char)'<'; - bufChars[bufPos++] = (char)'?'; + _bufChars[_bufPos++] = (char)'<'; + _bufChars[_bufPos++] = (char)'?'; RawText(name); if (text.Length > 0) { - bufChars[bufPos++] = (char)' '; + _bufChars[_bufPos++] = (char)' '; WriteCommentOrPi(text, '?'); } - bufChars[bufPos++] = (char)'?'; - bufChars[bufPos++] = (char)'>'; + _bufChars[_bufPos++] = (char)'?'; + _bufChars[_bufPos++] = (char)'>'; } // Serialize an entity reference. @@ -555,18 +555,18 @@ public override void WriteEntityRef(string name) { Debug.Assert(name != null && name.Length > 0); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[bufPos++] = (char)'&'; + _bufChars[_bufPos++] = (char)'&'; RawText(name); - bufChars[bufPos++] = (char)';'; + _bufChars[_bufPos++] = (char)';'; - if (bufPos > bufLen) + if (_bufPos > _bufLen) { FlushBuffer(); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize a character entity reference. @@ -574,26 +574,26 @@ public override void WriteCharEntity(char ch) { string strVal = ((int)ch).ToString("X", NumberFormatInfo.InvariantInfo); - if (checkCharacters && !xmlCharType.IsCharData(ch)) + if (_checkCharacters && !_xmlCharType.IsCharData(ch)) { // we just have a single char, not a surrogate, therefore we have to pass in '\0' for the second char throw XmlConvert.CreateInvalidCharException(ch, '\0'); } - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[bufPos++] = (char)'&'; - bufChars[bufPos++] = (char)'#'; - bufChars[bufPos++] = (char)'x'; + _bufChars[_bufPos++] = (char)'&'; + _bufChars[_bufPos++] = (char)'#'; + _bufChars[_bufPos++] = (char)'x'; RawText(strVal); - bufChars[bufPos++] = (char)';'; + _bufChars[_bufPos++] = (char)';'; - if (bufPos > bufLen) + if (_bufPos > _bufLen) { FlushBuffer(); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize a whitespace node. @@ -602,12 +602,12 @@ public override unsafe void WriteWhitespace(string ws) { Debug.Assert(ws != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } fixed (char* pSrc = ws) { char* pSrcEnd = pSrc + ws.Length; - if (inAttributeValue) + if (_inAttributeValue) { WriteAttributeTextBlock(pSrc, pSrcEnd); } @@ -624,12 +624,12 @@ public override unsafe void WriteString(string text) { Debug.Assert(text != null); - if (trackTextContent && inTextContent != true) { ChangeTextContentMark(true); } + if (_trackTextContent && _inTextContent != true) { ChangeTextContentMark(true); } fixed (char* pSrc = text) { char* pSrcEnd = pSrc + text.Length; - if (inAttributeValue) + if (_inAttributeValue) { WriteAttributeTextBlock(pSrc, pSrcEnd); } @@ -643,15 +643,15 @@ public override unsafe void WriteString(string text) // Serialize surrogate character entity. public override void WriteSurrogateCharEntity(char lowChar, char highChar) { - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } int surrogateChar = XmlCharType.CombineSurrogateChar(lowChar, highChar); - bufChars[bufPos++] = (char)'&'; - bufChars[bufPos++] = (char)'#'; - bufChars[bufPos++] = (char)'x'; + _bufChars[_bufPos++] = (char)'&'; + _bufChars[_bufPos++] = (char)'#'; + _bufChars[_bufPos++] = (char)'x'; RawText(surrogateChar.ToString("X", NumberFormatInfo.InvariantInfo)); - bufChars[bufPos++] = (char)';'; - textPos = bufPos; + _bufChars[_bufPos++] = (char)';'; + _textPos = _bufPos; } // Serialize either attribute or element text using XML rules. @@ -663,11 +663,11 @@ public override unsafe void WriteChars(char[] buffer, int index, int count) Debug.Assert(index >= 0); Debug.Assert(count >= 0 && index + count <= buffer.Length); - if (trackTextContent && inTextContent != true) { ChangeTextContentMark(true); } + if (_trackTextContent && _inTextContent != true) { ChangeTextContentMark(true); } fixed (char* pSrcBegin = &buffer[index]) { - if (inAttributeValue) + if (_inAttributeValue) { WriteAttributeTextBlock(pSrcBegin, pSrcBegin + count); } @@ -687,14 +687,14 @@ public override unsafe void WriteRaw(char[] buffer, int index, int count) Debug.Assert(index >= 0); Debug.Assert(count >= 0 && index + count <= buffer.Length); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } fixed (char* pSrcBegin = &buffer[index]) { WriteRawWithCharChecking(pSrcBegin, pSrcBegin + count); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize raw data. @@ -703,14 +703,14 @@ public override unsafe void WriteRaw(string data) { Debug.Assert(data != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } fixed (char* pSrcBegin = data) { WriteRawWithCharChecking(pSrcBegin, pSrcBegin + data.Length); } - textPos = bufPos; + _textPos = _bufPos; } // Flush all bytes in the buffer to output and close the output stream or writer. @@ -724,47 +724,47 @@ public override void Close() finally { // Future calls to Close or Flush shouldn't write to Stream or Writer - writeToNull = true; + _writeToNull = true; - if (stream != null) + if (_stream != null) { try { - stream.Flush(); + _stream.Flush(); } finally { try { - if (closeOutput) + if (_closeOutput) { - stream.Dispose(); + _stream.Dispose(); } } finally { - stream = null; + _stream = null; } } } - else if (writer != null) + else if (_writer != null) { try { - writer.Flush(); + _writer.Flush(); } finally { try { - if (closeOutput) + if (_closeOutput) { - writer.Dispose(); + _writer.Dispose(); } } finally { - writer = null; + _writer = null; } } } @@ -776,13 +776,13 @@ public override void Flush() { FlushBuffer(); FlushEncoder(); - if (stream != null) + if (_stream != null) { - stream.Flush(); + _stream.Flush(); } - else if (writer != null) + else if (_writer != null) { - writer.Flush(); + _writer.Flush(); } } @@ -795,13 +795,13 @@ protected virtual void FlushBuffer() try { // Output all characters (except for previous characters stored at beginning of buffer) - if (!writeToNull) + if (!_writeToNull) { - Debug.Assert(stream != null || writer != null); + Debug.Assert(_stream != null || _writer != null); - if (stream != null) + if (_stream != null) { - if (trackTextContent) + if (_trackTextContent) { _charEntityFallback.Reset(_textContentMarks, _lastMarkPos); // reset text content tracking @@ -819,14 +819,14 @@ protected virtual void FlushBuffer() } Debug.Assert(_textContentMarks[0] == 1); } - EncodeChars(1, bufPos, true); + EncodeChars(1, _bufPos, true); } else { - if (bufPos - 1 > 0) + if (_bufPos - 1 > 0) { // Write text to TextWriter - writer.Write(bufChars, 1, bufPos - 1); + _writer.Write(_bufChars, 1, _bufPos - 1); } } } @@ -834,20 +834,20 @@ protected virtual void FlushBuffer() catch { // Future calls to flush (i.e. when Close() is called) don't attempt to write to stream - writeToNull = true; + _writeToNull = true; throw; } finally { // Move last buffer character to the beginning of the buffer (so that previous character can always be determined) - bufChars[0] = bufChars[bufPos - 1]; + _bufChars[0] = _bufChars[_bufPos - 1]; // Reset buffer position - textPos = (textPos == bufPos) ? 1 : 0; - attrEndPos = (attrEndPos == bufPos) ? 1 : 0; - contentPos = 0; // Needs to be zero, since overwriting '>' character is no longer possible - cdataPos = 0; // Needs to be zero, since overwriting ']]>' characters is no longer possible - bufPos = 1; // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to + _textPos = (_textPos == _bufPos) ? 1 : 0; + _attrEndPos = (_attrEndPos == _bufPos) ? 1 : 0; + _contentPos = 0; // Needs to be zero, since overwriting '>' character is no longer possible + _cdataPos = 0; // Needs to be zero, since overwriting ']]>' characters is no longer possible + _bufPos = 1; // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to // close an empty element or in CDATA section detection of double ]; bufChars[0] will always be 0 } } @@ -864,35 +864,35 @@ private void EncodeChars(int startOffset, int endOffset, bool writeAllToStream) { _charEntityFallback.StartOffset = startOffset; } - encoder.Convert(bufChars, startOffset, endOffset - startOffset, bufBytes, bufBytesUsed, bufBytes.Length - bufBytesUsed, false, out chEnc, out bEnc, out completed); + _encoder.Convert(_bufChars, startOffset, endOffset - startOffset, _bufBytes, _bufBytesUsed, _bufBytes.Length - _bufBytesUsed, false, out chEnc, out bEnc, out completed); startOffset += chEnc; - bufBytesUsed += bEnc; - if (bufBytesUsed >= (bufBytes.Length - 16)) + _bufBytesUsed += bEnc; + if (_bufBytesUsed >= (_bufBytes.Length - 16)) { - stream.Write(bufBytes, 0, bufBytesUsed); - bufBytesUsed = 0; + _stream.Write(_bufBytes, 0, _bufBytesUsed); + _bufBytesUsed = 0; } } - if (writeAllToStream && bufBytesUsed > 0) + if (writeAllToStream && _bufBytesUsed > 0) { - stream.Write(bufBytes, 0, bufBytesUsed); - bufBytesUsed = 0; + _stream.Write(_bufBytes, 0, _bufBytesUsed); + _bufBytesUsed = 0; } } private void FlushEncoder() { - Debug.Assert(bufPos == 1); - if (stream != null) + Debug.Assert(_bufPos == 1); + if (_stream != null) { int chEnc; int bEnc; bool completed; // decode no chars, just flush - encoder.Convert(bufChars, 1, 0, bufBytes, 0, bufBytes.Length, true, out chEnc, out bEnc, out completed); + _encoder.Convert(_bufChars, 1, 0, _bufBytes, 0, _bufBytes.Length, true, out chEnc, out bEnc, out completed); if (bEnc != 0) { - stream.Write(bufBytes, 0, bEnc); + _stream.Write(_bufBytes, 0, bEnc); } } } @@ -901,20 +901,20 @@ private void FlushEncoder() // are entitized. protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) { - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) + while (pDst < pDstEnd && _xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) { *pDst = (char)ch; pDst++; @@ -931,7 +931,7 @@ protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -957,7 +957,7 @@ protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) pDst++; break; case (char)0x9: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (char)ch; pDst++; @@ -969,7 +969,7 @@ protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) } break; case (char)0xD: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (char)ch; pDst++; @@ -981,7 +981,7 @@ protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) } break; case (char)0xA: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (char)ch; pDst++; @@ -1016,7 +1016,7 @@ protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -1024,20 +1024,20 @@ protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) // are entitized. protected unsafe void WriteElementTextBlock(char* pSrc, char* pSrcEnd) { - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) + while (pDst < pDstEnd && _xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) { *pDst = (char)ch; pDst++; @@ -1054,7 +1054,7 @@ protected unsafe void WriteElementTextBlock(char* pSrc, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1079,7 +1079,7 @@ protected unsafe void WriteElementTextBlock(char* pSrc, char* pSrcEnd) pDst++; break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { pDst = WriteNewLine(pDst); } @@ -1090,7 +1090,7 @@ protected unsafe void WriteElementTextBlock(char* pSrc, char* pSrcEnd) } break; case (char)0xD: - switch (newLineHandling) + switch (_newLineHandling) { case NewLineHandling.Replace: // Replace "\r\n", or "\r" with NewLineChars @@ -1136,9 +1136,9 @@ protected unsafe void WriteElementTextBlock(char* pSrc, char* pSrcEnd) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); - textPos = bufPos; - contentPos = 0; + _bufPos = (int)(pDst - pDstBegin); + _textPos = _bufPos; + _contentPos = 0; } } @@ -1154,18 +1154,18 @@ protected unsafe void RawText(string s) protected unsafe void RawText(char* pSrcBegin, char* pSrcEnd) { - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; char* pSrc = pSrcBegin; int ch = 0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } while (pDst < pDstEnd && ((ch = *pSrc) < XmlCharType.SurHighStart)) @@ -1185,7 +1185,7 @@ protected unsafe void RawText(char* pSrcBegin, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1212,27 +1212,27 @@ protected unsafe void RawText(char* pSrcBegin, char* pSrcEnd) } } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } protected unsafe void WriteRawWithCharChecking(char* pSrcBegin, char* pSrcEnd) { - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { char* pSrc = pSrcBegin; - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && xmlCharType.IsTextChar((char)(ch = *pSrc))) + while (pDst < pDstEnd && _xmlCharType.IsTextChar((char)(ch = *pSrc))) { *pDst = (char)ch; pDst++; @@ -1250,7 +1250,7 @@ protected unsafe void WriteRawWithCharChecking(char* pSrcBegin, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1267,7 +1267,7 @@ protected unsafe void WriteRawWithCharChecking(char* pSrcBegin, char* pSrcEnd) pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1284,7 +1284,7 @@ protected unsafe void WriteRawWithCharChecking(char* pSrcBegin, char* pSrcEnd) } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { pDst = WriteNewLine(pDst); } @@ -1318,7 +1318,7 @@ protected unsafe void WriteRawWithCharChecking(char* pSrcBegin, char* pSrcEnd) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -1326,7 +1326,7 @@ protected unsafe void WriteCommentOrPi(string text, int stopChar) { if (text.Length == 0) { - if (bufPos >= bufLen) + if (_bufPos >= _bufLen) { FlushBuffer(); } @@ -1335,24 +1335,24 @@ protected unsafe void WriteCommentOrPi(string text, int stopChar) // write text fixed (char* pSrcBegin = text) - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { char* pSrc = pSrcBegin; char* pSrcEnd = pSrcBegin + text.Length; - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar)) + while (pDst < pDstEnd && (_xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar)) { *pDst = (char)ch; pDst++; @@ -1370,7 +1370,7 @@ protected unsafe void WriteCommentOrPi(string text, int stopChar) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1410,7 +1410,7 @@ protected unsafe void WriteCommentOrPi(string text, int stopChar) pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1427,7 +1427,7 @@ protected unsafe void WriteCommentOrPi(string text, int stopChar) } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { pDst = WriteNewLine(pDst); } @@ -1467,7 +1467,7 @@ protected unsafe void WriteCommentOrPi(string text, int stopChar) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -1475,7 +1475,7 @@ protected unsafe void WriteCDataSection(string text) { if (text.Length == 0) { - if (bufPos >= bufLen) + if (_bufPos >= _bufLen) { FlushBuffer(); } @@ -1486,24 +1486,24 @@ protected unsafe void WriteCDataSection(string text) fixed (char* pSrcBegin = text) - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { char* pSrc = pSrcBegin; char* pSrcEnd = pSrcBegin + text.Length; - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']')) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']')) { *pDst = (char)ch; pDst++; @@ -1521,7 +1521,7 @@ protected unsafe void WriteCDataSection(string text) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1531,7 +1531,7 @@ protected unsafe void WriteCDataSection(string text) switch (ch) { case '>': - if (hadDoubleBracket && pDst[-1] == (char)']') + if (_hadDoubleBracket && pDst[-1] == (char)']') { // pDst[-1] will always correct - there is a padding character at bufChars[0] // The characters "]]>" were found within the CData text pDst = RawEndCData(pDst); @@ -1543,17 +1543,17 @@ protected unsafe void WriteCDataSection(string text) case ']': if (pDst[-1] == (char)']') { // pDst[-1] will always correct - there is a padding character at bufChars[0] - hadDoubleBracket = true; + _hadDoubleBracket = true; } else { - hadDoubleBracket = false; + _hadDoubleBracket = false; } *pDst = (char)']'; pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1570,7 +1570,7 @@ protected unsafe void WriteCDataSection(string text) } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { pDst = WriteNewLine(pDst); } @@ -1612,7 +1612,7 @@ protected unsafe void WriteCDataSection(string text) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -1645,10 +1645,10 @@ protected unsafe void WriteCDataSection(string text) private unsafe char* InvalidXmlChar(int ch, char* pDst, bool entitize) { - Debug.Assert(!xmlCharType.IsWhiteSpace((char)ch)); - Debug.Assert(!xmlCharType.IsAttributeValueChar((char)ch)); + Debug.Assert(!_xmlCharType.IsWhiteSpace((char)ch)); + Debug.Assert(!_xmlCharType.IsAttributeValueChar((char)ch)); - if (checkCharacters) + if (_checkCharacters) { // This method will never be called on surrogates, so it is ok to pass in '\0' to the CreateInvalidCharException throw XmlConvert.CreateInvalidCharException((char)ch, '\0'); @@ -1695,14 +1695,14 @@ internal unsafe void EncodeChar(ref char* pSrc, char* pSrcEnd, ref char* pDst) protected void ChangeTextContentMark(bool value) { - Debug.Assert(inTextContent != value); - Debug.Assert(inTextContent || ((_lastMarkPos & 1) == 0)); - inTextContent = value; + Debug.Assert(_inTextContent != value); + Debug.Assert(_inTextContent || ((_lastMarkPos & 1) == 0)); + _inTextContent = value; if (_lastMarkPos + 1 == _textContentMarks.Length) { GrowTextContentMarks(); } - _textContentMarks[++_lastMarkPos] = bufPos; + _textContentMarks[++_lastMarkPos] = _bufPos; } private void GrowTextContentMarks() @@ -1715,12 +1715,12 @@ private void GrowTextContentMarks() // Write NewLineChars to the specified buffer position and return an updated position. protected unsafe char* WriteNewLine(char* pDst) { - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); // Let RawText do the real work - RawText(newLineChars); - return pDstBegin + bufPos; + RawText(_newLineChars); + return pDstBegin + _bufPos; } } @@ -1858,7 +1858,7 @@ protected unsafe void ValidateContentChars(string chars, string propertyName, bo { if (allowOnlyWhitespace) { - if (!xmlCharType.IsOnlyWhitespace(chars)) + if (!_xmlCharType.IsOnlyWhitespace(chars)) { throw new ArgumentException(SR.Format(SR.Xml_IndentCharsNotWhitespace, propertyName)); } @@ -1868,7 +1868,7 @@ protected unsafe void ValidateContentChars(string chars, string propertyName, bo string error = null; for (int i = 0; i < chars.Length; i++) { - if (!xmlCharType.IsTextChar(chars[i])) + if (!_xmlCharType.IsTextChar(chars[i])) { switch (chars[i]) { @@ -1918,14 +1918,14 @@ internal partial class XmlEncodedRawTextWriterIndent : XmlEncodedRawTextWriter // // Fields // - protected int indentLevel; - protected bool newLineOnAttributes; - protected string indentChars; + protected int _indentLevel; + protected bool _newLineOnAttributes; + protected string _indentChars; - protected bool mixedContent; + protected bool _mixedContent; private BitStack _mixedContentStack; - protected ConformanceLevel conformanceLevel = ConformanceLevel.Auto; + protected ConformanceLevel _conformanceLevel = ConformanceLevel.Auto; // // Constructors @@ -1951,8 +1951,8 @@ public override XmlWriterSettings Settings settings.ReadOnly = false; settings.Indent = true; - settings.IndentChars = indentChars; - settings.NewLineOnAttributes = newLineOnAttributes; + settings.IndentChars = _indentChars; + settings.NewLineOnAttributes = _newLineOnAttributes; settings.ReadOnly = true; return settings; @@ -1962,7 +1962,7 @@ public override XmlWriterSettings Settings public override void WriteDocType(string name, string pubid, string sysid, string subset) { // Add indentation - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { WriteIndent(); } @@ -1974,12 +1974,12 @@ public override void WriteStartElement(string prefix, string localName, string n Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null); // Add indentation - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { WriteIndent(); } - indentLevel++; - _mixedContentStack.PushBit(mixedContent); + _indentLevel++; + _mixedContentStack.PushBit(_mixedContent); base.WriteStartElement(prefix, localName, ns); } @@ -1987,16 +1987,16 @@ public override void WriteStartElement(string prefix, string localName, string n internal override void StartElementContent() { // If this is the root element and we're writing a document - // do not inherit the mixedContent flag into the root element. + // do not inherit the _mixedContent flag into the root element. // This is to allow for whitespace nodes on root level // without disabling indentation for the whole document. - if (indentLevel == 1 && conformanceLevel == ConformanceLevel.Document) + if (_indentLevel == 1 && _conformanceLevel == ConformanceLevel.Document) { - mixedContent = false; + _mixedContent = false; } else { - mixedContent = _mixedContentStack.PeekBit(); + _mixedContent = _mixedContentStack.PeekBit(); } base.StartElementContent(); } @@ -2004,22 +2004,22 @@ internal override void StartElementContent() internal override void OnRootElement(ConformanceLevel currentConformanceLevel) { // Just remember the current conformance level - conformanceLevel = currentConformanceLevel; + _conformanceLevel = currentConformanceLevel; } internal override void WriteEndElement(string prefix, string localName, string ns) { // Add indentation - indentLevel--; - if (!mixedContent && base.contentPos != base.bufPos) + _indentLevel--; + if (!_mixedContent && base._contentPos != base._bufPos) { // There was content, so try to indent - if (base.textPos != base.bufPos) + if (base._textPos != base._bufPos) { WriteIndent(); } } - mixedContent = _mixedContentStack.PopBit(); + _mixedContent = _mixedContentStack.PopBit(); base.WriteEndElement(prefix, localName, ns); } @@ -2027,16 +2027,16 @@ internal override void WriteEndElement(string prefix, string localName, string n internal override void WriteFullEndElement(string prefix, string localName, string ns) { // Add indentation - indentLevel--; - if (!mixedContent && base.contentPos != base.bufPos) + _indentLevel--; + if (!_mixedContent && base._contentPos != base._bufPos) { // There was content, so try to indent - if (base.textPos != base.bufPos) + if (base._textPos != base._bufPos) { WriteIndent(); } } - mixedContent = _mixedContentStack.PopBit(); + _mixedContent = _mixedContentStack.PopBit(); base.WriteFullEndElement(prefix, localName, ns); } @@ -2045,7 +2045,7 @@ internal override void WriteFullEndElement(string prefix, string localName, stri public override void WriteStartAttribute(string prefix, string localName, string ns) { // Add indentation - if (newLineOnAttributes) + if (_newLineOnAttributes) { WriteIndent(); } @@ -2055,13 +2055,13 @@ public override void WriteStartAttribute(string prefix, string localName, string public override void WriteCData(string text) { - mixedContent = true; + _mixedContent = true; base.WriteCData(text); } public override void WriteComment(string text) { - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { WriteIndent(); } @@ -2071,7 +2071,7 @@ public override void WriteComment(string text) public override void WriteProcessingInstruction(string target, string text) { - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { WriteIndent(); } @@ -2081,55 +2081,55 @@ public override void WriteProcessingInstruction(string target, string text) public override void WriteEntityRef(string name) { - mixedContent = true; + _mixedContent = true; base.WriteEntityRef(name); } public override void WriteCharEntity(char ch) { - mixedContent = true; + _mixedContent = true; base.WriteCharEntity(ch); } public override void WriteSurrogateCharEntity(char lowChar, char highChar) { - mixedContent = true; + _mixedContent = true; base.WriteSurrogateCharEntity(lowChar, highChar); } public override void WriteWhitespace(string ws) { - mixedContent = true; + _mixedContent = true; base.WriteWhitespace(ws); } public override void WriteString(string text) { - mixedContent = true; + _mixedContent = true; base.WriteString(text); } public override void WriteChars(char[] buffer, int index, int count) { - mixedContent = true; + _mixedContent = true; base.WriteChars(buffer, index, count); } public override void WriteRaw(char[] buffer, int index, int count) { - mixedContent = true; + _mixedContent = true; base.WriteRaw(buffer, index, count); } public override void WriteRaw(string data) { - mixedContent = true; + _mixedContent = true; base.WriteRaw(data); } public override void WriteBase64(byte[] buffer, int index, int count) { - mixedContent = true; + _mixedContent = true; base.WriteBase64(buffer, index, count); } @@ -2138,25 +2138,25 @@ public override void WriteBase64(byte[] buffer, int index, int count) // private void Init(XmlWriterSettings settings) { - indentLevel = 0; - indentChars = settings.IndentChars; - newLineOnAttributes = settings.NewLineOnAttributes; + _indentLevel = 0; + _indentChars = settings.IndentChars; + _newLineOnAttributes = settings.NewLineOnAttributes; _mixedContentStack = new BitStack(); // check indent characters that they are valid XML characters - if (base.checkCharacters) + if (base._checkCharacters) { - if (newLineOnAttributes) + if (_newLineOnAttributes) { - base.ValidateContentChars(indentChars, "IndentChars", true); - base.ValidateContentChars(newLineChars, "NewLineChars", true); + base.ValidateContentChars(_indentChars, "IndentChars", true); + base.ValidateContentChars(_newLineChars, "NewLineChars", true); } else { - base.ValidateContentChars(indentChars, "IndentChars", false); - if (base.newLineHandling != NewLineHandling.Replace) + base.ValidateContentChars(_indentChars, "IndentChars", false); + if (base._newLineHandling != NewLineHandling.Replace) { - base.ValidateContentChars(newLineChars, "NewLineChars", false); + base.ValidateContentChars(_newLineChars, "NewLineChars", false); } } } @@ -2165,10 +2165,10 @@ private void Init(XmlWriterSettings settings) // Add indentation to output. Write newline and then repeat IndentChars for each indent level. private void WriteIndent() { - RawText(base.newLineChars); - for (int i = indentLevel; i > 0; i--) + RawText(base._newLineChars); + for (int i = _indentLevel; i > 0; i--) { - RawText(indentChars); + RawText(_indentChars); } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.cs index dadeda60d0756..cbdb13361dfe5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEncodedRawTextWriterAsync.cs @@ -35,19 +35,19 @@ internal override async Task WriteXmlDeclarationAsync(XmlStandalone standalone) { CheckAsyncCall(); // Output xml declaration only if user allows it and it was not already output - if (!omitXmlDeclaration && !autoXmlDeclaration) + if (!_omitXmlDeclaration && !_autoXmlDeclaration) { - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } await RawTextAsync(" 0); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } await RawTextAsync("'; + _bufChars[_bufPos++] = (char)'>'; } // Serialize the beginning of an element start tag: " 0); Debug.Assert(prefix != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } Task task; - bufChars[bufPos++] = (char)'<'; + _bufChars[_bufPos++] = (char)'<'; if (prefix != null && prefix.Length != 0) { task = RawTextAsync(prefix, ":", localName); @@ -195,7 +195,7 @@ public override Task WriteStartElementAsync(string prefix, string localName, str private void WriteStartElementAsync_SetAttEndPos() { - attrEndPos = bufPos; + _attrEndPos = _bufPos; } // Serialize an element end tag: "", if content was output. Otherwise, serialize @@ -206,13 +206,13 @@ internal override Task WriteEndElementAsync(string prefix, string localName, str Debug.Assert(localName != null && localName.Length > 0); Debug.Assert(prefix != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - if (contentPos != bufPos) + if (_contentPos != _bufPos) { // Content has been output, so can't use shortcut syntax - bufChars[bufPos++] = (char)'<'; - bufChars[bufPos++] = (char)'/'; + _bufChars[_bufPos++] = (char)'<'; + _bufChars[_bufPos++] = (char)'/'; if (prefix != null && prefix.Length != 0) { @@ -226,10 +226,10 @@ internal override Task WriteEndElementAsync(string prefix, string localName, str else { // Use shortcut syntax; overwrite the already output '>' character - bufPos--; - bufChars[bufPos++] = (char)' '; - bufChars[bufPos++] = (char)'/'; - bufChars[bufPos++] = (char)'>'; + _bufPos--; + _bufChars[_bufPos++] = (char)' '; + _bufChars[_bufPos++] = (char)'/'; + _bufChars[_bufPos++] = (char)'>'; } return Task.CompletedTask; } @@ -241,10 +241,10 @@ internal override Task WriteFullEndElementAsync(string prefix, string localName, Debug.Assert(localName != null && localName.Length > 0); Debug.Assert(prefix != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[bufPos++] = (char)'<'; - bufChars[bufPos++] = (char)'/'; + _bufChars[_bufPos++] = (char)'<'; + _bufChars[_bufPos++] = (char)'/'; if (prefix != null && prefix.Length != 0) { @@ -263,11 +263,11 @@ protected internal override Task WriteStartAttributeAsync(string prefix, string Debug.Assert(localName != null && localName.Length > 0); Debug.Assert(prefix != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - if (attrEndPos == bufPos) + if (_attrEndPos == _bufPos) { - bufChars[bufPos++] = (char)' '; + _bufChars[_bufPos++] = (char)' '; } Task task; if (prefix != null && prefix.Length > 0) @@ -283,9 +283,9 @@ protected internal override Task WriteStartAttributeAsync(string prefix, string private void WriteStartAttribute_SetInAttribute() { - bufChars[bufPos++] = (char)'='; - bufChars[bufPos++] = (char)'"'; - inAttributeValue = true; + _bufChars[_bufPos++] = (char)'='; + _bufChars[_bufPos++] = (char)'"'; + _inAttributeValue = true; } // Serialize the end of an attribute value using double quotes: '"' @@ -293,11 +293,11 @@ protected internal override Task WriteEndAttributeAsync() { CheckAsyncCall(); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[bufPos++] = (char)'"'; - inAttributeValue = false; - attrEndPos = bufPos; + _bufChars[_bufPos++] = (char)'"'; + _inAttributeValue = false; + _attrEndPos = _bufPos; return Task.CompletedTask; } @@ -317,7 +317,7 @@ internal override async Task WriteStartNamespaceDeclarationAsync(string prefix) CheckAsyncCall(); Debug.Assert(prefix != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } if (prefix.Length == 0) { @@ -327,25 +327,25 @@ internal override async Task WriteStartNamespaceDeclarationAsync(string prefix) { await RawTextAsync(" xmlns:").ConfigureAwait(false); await RawTextAsync(prefix).ConfigureAwait(false); - bufChars[bufPos++] = (char)'='; - bufChars[bufPos++] = (char)'"'; + _bufChars[_bufPos++] = (char)'='; + _bufChars[_bufPos++] = (char)'"'; } - inAttributeValue = true; + _inAttributeValue = true; - if (trackTextContent && inTextContent != true) { ChangeTextContentMark(true); } + if (_trackTextContent && _inTextContent != true) { ChangeTextContentMark(true); } } internal override Task WriteEndNamespaceDeclarationAsync() { CheckAsyncCall(); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - inAttributeValue = false; + _inAttributeValue = false; - bufChars[bufPos++] = (char)'"'; - attrEndPos = bufPos; + _bufChars[_bufPos++] = (char)'"'; + _attrEndPos = _bufPos; return Task.CompletedTask; } @@ -357,36 +357,36 @@ public override async Task WriteCDataAsync(string text) CheckAsyncCall(); Debug.Assert(text != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - if (mergeCDataSections && bufPos == cdataPos) + if (_mergeCDataSections && _bufPos == _cdataPos) { // Merge adjacent cdata sections - overwrite the "]]>" characters - Debug.Assert(bufPos >= 4); - bufPos -= 3; + Debug.Assert(_bufPos >= 4); + _bufPos -= 3; } else { // Start a new cdata section - bufChars[bufPos++] = (char)'<'; - bufChars[bufPos++] = (char)'!'; - bufChars[bufPos++] = (char)'['; - bufChars[bufPos++] = (char)'C'; - bufChars[bufPos++] = (char)'D'; - bufChars[bufPos++] = (char)'A'; - bufChars[bufPos++] = (char)'T'; - bufChars[bufPos++] = (char)'A'; - bufChars[bufPos++] = (char)'['; + _bufChars[_bufPos++] = (char)'<'; + _bufChars[_bufPos++] = (char)'!'; + _bufChars[_bufPos++] = (char)'['; + _bufChars[_bufPos++] = (char)'C'; + _bufChars[_bufPos++] = (char)'D'; + _bufChars[_bufPos++] = (char)'A'; + _bufChars[_bufPos++] = (char)'T'; + _bufChars[_bufPos++] = (char)'A'; + _bufChars[_bufPos++] = (char)'['; } await WriteCDataSectionAsync(text).ConfigureAwait(false); - bufChars[bufPos++] = (char)']'; - bufChars[bufPos++] = (char)']'; - bufChars[bufPos++] = (char)'>'; + _bufChars[_bufPos++] = (char)']'; + _bufChars[_bufPos++] = (char)']'; + _bufChars[_bufPos++] = (char)'>'; - textPos = bufPos; - cdataPos = bufPos; + _textPos = _bufPos; + _cdataPos = _bufPos; } // Serialize a comment. @@ -395,18 +395,18 @@ public override async Task WriteCommentAsync(string text) CheckAsyncCall(); Debug.Assert(text != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[bufPos++] = (char)'<'; - bufChars[bufPos++] = (char)'!'; - bufChars[bufPos++] = (char)'-'; - bufChars[bufPos++] = (char)'-'; + _bufChars[_bufPos++] = (char)'<'; + _bufChars[_bufPos++] = (char)'!'; + _bufChars[_bufPos++] = (char)'-'; + _bufChars[_bufPos++] = (char)'-'; await WriteCommentOrPiAsync(text, '-').ConfigureAwait(false); - bufChars[bufPos++] = (char)'-'; - bufChars[bufPos++] = (char)'-'; - bufChars[bufPos++] = (char)'>'; + _bufChars[_bufPos++] = (char)'-'; + _bufChars[_bufPos++] = (char)'-'; + _bufChars[_bufPos++] = (char)'>'; } // Serialize a processing instruction. @@ -416,20 +416,20 @@ public override async Task WriteProcessingInstructionAsync(string name, string t Debug.Assert(name != null && name.Length > 0); Debug.Assert(text != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[bufPos++] = (char)'<'; - bufChars[bufPos++] = (char)'?'; + _bufChars[_bufPos++] = (char)'<'; + _bufChars[_bufPos++] = (char)'?'; await RawTextAsync(name).ConfigureAwait(false); if (text.Length > 0) { - bufChars[bufPos++] = (char)' '; + _bufChars[_bufPos++] = (char)' '; await WriteCommentOrPiAsync(text, '?').ConfigureAwait(false); } - bufChars[bufPos++] = (char)'?'; - bufChars[bufPos++] = (char)'>'; + _bufChars[_bufPos++] = (char)'?'; + _bufChars[_bufPos++] = (char)'>'; } // Serialize an entity reference. @@ -438,18 +438,18 @@ public override async Task WriteEntityRefAsync(string name) CheckAsyncCall(); Debug.Assert(name != null && name.Length > 0); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[bufPos++] = (char)'&'; + _bufChars[_bufPos++] = (char)'&'; await RawTextAsync(name).ConfigureAwait(false); - bufChars[bufPos++] = (char)';'; + _bufChars[_bufPos++] = (char)';'; - if (bufPos > bufLen) + if (_bufPos > _bufLen) { await FlushBufferAsync().ConfigureAwait(false); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize a character entity reference. @@ -458,26 +458,26 @@ public override async Task WriteCharEntityAsync(char ch) CheckAsyncCall(); string strVal = ((int)ch).ToString("X", NumberFormatInfo.InvariantInfo); - if (checkCharacters && !xmlCharType.IsCharData(ch)) + if (_checkCharacters && !_xmlCharType.IsCharData(ch)) { // we just have a single char, not a surrogate, therefore we have to pass in '\0' for the second char throw XmlConvert.CreateInvalidCharException(ch, '\0'); } - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - bufChars[bufPos++] = (char)'&'; - bufChars[bufPos++] = (char)'#'; - bufChars[bufPos++] = (char)'x'; + _bufChars[_bufPos++] = (char)'&'; + _bufChars[_bufPos++] = (char)'#'; + _bufChars[_bufPos++] = (char)'x'; await RawTextAsync(strVal).ConfigureAwait(false); - bufChars[bufPos++] = (char)';'; + _bufChars[_bufPos++] = (char)';'; - if (bufPos > bufLen) + if (_bufPos > _bufLen) { await FlushBufferAsync().ConfigureAwait(false); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize a whitespace node. @@ -487,9 +487,9 @@ public override Task WriteWhitespaceAsync(string ws) CheckAsyncCall(); Debug.Assert(ws != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } - if (inAttributeValue) + if (_inAttributeValue) { return WriteAttributeTextBlockAsync(ws); } @@ -506,9 +506,9 @@ public override Task WriteStringAsync(string text) CheckAsyncCall(); Debug.Assert(text != null); - if (trackTextContent && inTextContent != true) { ChangeTextContentMark(true); } + if (_trackTextContent && _inTextContent != true) { ChangeTextContentMark(true); } - if (inAttributeValue) + if (_inAttributeValue) { return WriteAttributeTextBlockAsync(text); } @@ -523,16 +523,16 @@ public override async Task WriteSurrogateCharEntityAsync(char lowChar, char high { CheckAsyncCall(); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } int surrogateChar = XmlCharType.CombineSurrogateChar(lowChar, highChar); - bufChars[bufPos++] = (char)'&'; - bufChars[bufPos++] = (char)'#'; - bufChars[bufPos++] = (char)'x'; + _bufChars[_bufPos++] = (char)'&'; + _bufChars[_bufPos++] = (char)'#'; + _bufChars[_bufPos++] = (char)'x'; await RawTextAsync(surrogateChar.ToString("X", NumberFormatInfo.InvariantInfo)).ConfigureAwait(false); - bufChars[bufPos++] = (char)';'; - textPos = bufPos; + _bufChars[_bufPos++] = (char)';'; + _textPos = _bufPos; } // Serialize either attribute or element text using XML rules. @@ -545,9 +545,9 @@ public override Task WriteCharsAsync(char[] buffer, int index, int count) Debug.Assert(index >= 0); Debug.Assert(count >= 0 && index + count <= buffer.Length); - if (trackTextContent && inTextContent != true) { ChangeTextContentMark(true); } + if (_trackTextContent && _inTextContent != true) { ChangeTextContentMark(true); } - if (inAttributeValue) + if (_inAttributeValue) { return WriteAttributeTextBlockAsync(buffer, index, count); } @@ -567,11 +567,11 @@ public override async Task WriteRawAsync(char[] buffer, int index, int count) Debug.Assert(index >= 0); Debug.Assert(count >= 0 && index + count <= buffer.Length); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } await WriteRawWithCharCheckingAsync(buffer, index, count).ConfigureAwait(false); - textPos = bufPos; + _textPos = _bufPos; } // Serialize raw data. @@ -581,11 +581,11 @@ public override async Task WriteRawAsync(string data) CheckAsyncCall(); Debug.Assert(data != null); - if (trackTextContent && inTextContent != false) { ChangeTextContentMark(false); } + if (_trackTextContent && _inTextContent != false) { ChangeTextContentMark(false); } await WriteRawWithCharCheckingAsync(data).ConfigureAwait(false); - textPos = bufPos; + _textPos = _bufPos; } // Flush all characters in the buffer to output and call Flush() on the output object. @@ -595,13 +595,13 @@ public override async Task FlushAsync() await FlushBufferAsync().ConfigureAwait(false); await FlushEncoderAsync().ConfigureAwait(false); - if (stream != null) + if (_stream != null) { - await stream.FlushAsync().ConfigureAwait(false); + await _stream.FlushAsync().ConfigureAwait(false); } - else if (writer != null) + else if (_writer != null) { - await writer.FlushAsync().ConfigureAwait(false); + await _writer.FlushAsync().ConfigureAwait(false); } } @@ -614,13 +614,13 @@ protected virtual async Task FlushBufferAsync() try { // Output all characters (except for previous characters stored at beginning of buffer) - if (!writeToNull) + if (!_writeToNull) { - Debug.Assert(stream != null || writer != null); + Debug.Assert(_stream != null || _writer != null); - if (stream != null) + if (_stream != null) { - if (trackTextContent) + if (_trackTextContent) { _charEntityFallback.Reset(_textContentMarks, _lastMarkPos); // reset text content tracking @@ -638,14 +638,14 @@ protected virtual async Task FlushBufferAsync() } Debug.Assert(_textContentMarks[0] == 1); } - await EncodeCharsAsync(1, bufPos, true).ConfigureAwait(false); + await EncodeCharsAsync(1, _bufPos, true).ConfigureAwait(false); } else { - if (bufPos - 1 > 0) + if (_bufPos - 1 > 0) { // Write text to TextWriter - await writer.WriteAsync(bufChars.AsMemory(1, bufPos - 1)).ConfigureAwait(false); + await _writer.WriteAsync(_bufChars.AsMemory(1, _bufPos - 1)).ConfigureAwait(false); } } } @@ -653,21 +653,21 @@ protected virtual async Task FlushBufferAsync() catch { // Future calls to flush (i.e. when Close() is called) don't attempt to write to stream - writeToNull = true; + _writeToNull = true; throw; } finally { // Move last buffer character to the beginning of the buffer (so that previous character can always be determined) - bufChars[0] = bufChars[bufPos - 1]; + _bufChars[0] = _bufChars[_bufPos - 1]; // Reset buffer position - textPos = (textPos == bufPos) ? 1 : 0; - attrEndPos = (attrEndPos == bufPos) ? 1 : 0; - contentPos = 0; // Needs to be zero, since overwriting '>' character is no longer possible - cdataPos = 0; // Needs to be zero, since overwriting ']]>' characters is no longer possible - bufPos = 1; // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to + _textPos = (_textPos == _bufPos) ? 1 : 0; + _attrEndPos = (_attrEndPos == _bufPos) ? 1 : 0; + _contentPos = 0; // Needs to be zero, since overwriting '>' character is no longer possible + _cdataPos = 0; // Needs to be zero, since overwriting ']]>' characters is no longer possible + _bufPos = 1; // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to // close an empty element or in CDATA section detection of double ]; _BUFFER[0] will always be 0 } } @@ -683,35 +683,35 @@ private async Task EncodeCharsAsync(int startOffset, int endOffset, bool writeAl { _charEntityFallback.StartOffset = startOffset; } - encoder.Convert(bufChars, startOffset, endOffset - startOffset, bufBytes, bufBytesUsed, bufBytes.Length - bufBytesUsed, false, out chEnc, out bEnc, out completed); + _encoder.Convert(_bufChars, startOffset, endOffset - startOffset, _bufBytes, _bufBytesUsed, _bufBytes.Length - _bufBytesUsed, false, out chEnc, out bEnc, out completed); startOffset += chEnc; - bufBytesUsed += bEnc; - if (bufBytesUsed >= (bufBytes.Length - 16)) + _bufBytesUsed += bEnc; + if (_bufBytesUsed >= (_bufBytes.Length - 16)) { - await stream.WriteAsync(bufBytes.AsMemory(0, bufBytesUsed)).ConfigureAwait(false); - bufBytesUsed = 0; + await _stream.WriteAsync(_bufBytes.AsMemory(0, _bufBytesUsed)).ConfigureAwait(false); + _bufBytesUsed = 0; } } - if (writeAllToStream && bufBytesUsed > 0) + if (writeAllToStream && _bufBytesUsed > 0) { - await stream.WriteAsync(bufBytes.AsMemory(0, bufBytesUsed)).ConfigureAwait(false); - bufBytesUsed = 0; + await _stream.WriteAsync(_bufBytes.AsMemory(0, _bufBytesUsed)).ConfigureAwait(false); + _bufBytesUsed = 0; } } private Task FlushEncoderAsync() { - Debug.Assert(bufPos == 1); - if (stream != null) + Debug.Assert(_bufPos == 1); + if (_stream != null) { int chEnc; int bEnc; bool completed; // decode no chars, just flush - encoder.Convert(bufChars, 1, 0, bufBytes, 0, bufBytes.Length, true, out chEnc, out bEnc, out completed); + _encoder.Convert(_bufChars, 1, 0, _bufBytes, 0, _bufBytes.Length, true, out chEnc, out bEnc, out completed); if (bEnc != 0) { - return stream.WriteAsync(bufBytes, 0, bEnc); + return _stream.WriteAsync(_bufBytes, 0, bEnc); } } @@ -724,20 +724,20 @@ protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd) { char* pRaw = pSrc; - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) + while (pDst < pDstEnd && _xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) { *pDst = (char)ch; pDst++; @@ -754,7 +754,7 @@ protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -778,7 +778,7 @@ protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd) pDst++; break; case (char)0x9: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (char)ch; pDst++; @@ -790,7 +790,7 @@ protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd) } break; case (char)0xD: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (char)ch; pDst++; @@ -802,7 +802,7 @@ protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd) } break; case (char)0xA: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (char)ch; pDst++; @@ -837,7 +837,7 @@ protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -928,20 +928,20 @@ protected unsafe int WriteElementTextBlockNoFlush(char* pSrc, char* pSrcEnd, out needWriteNewLine = false; char* pRaw = pSrc; - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) + while (pDst < pDstEnd && _xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) { *pDst = (char)ch; pDst++; @@ -958,7 +958,7 @@ protected unsafe int WriteElementTextBlockNoFlush(char* pSrc, char* pSrcEnd, out // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -981,9 +981,9 @@ protected unsafe int WriteElementTextBlockNoFlush(char* pSrc, char* pSrcEnd, out pDst++; break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -994,7 +994,7 @@ protected unsafe int WriteElementTextBlockNoFlush(char* pSrc, char* pSrcEnd, out } break; case (char)0xD: - switch (newLineHandling) + switch (_newLineHandling) { case NewLineHandling.Replace: // Replace "\r\n", or "\r" with NewLineChars @@ -1003,7 +1003,7 @@ protected unsafe int WriteElementTextBlockNoFlush(char* pSrc, char* pSrcEnd, out pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); @@ -1041,9 +1041,9 @@ protected unsafe int WriteElementTextBlockNoFlush(char* pSrc, char* pSrcEnd, out } pSrc++; } - bufPos = (int)(pDst - pDstBegin); - textPos = bufPos; - contentPos = 0; + _bufPos = (int)(pDst - pDstBegin); + _textPos = _bufPos; + _contentPos = 0; } return -1; @@ -1054,7 +1054,7 @@ protected unsafe int WriteElementTextBlockNoFlush(char[] chars, int index, int c needWriteNewLine = false; if (count == 0) { - contentPos = 0; + _contentPos = 0; return -1; } fixed (char* pSrc = &chars[index]) @@ -1070,7 +1070,7 @@ protected unsafe int WriteElementTextBlockNoFlush(string text, int index, int co needWriteNewLine = false; if (count == 0) { - contentPos = 0; + _contentPos = 0; return -1; } fixed (char* pSrc = text) @@ -1095,7 +1095,7 @@ protected async Task WriteElementTextBlockAsync(char[] chars, int index, int cou if (needWriteNewLine) { //hit WriteNewLine - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1135,7 +1135,7 @@ private async Task _WriteElementTextBlockAsync(bool newLine, string text, int cu if (newLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1152,7 +1152,7 @@ private async Task _WriteElementTextBlockAsync(bool newLine, string text, int cu if (needWriteNewLine) { //hit WriteNewLine - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1167,18 +1167,18 @@ protected unsafe int RawTextNoFlush(char* pSrcBegin, char* pSrcEnd) { char* pRaw = pSrcBegin; - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; char* pSrc = pSrcBegin; int ch = 0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } while (pDst < pDstEnd && ((ch = *pSrc) < XmlCharType.SurHighStart)) @@ -1198,7 +1198,7 @@ protected unsafe int RawTextNoFlush(char* pSrcBegin, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -1223,7 +1223,7 @@ protected unsafe int RawTextNoFlush(char* pSrcBegin, char* pSrcEnd) } } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -1342,21 +1342,21 @@ protected unsafe int WriteRawWithCharCheckingNoFlush(char* pSrcBegin, char* pSrc needWriteNewLine = false; char* pRaw = pSrcBegin; - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { char* pSrc = pSrcBegin; - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && xmlCharType.IsTextChar((char)(ch = *pSrc))) + while (pDst < pDstEnd && _xmlCharType.IsTextChar((char)(ch = *pSrc))) { *pDst = (char)ch; pDst++; @@ -1374,7 +1374,7 @@ protected unsafe int WriteRawWithCharCheckingNoFlush(char* pSrcBegin, char* pSrc // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -1389,7 +1389,7 @@ protected unsafe int WriteRawWithCharCheckingNoFlush(char* pSrcBegin, char* pSrc pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1397,7 +1397,7 @@ protected unsafe int WriteRawWithCharCheckingNoFlush(char* pSrcBegin, char* pSrc pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1408,9 +1408,9 @@ protected unsafe int WriteRawWithCharCheckingNoFlush(char* pSrcBegin, char* pSrc } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1444,7 +1444,7 @@ protected unsafe int WriteRawWithCharCheckingNoFlush(char* pSrcBegin, char* pSrc } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -1493,7 +1493,7 @@ protected async Task WriteRawWithCharCheckingAsync(char[] chars, int index, int leftCount -= writeLen; if (needWriteNewLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1517,7 +1517,7 @@ protected async Task WriteRawWithCharCheckingAsync(string text) leftCount -= writeLen; if (needWriteNewLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1539,7 +1539,7 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, { char* pSrcBegin = pSrcText + index; - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { char* pSrc = pSrcBegin; @@ -1547,18 +1547,18 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, char* pSrcEnd = pSrcBegin + count; - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar)) + while (pDst < pDstEnd && (_xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar)) { *pDst = (char)ch; pDst++; @@ -1576,7 +1576,7 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -1614,7 +1614,7 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1622,7 +1622,7 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1633,9 +1633,9 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1675,7 +1675,7 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -1686,7 +1686,7 @@ protected async Task WriteCommentOrPiAsync(string text, int stopChar) { if (text.Length == 0) { - if (bufPos >= bufLen) + if (_bufPos >= _bufLen) { await FlushBufferAsync().ConfigureAwait(false); } @@ -1704,7 +1704,7 @@ protected async Task WriteCommentOrPiAsync(string text, int stopChar) leftCount -= writeLen; if (needWriteNewLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1729,7 +1729,7 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, { char* pSrcBegin = pSrcText + index; - fixed (char* pDstBegin = bufChars) + fixed (char* pDstBegin = _bufChars) { char* pSrc = pSrcBegin; @@ -1737,18 +1737,18 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, char* pRaw = pSrc; - char* pDst = pDstBegin + bufPos; + char* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { char* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']')) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']')) { *pDst = (char)ch; pDst++; @@ -1766,7 +1766,7 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -1774,7 +1774,7 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, switch (ch) { case '>': - if (hadDoubleBracket && pDst[-1] == (char)']') + if (_hadDoubleBracket && pDst[-1] == (char)']') { // pDst[-1] will always correct - there is a padding character at _BUFFER[0] // The characters "]]>" were found within the CData text pDst = RawEndCData(pDst); @@ -1786,17 +1786,17 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, case ']': if (pDst[-1] == (char)']') { // pDst[-1] will always correct - there is a padding character at _BUFFER[0] - hadDoubleBracket = true; + _hadDoubleBracket = true; } else { - hadDoubleBracket = false; + _hadDoubleBracket = false; } *pDst = (char)']'; pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1804,7 +1804,7 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1815,9 +1815,9 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1859,7 +1859,7 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -1870,7 +1870,7 @@ protected async Task WriteCDataSectionAsync(string text) { if (text.Length == 0) { - if (bufPos >= bufLen) + if (_bufPos >= _bufLen) { await FlushBufferAsync().ConfigureAwait(false); } @@ -1888,7 +1888,7 @@ protected async Task WriteCDataSectionAsync(string text) leftCount -= writeLen; if (needWriteNewLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1907,7 +1907,7 @@ public override async Task WriteDocTypeAsync(string name, string pubid, string s { CheckAsyncCall(); // Add indentation - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } @@ -1920,12 +1920,12 @@ public override async Task WriteStartElementAsync(string prefix, string localNam Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null); // Add indentation - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } - indentLevel++; - _mixedContentStack.PushBit(mixedContent); + _indentLevel++; + _mixedContentStack.PushBit(_mixedContent); await base.WriteStartElementAsync(prefix, localName, ns).ConfigureAwait(false); } @@ -1934,16 +1934,16 @@ internal override async Task WriteEndElementAsync(string prefix, string localNam { CheckAsyncCall(); // Add indentation - indentLevel--; - if (!mixedContent && base.contentPos != base.bufPos) + _indentLevel--; + if (!_mixedContent && base._contentPos != base._bufPos) { // There was content, so try to indent - if (base.textPos != base.bufPos) + if (base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } } - mixedContent = _mixedContentStack.PopBit(); + _mixedContent = _mixedContentStack.PopBit(); await base.WriteEndElementAsync(prefix, localName, ns).ConfigureAwait(false); } @@ -1952,16 +1952,16 @@ internal override async Task WriteFullEndElementAsync(string prefix, string loca { CheckAsyncCall(); // Add indentation - indentLevel--; - if (!mixedContent && base.contentPos != base.bufPos) + _indentLevel--; + if (!_mixedContent && base._contentPos != base._bufPos) { // There was content, so try to indent - if (base.textPos != base.bufPos) + if (base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } } - mixedContent = _mixedContentStack.PopBit(); + _mixedContent = _mixedContentStack.PopBit(); await base.WriteFullEndElementAsync(prefix, localName, ns).ConfigureAwait(false); } @@ -1971,7 +1971,7 @@ protected internal override async Task WriteStartAttributeAsync(string prefix, s { CheckAsyncCall(); // Add indentation - if (newLineOnAttributes) + if (_newLineOnAttributes) { await WriteIndentAsync().ConfigureAwait(false); } @@ -1982,14 +1982,14 @@ protected internal override async Task WriteStartAttributeAsync(string prefix, s public override Task WriteCDataAsync(string text) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteCDataAsync(text); } public override async Task WriteCommentAsync(string text) { CheckAsyncCall(); - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } @@ -2000,7 +2000,7 @@ public override async Task WriteCommentAsync(string text) public override async Task WriteProcessingInstructionAsync(string target, string text) { CheckAsyncCall(); - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } @@ -2011,63 +2011,63 @@ public override async Task WriteProcessingInstructionAsync(string target, string public override Task WriteEntityRefAsync(string name) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteEntityRefAsync(name); } public override Task WriteCharEntityAsync(char ch) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteCharEntityAsync(ch); } public override Task WriteSurrogateCharEntityAsync(char lowChar, char highChar) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteSurrogateCharEntityAsync(lowChar, highChar); } public override Task WriteWhitespaceAsync(string ws) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteWhitespaceAsync(ws); } public override Task WriteStringAsync(string text) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteStringAsync(text); } public override Task WriteCharsAsync(char[] buffer, int index, int count) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteCharsAsync(buffer, index, count); } public override Task WriteRawAsync(char[] buffer, int index, int count) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteRawAsync(buffer, index, count); } public override Task WriteRawAsync(string data) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteRawAsync(data); } public override Task WriteBase64Async(byte[] buffer, int index, int count) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteBase64Async(buffer, index, count); } @@ -2075,10 +2075,10 @@ public override Task WriteBase64Async(byte[] buffer, int index, int count) private async Task WriteIndentAsync() { CheckAsyncCall(); - await RawTextAsync(base.newLineChars).ConfigureAwait(false); - for (int i = indentLevel; i > 0; i--) + await RawTextAsync(base._newLineChars).ConfigureAwait(false); + for (int i = _indentLevel; i > 0; i--) { - await RawTextAsync(indentChars).ConfigureAwait(false); + await RawTextAsync(_indentChars).ConfigureAwait(false); } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEventCache.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEventCache.cs index b036585efbb22..857f50f3c13af 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEventCache.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlEventCache.cs @@ -431,7 +431,7 @@ public override void Flush() /// public override void WriteValue(object value) { - WriteString(XmlUntypedConverter.Untyped.ToString(value, this.resolver)); + WriteString(XmlUntypedConverter.Untyped.ToString(value, this._resolver)); } public override void WriteValue(string value) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.ttinclude index 10464300bf5a7..f9704285b633f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.ttinclude +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGenerator.ttinclude @@ -28,44 +28,44 @@ namespace System.Xml private readonly bool _useAsync; // main buffer - protected byte[] bufBytes; + protected byte[] _bufBytes; // output stream - protected Stream stream; + protected Stream _stream; // encoding of the stream or text writer - protected Encoding encoding; + protected Encoding _encoding; // char type tables - protected XmlCharType xmlCharType = XmlCharType.Instance; + protected XmlCharType _xmlCharType = XmlCharType.Instance; // buffer positions - protected int bufPos = 1; // buffer position starts at 1, because we need to be able to safely step back -1 in case we need to - // close an empty element or in CDATA section detection of double ]; <#= BufferName #>[0] will always be 0 - protected int textPos = 1; // text end position; don't indent first element, pi, or comment - protected int contentPos; // element content end position - protected int cdataPos; // cdata end position - protected int attrEndPos; // end of the last attribute - protected int bufLen = BUFSIZE; + protected int _bufPos = 1; // buffer position starts at 1, because we need to be able to safely step back -1 in case we need to + // close an empty element or in CDATA section detection of double ]; <#= BufferName #>[0] will always be 0 + protected int _textPos = 1; // text end position; don't indent first element, pi, or comment + protected int _contentPos; // element content end position + protected int _cdataPos; // cdata end position + protected int _attrEndPos; // end of the last attribute + protected int _bufLen = BUFSIZE; // flags - protected bool writeToNull; - protected bool hadDoubleBracket; - protected bool inAttributeValue; + protected bool _writeToNull; + protected bool _hadDoubleBracket; + protected bool _inAttributeValue; <# if (WriterType == RawTextWriterType.Encoded) { #> - protected int bufBytesUsed; - protected char[] bufChars; + protected int _bufBytesUsed; + protected char[] _bufChars; // encoder for encoding chars in specified encoding when writing to stream - protected Encoder encoder; + protected Encoder _encoder; // output text writer - protected TextWriter writer; + protected TextWriter _writer; // escaping of characters invalid in the output encoding - protected bool trackTextContent; - protected bool inTextContent; + protected bool _trackTextContent; + protected bool _inTextContent; private int _lastMarkPos; private int[] _textContentMarks; // even indices contain text content start positions // odd indices contain markup start positions @@ -73,17 +73,17 @@ namespace System.Xml <# } #> // writer settings - protected NewLineHandling newLineHandling; - protected bool closeOutput; - protected bool omitXmlDeclaration; - protected string newLineChars; - protected bool checkCharacters; + protected NewLineHandling _newLineHandling; + protected bool _closeOutput; + protected bool _omitXmlDeclaration; + protected string _newLineChars; + protected bool _checkCharacters; - protected XmlStandalone standalone; - protected XmlOutputMethod outputMethod; + protected XmlStandalone _standalone; + protected XmlOutputMethod _outputMethod; - protected bool autoXmlDeclaration; - protected bool mergeCDataSections; + protected bool _autoXmlDeclaration; + protected bool _mergeCDataSections; // // Constants @@ -102,19 +102,19 @@ namespace System.Xml _useAsync = settings.Async; // copy settings - newLineHandling = settings.NewLineHandling; - omitXmlDeclaration = settings.OmitXmlDeclaration; - newLineChars = settings.NewLineChars; - checkCharacters = settings.CheckCharacters; - closeOutput = settings.CloseOutput; + _newLineHandling = settings.NewLineHandling; + _omitXmlDeclaration = settings.OmitXmlDeclaration; + _newLineChars = settings.NewLineChars; + _checkCharacters = settings.CheckCharacters; + _closeOutput = settings.CloseOutput; - standalone = settings.Standalone; - outputMethod = settings.OutputMethod; - mergeCDataSections = settings.MergeCDataSections; + _standalone = settings.Standalone; + _outputMethod = settings.OutputMethod; + _mergeCDataSections = settings.MergeCDataSections; - if (checkCharacters && newLineHandling == NewLineHandling.Replace) + if (_checkCharacters && _newLineHandling == NewLineHandling.Replace) { - ValidateContentChars(newLineChars, "NewLineChars", false); + ValidateContentChars(_newLineChars, "NewLineChars", false); } } <# if (WriterType == RawTextWriterType.Encoded) { #> @@ -124,20 +124,20 @@ namespace System.Xml { Debug.Assert(writer != null && settings != null); - this.writer = writer; - this.encoding = writer.Encoding; + this._writer = writer; + this._encoding = writer.Encoding; // the buffer is allocated will OVERFLOW in order to reduce checks when writing out constant size markup if (settings.Async) { - bufLen = ASYNCBUFSIZE; + _bufLen = ASYNCBUFSIZE; } - this.bufChars = new <#= BufferType #>[bufLen + OVERFLOW]; + this._bufChars = new <#= BufferType #>[_bufLen + OVERFLOW]; // Write the xml declaration if (settings.AutoXmlDeclaration) { - WriteXmlDeclaration(standalone); - autoXmlDeclaration = true; + WriteXmlDeclaration(_standalone); + _autoXmlDeclaration = true; } } <# } #> @@ -147,35 +147,35 @@ namespace System.Xml { Debug.Assert(stream != null && settings != null); - this.stream = stream; - this.encoding = settings.Encoding; + this._stream = stream; + this._encoding = settings.Encoding; // the buffer is allocated will OVERFLOW in order to reduce checks when writing out constant size markup if (settings.Async) { - bufLen = ASYNCBUFSIZE; + _bufLen = ASYNCBUFSIZE; } - <#= BufferName #> = new <#= BufferType #>[bufLen + OVERFLOW]; + <#= BufferName #> = new <#= BufferType #>[_bufLen + OVERFLOW]; <# if (WriterType == RawTextWriterType.Utf8) { #> // Output UTF-8 byte order mark if Encoding object wants it if (!stream.CanSeek || stream.Position == 0) { - ReadOnlySpan bom = encoding.Preamble; + ReadOnlySpan bom = _encoding.Preamble; if (bom.Length != 0) { - bom.CopyTo(new Span(bufBytes).Slice(1)); - bufPos += bom.Length; - textPos += bom.Length; + bom.CopyTo(new Span(_bufBytes).Slice(1)); + _bufPos += bom.Length; + _textPos += bom.Length; } } <# } else { #> - bufBytes = new byte[bufChars.Length]; - bufBytesUsed = 0; + _bufBytes = new byte[_bufChars.Length]; + _bufBytesUsed = 0; // Init escaping of characters not fitting into the target encoding - trackTextContent = true; - inTextContent = false; + _trackTextContent = true; + _inTextContent = false; _lastMarkPos = 0; _textContentMarks = new int[INIT_MARKS_COUNT]; _textContentMarks[0] = 1; @@ -183,21 +183,21 @@ namespace System.Xml _charEntityFallback = new CharEntityEncoderFallback(); // grab bom before possibly changing encoding settings - ReadOnlySpan bom = encoding.Preamble; + ReadOnlySpan bom = _encoding.Preamble; // the encoding instance this creates can differ from the one passed in - this.encoding = Encoding.GetEncoding( + this._encoding = Encoding.GetEncoding( settings.Encoding.CodePage, _charEntityFallback, settings.Encoding.DecoderFallback); - encoder = encoding.GetEncoder(); + _encoder = _encoding.GetEncoder(); - if (!stream.CanSeek || stream.Position == 0) + if (!_stream.CanSeek || _stream.Position == 0) { if (bom.Length != 0) { - this.stream.Write(bom); + this._stream.Write(bom); } } <# } #> @@ -205,8 +205,8 @@ namespace System.Xml // Write the xml declaration if (settings.AutoXmlDeclaration) { - WriteXmlDeclaration(standalone); - autoXmlDeclaration = true; + WriteXmlDeclaration(_standalone); + _autoXmlDeclaration = true; } } @@ -220,17 +220,17 @@ namespace System.Xml { XmlWriterSettings settings = new XmlWriterSettings(); - settings.Encoding = encoding; - settings.OmitXmlDeclaration = omitXmlDeclaration; - settings.NewLineHandling = newLineHandling; - settings.NewLineChars = newLineChars; - settings.CloseOutput = closeOutput; + settings.Encoding = _encoding; + settings.OmitXmlDeclaration = _omitXmlDeclaration; + settings.NewLineHandling = _newLineHandling; + settings.NewLineChars = _newLineChars; + settings.CloseOutput = _closeOutput; settings.ConformanceLevel = ConformanceLevel.Auto; - settings.CheckCharacters = checkCharacters; + settings.CheckCharacters = _checkCharacters; - settings.AutoXmlDeclaration = autoXmlDeclaration; - settings.Standalone = standalone; - settings.OutputMethod = outputMethod; + settings.AutoXmlDeclaration = _autoXmlDeclaration; + settings.Standalone = _standalone; + settings.OutputMethod = _outputMethod; settings.ReadOnly = true; return settings; @@ -241,7 +241,7 @@ namespace System.Xml internal override void WriteXmlDeclaration(XmlStandalone standalone) { // Output xml declaration only if user allows it and it was not already output - if (!omitXmlDeclaration && !autoXmlDeclaration) + if (!_omitXmlDeclaration && !_autoXmlDeclaration) {<# /* Code block is to squash extra line. */ #><#= SetTextContentMark(4, 1, false) #> RawText("[bufPos++] = (<#= BufferType #>)'"'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"'; } else if (sysid != null) { RawText(" SYSTEM \""); RawText(sysid); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"'; } else { - <#= BufferName #>[bufPos++] = (<#= BufferType #>)' '; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)' '; } if (subset != null) { - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'['; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'['; RawText(subset); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)']'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)']'; } - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'>'; } // Serialize the beginning of an element start tag: "<#= SetTextContentMark(3, false) #> - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'<'; if (prefix != null && prefix.Length != 0) { RawText(prefix); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)':'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)':'; } RawText(localName); - attrEndPos = bufPos; + _attrEndPos = _bufPos; } // Serialize the end of an element start tag in preparation for content serialization: ">" internal override void StartElementContent() { - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'>'; // StartElementContent is always called; therefore, in order to allow shortcut syntax, we save the // position of the '>' character. If WriteEndElement is called and no other characters have been // output, then the '>' character can be overwritten with the shortcut syntax " />". - contentPos = bufPos; + _contentPos = _bufPos; } // Serialize an element end tag: "", if content was output. Otherwise, serialize @@ -357,27 +357,27 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - if (contentPos != bufPos) + if (_contentPos != _bufPos) { // Content has been output, so can't use shortcut syntax - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'/'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'<'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'/'; if (prefix != null && prefix.Length != 0) { RawText(prefix); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)':'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)':'; } RawText(localName); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'>'; } else { // Use shortcut syntax; overwrite the already output '>' character - bufPos--; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)' '; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'/'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>'; + _bufPos--; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)' '; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'/'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'>'; } } @@ -389,16 +389,16 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'/'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'<'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'/'; if (prefix != null && prefix.Length != 0) { RawText(prefix); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)':'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)':'; } RawText(localName); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'>'; } // Serialize an attribute tag using double quotes around the attribute value: 'prefix:localName="' @@ -409,21 +409,21 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - if (attrEndPos == bufPos) + if (_attrEndPos == _bufPos) { - <#= BufferName #>[bufPos++] = (<#= BufferType #>)' '; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)' '; } if (prefix != null && prefix.Length > 0) { RawText(prefix); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)':'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)':'; } RawText(localName); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'='; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'='; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"'; - inAttributeValue = true; + _inAttributeValue = true; } // Serialize the end of an attribute value using double quotes: '"' @@ -431,9 +431,9 @@ namespace System.Xml {<# #><#= SetTextContentMark(3, 1, false) #> - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"'; - inAttributeValue = false; - attrEndPos = bufPos; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"'; + _inAttributeValue = false; + _attrEndPos = _bufPos; } internal override void WriteNamespaceDeclaration(string prefix, string namespaceName) @@ -467,21 +467,21 @@ namespace System.Xml { RawText(" xmlns:"); RawText(prefix); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'='; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'='; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"'; } - inAttributeValue = true;<# + _inAttributeValue = true;<# #><#= SetTextContentMark(3, true) #> } internal override void WriteEndNamespaceDeclaration() {<# #><#= SetTextContentMark(3, 1, false) #> - inAttributeValue = false; + _inAttributeValue = false; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"'; - attrEndPos = bufPos; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"'; + _attrEndPos = _bufPos; } // Serialize a CData section. If the "]]>" pattern is found within @@ -492,34 +492,34 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - if (mergeCDataSections && bufPos == cdataPos) + if (_mergeCDataSections && _bufPos == _cdataPos) { // Merge adjacent cdata sections - overwrite the "]]>" characters - Debug.Assert(bufPos >= 4); - bufPos -= 3; + Debug.Assert(_bufPos >= 4); + _bufPos -= 3; } else { // Start a new cdata section - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'!'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'['; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'C'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'D'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'A'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'T'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'A'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'['; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'<'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'!'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'['; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'C'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'D'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'A'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'T'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'A'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'['; } WriteCDataSection(text); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)']'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)']'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)']'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)']'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'>'; - textPos = bufPos; - cdataPos = bufPos; + _textPos = _bufPos; + _cdataPos = _bufPos; } // Serialize a comment. @@ -529,16 +529,16 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'!'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'<'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'!'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'-'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'-'; WriteCommentOrPi(text, '-'); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'-'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'-'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'>'; } // Serialize a processing instruction. @@ -549,18 +549,18 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'?'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'<'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'?'; RawText(name); if (text.Length > 0) { - <#= BufferName #>[bufPos++] = (<#= BufferType #>)' '; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)' '; WriteCommentOrPi(text, '?'); } - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'?'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'?'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'>'; } // Serialize an entity reference. @@ -570,16 +570,16 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'&'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'&'; RawText(name); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)';'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)';'; - if (bufPos > bufLen) + if (_bufPos > _bufLen) { FlushBuffer(); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize a character entity reference. @@ -587,7 +587,7 @@ namespace System.Xml { string strVal = ((int)ch).ToString("X", NumberFormatInfo.InvariantInfo); - if (checkCharacters && !xmlCharType.IsCharData(ch)) + if (_checkCharacters && !_xmlCharType.IsCharData(ch)) { // we just have a single char, not a surrogate, therefore we have to pass in '\0' for the second char throw XmlConvert.CreateInvalidCharException(ch, '\0'); @@ -595,18 +595,18 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'&'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'#'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'x'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'&'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'#'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'x'; RawText(strVal); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)';'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)';'; - if (bufPos > bufLen) + if (_bufPos > _bufLen) { FlushBuffer(); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize a whitespace node. @@ -620,7 +620,7 @@ namespace System.Xml fixed (char* pSrc = ws) { char* pSrcEnd = pSrc + ws.Length; - if (inAttributeValue) + if (_inAttributeValue) { WriteAttributeTextBlock(pSrc, pSrcEnd); } @@ -642,7 +642,7 @@ namespace System.Xml fixed (char* pSrc = text) { char* pSrcEnd = pSrc + text.Length; - if (inAttributeValue) + if (_inAttributeValue) { WriteAttributeTextBlock(pSrc, pSrcEnd); } @@ -659,12 +659,12 @@ namespace System.Xml #><#= SetTextContentMark(3, 1, false) #> int surrogateChar = XmlCharType.CombineSurrogateChar(lowChar, highChar); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'&'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'#'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'x'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'&'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'#'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'x'; RawText(surrogateChar.ToString("X", NumberFormatInfo.InvariantInfo)); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)';'; - textPos = bufPos; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)';'; + _textPos = _bufPos; } // Serialize either attribute or element text using XML rules. @@ -680,7 +680,7 @@ namespace System.Xml fixed (char* pSrcBegin = &buffer[index]) { - if (inAttributeValue) + if (_inAttributeValue) { WriteAttributeTextBlock(pSrcBegin, pSrcBegin + count); } @@ -707,7 +707,7 @@ namespace System.Xml WriteRawWithCharChecking(pSrcBegin, pSrcBegin + count); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize raw data. @@ -723,7 +723,7 @@ namespace System.Xml WriteRawWithCharChecking(pSrcBegin, pSrcBegin + data.Length); } - textPos = bufPos; + _textPos = _bufPos; } // Flush all bytes in the buffer to output and close the output stream or writer. @@ -737,48 +737,48 @@ namespace System.Xml finally { // Future calls to Close or Flush shouldn't write to Stream or Writer - writeToNull = true; + _writeToNull = true; - if (stream != null) + if (_stream != null) { try { - stream.Flush(); + _stream.Flush(); } finally { try { - if (closeOutput) + if (_closeOutput) { - stream.Dispose(); + _stream.Dispose(); } } finally { - stream = null; + _stream = null; } } } <# if (WriterType == RawTextWriterType.Encoded) { #> - else if (writer != null) + else if (_writer != null) { try { - writer.Flush(); + _writer.Flush(); } finally { try { - if (closeOutput) + if (_closeOutput) { - writer.Dispose(); + _writer.Dispose(); } } finally { - writer = null; + _writer = null; } } } @@ -792,18 +792,18 @@ namespace System.Xml FlushBuffer(); FlushEncoder(); <# if (WriterType == RawTextWriterType.Utf8) { #> - if (stream != null) + if (_stream != null) { - stream.Flush(); + _stream.Flush(); } <# } else { #> - if (stream != null) + if (_stream != null) { - stream.Flush(); + _stream.Flush(); } - else if (writer != null) + else if (_writer != null) { - writer.Flush(); + _writer.Flush(); } <# } #> } @@ -817,20 +817,20 @@ namespace System.Xml try { // Output all characters (except for previous characters stored at beginning of buffer) - if (!writeToNull) + if (!_writeToNull) { <# if (WriterType == RawTextWriterType.Utf8) { #> - if (bufPos - 1 > 0) + if (_bufPos - 1 > 0) { - Debug.Assert(stream != null); - stream.Write(<#= BufferName #>, 1, bufPos - 1); + Debug.Assert(_stream != null); + _stream.Write(<#= BufferName #>, 1, _bufPos - 1); } <# } else { #> - Debug.Assert(stream != null || writer != null); + Debug.Assert(_stream != null || _writer != null); - if (stream != null) + if (_stream != null) { - if (trackTextContent) + if (_trackTextContent) { _charEntityFallback.Reset(_textContentMarks, _lastMarkPos); // reset text content tracking @@ -848,14 +848,14 @@ namespace System.Xml } Debug.Assert(_textContentMarks[0] == 1); } - EncodeChars(1, bufPos, true); + EncodeChars(1, _bufPos, true); } else { - if (bufPos - 1 > 0) + if (_bufPos - 1 > 0) { // Write text to TextWriter - writer.Write(<#= BufferName #>, 1, bufPos - 1); + _writer.Write(<#= BufferName #>, 1, _bufPos - 1); } } <# } #> @@ -864,30 +864,30 @@ namespace System.Xml catch { // Future calls to flush (i.e. when Close() is called) don't attempt to write to stream - writeToNull = true; + _writeToNull = true; throw; } finally { // Move last buffer character to the beginning of the buffer (so that previous character can always be determined) - <#= BufferName #>[0] = <#= BufferName #>[bufPos - 1]; + <#= BufferName #>[0] = <#= BufferName #>[_bufPos - 1]; <# if (WriterType == RawTextWriterType.Utf8) { #> if (IsSurrogateByte(<#= BufferName #>[0])) { // Last character was the first byte in a surrogate encoding, so move last three // bytes of encoding to the beginning of the buffer. - <#= BufferName #>[1] = <#= BufferName #>[bufPos]; - <#= BufferName #>[2] = <#= BufferName #>[bufPos + 1]; - <#= BufferName #>[3] = <#= BufferName #>[bufPos + 2]; + <#= BufferName #>[1] = <#= BufferName #>[_bufPos]; + <#= BufferName #>[2] = <#= BufferName #>[_bufPos + 1]; + <#= BufferName #>[3] = <#= BufferName #>[_bufPos + 2]; } <# } #> // Reset buffer position - textPos = (textPos == bufPos) ? 1 : 0; - attrEndPos = (attrEndPos == bufPos) ? 1 : 0; - contentPos = 0; // Needs to be zero, since overwriting '>' character is no longer possible - cdataPos = 0; // Needs to be zero, since overwriting ']]>' characters is no longer possible - bufPos = 1; // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to + _textPos = (_textPos == _bufPos) ? 1 : 0; + _attrEndPos = (_attrEndPos == _bufPos) ? 1 : 0; + _contentPos = 0; // Needs to be zero, since overwriting '>' character is no longer possible + _cdataPos = 0; // Needs to be zero, since overwriting ']]>' characters is no longer possible + _bufPos = 1; // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to // close an empty element or in CDATA section detection of double ]; <#= BufferName #>[0] will always be 0 } } @@ -911,35 +911,35 @@ namespace System.Xml { _charEntityFallback.StartOffset = startOffset; } - encoder.Convert(<#= BufferName #>, startOffset, endOffset - startOffset, bufBytes, bufBytesUsed, bufBytes.Length - bufBytesUsed, false, out chEnc, out bEnc, out completed); + _encoder.Convert(<#= BufferName #>, startOffset, endOffset - startOffset, _bufBytes, _bufBytesUsed, _bufBytes.Length - _bufBytesUsed, false, out chEnc, out bEnc, out completed); startOffset += chEnc; - bufBytesUsed += bEnc; - if (bufBytesUsed >= (bufBytes.Length - 16)) + _bufBytesUsed += bEnc; + if (_bufBytesUsed >= (_bufBytes.Length - 16)) { - stream.Write(bufBytes, 0, bufBytesUsed); - bufBytesUsed = 0; + _stream.Write(_bufBytes, 0, _bufBytesUsed); + _bufBytesUsed = 0; } } - if (writeAllToStream && bufBytesUsed > 0) + if (writeAllToStream && _bufBytesUsed > 0) { - stream.Write(bufBytes, 0, bufBytesUsed); - bufBytesUsed = 0; + _stream.Write(_bufBytes, 0, _bufBytesUsed); + _bufBytesUsed = 0; } } private void FlushEncoder() { - Debug.Assert(bufPos == 1); - if (stream != null) + Debug.Assert(_bufPos == 1); + if (_stream != null) { int chEnc; int bEnc; bool completed; // decode no chars, just flush - encoder.Convert(<#= BufferName #>, 1, 0, bufBytes, 0, bufBytes.Length, true, out chEnc, out bEnc, out completed); + _encoder.Convert(<#= BufferName #>, 1, 0, _bufBytes, 0, _bufBytes.Length, true, out chEnc, out bEnc, out completed); if (bEnc != 0) { - stream.Write(bufBytes, 0, bEnc); + _stream.Write(_bufBytes, 0, bEnc); } } } @@ -951,21 +951,21 @@ namespace System.Xml { fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>) { - <#= BufferType #>* pDst = pDstBegin + bufPos; + <#= BufferType #>* pDst = pDstBegin + _bufPos; int ch = 0; for (;;) { <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } <# if (WriterType == RawTextWriterType.Utf8) { #> - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) <# } else { #> - while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) + while (pDst < pDstEnd && _xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) <# } #> { *pDst = (<#= BufferType #>)ch; @@ -983,7 +983,7 @@ namespace System.Xml // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1009,7 +1009,7 @@ namespace System.Xml pDst++; break; case (char)0x9: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (<#= BufferType #>)ch; pDst++; @@ -1021,7 +1021,7 @@ namespace System.Xml } break; case (char)0xD: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (<#= BufferType #>)ch; pDst++; @@ -1033,7 +1033,7 @@ namespace System.Xml } break; case (char)0xA: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (<#= BufferType #>)ch; pDst++; @@ -1050,7 +1050,7 @@ namespace System.Xml } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -1060,21 +1060,21 @@ namespace System.Xml { fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>) { - <#= BufferType #>* pDst = pDstBegin + bufPos; + <#= BufferType #>* pDst = pDstBegin + _bufPos; int ch = 0; for (;;) { <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } <# if (WriterType == RawTextWriterType.Utf8) { #> - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) <# } else { #> - while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) + while (pDst < pDstEnd && _xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) <# } #> { *pDst = (<#= BufferType #>)ch; @@ -1092,7 +1092,7 @@ namespace System.Xml // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1117,7 +1117,7 @@ namespace System.Xml pDst++; break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { pDst = WriteNewLine(pDst); } @@ -1128,7 +1128,7 @@ namespace System.Xml } break; case (char)0xD: - switch (newLineHandling) + switch (_newLineHandling) { case NewLineHandling.Replace: // Replace "\r\n", or "\r" with NewLineChars @@ -1156,9 +1156,9 @@ namespace System.Xml } pSrc++; } - bufPos = (int)(pDst - pDstBegin); - textPos = bufPos; - contentPos = 0; + _bufPos = (int)(pDst - pDstBegin); + _textPos = _bufPos; + _contentPos = 0; } } @@ -1176,16 +1176,16 @@ namespace System.Xml { fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>) { - <#= BufferType #>* pDst = pDstBegin + bufPos; + <#= BufferType #>* pDst = pDstBegin + _bufPos; char* pSrc = pSrcBegin; int ch = 0; for (;;) { <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } <# if (WriterType == RawTextWriterType.Utf8) { #> @@ -1209,7 +1209,7 @@ namespace System.Xml // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1218,7 +1218,7 @@ namespace System.Xml <#= EncodeChar(5, false) #> } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -1227,21 +1227,21 @@ namespace System.Xml fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>) { char* pSrc = pSrcBegin; - <#= BufferType #>* pDst = pDstBegin + bufPos; + <#= BufferType #>* pDst = pDstBegin + _bufPos; int ch = 0; for (;;) { <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } <# if (WriterType == RawTextWriterType.Utf8) { #> - while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch <= 0x7F)) <# } else { #> - while (pDst < pDstEnd && xmlCharType.IsTextChar((char)(ch = *pSrc))) + while (pDst < pDstEnd && _xmlCharType.IsTextChar((char)(ch = *pSrc))) <# } #> { *pDst = (<#= BufferType #>)ch; @@ -1260,7 +1260,7 @@ namespace System.Xml // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1277,7 +1277,7 @@ namespace System.Xml pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1294,7 +1294,7 @@ namespace System.Xml } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { pDst = WriteNewLine(pDst); } @@ -1310,7 +1310,7 @@ namespace System.Xml } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -1318,7 +1318,7 @@ namespace System.Xml { if (text.Length == 0) { - if (bufPos >= bufLen) + if (_bufPos >= _bufLen) { FlushBuffer(); } @@ -1333,21 +1333,21 @@ namespace System.Xml char* pSrcEnd = pSrcBegin + text.Length; - <#= BufferType #>* pDst = pDstBegin + bufPos; + <#= BufferType #>* pDst = pDstBegin + _bufPos; int ch = 0; for (;;) { <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } <# if (WriterType == RawTextWriterType.Utf8) { #> - while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar && ch <= 0x7F)) <# } else { #> - while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar)) + while (pDst < pDstEnd && (_xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar)) <# } #> { *pDst = (<#= BufferType #>)ch; @@ -1366,7 +1366,7 @@ namespace System.Xml // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1406,7 +1406,7 @@ namespace System.Xml pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1423,7 +1423,7 @@ namespace System.Xml } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { pDst = WriteNewLine(pDst); } @@ -1445,7 +1445,7 @@ namespace System.Xml } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -1453,7 +1453,7 @@ namespace System.Xml { if (text.Length == 0) { - if (bufPos >= bufLen) + if (_bufPos >= _bufLen) { FlushBuffer(); } @@ -1470,21 +1470,21 @@ namespace System.Xml char* pSrcEnd = pSrcBegin + text.Length; - <#= BufferType #>* pDst = pDstBegin + bufPos; + <#= BufferType #>* pDst = pDstBegin + _bufPos; int ch = 0; for (;;) { <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } <# if (WriterType == RawTextWriterType.Utf8) { #> - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']' && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']' && ch <= 0x7F)) <# } else { #> - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']')) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']')) <# } #> { *pDst = (<#= BufferType #>)ch; @@ -1503,7 +1503,7 @@ namespace System.Xml // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1513,7 +1513,7 @@ namespace System.Xml switch (ch) { case '>': - if (hadDoubleBracket && pDst[-1] == (<#= BufferType #>)']') + if (_hadDoubleBracket && pDst[-1] == (<#= BufferType #>)']') { // pDst[-1] will always correct - there is a padding character at <#= BufferName #>[0] // The characters "]]>" were found within the CData text pDst = RawEndCData(pDst); @@ -1525,17 +1525,17 @@ namespace System.Xml case ']': if (pDst[-1] == (<#= BufferType #>)']') { // pDst[-1] will always correct - there is a padding character at <#= BufferName #>[0] - hadDoubleBracket = true; + _hadDoubleBracket = true; } else { - hadDoubleBracket = false; + _hadDoubleBracket = false; } *pDst = (<#= BufferType #>)']'; pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1552,7 +1552,7 @@ namespace System.Xml } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { pDst = WriteNewLine(pDst); } @@ -1576,7 +1576,7 @@ namespace System.Xml } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -1630,10 +1630,10 @@ namespace System.Xml private unsafe <#= BufferType #>* InvalidXmlChar(int ch, <#= BufferType #>* pDst, bool entitize) { - Debug.Assert(!xmlCharType.IsWhiteSpace((char)ch)); - Debug.Assert(!xmlCharType.IsAttributeValueChar((char)ch)); + Debug.Assert(!_xmlCharType.IsWhiteSpace((char)ch)); + Debug.Assert(!_xmlCharType.IsAttributeValueChar((char)ch)); - if (checkCharacters) + if (_checkCharacters) { // This method will never be called on surrogates, so it is ok to pass in '\0' to the CreateInvalidCharException throw XmlConvert.CreateInvalidCharException((char)ch, '\0'); @@ -1724,14 +1724,14 @@ namespace System.Xml <# if (WriterType == RawTextWriterType.Encoded) { #> protected void ChangeTextContentMark(bool value) { - Debug.Assert(inTextContent != value); - Debug.Assert(inTextContent || ((_lastMarkPos & 1) == 0)); - inTextContent = value; + Debug.Assert(_inTextContent != value); + Debug.Assert(_inTextContent || ((_lastMarkPos & 1) == 0)); + _inTextContent = value; if (_lastMarkPos + 1 == _textContentMarks.Length) { GrowTextContentMarks(); } - _textContentMarks[++_lastMarkPos] = bufPos; + _textContentMarks[++_lastMarkPos] = _bufPos; } private void GrowTextContentMarks() @@ -1747,10 +1747,10 @@ namespace System.Xml { fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); // Let RawText do the real work - RawText(newLineChars); - return pDstBegin + bufPos; + RawText(_newLineChars); + return pDstBegin + _bufPos; } } @@ -1888,7 +1888,7 @@ namespace System.Xml { if (allowOnlyWhitespace) { - if (!xmlCharType.IsOnlyWhitespace(chars)) + if (!_xmlCharType.IsOnlyWhitespace(chars)) { throw new ArgumentException(SR.Format(SR.Xml_IndentCharsNotWhitespace, propertyName)); } @@ -1898,7 +1898,7 @@ namespace System.Xml string error = null; for (int i = 0; i < chars.Length; i++) { - if (!xmlCharType.IsTextChar(chars[i])) + if (!_xmlCharType.IsTextChar(chars[i])) { switch (chars[i]) { @@ -1948,14 +1948,14 @@ namespace System.Xml // // Fields // - protected int indentLevel; - protected bool newLineOnAttributes; - protected string indentChars; + protected int _indentLevel; + protected bool _newLineOnAttributes; + protected string _indentChars; - protected bool mixedContent; + protected bool _mixedContent; private BitStack _mixedContentStack; - protected ConformanceLevel conformanceLevel = ConformanceLevel.Auto; + protected ConformanceLevel _conformanceLevel = ConformanceLevel.Auto; // // Constructors @@ -1984,8 +1984,8 @@ namespace System.Xml settings.ReadOnly = false; settings.Indent = true; - settings.IndentChars = indentChars; - settings.NewLineOnAttributes = newLineOnAttributes; + settings.IndentChars = _indentChars; + settings.NewLineOnAttributes = _newLineOnAttributes; settings.ReadOnly = true; return settings; @@ -1995,7 +1995,7 @@ namespace System.Xml public override void WriteDocType(string name, string pubid, string sysid, string subset) { // Add indentation - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { WriteIndent(); } @@ -2007,12 +2007,12 @@ namespace System.Xml Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null); // Add indentation - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { WriteIndent(); } - indentLevel++; - _mixedContentStack.PushBit(mixedContent); + _indentLevel++; + _mixedContentStack.PushBit(_mixedContent); base.WriteStartElement(prefix, localName, ns); } @@ -2020,16 +2020,16 @@ namespace System.Xml internal override void StartElementContent() { // If this is the root element and we're writing a document - // do not inherit the mixedContent flag into the root element. + // do not inherit the _mixedContent flag into the root element. // This is to allow for whitespace nodes on root level // without disabling indentation for the whole document. - if (indentLevel == 1 && conformanceLevel == ConformanceLevel.Document) + if (_indentLevel == 1 && _conformanceLevel == ConformanceLevel.Document) { - mixedContent = false; + _mixedContent = false; } else { - mixedContent = _mixedContentStack.PeekBit(); + _mixedContent = _mixedContentStack.PeekBit(); } base.StartElementContent(); } @@ -2037,22 +2037,22 @@ namespace System.Xml internal override void OnRootElement(ConformanceLevel currentConformanceLevel) { // Just remember the current conformance level - conformanceLevel = currentConformanceLevel; + _conformanceLevel = currentConformanceLevel; } internal override void WriteEndElement(string prefix, string localName, string ns) { // Add indentation - indentLevel--; - if (!mixedContent && base.contentPos != base.bufPos) + _indentLevel--; + if (!_mixedContent && base._contentPos != base._bufPos) { // There was content, so try to indent - if (base.textPos != base.bufPos) + if (base._textPos != base._bufPos) { WriteIndent(); } } - mixedContent = _mixedContentStack.PopBit(); + _mixedContent = _mixedContentStack.PopBit(); base.WriteEndElement(prefix, localName, ns); } @@ -2060,16 +2060,16 @@ namespace System.Xml internal override void WriteFullEndElement(string prefix, string localName, string ns) { // Add indentation - indentLevel--; - if (!mixedContent && base.contentPos != base.bufPos) + _indentLevel--; + if (!_mixedContent && base._contentPos != base._bufPos) { // There was content, so try to indent - if (base.textPos != base.bufPos) + if (base._textPos != base._bufPos) { WriteIndent(); } } - mixedContent = _mixedContentStack.PopBit(); + _mixedContent = _mixedContentStack.PopBit(); base.WriteFullEndElement(prefix, localName, ns); } @@ -2078,7 +2078,7 @@ namespace System.Xml public override void WriteStartAttribute(string prefix, string localName, string ns) { // Add indentation - if (newLineOnAttributes) + if (_newLineOnAttributes) { WriteIndent(); } @@ -2088,13 +2088,13 @@ namespace System.Xml public override void WriteCData(string text) { - mixedContent = true; + _mixedContent = true; base.WriteCData(text); } public override void WriteComment(string text) { - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { WriteIndent(); } @@ -2104,7 +2104,7 @@ namespace System.Xml public override void WriteProcessingInstruction(string target, string text) { - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { WriteIndent(); } @@ -2114,55 +2114,55 @@ namespace System.Xml public override void WriteEntityRef(string name) { - mixedContent = true; + _mixedContent = true; base.WriteEntityRef(name); } public override void WriteCharEntity(char ch) { - mixedContent = true; + _mixedContent = true; base.WriteCharEntity(ch); } public override void WriteSurrogateCharEntity(char lowChar, char highChar) { - mixedContent = true; + _mixedContent = true; base.WriteSurrogateCharEntity(lowChar, highChar); } public override void WriteWhitespace(string ws) { - mixedContent = true; + _mixedContent = true; base.WriteWhitespace(ws); } public override void WriteString(string text) { - mixedContent = true; + _mixedContent = true; base.WriteString(text); } public override void WriteChars(char[] buffer, int index, int count) { - mixedContent = true; + _mixedContent = true; base.WriteChars(buffer, index, count); } public override void WriteRaw(char[] buffer, int index, int count) { - mixedContent = true; + _mixedContent = true; base.WriteRaw(buffer, index, count); } public override void WriteRaw(string data) { - mixedContent = true; + _mixedContent = true; base.WriteRaw(data); } public override void WriteBase64(byte[] buffer, int index, int count) { - mixedContent = true; + _mixedContent = true; base.WriteBase64(buffer, index, count); } @@ -2171,25 +2171,25 @@ namespace System.Xml // private void Init(XmlWriterSettings settings) { - indentLevel = 0; - indentChars = settings.IndentChars; - newLineOnAttributes = settings.NewLineOnAttributes; + _indentLevel = 0; + _indentChars = settings.IndentChars; + _newLineOnAttributes = settings.NewLineOnAttributes; _mixedContentStack = new BitStack(); // check indent characters that they are valid XML characters - if (base.checkCharacters) + if (base._checkCharacters) { - if (newLineOnAttributes) + if (_newLineOnAttributes) { - base.ValidateContentChars(indentChars, "IndentChars", true); - base.ValidateContentChars(newLineChars, "NewLineChars", true); + base.ValidateContentChars(_indentChars, "IndentChars", true); + base.ValidateContentChars(_newLineChars, "NewLineChars", true); } else { - base.ValidateContentChars(indentChars, "IndentChars", false); - if (base.newLineHandling != NewLineHandling.Replace) + base.ValidateContentChars(_indentChars, "IndentChars", false); + if (base._newLineHandling != NewLineHandling.Replace) { - base.ValidateContentChars(newLineChars, "NewLineChars", false); + base.ValidateContentChars(_newLineChars, "NewLineChars", false); } } } @@ -2198,10 +2198,10 @@ namespace System.Xml // Add indentation to output. Write newline and then repeat IndentChars for each indent level. private void WriteIndent() { - RawText(base.newLineChars); - for (int i = indentLevel; i > 0; i--) + RawText(base._newLineChars); + for (int i = _indentLevel; i > 0; i--) { - RawText(indentChars); + RawText(_indentChars); } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude index a87f83b553c79..f5ce13f095197 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawTextWriterGeneratorAsync.ttinclude @@ -37,7 +37,7 @@ namespace System.Xml { CheckAsyncCall(); // Output xml declaration only if user allows it and it was not already output - if (!omitXmlDeclaration && !autoXmlDeclaration) + if (!_omitXmlDeclaration && !_autoXmlDeclaration) {<# /* Code block is to squash extra line. */ #><#= SetTextContentMark(4, 1, false) #> await RawTextAsync(" - else if (writer != null) + else if (_writer != null) { try { - await writer.FlushAsync().ConfigureAwait(false); + await _writer.FlushAsync().ConfigureAwait(false); } finally { try { - if (closeOutput) + if (_closeOutput) { - await writer.DisposeAsync().ConfigureAwait(false); + await _writer.DisposeAsync().ConfigureAwait(false); } } finally { - writer = null; + _writer = null; } } } @@ -152,27 +152,27 @@ namespace System.Xml { await RawTextAsync(sysid).ConfigureAwait(false); } - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"'; } else if (sysid != null) { await RawTextAsync(" SYSTEM \"").ConfigureAwait(false); await RawTextAsync(sysid).ConfigureAwait(false); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"'; } else { - <#= BufferName #>[bufPos++] = (<#= BufferType #>)' '; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)' '; } if (subset != null) { - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'['; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'['; await RawTextAsync(subset).ConfigureAwait(false); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)']'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)']'; } - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'>'; } // Serialize the beginning of an element start tag: "<#= SetTextContentMark(3, false) #> Task task; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'<'; if (prefix != null && prefix.Length != 0) { task = RawTextAsync(prefix, ":", localName); @@ -199,7 +199,7 @@ namespace System.Xml private void WriteStartElementAsync_SetAttEndPos() { - attrEndPos = bufPos; + _attrEndPos = _bufPos; } // Serialize an element end tag: "", if content was output. Otherwise, serialize @@ -212,11 +212,11 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - if (contentPos != bufPos) + if (_contentPos != _bufPos) { // Content has been output, so can't use shortcut syntax - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'/'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'<'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'/'; if (prefix != null && prefix.Length != 0) { @@ -230,10 +230,10 @@ namespace System.Xml else { // Use shortcut syntax; overwrite the already output '>' character - bufPos--; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)' '; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'/'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>'; + _bufPos--; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)' '; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'/'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'>'; } return Task.CompletedTask; } @@ -247,8 +247,8 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'/'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'<'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'/'; if (prefix != null && prefix.Length != 0) { @@ -269,9 +269,9 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - if (attrEndPos == bufPos) + if (_attrEndPos == _bufPos) { - <#= BufferName #>[bufPos++] = (<#= BufferType #>)' '; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)' '; } Task task; if (prefix != null && prefix.Length > 0) @@ -287,9 +287,9 @@ namespace System.Xml private void WriteStartAttribute_SetInAttribute() { - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'='; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"'; - inAttributeValue = true; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'='; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"'; + _inAttributeValue = true; } // Serialize the end of an attribute value using double quotes: '"' @@ -299,9 +299,9 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"'; - inAttributeValue = false; - attrEndPos = bufPos; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"'; + _inAttributeValue = false; + _attrEndPos = _bufPos; return Task.CompletedTask; } @@ -331,11 +331,11 @@ namespace System.Xml { await RawTextAsync(" xmlns:").ConfigureAwait(false); await RawTextAsync(prefix).ConfigureAwait(false); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'='; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'='; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"'; } - inAttributeValue = true;<# + _inAttributeValue = true;<# #><#= SetTextContentMark(3, true) #> } @@ -345,10 +345,10 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - inAttributeValue = false; + _inAttributeValue = false; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'"'; - attrEndPos = bufPos; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'"'; + _attrEndPos = _bufPos; return Task.CompletedTask; } @@ -362,34 +362,34 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - if (mergeCDataSections && bufPos == cdataPos) + if (_mergeCDataSections && _bufPos == _cdataPos) { // Merge adjacent cdata sections - overwrite the "]]>" characters - Debug.Assert(bufPos >= 4); - bufPos -= 3; + Debug.Assert(_bufPos >= 4); + _bufPos -= 3; } else { // Start a new cdata section - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'!'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'['; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'C'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'D'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'A'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'T'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'A'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'['; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'<'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'!'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'['; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'C'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'D'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'A'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'T'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'A'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'['; } await WriteCDataSectionAsync(text).ConfigureAwait(false); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)']'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)']'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)']'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)']'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'>'; - textPos = bufPos; - cdataPos = bufPos; + _textPos = _bufPos; + _cdataPos = _bufPos; } // Serialize a comment. @@ -400,16 +400,16 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'!'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'<'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'!'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'-'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'-'; await WriteCommentOrPiAsync(text, '-').ConfigureAwait(false); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'-'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'-'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'-'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'>'; } // Serialize a processing instruction. @@ -421,18 +421,18 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'<'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'?'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'<'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'?'; await RawTextAsync(name).ConfigureAwait(false); if (text.Length > 0) { - <#= BufferName #>[bufPos++] = (<#= BufferType #>)' '; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)' '; await WriteCommentOrPiAsync(text, '?').ConfigureAwait(false); } - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'?'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'>'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'?'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'>'; } // Serialize an entity reference. @@ -443,16 +443,16 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'&'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'&'; await RawTextAsync(name).ConfigureAwait(false); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)';'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)';'; - if (bufPos > bufLen) + if (_bufPos > _bufLen) { await FlushBufferAsync().ConfigureAwait(false); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize a character entity reference. @@ -461,7 +461,7 @@ namespace System.Xml CheckAsyncCall(); string strVal = ((int)ch).ToString("X", NumberFormatInfo.InvariantInfo); - if (checkCharacters && !xmlCharType.IsCharData(ch)) + if (_checkCharacters && !_xmlCharType.IsCharData(ch)) { // we just have a single char, not a surrogate, therefore we have to pass in '\0' for the second char throw XmlConvert.CreateInvalidCharException(ch, '\0'); @@ -469,18 +469,18 @@ namespace System.Xml #><#= SetTextContentMark(3, false) #> - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'&'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'#'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'x'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'&'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'#'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'x'; await RawTextAsync(strVal).ConfigureAwait(false); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)';'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)';'; - if (bufPos > bufLen) + if (_bufPos > _bufLen) { await FlushBufferAsync().ConfigureAwait(false); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize a whitespace node. @@ -491,7 +491,7 @@ namespace System.Xml Debug.Assert(ws != null);<# #><#= SetTextContentMark(3, false) #> - if (inAttributeValue) + if (_inAttributeValue) { return WriteAttributeTextBlockAsync(ws); } @@ -509,7 +509,7 @@ namespace System.Xml Debug.Assert(text != null);<# #><#= SetTextContentMark(3, true) #> - if (inAttributeValue) + if (_inAttributeValue) { return WriteAttributeTextBlockAsync(text); } @@ -527,12 +527,12 @@ namespace System.Xml int surrogateChar = XmlCharType.CombineSurrogateChar(lowChar, highChar); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'&'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'#'; - <#= BufferName #>[bufPos++] = (<#= BufferType #>)'x'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'&'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'#'; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)'x'; await RawTextAsync(surrogateChar.ToString("X", NumberFormatInfo.InvariantInfo)).ConfigureAwait(false); - <#= BufferName #>[bufPos++] = (<#= BufferType #>)';'; - textPos = bufPos; + <#= BufferName #>[_bufPos++] = (<#= BufferType #>)';'; + _textPos = _bufPos; } // Serialize either attribute or element text using XML rules. @@ -547,7 +547,7 @@ namespace System.Xml #><#= SetTextContentMark(3, true) #> - if (inAttributeValue) + if (_inAttributeValue) { return WriteAttributeTextBlockAsync(buffer, index, count); } @@ -571,7 +571,7 @@ namespace System.Xml await WriteRawWithCharCheckingAsync(buffer, index, count).ConfigureAwait(false); - textPos = bufPos; + _textPos = _bufPos; } // Serialize raw data. @@ -585,7 +585,7 @@ namespace System.Xml await WriteRawWithCharCheckingAsync(data).ConfigureAwait(false); - textPos = bufPos; + _textPos = _bufPos; } // Flush all characters in the buffer to output and call Flush() on the output object. @@ -597,14 +597,14 @@ namespace System.Xml await FlushEncoderAsync().ConfigureAwait(false); <# } #> - if (stream != null) + if (_stream != null) { - await stream.FlushAsync().ConfigureAwait(false); + await _stream.FlushAsync().ConfigureAwait(false); } <# if (WriterType == RawTextWriterType.Encoded) { #> - else if (writer != null) + else if (_writer != null) { - await writer.FlushAsync().ConfigureAwait(false); + await _writer.FlushAsync().ConfigureAwait(false); } <# } #> } @@ -618,20 +618,20 @@ namespace System.Xml try { // Output all characters (except for previous characters stored at beginning of buffer) - if (!writeToNull) + if (!_writeToNull) { <# if (WriterType == RawTextWriterType.Utf8) { #> - if (bufPos - 1 > 0) + if (_bufPos - 1 > 0) { - Debug.Assert(stream != null); - await stream.WriteAsync(bufBytes.AsMemory(1, bufPos - 1)).ConfigureAwait(false); + Debug.Assert(_stream != null); + await _stream.WriteAsync(_bufBytes.AsMemory(1, _bufPos - 1)).ConfigureAwait(false); } <# } else { #> - Debug.Assert(stream != null || writer != null); + Debug.Assert(_stream != null || _writer != null); - if (stream != null) + if (_stream != null) { - if (trackTextContent) + if (_trackTextContent) { _charEntityFallback.Reset(_textContentMarks, _lastMarkPos); // reset text content tracking @@ -649,14 +649,14 @@ namespace System.Xml } Debug.Assert(_textContentMarks[0] == 1); } - await EncodeCharsAsync(1, bufPos, true).ConfigureAwait(false); + await EncodeCharsAsync(1, _bufPos, true).ConfigureAwait(false); } else { - if (bufPos - 1 > 0) + if (_bufPos - 1 > 0) { // Write text to TextWriter - await writer.WriteAsync(<#= BufferName #>.AsMemory(1, bufPos - 1)).ConfigureAwait(false); + await _writer.WriteAsync(<#= BufferName #>.AsMemory(1, _bufPos - 1)).ConfigureAwait(false); } } <# } #> @@ -665,31 +665,31 @@ namespace System.Xml catch { // Future calls to flush (i.e. when Close() is called) don't attempt to write to stream - writeToNull = true; + _writeToNull = true; throw; } finally { // Move last buffer character to the beginning of the buffer (so that previous character can always be determined) - <#= BufferName #>[0] = <#= BufferName #>[bufPos - 1]; + <#= BufferName #>[0] = <#= BufferName #>[_bufPos - 1]; <# if (WriterType == RawTextWriterType.Utf8) { #> - if (IsSurrogateByte(bufBytes[0])) + if (IsSurrogateByte(_bufBytes[0])) { // Last character was the first byte in a surrogate encoding, so move last three // bytes of encoding to the beginning of the buffer. - bufBytes[1] = bufBytes[bufPos]; - bufBytes[2] = bufBytes[bufPos + 1]; - bufBytes[3] = bufBytes[bufPos + 2]; + _bufBytes[1] = _bufBytes[_bufPos]; + _bufBytes[2] = _bufBytes[_bufPos + 1]; + _bufBytes[3] = _bufBytes[_bufPos + 2]; } <# } #> // Reset buffer position - textPos = (textPos == bufPos) ? 1 : 0; - attrEndPos = (attrEndPos == bufPos) ? 1 : 0; - contentPos = 0; // Needs to be zero, since overwriting '>' character is no longer possible - cdataPos = 0; // Needs to be zero, since overwriting ']]>' characters is no longer possible - bufPos = 1; // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to + _textPos = (_textPos == _bufPos) ? 1 : 0; + _attrEndPos = (_attrEndPos == _bufPos) ? 1 : 0; + _contentPos = 0; // Needs to be zero, since overwriting '>' character is no longer possible + _cdataPos = 0; // Needs to be zero, since overwriting ']]>' characters is no longer possible + _bufPos = 1; // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to // close an empty element or in CDATA section detection of double ]; _BUFFER[0] will always be 0 } } @@ -706,35 +706,35 @@ namespace System.Xml { _charEntityFallback.StartOffset = startOffset; } - encoder.Convert(<#= BufferName #>, startOffset, endOffset - startOffset, bufBytes, bufBytesUsed, bufBytes.Length - bufBytesUsed, false, out chEnc, out bEnc, out completed); + _encoder.Convert(<#= BufferName #>, startOffset, endOffset - startOffset, _bufBytes, _bufBytesUsed, _bufBytes.Length - _bufBytesUsed, false, out chEnc, out bEnc, out completed); startOffset += chEnc; - bufBytesUsed += bEnc; - if (bufBytesUsed >= (bufBytes.Length - 16)) + _bufBytesUsed += bEnc; + if (_bufBytesUsed >= (_bufBytes.Length - 16)) { - await stream.WriteAsync(bufBytes.AsMemory(0, bufBytesUsed)).ConfigureAwait(false); - bufBytesUsed = 0; + await _stream.WriteAsync(_bufBytes.AsMemory(0, _bufBytesUsed)).ConfigureAwait(false); + _bufBytesUsed = 0; } } - if (writeAllToStream && bufBytesUsed > 0) + if (writeAllToStream && _bufBytesUsed > 0) { - await stream.WriteAsync(bufBytes.AsMemory(0, bufBytesUsed)).ConfigureAwait(false); - bufBytesUsed = 0; + await _stream.WriteAsync(_bufBytes.AsMemory(0, _bufBytesUsed)).ConfigureAwait(false); + _bufBytesUsed = 0; } } private Task FlushEncoderAsync() { - Debug.Assert(bufPos == 1); - if (stream != null) + Debug.Assert(_bufPos == 1); + if (_stream != null) { int chEnc; int bEnc; bool completed; // decode no chars, just flush - encoder.Convert(<#= BufferName #>, 1, 0, bufBytes, 0, bufBytes.Length, true, out chEnc, out bEnc, out completed); + _encoder.Convert(<#= BufferName #>, 1, 0, _bufBytes, 0, _bufBytes.Length, true, out chEnc, out bEnc, out completed); if (bEnc != 0) { - return stream.WriteAsync(bufBytes, 0, bEnc); + return _stream.WriteAsync(_bufBytes, 0, bEnc); } } @@ -750,21 +750,21 @@ namespace System.Xml fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>) { - <#= BufferType #>* pDst = pDstBegin + bufPos; + <#= BufferType #>* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } <# if (WriterType == RawTextWriterType.Utf8) { #> - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) <# } else { #> - while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) + while (pDst < pDstEnd && _xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) <# } #> { *pDst = (<#= BufferType #>)ch; @@ -782,7 +782,7 @@ namespace System.Xml // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -806,7 +806,7 @@ namespace System.Xml pDst++; break; case (char)0x9: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (<#= BufferType #>)ch; pDst++; @@ -818,7 +818,7 @@ namespace System.Xml } break; case (char)0xD: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (<#= BufferType #>)ch; pDst++; @@ -830,7 +830,7 @@ namespace System.Xml } break; case (char)0xA: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (<#= BufferType #>)ch; pDst++; @@ -847,7 +847,7 @@ namespace System.Xml } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -940,21 +940,21 @@ namespace System.Xml fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>) { - <#= BufferType #>* pDst = pDstBegin + bufPos; + <#= BufferType #>* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } <# if (WriterType == RawTextWriterType.Utf8) { #> - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) <# } else { #> - while (pDst < pDstEnd && xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) + while (pDst < pDstEnd && _xmlCharType.IsAttributeValueChar((char)(ch = *pSrc))) <# } #> { *pDst = (<#= BufferType #>)ch; @@ -972,7 +972,7 @@ namespace System.Xml // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -995,9 +995,9 @@ namespace System.Xml pDst++; break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1008,7 +1008,7 @@ namespace System.Xml } break; case (char)0xD: - switch (newLineHandling) + switch (_newLineHandling) { case NewLineHandling.Replace: // Replace "\r\n", or "\r" with NewLineChars @@ -1017,7 +1017,7 @@ namespace System.Xml pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); @@ -1037,9 +1037,9 @@ namespace System.Xml } pSrc++; } - bufPos = (int)(pDst - pDstBegin); - textPos = bufPos; - contentPos = 0; + _bufPos = (int)(pDst - pDstBegin); + _textPos = _bufPos; + _contentPos = 0; } return -1; @@ -1050,7 +1050,7 @@ namespace System.Xml needWriteNewLine = false; if (count == 0) { - contentPos = 0; + _contentPos = 0; return -1; } fixed (char* pSrc = &chars[index]) @@ -1066,7 +1066,7 @@ namespace System.Xml needWriteNewLine = false; if (count == 0) { - contentPos = 0; + _contentPos = 0; return -1; } fixed (char* pSrc = text) @@ -1091,7 +1091,7 @@ namespace System.Xml if (needWriteNewLine) { //hit WriteNewLine - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1131,7 +1131,7 @@ namespace System.Xml if (newLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1148,7 +1148,7 @@ namespace System.Xml if (needWriteNewLine) { //hit WriteNewLine - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1165,16 +1165,16 @@ namespace System.Xml fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>) { - <#= BufferType #>* pDst = pDstBegin + bufPos; + <#= BufferType #>* pDst = pDstBegin + _bufPos; char* pSrc = pSrcBegin; int ch = 0; while (true) { <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } <# if (WriterType == RawTextWriterType.Utf8) { #> @@ -1198,14 +1198,14 @@ namespace System.Xml // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } <#= EncodeChar(5, false) #> } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -1327,21 +1327,21 @@ namespace System.Xml fixed (<#= BufferType #>* pDstBegin = <#= BufferName #>) { char* pSrc = pSrcBegin; - <#= BufferType #>* pDst = pDstBegin + bufPos; + <#= BufferType #>* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } <# if (WriterType == RawTextWriterType.Utf8) { #> - while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch <= 0x7F)) <# } else { #> - while (pDst < pDstEnd && xmlCharType.IsTextChar((char)(ch = *pSrc))) + while (pDst < pDstEnd && _xmlCharType.IsTextChar((char)(ch = *pSrc))) <# } #> { *pDst = (<#= BufferType #>)ch; @@ -1360,7 +1360,7 @@ namespace System.Xml // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -1375,7 +1375,7 @@ namespace System.Xml pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1383,7 +1383,7 @@ namespace System.Xml pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1394,9 +1394,9 @@ namespace System.Xml } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1412,7 +1412,7 @@ namespace System.Xml } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -1461,7 +1461,7 @@ namespace System.Xml leftCount -= writeLen; if (needWriteNewLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1485,7 +1485,7 @@ namespace System.Xml leftCount -= writeLen; if (needWriteNewLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1515,21 +1515,21 @@ namespace System.Xml char* pSrcEnd = pSrcBegin + count; - <#= BufferType #>* pDst = pDstBegin + bufPos; + <#= BufferType #>* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } <# if (WriterType == RawTextWriterType.Utf8) { #> - while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar && ch <= 0x7F)) <# } else { #> - while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar)) + while (pDst < pDstEnd && (_xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar)) <# } #> { *pDst = (<#= BufferType #>)ch; @@ -1548,7 +1548,7 @@ namespace System.Xml // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -1586,7 +1586,7 @@ namespace System.Xml pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1594,7 +1594,7 @@ namespace System.Xml pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1605,9 +1605,9 @@ namespace System.Xml } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1629,7 +1629,7 @@ namespace System.Xml } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -1640,7 +1640,7 @@ namespace System.Xml { if (text.Length == 0) { - if (bufPos >= bufLen) + if (_bufPos >= _bufLen) { await FlushBufferAsync().ConfigureAwait(false); } @@ -1658,7 +1658,7 @@ namespace System.Xml leftCount -= writeLen; if (needWriteNewLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1691,21 +1691,21 @@ namespace System.Xml char* pRaw = pSrc; - <#= BufferType #>* pDst = pDstBegin + bufPos; + <#= BufferType #>* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { <#= BufferType #>* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } <# if (WriterType == RawTextWriterType.Utf8) { #> - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']' && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']' && ch <= 0x7F)) <# } else { #> - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']')) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']')) <# } #> { *pDst = (<#= BufferType #>)ch; @@ -1724,7 +1724,7 @@ namespace System.Xml // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -1732,7 +1732,7 @@ namespace System.Xml switch (ch) { case '>': - if (hadDoubleBracket && pDst[-1] == (<#= BufferType #>)']') + if (_hadDoubleBracket && pDst[-1] == (<#= BufferType #>)']') { // pDst[-1] will always correct - there is a padding character at _BUFFER[0] // The characters "]]>" were found within the CData text pDst = RawEndCData(pDst); @@ -1744,17 +1744,17 @@ namespace System.Xml case ']': if (pDst[-1] == (<#= BufferType #>)']') { // pDst[-1] will always correct - there is a padding character at _BUFFER[0] - hadDoubleBracket = true; + _hadDoubleBracket = true; } else { - hadDoubleBracket = false; + _hadDoubleBracket = false; } *pDst = (<#= BufferType #>)']'; pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1762,7 +1762,7 @@ namespace System.Xml pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1773,9 +1773,9 @@ namespace System.Xml } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1799,7 +1799,7 @@ namespace System.Xml } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -1810,7 +1810,7 @@ namespace System.Xml { if (text.Length == 0) { - if (bufPos >= bufLen) + if (_bufPos >= _bufLen) { await FlushBufferAsync().ConfigureAwait(false); } @@ -1828,7 +1828,7 @@ namespace System.Xml leftCount -= writeLen; if (needWriteNewLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1847,7 +1847,7 @@ namespace System.Xml { CheckAsyncCall(); // Add indentation - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } @@ -1860,12 +1860,12 @@ namespace System.Xml Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null); // Add indentation - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } - indentLevel++; - _mixedContentStack.PushBit(mixedContent); + _indentLevel++; + _mixedContentStack.PushBit(_mixedContent); await base.WriteStartElementAsync(prefix, localName, ns).ConfigureAwait(false); } @@ -1874,16 +1874,16 @@ namespace System.Xml { CheckAsyncCall(); // Add indentation - indentLevel--; - if (!mixedContent && base.contentPos != base.bufPos) + _indentLevel--; + if (!_mixedContent && base._contentPos != base._bufPos) { // There was content, so try to indent - if (base.textPos != base.bufPos) + if (base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } } - mixedContent = _mixedContentStack.PopBit(); + _mixedContent = _mixedContentStack.PopBit(); await base.WriteEndElementAsync(prefix, localName, ns).ConfigureAwait(false); } @@ -1892,16 +1892,16 @@ namespace System.Xml { CheckAsyncCall(); // Add indentation - indentLevel--; - if (!mixedContent && base.contentPos != base.bufPos) + _indentLevel--; + if (!_mixedContent && base._contentPos != base._bufPos) { // There was content, so try to indent - if (base.textPos != base.bufPos) + if (base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } } - mixedContent = _mixedContentStack.PopBit(); + _mixedContent = _mixedContentStack.PopBit(); await base.WriteFullEndElementAsync(prefix, localName, ns).ConfigureAwait(false); } @@ -1911,7 +1911,7 @@ namespace System.Xml { CheckAsyncCall(); // Add indentation - if (newLineOnAttributes) + if (_newLineOnAttributes) { await WriteIndentAsync().ConfigureAwait(false); } @@ -1922,14 +1922,14 @@ namespace System.Xml public override Task WriteCDataAsync(string text) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteCDataAsync(text); } public override async Task WriteCommentAsync(string text) { CheckAsyncCall(); - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } @@ -1940,7 +1940,7 @@ namespace System.Xml public override async Task WriteProcessingInstructionAsync(string target, string text) { CheckAsyncCall(); - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } @@ -1951,63 +1951,63 @@ namespace System.Xml public override Task WriteEntityRefAsync(string name) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteEntityRefAsync(name); } public override Task WriteCharEntityAsync(char ch) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteCharEntityAsync(ch); } public override Task WriteSurrogateCharEntityAsync(char lowChar, char highChar) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteSurrogateCharEntityAsync(lowChar, highChar); } public override Task WriteWhitespaceAsync(string ws) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteWhitespaceAsync(ws); } public override Task WriteStringAsync(string text) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteStringAsync(text); } public override Task WriteCharsAsync(char[] buffer, int index, int count) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteCharsAsync(buffer, index, count); } public override Task WriteRawAsync(char[] buffer, int index, int count) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteRawAsync(buffer, index, count); } public override Task WriteRawAsync(string data) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteRawAsync(data); } public override Task WriteBase64Async(byte[] buffer, int index, int count) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteBase64Async(buffer, index, count); } @@ -2015,10 +2015,10 @@ namespace System.Xml private async Task WriteIndentAsync() { CheckAsyncCall(); - await RawTextAsync(base.newLineChars).ConfigureAwait(false); - for (int i = indentLevel; i > 0; i--) + await RawTextAsync(base._newLineChars).ConfigureAwait(false); + for (int i = _indentLevel; i > 0; i--) { - await RawTextAsync(indentChars).ConfigureAwait(false); + await RawTextAsync(_indentChars).ConfigureAwait(false); } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs index 81f8a09aad9bc..e9d8937b34913 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriter.cs @@ -44,10 +44,10 @@ internal abstract partial class XmlRawWriter : XmlWriter // Fields // // base64 converter - protected XmlRawWriterBase64Encoder? base64Encoder; + protected XmlRawWriterBase64Encoder? _base64Encoder; // namespace resolver - protected IXmlNamespaceResolver? resolver; + protected IXmlNamespaceResolver? _resolver; // // XmlWriter implementation @@ -88,13 +88,13 @@ public override void WriteFullEndElement() // By default, convert base64 value to string and call WriteString. public override void WriteBase64(byte[] buffer, int index, int count) { - if (base64Encoder == null) + if (_base64Encoder == null) { - base64Encoder = new XmlRawWriterBase64Encoder(this); + _base64Encoder = new XmlRawWriterBase64Encoder(this); } // Encode will call WriteRaw to write out the encoded characters - base64Encoder.Encode(buffer, index, count); + _base64Encoder.Encode(buffer, index, count); } // Raw writers do not have to keep track of namespaces. @@ -193,7 +193,7 @@ public override void WriteValue(object? value) throw new ArgumentNullException(nameof(value)); } - WriteString(XmlUntypedConverter.Untyped.ToString(value, resolver)); + WriteString(XmlUntypedConverter.Untyped.ToString(value, _resolver)); } // Override in order to handle Xml simple typed values and to pass resolver for QName values @@ -234,11 +234,11 @@ public override void WriteNode(System.Xml.XPath.XPathNavigator navigator, bool d { get { - return resolver; + return _resolver; } set { - resolver = value; + _resolver = value; } } @@ -315,8 +315,8 @@ internal virtual void WriteEndNamespaceDeclaration() internal virtual void WriteEndBase64() { // The Flush will call WriteRaw to write out the rest of the encoded characters - Debug.Assert(base64Encoder != null); - base64Encoder.Flush(); + Debug.Assert(_base64Encoder != null); + _base64Encoder.Flush(); } internal virtual void Close(WriteState currentState) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs index 61a23299b99da..c668e07932fb7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlRawWriterAsync.cs @@ -81,12 +81,12 @@ public override Task WriteFullEndElementAsync() // By default, convert base64 value to string and call WriteString. public override Task WriteBase64Async(byte[] buffer, int index, int count) { - if (base64Encoder == null) + if (_base64Encoder == null) { - base64Encoder = new XmlRawWriterBase64Encoder(this); + _base64Encoder = new XmlRawWriterBase64Encoder(this); } // Encode will call WriteRaw to write out the encoded characters - return base64Encoder.EncodeAsync(buffer, index, count); + return _base64Encoder.EncodeAsync(buffer, index, count); } // Raw writers do not have to verify NmToken values. @@ -226,8 +226,8 @@ internal virtual Task WriteEndNamespaceDeclarationAsync() internal virtual Task WriteEndBase64Async() { // The Flush will call WriteRaw to write out the rest of the encoded characters - Debug.Assert(base64Encoder != null); - return base64Encoder.FlushAsync(); + Debug.Assert(_base64Encoder != null); + return _base64Encoder.FlushAsync(); } internal virtual ValueTask DisposeAsyncCore(WriteState currentState) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs index 3781b016706e5..dddd35f6ceeda 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriter.cs @@ -26,44 +26,44 @@ internal partial class XmlUtf8RawTextWriter : XmlRawWriter private readonly bool _useAsync; // main buffer - protected byte[] bufBytes; + protected byte[] _bufBytes; // output stream - protected Stream stream; + protected Stream _stream; // encoding of the stream or text writer - protected Encoding encoding; + protected Encoding _encoding; // char type tables - protected XmlCharType xmlCharType = XmlCharType.Instance; + protected XmlCharType _xmlCharType = XmlCharType.Instance; // buffer positions - protected int bufPos = 1; // buffer position starts at 1, because we need to be able to safely step back -1 in case we need to - // close an empty element or in CDATA section detection of double ]; bufBytes[0] will always be 0 - protected int textPos = 1; // text end position; don't indent first element, pi, or comment - protected int contentPos; // element content end position - protected int cdataPos; // cdata end position - protected int attrEndPos; // end of the last attribute - protected int bufLen = BUFSIZE; + protected int _bufPos = 1; // buffer position starts at 1, because we need to be able to safely step back -1 in case we need to + // close an empty element or in CDATA section detection of double ]; bufBytes[0] will always be 0 + protected int _textPos = 1; // text end position; don't indent first element, pi, or comment + protected int _contentPos; // element content end position + protected int _cdataPos; // cdata end position + protected int _attrEndPos; // end of the last attribute + protected int _bufLen = BUFSIZE; // flags - protected bool writeToNull; - protected bool hadDoubleBracket; - protected bool inAttributeValue; + protected bool _writeToNull; + protected bool _hadDoubleBracket; + protected bool _inAttributeValue; // writer settings - protected NewLineHandling newLineHandling; - protected bool closeOutput; - protected bool omitXmlDeclaration; - protected string newLineChars; - protected bool checkCharacters; + protected NewLineHandling _newLineHandling; + protected bool _closeOutput; + protected bool _omitXmlDeclaration; + protected string _newLineChars; + protected bool _checkCharacters; - protected XmlStandalone standalone; - protected XmlOutputMethod outputMethod; + protected XmlStandalone _standalone; + protected XmlOutputMethod _outputMethod; - protected bool autoXmlDeclaration; - protected bool mergeCDataSections; + protected bool _autoXmlDeclaration; + protected bool _mergeCDataSections; // // Constants @@ -81,19 +81,19 @@ protected XmlUtf8RawTextWriter(XmlWriterSettings settings) _useAsync = settings.Async; // copy settings - newLineHandling = settings.NewLineHandling; - omitXmlDeclaration = settings.OmitXmlDeclaration; - newLineChars = settings.NewLineChars; - checkCharacters = settings.CheckCharacters; - closeOutput = settings.CloseOutput; + _newLineHandling = settings.NewLineHandling; + _omitXmlDeclaration = settings.OmitXmlDeclaration; + _newLineChars = settings.NewLineChars; + _checkCharacters = settings.CheckCharacters; + _closeOutput = settings.CloseOutput; - standalone = settings.Standalone; - outputMethod = settings.OutputMethod; - mergeCDataSections = settings.MergeCDataSections; + _standalone = settings.Standalone; + _outputMethod = settings.OutputMethod; + _mergeCDataSections = settings.MergeCDataSections; - if (checkCharacters && newLineHandling == NewLineHandling.Replace) + if (_checkCharacters && _newLineHandling == NewLineHandling.Replace) { - ValidateContentChars(newLineChars, "NewLineChars", false); + ValidateContentChars(_newLineChars, "NewLineChars", false); } } @@ -102,33 +102,33 @@ public XmlUtf8RawTextWriter(Stream stream, XmlWriterSettings settings) : this(se { Debug.Assert(stream != null && settings != null); - this.stream = stream; - this.encoding = settings.Encoding; + this._stream = stream; + this._encoding = settings.Encoding; // the buffer is allocated will OVERFLOW in order to reduce checks when writing out constant size markup if (settings.Async) { - bufLen = ASYNCBUFSIZE; + _bufLen = ASYNCBUFSIZE; } - bufBytes = new byte[bufLen + OVERFLOW]; + _bufBytes = new byte[_bufLen + OVERFLOW]; // Output UTF-8 byte order mark if Encoding object wants it if (!stream.CanSeek || stream.Position == 0) { - ReadOnlySpan bom = encoding.Preamble; + ReadOnlySpan bom = _encoding.Preamble; if (bom.Length != 0) { - bom.CopyTo(new Span(bufBytes).Slice(1)); - bufPos += bom.Length; - textPos += bom.Length; + bom.CopyTo(new Span(_bufBytes).Slice(1)); + _bufPos += bom.Length; + _textPos += bom.Length; } } // Write the xml declaration if (settings.AutoXmlDeclaration) { - WriteXmlDeclaration(standalone); - autoXmlDeclaration = true; + WriteXmlDeclaration(_standalone); + _autoXmlDeclaration = true; } } @@ -142,17 +142,17 @@ public override XmlWriterSettings Settings { XmlWriterSettings settings = new XmlWriterSettings(); - settings.Encoding = encoding; - settings.OmitXmlDeclaration = omitXmlDeclaration; - settings.NewLineHandling = newLineHandling; - settings.NewLineChars = newLineChars; - settings.CloseOutput = closeOutput; + settings.Encoding = _encoding; + settings.OmitXmlDeclaration = _omitXmlDeclaration; + settings.NewLineHandling = _newLineHandling; + settings.NewLineChars = _newLineChars; + settings.CloseOutput = _closeOutput; settings.ConformanceLevel = ConformanceLevel.Auto; - settings.CheckCharacters = checkCharacters; + settings.CheckCharacters = _checkCharacters; - settings.AutoXmlDeclaration = autoXmlDeclaration; - settings.Standalone = standalone; - settings.OutputMethod = outputMethod; + settings.AutoXmlDeclaration = _autoXmlDeclaration; + settings.Standalone = _standalone; + settings.OutputMethod = _outputMethod; settings.ReadOnly = true; return settings; @@ -163,7 +163,7 @@ public override XmlWriterSettings Settings internal override void WriteXmlDeclaration(XmlStandalone standalone) { // Output xml declaration only if user allows it and it was not already output - if (!omitXmlDeclaration && !autoXmlDeclaration) + if (!_omitXmlDeclaration && !_autoXmlDeclaration) { RawText("'; + _bufBytes[_bufPos++] = (byte)'>'; } // Serialize the beginning of an element start tag: " 0); Debug.Assert(prefix != null); - bufBytes[bufPos++] = (byte)'<'; + _bufBytes[_bufPos++] = (byte)'<'; if (prefix != null && prefix.Length != 0) { RawText(prefix); - bufBytes[bufPos++] = (byte)':'; + _bufBytes[_bufPos++] = (byte)':'; } RawText(localName); - attrEndPos = bufPos; + _attrEndPos = _bufPos; } // Serialize the end of an element start tag in preparation for content serialization: ">" internal override void StartElementContent() { - bufBytes[bufPos++] = (byte)'>'; + _bufBytes[_bufPos++] = (byte)'>'; // StartElementContent is always called; therefore, in order to allow shortcut syntax, we save the // position of the '>' character. If WriteEndElement is called and no other characters have been // output, then the '>' character can be overwritten with the shortcut syntax " />". - contentPos = bufPos; + _contentPos = _bufPos; } // Serialize an element end tag: "", if content was output. Otherwise, serialize @@ -272,27 +272,27 @@ internal override void WriteEndElement(string prefix, string localName, string n Debug.Assert(localName != null && localName.Length > 0); Debug.Assert(prefix != null); - if (contentPos != bufPos) + if (_contentPos != _bufPos) { // Content has been output, so can't use shortcut syntax - bufBytes[bufPos++] = (byte)'<'; - bufBytes[bufPos++] = (byte)'/'; + _bufBytes[_bufPos++] = (byte)'<'; + _bufBytes[_bufPos++] = (byte)'/'; if (prefix != null && prefix.Length != 0) { RawText(prefix); - bufBytes[bufPos++] = (byte)':'; + _bufBytes[_bufPos++] = (byte)':'; } RawText(localName); - bufBytes[bufPos++] = (byte)'>'; + _bufBytes[_bufPos++] = (byte)'>'; } else { // Use shortcut syntax; overwrite the already output '>' character - bufPos--; - bufBytes[bufPos++] = (byte)' '; - bufBytes[bufPos++] = (byte)'/'; - bufBytes[bufPos++] = (byte)'>'; + _bufPos--; + _bufBytes[_bufPos++] = (byte)' '; + _bufBytes[_bufPos++] = (byte)'/'; + _bufBytes[_bufPos++] = (byte)'>'; } } @@ -302,16 +302,16 @@ internal override void WriteFullEndElement(string prefix, string localName, stri Debug.Assert(localName != null && localName.Length > 0); Debug.Assert(prefix != null); - bufBytes[bufPos++] = (byte)'<'; - bufBytes[bufPos++] = (byte)'/'; + _bufBytes[_bufPos++] = (byte)'<'; + _bufBytes[_bufPos++] = (byte)'/'; if (prefix != null && prefix.Length != 0) { RawText(prefix); - bufBytes[bufPos++] = (byte)':'; + _bufBytes[_bufPos++] = (byte)':'; } RawText(localName); - bufBytes[bufPos++] = (byte)'>'; + _bufBytes[_bufPos++] = (byte)'>'; } // Serialize an attribute tag using double quotes around the attribute value: 'prefix:localName="' @@ -320,30 +320,30 @@ public override void WriteStartAttribute(string prefix, string localName, string Debug.Assert(localName != null && localName.Length > 0); Debug.Assert(prefix != null); - if (attrEndPos == bufPos) + if (_attrEndPos == _bufPos) { - bufBytes[bufPos++] = (byte)' '; + _bufBytes[_bufPos++] = (byte)' '; } if (prefix != null && prefix.Length > 0) { RawText(prefix); - bufBytes[bufPos++] = (byte)':'; + _bufBytes[_bufPos++] = (byte)':'; } RawText(localName); - bufBytes[bufPos++] = (byte)'='; - bufBytes[bufPos++] = (byte)'"'; + _bufBytes[_bufPos++] = (byte)'='; + _bufBytes[_bufPos++] = (byte)'"'; - inAttributeValue = true; + _inAttributeValue = true; } // Serialize the end of an attribute value using double quotes: '"' public override void WriteEndAttribute() { - bufBytes[bufPos++] = (byte)'"'; - inAttributeValue = false; - attrEndPos = bufPos; + _bufBytes[_bufPos++] = (byte)'"'; + _inAttributeValue = false; + _attrEndPos = _bufPos; } internal override void WriteNamespaceDeclaration(string prefix, string namespaceName) @@ -375,19 +375,19 @@ internal override void WriteStartNamespaceDeclaration(string prefix) { RawText(" xmlns:"); RawText(prefix); - bufBytes[bufPos++] = (byte)'='; - bufBytes[bufPos++] = (byte)'"'; + _bufBytes[_bufPos++] = (byte)'='; + _bufBytes[_bufPos++] = (byte)'"'; } - inAttributeValue = true; + _inAttributeValue = true; } internal override void WriteEndNamespaceDeclaration() { - inAttributeValue = false; + _inAttributeValue = false; - bufBytes[bufPos++] = (byte)'"'; - attrEndPos = bufPos; + _bufBytes[_bufPos++] = (byte)'"'; + _attrEndPos = _bufPos; } // Serialize a CData section. If the "]]>" pattern is found within @@ -396,34 +396,34 @@ public override void WriteCData(string text) { Debug.Assert(text != null); - if (mergeCDataSections && bufPos == cdataPos) + if (_mergeCDataSections && _bufPos == _cdataPos) { // Merge adjacent cdata sections - overwrite the "]]>" characters - Debug.Assert(bufPos >= 4); - bufPos -= 3; + Debug.Assert(_bufPos >= 4); + _bufPos -= 3; } else { // Start a new cdata section - bufBytes[bufPos++] = (byte)'<'; - bufBytes[bufPos++] = (byte)'!'; - bufBytes[bufPos++] = (byte)'['; - bufBytes[bufPos++] = (byte)'C'; - bufBytes[bufPos++] = (byte)'D'; - bufBytes[bufPos++] = (byte)'A'; - bufBytes[bufPos++] = (byte)'T'; - bufBytes[bufPos++] = (byte)'A'; - bufBytes[bufPos++] = (byte)'['; + _bufBytes[_bufPos++] = (byte)'<'; + _bufBytes[_bufPos++] = (byte)'!'; + _bufBytes[_bufPos++] = (byte)'['; + _bufBytes[_bufPos++] = (byte)'C'; + _bufBytes[_bufPos++] = (byte)'D'; + _bufBytes[_bufPos++] = (byte)'A'; + _bufBytes[_bufPos++] = (byte)'T'; + _bufBytes[_bufPos++] = (byte)'A'; + _bufBytes[_bufPos++] = (byte)'['; } WriteCDataSection(text); - bufBytes[bufPos++] = (byte)']'; - bufBytes[bufPos++] = (byte)']'; - bufBytes[bufPos++] = (byte)'>'; + _bufBytes[_bufPos++] = (byte)']'; + _bufBytes[_bufPos++] = (byte)']'; + _bufBytes[_bufPos++] = (byte)'>'; - textPos = bufPos; - cdataPos = bufPos; + _textPos = _bufPos; + _cdataPos = _bufPos; } // Serialize a comment. @@ -431,16 +431,16 @@ public override void WriteComment(string text) { Debug.Assert(text != null); - bufBytes[bufPos++] = (byte)'<'; - bufBytes[bufPos++] = (byte)'!'; - bufBytes[bufPos++] = (byte)'-'; - bufBytes[bufPos++] = (byte)'-'; + _bufBytes[_bufPos++] = (byte)'<'; + _bufBytes[_bufPos++] = (byte)'!'; + _bufBytes[_bufPos++] = (byte)'-'; + _bufBytes[_bufPos++] = (byte)'-'; WriteCommentOrPi(text, '-'); - bufBytes[bufPos++] = (byte)'-'; - bufBytes[bufPos++] = (byte)'-'; - bufBytes[bufPos++] = (byte)'>'; + _bufBytes[_bufPos++] = (byte)'-'; + _bufBytes[_bufPos++] = (byte)'-'; + _bufBytes[_bufPos++] = (byte)'>'; } // Serialize a processing instruction. @@ -449,18 +449,18 @@ public override void WriteProcessingInstruction(string name, string text) Debug.Assert(name != null && name.Length > 0); Debug.Assert(text != null); - bufBytes[bufPos++] = (byte)'<'; - bufBytes[bufPos++] = (byte)'?'; + _bufBytes[_bufPos++] = (byte)'<'; + _bufBytes[_bufPos++] = (byte)'?'; RawText(name); if (text.Length > 0) { - bufBytes[bufPos++] = (byte)' '; + _bufBytes[_bufPos++] = (byte)' '; WriteCommentOrPi(text, '?'); } - bufBytes[bufPos++] = (byte)'?'; - bufBytes[bufPos++] = (byte)'>'; + _bufBytes[_bufPos++] = (byte)'?'; + _bufBytes[_bufPos++] = (byte)'>'; } // Serialize an entity reference. @@ -468,16 +468,16 @@ public override void WriteEntityRef(string name) { Debug.Assert(name != null && name.Length > 0); - bufBytes[bufPos++] = (byte)'&'; + _bufBytes[_bufPos++] = (byte)'&'; RawText(name); - bufBytes[bufPos++] = (byte)';'; + _bufBytes[_bufPos++] = (byte)';'; - if (bufPos > bufLen) + if (_bufPos > _bufLen) { FlushBuffer(); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize a character entity reference. @@ -485,24 +485,24 @@ public override void WriteCharEntity(char ch) { string strVal = ((int)ch).ToString("X", NumberFormatInfo.InvariantInfo); - if (checkCharacters && !xmlCharType.IsCharData(ch)) + if (_checkCharacters && !_xmlCharType.IsCharData(ch)) { // we just have a single char, not a surrogate, therefore we have to pass in '\0' for the second char throw XmlConvert.CreateInvalidCharException(ch, '\0'); } - bufBytes[bufPos++] = (byte)'&'; - bufBytes[bufPos++] = (byte)'#'; - bufBytes[bufPos++] = (byte)'x'; + _bufBytes[_bufPos++] = (byte)'&'; + _bufBytes[_bufPos++] = (byte)'#'; + _bufBytes[_bufPos++] = (byte)'x'; RawText(strVal); - bufBytes[bufPos++] = (byte)';'; + _bufBytes[_bufPos++] = (byte)';'; - if (bufPos > bufLen) + if (_bufPos > _bufLen) { FlushBuffer(); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize a whitespace node. @@ -514,7 +514,7 @@ public override unsafe void WriteWhitespace(string ws) fixed (char* pSrc = ws) { char* pSrcEnd = pSrc + ws.Length; - if (inAttributeValue) + if (_inAttributeValue) { WriteAttributeTextBlock(pSrc, pSrcEnd); } @@ -534,7 +534,7 @@ public override unsafe void WriteString(string text) fixed (char* pSrc = text) { char* pSrcEnd = pSrc + text.Length; - if (inAttributeValue) + if (_inAttributeValue) { WriteAttributeTextBlock(pSrc, pSrcEnd); } @@ -550,12 +550,12 @@ public override void WriteSurrogateCharEntity(char lowChar, char highChar) { int surrogateChar = XmlCharType.CombineSurrogateChar(lowChar, highChar); - bufBytes[bufPos++] = (byte)'&'; - bufBytes[bufPos++] = (byte)'#'; - bufBytes[bufPos++] = (byte)'x'; + _bufBytes[_bufPos++] = (byte)'&'; + _bufBytes[_bufPos++] = (byte)'#'; + _bufBytes[_bufPos++] = (byte)'x'; RawText(surrogateChar.ToString("X", NumberFormatInfo.InvariantInfo)); - bufBytes[bufPos++] = (byte)';'; - textPos = bufPos; + _bufBytes[_bufPos++] = (byte)';'; + _textPos = _bufPos; } // Serialize either attribute or element text using XML rules. @@ -569,7 +569,7 @@ public override unsafe void WriteChars(char[] buffer, int index, int count) fixed (char* pSrcBegin = &buffer[index]) { - if (inAttributeValue) + if (_inAttributeValue) { WriteAttributeTextBlock(pSrcBegin, pSrcBegin + count); } @@ -594,7 +594,7 @@ public override unsafe void WriteRaw(char[] buffer, int index, int count) WriteRawWithCharChecking(pSrcBegin, pSrcBegin + count); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize raw data. @@ -608,7 +608,7 @@ public override unsafe void WriteRaw(string data) WriteRawWithCharChecking(pSrcBegin, pSrcBegin + data.Length); } - textPos = bufPos; + _textPos = _bufPos; } // Flush all bytes in the buffer to output and close the output stream or writer. @@ -622,26 +622,26 @@ public override void Close() finally { // Future calls to Close or Flush shouldn't write to Stream or Writer - writeToNull = true; + _writeToNull = true; - if (stream != null) + if (_stream != null) { try { - stream.Flush(); + _stream.Flush(); } finally { try { - if (closeOutput) + if (_closeOutput) { - stream.Dispose(); + _stream.Dispose(); } } finally { - stream = null; + _stream = null; } } } @@ -653,9 +653,9 @@ public override void Flush() { FlushBuffer(); FlushEncoder(); - if (stream != null) + if (_stream != null) { - stream.Flush(); + _stream.Flush(); } } @@ -668,40 +668,40 @@ protected virtual void FlushBuffer() try { // Output all characters (except for previous characters stored at beginning of buffer) - if (!writeToNull) + if (!_writeToNull) { - if (bufPos - 1 > 0) + if (_bufPos - 1 > 0) { - Debug.Assert(stream != null); - stream.Write(bufBytes, 1, bufPos - 1); + Debug.Assert(_stream != null); + _stream.Write(_bufBytes, 1, _bufPos - 1); } } } catch { // Future calls to flush (i.e. when Close() is called) don't attempt to write to stream - writeToNull = true; + _writeToNull = true; throw; } finally { // Move last buffer character to the beginning of the buffer (so that previous character can always be determined) - bufBytes[0] = bufBytes[bufPos - 1]; - if (IsSurrogateByte(bufBytes[0])) + _bufBytes[0] = _bufBytes[_bufPos - 1]; + if (IsSurrogateByte(_bufBytes[0])) { // Last character was the first byte in a surrogate encoding, so move last three // bytes of encoding to the beginning of the buffer. - bufBytes[1] = bufBytes[bufPos]; - bufBytes[2] = bufBytes[bufPos + 1]; - bufBytes[3] = bufBytes[bufPos + 2]; + _bufBytes[1] = _bufBytes[_bufPos]; + _bufBytes[2] = _bufBytes[_bufPos + 1]; + _bufBytes[3] = _bufBytes[_bufPos + 2]; } // Reset buffer position - textPos = (textPos == bufPos) ? 1 : 0; - attrEndPos = (attrEndPos == bufPos) ? 1 : 0; - contentPos = 0; // Needs to be zero, since overwriting '>' character is no longer possible - cdataPos = 0; // Needs to be zero, since overwriting ']]>' characters is no longer possible - bufPos = 1; // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to + _textPos = (_textPos == _bufPos) ? 1 : 0; + _attrEndPos = (_attrEndPos == _bufPos) ? 1 : 0; + _contentPos = 0; // Needs to be zero, since overwriting '>' character is no longer possible + _cdataPos = 0; // Needs to be zero, since overwriting ']]>' characters is no longer possible + _bufPos = 1; // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to // close an empty element or in CDATA section detection of double ]; bufBytes[0] will always be 0 } } @@ -716,20 +716,20 @@ private void FlushEncoder() // are entitized. protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) { - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) { *pDst = (byte)ch; pDst++; @@ -746,7 +746,7 @@ protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -772,7 +772,7 @@ protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) pDst++; break; case (char)0x9: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (byte)ch; pDst++; @@ -784,7 +784,7 @@ protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) } break; case (char)0xD: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (byte)ch; pDst++; @@ -796,7 +796,7 @@ protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) } break; case (char)0xA: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (byte)ch; pDst++; @@ -830,7 +830,7 @@ protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -838,20 +838,20 @@ protected unsafe void WriteAttributeTextBlock(char* pSrc, char* pSrcEnd) // are entitized. protected unsafe void WriteElementTextBlock(char* pSrc, char* pSrcEnd) { - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) { *pDst = (byte)ch; pDst++; @@ -868,7 +868,7 @@ protected unsafe void WriteElementTextBlock(char* pSrc, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -893,7 +893,7 @@ protected unsafe void WriteElementTextBlock(char* pSrc, char* pSrcEnd) pDst++; break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { pDst = WriteNewLine(pDst); } @@ -904,7 +904,7 @@ protected unsafe void WriteElementTextBlock(char* pSrc, char* pSrcEnd) } break; case (char)0xD: - switch (newLineHandling) + switch (_newLineHandling) { case NewLineHandling.Replace: // Replace "\r\n", or "\r" with NewLineChars @@ -949,9 +949,9 @@ protected unsafe void WriteElementTextBlock(char* pSrc, char* pSrcEnd) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); - textPos = bufPos; - contentPos = 0; + _bufPos = (int)(pDst - pDstBegin); + _textPos = _bufPos; + _contentPos = 0; } } @@ -967,18 +967,18 @@ protected unsafe void RawText(string s) protected unsafe void RawText(char* pSrcBegin, char* pSrcEnd) { - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; char* pSrc = pSrcBegin; int ch = 0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } while (pDst < pDstEnd && ((ch = *pSrc) <= 0x7F)) @@ -998,7 +998,7 @@ protected unsafe void RawText(char* pSrcBegin, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1024,27 +1024,27 @@ protected unsafe void RawText(char* pSrcBegin, char* pSrcEnd) } } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } protected unsafe void WriteRawWithCharChecking(char* pSrcBegin, char* pSrcEnd) { - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { char* pSrc = pSrcBegin; - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch <= 0x7F)) { *pDst = (byte)ch; pDst++; @@ -1062,7 +1062,7 @@ protected unsafe void WriteRawWithCharChecking(char* pSrcBegin, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1079,7 +1079,7 @@ protected unsafe void WriteRawWithCharChecking(char* pSrcBegin, char* pSrcEnd) pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1096,7 +1096,7 @@ protected unsafe void WriteRawWithCharChecking(char* pSrcBegin, char* pSrcEnd) } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { pDst = WriteNewLine(pDst); } @@ -1129,7 +1129,7 @@ protected unsafe void WriteRawWithCharChecking(char* pSrcBegin, char* pSrcEnd) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -1137,7 +1137,7 @@ protected unsafe void WriteCommentOrPi(string text, int stopChar) { if (text.Length == 0) { - if (bufPos >= bufLen) + if (_bufPos >= _bufLen) { FlushBuffer(); } @@ -1146,24 +1146,24 @@ protected unsafe void WriteCommentOrPi(string text, int stopChar) // write text fixed (char* pSrcBegin = text) - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { char* pSrc = pSrcBegin; char* pSrcEnd = pSrcBegin + text.Length; - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar && ch <= 0x7F)) { *pDst = (byte)ch; pDst++; @@ -1181,7 +1181,7 @@ protected unsafe void WriteCommentOrPi(string text, int stopChar) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1221,7 +1221,7 @@ protected unsafe void WriteCommentOrPi(string text, int stopChar) pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1238,7 +1238,7 @@ protected unsafe void WriteCommentOrPi(string text, int stopChar) } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { pDst = WriteNewLine(pDst); } @@ -1277,7 +1277,7 @@ protected unsafe void WriteCommentOrPi(string text, int stopChar) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -1285,7 +1285,7 @@ protected unsafe void WriteCDataSection(string text) { if (text.Length == 0) { - if (bufPos >= bufLen) + if (_bufPos >= _bufLen) { FlushBuffer(); } @@ -1296,24 +1296,24 @@ protected unsafe void WriteCDataSection(string text) fixed (char* pSrcBegin = text) - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { char* pSrc = pSrcBegin; char* pSrcEnd = pSrcBegin + text.Length; - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']' && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']' && ch <= 0x7F)) { *pDst = (byte)ch; pDst++; @@ -1331,7 +1331,7 @@ protected unsafe void WriteCDataSection(string text) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; @@ -1341,7 +1341,7 @@ protected unsafe void WriteCDataSection(string text) switch (ch) { case '>': - if (hadDoubleBracket && pDst[-1] == (byte)']') + if (_hadDoubleBracket && pDst[-1] == (byte)']') { // pDst[-1] will always correct - there is a padding character at bufBytes[0] // The characters "]]>" were found within the CData text pDst = RawEndCData(pDst); @@ -1353,17 +1353,17 @@ protected unsafe void WriteCDataSection(string text) case ']': if (pDst[-1] == (byte)']') { // pDst[-1] will always correct - there is a padding character at bufBytes[0] - hadDoubleBracket = true; + _hadDoubleBracket = true; } else { - hadDoubleBracket = false; + _hadDoubleBracket = false; } *pDst = (byte)']'; pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1380,7 +1380,7 @@ protected unsafe void WriteCDataSection(string text) } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { pDst = WriteNewLine(pDst); } @@ -1421,7 +1421,7 @@ protected unsafe void WriteCDataSection(string text) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } } @@ -1467,10 +1467,10 @@ private static bool IsSurrogateByte(byte b) private unsafe byte* InvalidXmlChar(int ch, byte* pDst, bool entitize) { - Debug.Assert(!xmlCharType.IsWhiteSpace((char)ch)); - Debug.Assert(!xmlCharType.IsAttributeValueChar((char)ch)); + Debug.Assert(!_xmlCharType.IsWhiteSpace((char)ch)); + Debug.Assert(!_xmlCharType.IsAttributeValueChar((char)ch)); - if (checkCharacters) + if (_checkCharacters) { // This method will never be called on surrogates, so it is ok to pass in '\0' to the CreateInvalidCharException throw XmlConvert.CreateInvalidCharException((char)ch, '\0'); @@ -1572,12 +1572,12 @@ internal static unsafe void CharToUTF8(ref char* pSrc, char* pSrcEnd, ref byte* // Write NewLineChars to the specified buffer position and return an updated position. protected unsafe byte* WriteNewLine(byte* pDst) { - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); // Let RawText do the real work - RawText(newLineChars); - return pDstBegin + bufPos; + RawText(_newLineChars); + return pDstBegin + _bufPos; } } @@ -1715,7 +1715,7 @@ protected void ValidateContentChars(string chars, string propertyName, bool allo { if (allowOnlyWhitespace) { - if (!xmlCharType.IsOnlyWhitespace(chars)) + if (!_xmlCharType.IsOnlyWhitespace(chars)) { throw new ArgumentException(SR.Format(SR.Xml_IndentCharsNotWhitespace, propertyName)); } @@ -1725,7 +1725,7 @@ protected void ValidateContentChars(string chars, string propertyName, bool allo string error = null; for (int i = 0; i < chars.Length; i++) { - if (!xmlCharType.IsTextChar(chars[i])) + if (!_xmlCharType.IsTextChar(chars[i])) { switch (chars[i]) { @@ -1775,14 +1775,14 @@ internal partial class XmlUtf8RawTextWriterIndent : XmlUtf8RawTextWriter // // Fields // - protected int indentLevel; - protected bool newLineOnAttributes; - protected string indentChars; + protected int _indentLevel; + protected bool _newLineOnAttributes; + protected string _indentChars; - protected bool mixedContent; + protected bool _mixedContent; private BitStack _mixedContentStack; - protected ConformanceLevel conformanceLevel = ConformanceLevel.Auto; + protected ConformanceLevel _conformanceLevel = ConformanceLevel.Auto; // // Constructors @@ -1804,8 +1804,8 @@ public override XmlWriterSettings Settings settings.ReadOnly = false; settings.Indent = true; - settings.IndentChars = indentChars; - settings.NewLineOnAttributes = newLineOnAttributes; + settings.IndentChars = _indentChars; + settings.NewLineOnAttributes = _newLineOnAttributes; settings.ReadOnly = true; return settings; @@ -1815,7 +1815,7 @@ public override XmlWriterSettings Settings public override void WriteDocType(string name, string pubid, string sysid, string subset) { // Add indentation - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { WriteIndent(); } @@ -1827,12 +1827,12 @@ public override void WriteStartElement(string prefix, string localName, string n Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null); // Add indentation - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { WriteIndent(); } - indentLevel++; - _mixedContentStack.PushBit(mixedContent); + _indentLevel++; + _mixedContentStack.PushBit(_mixedContent); base.WriteStartElement(prefix, localName, ns); } @@ -1840,16 +1840,16 @@ public override void WriteStartElement(string prefix, string localName, string n internal override void StartElementContent() { // If this is the root element and we're writing a document - // do not inherit the mixedContent flag into the root element. + // do not inherit the _mixedContent flag into the root element. // This is to allow for whitespace nodes on root level // without disabling indentation for the whole document. - if (indentLevel == 1 && conformanceLevel == ConformanceLevel.Document) + if (_indentLevel == 1 && _conformanceLevel == ConformanceLevel.Document) { - mixedContent = false; + _mixedContent = false; } else { - mixedContent = _mixedContentStack.PeekBit(); + _mixedContent = _mixedContentStack.PeekBit(); } base.StartElementContent(); } @@ -1857,22 +1857,22 @@ internal override void StartElementContent() internal override void OnRootElement(ConformanceLevel currentConformanceLevel) { // Just remember the current conformance level - conformanceLevel = currentConformanceLevel; + _conformanceLevel = currentConformanceLevel; } internal override void WriteEndElement(string prefix, string localName, string ns) { // Add indentation - indentLevel--; - if (!mixedContent && base.contentPos != base.bufPos) + _indentLevel--; + if (!_mixedContent && base._contentPos != base._bufPos) { // There was content, so try to indent - if (base.textPos != base.bufPos) + if (base._textPos != base._bufPos) { WriteIndent(); } } - mixedContent = _mixedContentStack.PopBit(); + _mixedContent = _mixedContentStack.PopBit(); base.WriteEndElement(prefix, localName, ns); } @@ -1880,16 +1880,16 @@ internal override void WriteEndElement(string prefix, string localName, string n internal override void WriteFullEndElement(string prefix, string localName, string ns) { // Add indentation - indentLevel--; - if (!mixedContent && base.contentPos != base.bufPos) + _indentLevel--; + if (!_mixedContent && base._contentPos != base._bufPos) { // There was content, so try to indent - if (base.textPos != base.bufPos) + if (base._textPos != base._bufPos) { WriteIndent(); } } - mixedContent = _mixedContentStack.PopBit(); + _mixedContent = _mixedContentStack.PopBit(); base.WriteFullEndElement(prefix, localName, ns); } @@ -1898,7 +1898,7 @@ internal override void WriteFullEndElement(string prefix, string localName, stri public override void WriteStartAttribute(string prefix, string localName, string ns) { // Add indentation - if (newLineOnAttributes) + if (_newLineOnAttributes) { WriteIndent(); } @@ -1908,13 +1908,13 @@ public override void WriteStartAttribute(string prefix, string localName, string public override void WriteCData(string text) { - mixedContent = true; + _mixedContent = true; base.WriteCData(text); } public override void WriteComment(string text) { - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { WriteIndent(); } @@ -1924,7 +1924,7 @@ public override void WriteComment(string text) public override void WriteProcessingInstruction(string target, string text) { - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { WriteIndent(); } @@ -1934,55 +1934,55 @@ public override void WriteProcessingInstruction(string target, string text) public override void WriteEntityRef(string name) { - mixedContent = true; + _mixedContent = true; base.WriteEntityRef(name); } public override void WriteCharEntity(char ch) { - mixedContent = true; + _mixedContent = true; base.WriteCharEntity(ch); } public override void WriteSurrogateCharEntity(char lowChar, char highChar) { - mixedContent = true; + _mixedContent = true; base.WriteSurrogateCharEntity(lowChar, highChar); } public override void WriteWhitespace(string ws) { - mixedContent = true; + _mixedContent = true; base.WriteWhitespace(ws); } public override void WriteString(string text) { - mixedContent = true; + _mixedContent = true; base.WriteString(text); } public override void WriteChars(char[] buffer, int index, int count) { - mixedContent = true; + _mixedContent = true; base.WriteChars(buffer, index, count); } public override void WriteRaw(char[] buffer, int index, int count) { - mixedContent = true; + _mixedContent = true; base.WriteRaw(buffer, index, count); } public override void WriteRaw(string data) { - mixedContent = true; + _mixedContent = true; base.WriteRaw(data); } public override void WriteBase64(byte[] buffer, int index, int count) { - mixedContent = true; + _mixedContent = true; base.WriteBase64(buffer, index, count); } @@ -1991,25 +1991,25 @@ public override void WriteBase64(byte[] buffer, int index, int count) // private void Init(XmlWriterSettings settings) { - indentLevel = 0; - indentChars = settings.IndentChars; - newLineOnAttributes = settings.NewLineOnAttributes; + _indentLevel = 0; + _indentChars = settings.IndentChars; + _newLineOnAttributes = settings.NewLineOnAttributes; _mixedContentStack = new BitStack(); // check indent characters that they are valid XML characters - if (base.checkCharacters) + if (base._checkCharacters) { - if (newLineOnAttributes) + if (_newLineOnAttributes) { - base.ValidateContentChars(indentChars, "IndentChars", true); - base.ValidateContentChars(newLineChars, "NewLineChars", true); + base.ValidateContentChars(_indentChars, "IndentChars", true); + base.ValidateContentChars(_newLineChars, "NewLineChars", true); } else { - base.ValidateContentChars(indentChars, "IndentChars", false); - if (base.newLineHandling != NewLineHandling.Replace) + base.ValidateContentChars(_indentChars, "IndentChars", false); + if (base._newLineHandling != NewLineHandling.Replace) { - base.ValidateContentChars(newLineChars, "NewLineChars", false); + base.ValidateContentChars(_newLineChars, "NewLineChars", false); } } } @@ -2018,10 +2018,10 @@ private void Init(XmlWriterSettings settings) // Add indentation to output. Write newline and then repeat IndentChars for each indent level. private void WriteIndent() { - RawText(base.newLineChars); - for (int i = indentLevel; i > 0; i--) + RawText(base._newLineChars); + for (int i = _indentLevel; i > 0; i--) { - RawText(indentChars); + RawText(_indentChars); } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs index 950ebe60acd85..358c774d59d0a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlUtf8RawTextWriterAsync.cs @@ -35,7 +35,7 @@ internal override async Task WriteXmlDeclarationAsync(XmlStandalone standalone) { CheckAsyncCall(); // Output xml declaration only if user allows it and it was not already output - if (!omitXmlDeclaration && !autoXmlDeclaration) + if (!_omitXmlDeclaration && !_autoXmlDeclaration) { await RawTextAsync("'; + _bufBytes[_bufPos++] = (byte)'>'; } // Serialize the beginning of an element start tag: "", if content was output. Otherwise, serialize @@ -180,11 +180,11 @@ internal override Task WriteEndElementAsync(string prefix, string localName, str Debug.Assert(localName != null && localName.Length > 0); Debug.Assert(prefix != null); - if (contentPos != bufPos) + if (_contentPos != _bufPos) { // Content has been output, so can't use shortcut syntax - bufBytes[bufPos++] = (byte)'<'; - bufBytes[bufPos++] = (byte)'/'; + _bufBytes[_bufPos++] = (byte)'<'; + _bufBytes[_bufPos++] = (byte)'/'; if (prefix != null && prefix.Length != 0) { @@ -198,10 +198,10 @@ internal override Task WriteEndElementAsync(string prefix, string localName, str else { // Use shortcut syntax; overwrite the already output '>' character - bufPos--; - bufBytes[bufPos++] = (byte)' '; - bufBytes[bufPos++] = (byte)'/'; - bufBytes[bufPos++] = (byte)'>'; + _bufPos--; + _bufBytes[_bufPos++] = (byte)' '; + _bufBytes[_bufPos++] = (byte)'/'; + _bufBytes[_bufPos++] = (byte)'>'; } return Task.CompletedTask; } @@ -213,8 +213,8 @@ internal override Task WriteFullEndElementAsync(string prefix, string localName, Debug.Assert(localName != null && localName.Length > 0); Debug.Assert(prefix != null); - bufBytes[bufPos++] = (byte)'<'; - bufBytes[bufPos++] = (byte)'/'; + _bufBytes[_bufPos++] = (byte)'<'; + _bufBytes[_bufPos++] = (byte)'/'; if (prefix != null && prefix.Length != 0) { @@ -233,9 +233,9 @@ protected internal override Task WriteStartAttributeAsync(string prefix, string Debug.Assert(localName != null && localName.Length > 0); Debug.Assert(prefix != null); - if (attrEndPos == bufPos) + if (_attrEndPos == _bufPos) { - bufBytes[bufPos++] = (byte)' '; + _bufBytes[_bufPos++] = (byte)' '; } Task task; if (prefix != null && prefix.Length > 0) @@ -251,9 +251,9 @@ protected internal override Task WriteStartAttributeAsync(string prefix, string private void WriteStartAttribute_SetInAttribute() { - bufBytes[bufPos++] = (byte)'='; - bufBytes[bufPos++] = (byte)'"'; - inAttributeValue = true; + _bufBytes[_bufPos++] = (byte)'='; + _bufBytes[_bufPos++] = (byte)'"'; + _inAttributeValue = true; } // Serialize the end of an attribute value using double quotes: '"' @@ -261,9 +261,9 @@ protected internal override Task WriteEndAttributeAsync() { CheckAsyncCall(); - bufBytes[bufPos++] = (byte)'"'; - inAttributeValue = false; - attrEndPos = bufPos; + _bufBytes[_bufPos++] = (byte)'"'; + _inAttributeValue = false; + _attrEndPos = _bufPos; return Task.CompletedTask; } @@ -291,21 +291,21 @@ internal override async Task WriteStartNamespaceDeclarationAsync(string prefix) { await RawTextAsync(" xmlns:").ConfigureAwait(false); await RawTextAsync(prefix).ConfigureAwait(false); - bufBytes[bufPos++] = (byte)'='; - bufBytes[bufPos++] = (byte)'"'; + _bufBytes[_bufPos++] = (byte)'='; + _bufBytes[_bufPos++] = (byte)'"'; } - inAttributeValue = true; + _inAttributeValue = true; } internal override Task WriteEndNamespaceDeclarationAsync() { CheckAsyncCall(); - inAttributeValue = false; + _inAttributeValue = false; - bufBytes[bufPos++] = (byte)'"'; - attrEndPos = bufPos; + _bufBytes[_bufPos++] = (byte)'"'; + _attrEndPos = _bufPos; return Task.CompletedTask; } @@ -317,34 +317,34 @@ public override async Task WriteCDataAsync(string text) CheckAsyncCall(); Debug.Assert(text != null); - if (mergeCDataSections && bufPos == cdataPos) + if (_mergeCDataSections && _bufPos == _cdataPos) { // Merge adjacent cdata sections - overwrite the "]]>" characters - Debug.Assert(bufPos >= 4); - bufPos -= 3; + Debug.Assert(_bufPos >= 4); + _bufPos -= 3; } else { // Start a new cdata section - bufBytes[bufPos++] = (byte)'<'; - bufBytes[bufPos++] = (byte)'!'; - bufBytes[bufPos++] = (byte)'['; - bufBytes[bufPos++] = (byte)'C'; - bufBytes[bufPos++] = (byte)'D'; - bufBytes[bufPos++] = (byte)'A'; - bufBytes[bufPos++] = (byte)'T'; - bufBytes[bufPos++] = (byte)'A'; - bufBytes[bufPos++] = (byte)'['; + _bufBytes[_bufPos++] = (byte)'<'; + _bufBytes[_bufPos++] = (byte)'!'; + _bufBytes[_bufPos++] = (byte)'['; + _bufBytes[_bufPos++] = (byte)'C'; + _bufBytes[_bufPos++] = (byte)'D'; + _bufBytes[_bufPos++] = (byte)'A'; + _bufBytes[_bufPos++] = (byte)'T'; + _bufBytes[_bufPos++] = (byte)'A'; + _bufBytes[_bufPos++] = (byte)'['; } await WriteCDataSectionAsync(text).ConfigureAwait(false); - bufBytes[bufPos++] = (byte)']'; - bufBytes[bufPos++] = (byte)']'; - bufBytes[bufPos++] = (byte)'>'; + _bufBytes[_bufPos++] = (byte)']'; + _bufBytes[_bufPos++] = (byte)']'; + _bufBytes[_bufPos++] = (byte)'>'; - textPos = bufPos; - cdataPos = bufPos; + _textPos = _bufPos; + _cdataPos = _bufPos; } // Serialize a comment. @@ -353,16 +353,16 @@ public override async Task WriteCommentAsync(string text) CheckAsyncCall(); Debug.Assert(text != null); - bufBytes[bufPos++] = (byte)'<'; - bufBytes[bufPos++] = (byte)'!'; - bufBytes[bufPos++] = (byte)'-'; - bufBytes[bufPos++] = (byte)'-'; + _bufBytes[_bufPos++] = (byte)'<'; + _bufBytes[_bufPos++] = (byte)'!'; + _bufBytes[_bufPos++] = (byte)'-'; + _bufBytes[_bufPos++] = (byte)'-'; await WriteCommentOrPiAsync(text, '-').ConfigureAwait(false); - bufBytes[bufPos++] = (byte)'-'; - bufBytes[bufPos++] = (byte)'-'; - bufBytes[bufPos++] = (byte)'>'; + _bufBytes[_bufPos++] = (byte)'-'; + _bufBytes[_bufPos++] = (byte)'-'; + _bufBytes[_bufPos++] = (byte)'>'; } // Serialize a processing instruction. @@ -372,18 +372,18 @@ public override async Task WriteProcessingInstructionAsync(string name, string t Debug.Assert(name != null && name.Length > 0); Debug.Assert(text != null); - bufBytes[bufPos++] = (byte)'<'; - bufBytes[bufPos++] = (byte)'?'; + _bufBytes[_bufPos++] = (byte)'<'; + _bufBytes[_bufPos++] = (byte)'?'; await RawTextAsync(name).ConfigureAwait(false); if (text.Length > 0) { - bufBytes[bufPos++] = (byte)' '; + _bufBytes[_bufPos++] = (byte)' '; await WriteCommentOrPiAsync(text, '?').ConfigureAwait(false); } - bufBytes[bufPos++] = (byte)'?'; - bufBytes[bufPos++] = (byte)'>'; + _bufBytes[_bufPos++] = (byte)'?'; + _bufBytes[_bufPos++] = (byte)'>'; } // Serialize an entity reference. @@ -392,16 +392,16 @@ public override async Task WriteEntityRefAsync(string name) CheckAsyncCall(); Debug.Assert(name != null && name.Length > 0); - bufBytes[bufPos++] = (byte)'&'; + _bufBytes[_bufPos++] = (byte)'&'; await RawTextAsync(name).ConfigureAwait(false); - bufBytes[bufPos++] = (byte)';'; + _bufBytes[_bufPos++] = (byte)';'; - if (bufPos > bufLen) + if (_bufPos > _bufLen) { await FlushBufferAsync().ConfigureAwait(false); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize a character entity reference. @@ -410,24 +410,24 @@ public override async Task WriteCharEntityAsync(char ch) CheckAsyncCall(); string strVal = ((int)ch).ToString("X", NumberFormatInfo.InvariantInfo); - if (checkCharacters && !xmlCharType.IsCharData(ch)) + if (_checkCharacters && !_xmlCharType.IsCharData(ch)) { // we just have a single char, not a surrogate, therefore we have to pass in '\0' for the second char throw XmlConvert.CreateInvalidCharException(ch, '\0'); } - bufBytes[bufPos++] = (byte)'&'; - bufBytes[bufPos++] = (byte)'#'; - bufBytes[bufPos++] = (byte)'x'; + _bufBytes[_bufPos++] = (byte)'&'; + _bufBytes[_bufPos++] = (byte)'#'; + _bufBytes[_bufPos++] = (byte)'x'; await RawTextAsync(strVal).ConfigureAwait(false); - bufBytes[bufPos++] = (byte)';'; + _bufBytes[_bufPos++] = (byte)';'; - if (bufPos > bufLen) + if (_bufPos > _bufLen) { await FlushBufferAsync().ConfigureAwait(false); } - textPos = bufPos; + _textPos = _bufPos; } // Serialize a whitespace node. @@ -437,7 +437,7 @@ public override Task WriteWhitespaceAsync(string ws) CheckAsyncCall(); Debug.Assert(ws != null); - if (inAttributeValue) + if (_inAttributeValue) { return WriteAttributeTextBlockAsync(ws); } @@ -454,7 +454,7 @@ public override Task WriteStringAsync(string text) CheckAsyncCall(); Debug.Assert(text != null); - if (inAttributeValue) + if (_inAttributeValue) { return WriteAttributeTextBlockAsync(text); } @@ -471,12 +471,12 @@ public override async Task WriteSurrogateCharEntityAsync(char lowChar, char high int surrogateChar = XmlCharType.CombineSurrogateChar(lowChar, highChar); - bufBytes[bufPos++] = (byte)'&'; - bufBytes[bufPos++] = (byte)'#'; - bufBytes[bufPos++] = (byte)'x'; + _bufBytes[_bufPos++] = (byte)'&'; + _bufBytes[_bufPos++] = (byte)'#'; + _bufBytes[_bufPos++] = (byte)'x'; await RawTextAsync(surrogateChar.ToString("X", NumberFormatInfo.InvariantInfo)).ConfigureAwait(false); - bufBytes[bufPos++] = (byte)';'; - textPos = bufPos; + _bufBytes[_bufPos++] = (byte)';'; + _textPos = _bufPos; } // Serialize either attribute or element text using XML rules. @@ -489,7 +489,7 @@ public override Task WriteCharsAsync(char[] buffer, int index, int count) Debug.Assert(index >= 0); Debug.Assert(count >= 0 && index + count <= buffer.Length); - if (inAttributeValue) + if (_inAttributeValue) { return WriteAttributeTextBlockAsync(buffer, index, count); } @@ -511,7 +511,7 @@ public override async Task WriteRawAsync(char[] buffer, int index, int count) await WriteRawWithCharCheckingAsync(buffer, index, count).ConfigureAwait(false); - textPos = bufPos; + _textPos = _bufPos; } // Serialize raw data. @@ -523,7 +523,7 @@ public override async Task WriteRawAsync(string data) await WriteRawWithCharCheckingAsync(data).ConfigureAwait(false); - textPos = bufPos; + _textPos = _bufPos; } // Flush all characters in the buffer to output and call Flush() on the output object. @@ -532,9 +532,9 @@ public override async Task FlushAsync() CheckAsyncCall(); await FlushBufferAsync().ConfigureAwait(false); - if (stream != null) + if (_stream != null) { - await stream.FlushAsync().ConfigureAwait(false); + await _stream.FlushAsync().ConfigureAwait(false); } } @@ -547,41 +547,41 @@ protected virtual async Task FlushBufferAsync() try { // Output all characters (except for previous characters stored at beginning of buffer) - if (!writeToNull) + if (!_writeToNull) { - if (bufPos - 1 > 0) + if (_bufPos - 1 > 0) { - Debug.Assert(stream != null); - await stream.WriteAsync(bufBytes.AsMemory(1, bufPos - 1)).ConfigureAwait(false); + Debug.Assert(_stream != null); + await _stream.WriteAsync(_bufBytes.AsMemory(1, _bufPos - 1)).ConfigureAwait(false); } } } catch { // Future calls to flush (i.e. when Close() is called) don't attempt to write to stream - writeToNull = true; + _writeToNull = true; throw; } finally { // Move last buffer character to the beginning of the buffer (so that previous character can always be determined) - bufBytes[0] = bufBytes[bufPos - 1]; + _bufBytes[0] = _bufBytes[_bufPos - 1]; - if (IsSurrogateByte(bufBytes[0])) + if (IsSurrogateByte(_bufBytes[0])) { // Last character was the first byte in a surrogate encoding, so move last three // bytes of encoding to the beginning of the buffer. - bufBytes[1] = bufBytes[bufPos]; - bufBytes[2] = bufBytes[bufPos + 1]; - bufBytes[3] = bufBytes[bufPos + 2]; + _bufBytes[1] = _bufBytes[_bufPos]; + _bufBytes[2] = _bufBytes[_bufPos + 1]; + _bufBytes[3] = _bufBytes[_bufPos + 2]; } // Reset buffer position - textPos = (textPos == bufPos) ? 1 : 0; - attrEndPos = (attrEndPos == bufPos) ? 1 : 0; - contentPos = 0; // Needs to be zero, since overwriting '>' character is no longer possible - cdataPos = 0; // Needs to be zero, since overwriting ']]>' characters is no longer possible - bufPos = 1; // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to + _textPos = (_textPos == _bufPos) ? 1 : 0; + _attrEndPos = (_attrEndPos == _bufPos) ? 1 : 0; + _contentPos = 0; // Needs to be zero, since overwriting '>' character is no longer possible + _cdataPos = 0; // Needs to be zero, since overwriting ']]>' characters is no longer possible + _bufPos = 1; // Buffer position starts at 1, because we need to be able to safely step back -1 in case we need to // close an empty element or in CDATA section detection of double ]; _BUFFER[0] will always be 0 } } @@ -592,20 +592,20 @@ protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd) { char* pRaw = pSrc; - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) { *pDst = (byte)ch; pDst++; @@ -622,7 +622,7 @@ protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -646,7 +646,7 @@ protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd) pDst++; break; case (char)0x9: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (byte)ch; pDst++; @@ -658,7 +658,7 @@ protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd) } break; case (char)0xD: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (byte)ch; pDst++; @@ -670,7 +670,7 @@ protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd) } break; case (char)0xA: - if (newLineHandling == NewLineHandling.None) + if (_newLineHandling == NewLineHandling.None) { *pDst = (byte)ch; pDst++; @@ -704,7 +704,7 @@ protected unsafe int WriteAttributeTextBlockNoFlush(char* pSrc, char* pSrcEnd) } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -795,20 +795,20 @@ protected unsafe int WriteElementTextBlockNoFlush(char* pSrc, char* pSrcEnd, out needWriteNewLine = false; char* pRaw = pSrc; - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F)) { *pDst = (byte)ch; pDst++; @@ -825,7 +825,7 @@ protected unsafe int WriteElementTextBlockNoFlush(char* pSrc, char* pSrcEnd, out // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -848,9 +848,9 @@ protected unsafe int WriteElementTextBlockNoFlush(char* pSrc, char* pSrcEnd, out pDst++; break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -861,7 +861,7 @@ protected unsafe int WriteElementTextBlockNoFlush(char* pSrc, char* pSrcEnd, out } break; case (char)0xD: - switch (newLineHandling) + switch (_newLineHandling) { case NewLineHandling.Replace: // Replace "\r\n", or "\r" with NewLineChars @@ -870,7 +870,7 @@ protected unsafe int WriteElementTextBlockNoFlush(char* pSrc, char* pSrcEnd, out pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); @@ -907,9 +907,9 @@ protected unsafe int WriteElementTextBlockNoFlush(char* pSrc, char* pSrcEnd, out } pSrc++; } - bufPos = (int)(pDst - pDstBegin); - textPos = bufPos; - contentPos = 0; + _bufPos = (int)(pDst - pDstBegin); + _textPos = _bufPos; + _contentPos = 0; } return -1; @@ -920,7 +920,7 @@ protected unsafe int WriteElementTextBlockNoFlush(char[] chars, int index, int c needWriteNewLine = false; if (count == 0) { - contentPos = 0; + _contentPos = 0; return -1; } fixed (char* pSrc = &chars[index]) @@ -936,7 +936,7 @@ protected unsafe int WriteElementTextBlockNoFlush(string text, int index, int co needWriteNewLine = false; if (count == 0) { - contentPos = 0; + _contentPos = 0; return -1; } fixed (char* pSrc = text) @@ -961,7 +961,7 @@ protected async Task WriteElementTextBlockAsync(char[] chars, int index, int cou if (needWriteNewLine) { //hit WriteNewLine - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1001,7 +1001,7 @@ private async Task _WriteElementTextBlockAsync(bool newLine, string text, int cu if (newLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1018,7 +1018,7 @@ private async Task _WriteElementTextBlockAsync(bool newLine, string text, int cu if (needWriteNewLine) { //hit WriteNewLine - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1033,18 +1033,18 @@ protected unsafe int RawTextNoFlush(char* pSrcBegin, char* pSrcEnd) { char* pRaw = pSrcBegin; - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; char* pSrc = pSrcBegin; int ch = 0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } while (pDst < pDstEnd && ((ch = *pSrc) <= 0x7F)) @@ -1064,7 +1064,7 @@ protected unsafe int RawTextNoFlush(char* pSrcBegin, char* pSrcEnd) // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -1088,7 +1088,7 @@ protected unsafe int RawTextNoFlush(char* pSrcBegin, char* pSrcEnd) } } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -1207,21 +1207,21 @@ protected unsafe int WriteRawWithCharCheckingNoFlush(char* pSrcBegin, char* pSrc needWriteNewLine = false; char* pRaw = pSrcBegin; - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { char* pSrc = pSrcBegin; - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch <= 0x7F)) { *pDst = (byte)ch; pDst++; @@ -1239,7 +1239,7 @@ protected unsafe int WriteRawWithCharCheckingNoFlush(char* pSrcBegin, char* pSrc // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -1254,7 +1254,7 @@ protected unsafe int WriteRawWithCharCheckingNoFlush(char* pSrcBegin, char* pSrc pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1262,7 +1262,7 @@ protected unsafe int WriteRawWithCharCheckingNoFlush(char* pSrcBegin, char* pSrc pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1273,9 +1273,9 @@ protected unsafe int WriteRawWithCharCheckingNoFlush(char* pSrcBegin, char* pSrc } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1308,7 +1308,7 @@ protected unsafe int WriteRawWithCharCheckingNoFlush(char* pSrcBegin, char* pSrc } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -1357,7 +1357,7 @@ protected async Task WriteRawWithCharCheckingAsync(char[] chars, int index, int leftCount -= writeLen; if (needWriteNewLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1381,7 +1381,7 @@ protected async Task WriteRawWithCharCheckingAsync(string text) leftCount -= writeLen; if (needWriteNewLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1403,7 +1403,7 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, { char* pSrcBegin = pSrcText + index; - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { char* pSrc = pSrcBegin; @@ -1411,18 +1411,18 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, char* pSrcEnd = pSrcBegin + count; - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsTextChar((char)(ch = *pSrc)) && ch != stopChar && ch <= 0x7F)) { *pDst = (byte)ch; pDst++; @@ -1440,7 +1440,7 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -1478,7 +1478,7 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1486,7 +1486,7 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1497,9 +1497,9 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1538,7 +1538,7 @@ protected unsafe int WriteCommentOrPiNoFlush(string text, int index, int count, } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -1549,7 +1549,7 @@ protected async Task WriteCommentOrPiAsync(string text, int stopChar) { if (text.Length == 0) { - if (bufPos >= bufLen) + if (_bufPos >= _bufLen) { await FlushBufferAsync().ConfigureAwait(false); } @@ -1567,7 +1567,7 @@ protected async Task WriteCommentOrPiAsync(string text, int stopChar) leftCount -= writeLen; if (needWriteNewLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1592,7 +1592,7 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, { char* pSrcBegin = pSrcText + index; - fixed (byte* pDstBegin = bufBytes) + fixed (byte* pDstBegin = _bufBytes) { char* pSrc = pSrcBegin; @@ -1600,18 +1600,18 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, char* pRaw = pSrc; - byte* pDst = pDstBegin + bufPos; + byte* pDst = pDstBegin + _bufPos; int ch = 0; while (true) { byte* pDstEnd = pDst + (pSrcEnd - pSrc); - if (pDstEnd > pDstBegin + bufLen) + if (pDstEnd > pDstBegin + _bufLen) { - pDstEnd = pDstBegin + bufLen; + pDstEnd = pDstBegin + _bufLen; } - while (pDst < pDstEnd && (xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']' && ch <= 0x7F)) + while (pDst < pDstEnd && (_xmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch != ']' && ch <= 0x7F)) { *pDst = (byte)ch; pDst++; @@ -1629,7 +1629,7 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, // end of buffer if (pDst >= pDstEnd) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); return (int)(pSrc - pRaw); } @@ -1637,7 +1637,7 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, switch (ch) { case '>': - if (hadDoubleBracket && pDst[-1] == (byte)']') + if (_hadDoubleBracket && pDst[-1] == (byte)']') { // pDst[-1] will always correct - there is a padding character at _BUFFER[0] // The characters "]]>" were found within the CData text pDst = RawEndCData(pDst); @@ -1649,17 +1649,17 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, case ']': if (pDst[-1] == (byte)']') { // pDst[-1] will always correct - there is a padding character at _BUFFER[0] - hadDoubleBracket = true; + _hadDoubleBracket = true; } else { - hadDoubleBracket = false; + _hadDoubleBracket = false; } *pDst = (byte)']'; pDst++; break; case (char)0xD: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { // Normalize "\r\n", or "\r" to NewLineChars if (pSrc + 1 < pSrcEnd && pSrc[1] == '\n') @@ -1667,7 +1667,7 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1678,9 +1678,9 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, } break; case (char)0xA: - if (newLineHandling == NewLineHandling.Replace) + if (_newLineHandling == NewLineHandling.Replace) { - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); needWriteNewLine = true; return (int)(pSrc - pRaw); } @@ -1721,7 +1721,7 @@ protected unsafe int WriteCDataSectionNoFlush(string text, int index, int count, } pSrc++; } - bufPos = (int)(pDst - pDstBegin); + _bufPos = (int)(pDst - pDstBegin); } return -1; @@ -1732,7 +1732,7 @@ protected async Task WriteCDataSectionAsync(string text) { if (text.Length == 0) { - if (bufPos >= bufLen) + if (_bufPos >= _bufLen) { await FlushBufferAsync().ConfigureAwait(false); } @@ -1750,7 +1750,7 @@ protected async Task WriteCDataSectionAsync(string text) leftCount -= writeLen; if (needWriteNewLine) { - await RawTextAsync(newLineChars).ConfigureAwait(false); + await RawTextAsync(_newLineChars).ConfigureAwait(false); curIndex++; leftCount--; } @@ -1769,7 +1769,7 @@ public override async Task WriteDocTypeAsync(string name, string pubid, string s { CheckAsyncCall(); // Add indentation - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } @@ -1782,12 +1782,12 @@ public override async Task WriteStartElementAsync(string prefix, string localNam Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null); // Add indentation - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } - indentLevel++; - _mixedContentStack.PushBit(mixedContent); + _indentLevel++; + _mixedContentStack.PushBit(_mixedContent); await base.WriteStartElementAsync(prefix, localName, ns).ConfigureAwait(false); } @@ -1796,16 +1796,16 @@ internal override async Task WriteEndElementAsync(string prefix, string localNam { CheckAsyncCall(); // Add indentation - indentLevel--; - if (!mixedContent && base.contentPos != base.bufPos) + _indentLevel--; + if (!_mixedContent && base._contentPos != base._bufPos) { // There was content, so try to indent - if (base.textPos != base.bufPos) + if (base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } } - mixedContent = _mixedContentStack.PopBit(); + _mixedContent = _mixedContentStack.PopBit(); await base.WriteEndElementAsync(prefix, localName, ns).ConfigureAwait(false); } @@ -1814,16 +1814,16 @@ internal override async Task WriteFullEndElementAsync(string prefix, string loca { CheckAsyncCall(); // Add indentation - indentLevel--; - if (!mixedContent && base.contentPos != base.bufPos) + _indentLevel--; + if (!_mixedContent && base._contentPos != base._bufPos) { // There was content, so try to indent - if (base.textPos != base.bufPos) + if (base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } } - mixedContent = _mixedContentStack.PopBit(); + _mixedContent = _mixedContentStack.PopBit(); await base.WriteFullEndElementAsync(prefix, localName, ns).ConfigureAwait(false); } @@ -1833,7 +1833,7 @@ protected internal override async Task WriteStartAttributeAsync(string prefix, s { CheckAsyncCall(); // Add indentation - if (newLineOnAttributes) + if (_newLineOnAttributes) { await WriteIndentAsync().ConfigureAwait(false); } @@ -1844,14 +1844,14 @@ protected internal override async Task WriteStartAttributeAsync(string prefix, s public override Task WriteCDataAsync(string text) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteCDataAsync(text); } public override async Task WriteCommentAsync(string text) { CheckAsyncCall(); - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } @@ -1862,7 +1862,7 @@ public override async Task WriteCommentAsync(string text) public override async Task WriteProcessingInstructionAsync(string target, string text) { CheckAsyncCall(); - if (!mixedContent && base.textPos != base.bufPos) + if (!_mixedContent && base._textPos != base._bufPos) { await WriteIndentAsync().ConfigureAwait(false); } @@ -1873,63 +1873,63 @@ public override async Task WriteProcessingInstructionAsync(string target, string public override Task WriteEntityRefAsync(string name) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteEntityRefAsync(name); } public override Task WriteCharEntityAsync(char ch) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteCharEntityAsync(ch); } public override Task WriteSurrogateCharEntityAsync(char lowChar, char highChar) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteSurrogateCharEntityAsync(lowChar, highChar); } public override Task WriteWhitespaceAsync(string ws) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteWhitespaceAsync(ws); } public override Task WriteStringAsync(string text) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteStringAsync(text); } public override Task WriteCharsAsync(char[] buffer, int index, int count) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteCharsAsync(buffer, index, count); } public override Task WriteRawAsync(char[] buffer, int index, int count) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteRawAsync(buffer, index, count); } public override Task WriteRawAsync(string data) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteRawAsync(data); } public override Task WriteBase64Async(byte[] buffer, int index, int count) { CheckAsyncCall(); - mixedContent = true; + _mixedContent = true; return base.WriteBase64Async(buffer, index, count); } @@ -1937,10 +1937,10 @@ public override Task WriteBase64Async(byte[] buffer, int index, int count) private async Task WriteIndentAsync() { CheckAsyncCall(); - await RawTextAsync(base.newLineChars).ConfigureAwait(false); - for (int i = indentLevel; i > 0; i--) + await RawTextAsync(base._newLineChars).ConfigureAwait(false); + for (int i = _indentLevel; i > 0; i--) { - await RawTextAsync(indentChars).ConfigureAwait(false); + await RawTextAsync(_indentChars).ConfigureAwait(false); } } } From 49f59a3cb935523c07187ce26bb03c7fa7fd66bd Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Mon, 18 May 2020 21:11:09 -0400 Subject: [PATCH 267/420] WASM app builder changes. (#36422) * Add an ExtraAssemblies parameter to the WasmAppBuilder task. * Pass more assemblies to the pinvoke table generator. * Improve the wasm sample. * Move WasmAppBuilder to tools-local. --- src/mono/mono.proj | 9 +-------- src/mono/netcore/sample/wasm/Makefile | 9 +++++++-- src/mono/netcore/sample/wasm/WasmSample.csproj | 4 ++-- src/mono/wasm/Makefile | 6 ++++-- src/mono/wasm/wasm.proj | 11 ++++++++--- .../WasmAppBuilder/PInvokeTableGenerator.cs | 0 .../mobile.tasks}/WasmAppBuilder/WasmAppBuilder.cs | 10 +++++++++- .../WasmAppBuilder/WasmAppBuilder.csproj | 2 ++ tools-local/tasks/tasks.proj | 2 ++ 9 files changed, 35 insertions(+), 18 deletions(-) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/WasmAppBuilder/PInvokeTableGenerator.cs (100%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/WasmAppBuilder/WasmAppBuilder.cs (90%) rename {src/mono/msbuild => tools-local/tasks/mobile.tasks}/WasmAppBuilder/WasmAppBuilder.csproj (90%) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 175622ca9546c..20b28c5303cf6 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -886,16 +886,9 @@ - - - - - - + <_MonoRuntimeFilePath Condition="'$(TargetsWindows)' == 'true' and '$(Platform)' == 'x64'">$(MonoObjDir)x64\Bin\$(Configuration)\mono-2.0-sgen.dll <_MonoRuntimeFilePath Condition="'$(TargetsWindows)' == 'true' and '$(Platform)' == 'x86'">$(MonoObjDir)Win32\Bin\$(Configuration)\mono-2.0-sgen.dll diff --git a/src/mono/netcore/sample/wasm/Makefile b/src/mono/netcore/sample/wasm/Makefile index 09c42a4d3638c..e798a00fd1e22 100644 --- a/src/mono/netcore/sample/wasm/Makefile +++ b/src/mono/netcore/sample/wasm/Makefile @@ -1,12 +1,17 @@ TOP=../../../../.. +DOTNET_Q_ARGS=--nologo -v:q -consoleloggerparameters:NoSummary + all: build build: - $(TOP)/.dotnet/dotnet build /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=Release + $(TOP)/.dotnet/dotnet build $(DOTNET_Q_ARGS) /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=Release clean: rm -rf bin run: - cd bin/Release/publish && ~/.jsvu/v8 --expose_wasm runtime.js -- --run WasmSample.dll + cd bin/Release/publish && ~/.jsvu/v8 --expose_wasm runtime.js -- --enable-gc --run WasmSample.dll + +runtimepack: + EMSDK_PATH=$(TOP)/src/mono/wasm/emsdk $(TOP)/build.sh -c $(MONO_CONFIG) -os Browser -arch wasm -subset Mono+Libs diff --git a/src/mono/netcore/sample/wasm/WasmSample.csproj b/src/mono/netcore/sample/wasm/WasmSample.csproj index 588f292924439..535fd287c058c 100644 --- a/src/mono/netcore/sample/wasm/WasmSample.csproj +++ b/src/mono/netcore/sample/wasm/WasmSample.csproj @@ -12,12 +12,12 @@ - + AssemblyFile="$(ArtifactsBinDir)\WasmAppBuilder\$(Configuration)\$(NetCoreAppCurrent)\publish\WasmAppBuilder.dll"/> diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile index 9cd0b9ba169fe..6dc4699c7e429 100644 --- a/src/mono/wasm/Makefile +++ b/src/mono/wasm/Makefile @@ -43,10 +43,12 @@ emsdk_env.sh: | provision-wasm cd $(EMSDK_PATH) && ./emsdk construct_env $(CURDIR)/emsdk_env.sh MONO_OBJ_DIR=$(OBJDIR)/mono/Browser.wasm.$(CONFIG) -MONO_LIBS = $(MONO_BIN_DIR)/{libmono-ee-interp.a,libmonosgen-2.0.a,libmono-ilgen.a,libmono-icall-table.a} ${SYS_NATIVE_DIR}/libSystem.Native.a MONO_INCLUDE_DIR=$(MONO_BIN_DIR)/include/mono-2.0 BUILDS_BIN_DIR=$(MONO_BIN_DIR)/wasm/runtimes BUILDS_OBJ_DIR=$(MONO_OBJ_DIR)/wasm/runtimes +MONO_LIBS = \ + $(MONO_BIN_DIR)/{libmono-ee-interp.a,libmonosgen-2.0.a,libmono-ilgen.a,libmono-icall-table.a} \ + ${SYS_NATIVE_DIR}/libSystem.Native.a EMCC_FLAGS=--profiling-funcs -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN=1 -s ALIASING_FUNCTION_POINTERS=0 -s NO_EXIT_RUNTIME=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'FS_createPath', 'FS_createDataFile', 'cwrap', 'setValue', 'getValue', 'UTF8ToString', 'addFunction']" -s "EXPORTED_FUNCTIONS=['_putchar']" --source-map-base http://example.com -s WASM_OBJECT_FILES=0 -s FORCE_FILESYSTEM=1 -s USE_ZLIB=1 EMCC_DEBUG_FLAGS =-g -Os -s ASSERTIONS=1 -DENABLE_NETCORE=1 @@ -90,7 +92,7 @@ $(eval $(call InterpBuildTemplate,debug,,$(EMCC_DEBUG_FLAGS),$(MONO_LIBS))) $(eval $(call InterpBuildTemplate,release,,$(EMCC_RELEASE_FLAGS),$(MONO_LIBS))) build: - EMSDK_PATH=$(PWD)/wasm/emsdk ../../../.dotnet/dotnet build /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=Release + EMSDK_PATH=$(PWD)/wasm/emsdk ../../../.dotnet/dotnet build /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=$(CONFIG) clean-emsdk: $(RM) -rf $(EMSDK_LOCAL_PATH) diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 3ea7167a8c5c3..d83f1fcd4e160 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -4,7 +4,7 @@ + AssemblyFile="$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'WasmAppBuilder', '$(MonoConfiguration)', '$(NetCoreAppCurrent)'))publish\WasmAppBuilder.dll"/> $(MonoObjDir)wasm/pinvoke-table.h @@ -13,9 +13,13 @@ + + + + @@ -25,9 +29,10 @@ - + + Targets="Restore;Build;Publish"/> diff --git a/src/mono/msbuild/WasmAppBuilder/PInvokeTableGenerator.cs b/tools-local/tasks/mobile.tasks/WasmAppBuilder/PInvokeTableGenerator.cs similarity index 100% rename from src/mono/msbuild/WasmAppBuilder/PInvokeTableGenerator.cs rename to tools-local/tasks/mobile.tasks/WasmAppBuilder/PInvokeTableGenerator.cs diff --git a/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.cs b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs similarity index 90% rename from src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.cs rename to tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs index 77538e69107da..e2b76bdf4ca11 100644 --- a/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -28,6 +28,7 @@ public class WasmAppBuilder : Task public string? MainJS { get; set; } [Required] public ITaskItem[]? AssemblySearchPaths { get; set; } + public ITaskItem[]? ExtraAssemblies { get; set; } Dictionary? Assemblies; Resolver? Resolver; @@ -54,6 +55,13 @@ public class WasmAppBuilder : Task var mainAssembly = mlc.LoadFromAssemblyPath (MainAssembly); Add (mlc, mainAssembly); + if (ExtraAssemblies != null) { + foreach (var item in ExtraAssemblies) { + var refAssembly = mlc.LoadFromAssemblyPath (item.ItemSpec); + Add (mlc, refAssembly); + } + } + // Create app Directory.CreateDirectory (AppDir!); Directory.CreateDirectory (Path.Join (AppDir, "managed")); @@ -78,7 +86,7 @@ public class WasmAppBuilder : Task } using (var sw = File.CreateText (Path.Join (AppDir, "run-v8.sh"))) { - sw.WriteLine ("v8 --expose_wasm runtime.js -- --run " + Path.GetFileName (MainAssembly)); + sw.WriteLine ("v8 --expose_wasm runtime.js -- --enable-gc --run " + Path.GetFileName (MainAssembly) + " $*"); } return true; diff --git a/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.csproj b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.csproj similarity index 90% rename from src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.csproj rename to tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.csproj index aa09da974f64a..7913d15f6a944 100644 --- a/src/mono/msbuild/WasmAppBuilder/WasmAppBuilder.csproj +++ b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.csproj @@ -1,7 +1,9 @@ + $(NetCoreAppCurrent) Library false + enable diff --git a/tools-local/tasks/tasks.proj b/tools-local/tasks/tasks.proj index 5fc0d0abf5de0..a81e2f9590eb6 100644 --- a/tools-local/tasks/tasks.proj +++ b/tools-local/tasks/tasks.proj @@ -5,6 +5,8 @@ Condition="'$(TargetOS)' != 'Android'" /> + From cd4607ee38f185446a3c526fe9192be995f383b0 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Tue, 19 May 2020 14:08:03 +0300 Subject: [PATCH 268/420] [mono] Enable System.Runtime.Tests on Android (#36655) --- .config/dotnet-tools.json | 2 +- .../System.Runtime/tests/System/Type/TypeTests.cs | 2 ++ src/mono/netcore/sample/Android/Makefile | 2 +- src/mono/netcore/sample/Android/Program.csproj | 4 ++++ .../mobile.tasks/AndroidAppBuilder/ApkBuilder.cs | 11 ++++++++++- .../AndroidAppBuilder/Templates/runtime-android.c | 11 ++++++++++- 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index fa001915d85d3..fcd09033203e0 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "1.0.0-prerelease.20264.9", + "version": "1.0.0-prerelease.20265.8", "commands": [ "xharness" ] diff --git a/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs b/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs index 7f8cd6368d03c..d45b52c90c57c 100644 --- a/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs +++ b/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs @@ -688,6 +688,8 @@ public static IEnumerable GetInterfaceMap_TestData() [Theory] [MemberData(nameof(GetInterfaceMap_TestData))] + // Android-only, change to TestPlatforms.Android once arcade dependency is updated + [ActiveIssue("https://github.com/dotnet/runtime/issues/36653", TestRuntimes.Mono)] public void GetInterfaceMap(Type interfaceType, Type classType, Tuple[] expectedMap) { InterfaceMapping actualMapping = classType.GetInterfaceMap(interfaceType); diff --git a/src/mono/netcore/sample/Android/Makefile b/src/mono/netcore/sample/Android/Makefile index 32d038d5a2ed0..80211c3408d94 100644 --- a/src/mono/netcore/sample/Android/Makefile +++ b/src/mono/netcore/sample/Android/Makefile @@ -11,7 +11,7 @@ runtimepack: ../../../../.././build.sh Mono+Libs -os Android -arch $(MONO_ARCH) -c $(MONO_CONFIG) apk: clean appbuilder - $(DOTNET) publish -c Release -r android-$(MONO_ARCH) \ + $(DOTNET) publish -c $(MONO_CONFIG) -r android-$(MONO_ARCH) \ /p:Platform=$(MONO_ARCH) /p:DeployAndRun=true clean: diff --git a/src/mono/netcore/sample/Android/Program.csproj b/src/mono/netcore/sample/Android/Program.csproj index d7516dc186290..406e6fa62c83e 100644 --- a/src/mono/netcore/sample/Android/Program.csproj +++ b/src/mono/netcore/sample/Android/Program.csproj @@ -58,9 +58,13 @@ + + + + diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs index b252a46530af4..409cbb5224c21 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs @@ -140,7 +140,8 @@ public class ApkBuilder File.WriteAllText(Path.Combine(OutputDir, "CMakeLists.txt"), cmakeLists); string runtimeAndroidSrc = Utils.GetEmbeddedResource("runtime-android.c") - .Replace("%EntryPointLibName%", Path.GetFileName(entryPointLib)); + .Replace("%EntryPointLibName%", Path.GetFileName(entryPointLib) + .Replace("%RID%", GetRid(abi))); File.WriteAllText(Path.Combine(OutputDir, "runtime-android.c"), runtimeAndroidSrc); string cmakeGenArgs = $"-DCMAKE_TOOLCHAIN_FILE={androidToolchain} -DANDROID_ABI=\"{abi}\" -DANDROID_STL=none " + @@ -236,6 +237,14 @@ public class ApkBuilder return (alignedApk, packageId); } + + private static string GetRid(string abi) => abi switch + { + "arm64-v8a" => "android-arm64", + "armeabi-v7a" => "android-arm", + "x86_64" => "android-x64", + _ => "android-" + abi + }; /// /// Scan android SDK for build tools (ignore preview versions) diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/runtime-android.c b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/runtime-android.c index 8cfdaaf4b998e..4a2af6a62ead7 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/runtime-android.c +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/runtime-android.c @@ -146,7 +146,16 @@ mono_mobile_runtime_init (void) chdir (bundle_path); // TODO: set TRUSTED_PLATFORM_ASSEMBLIES, APP_PATHS and NATIVE_DLL_SEARCH_DIRECTORIES - monovm_initialize(0, NULL, NULL); + + const char* appctx_keys[2]; + appctx_keys[0] = "RUNTIME_IDENTIFIER"; + appctx_keys[1] = "APP_CONTEXT_BASE_DIRECTORY"; + + const char* appctx_values[2]; + appctx_values[0] = "%RID%"; + appctx_values[1] = bundle_path; + + monovm_initialize(2, appctx_keys, appctx_values); mono_debug_init (MONO_DEBUG_FORMAT_MONO); mono_install_assembly_preload_hook (assembly_preload_hook, NULL); From 055423abe4ad6b66d3f1d7983b32f1d8ba2a1e84 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Tue, 19 May 2020 07:42:06 -0400 Subject: [PATCH 269/420] Rewrite NegotiateStream.XxAsync operations with async/await (#36583) * Rewrite NegotiateStream.Read/Write* operations with async/await Gets rid of a bunch of IAsyncResult cruft and makes the XxAsync APIs cancelable. * Combine NegoState into NegotiateStream * Rewrite AuthenticateAs* with async/await * Add more NegotiateStream tests Including for cancellation and a product fix to enable cancellation. * Update ref with overrides * Remove custom IAsyncResults from System.Net.Security * Fix UnitTests project --- .../Interop.NetSecurityNative.cs | 20 +- .../Net/Security/NegotiateStreamPal.Unix.cs | 22 +- .../src/System/Threading/Tasks/TaskToApm.cs | 13 +- .../VirtualNetwork/VirtualNetworkStream.cs | 25 +- .../System.Net.Security.Native/pal_gssapi.c | 6 +- .../System.Net.Security.Native/pal_gssapi.h | 1 - .../ref/System.Net.Security.cs | 4 + .../src/System.Net.Security.csproj | 21 +- .../src/System/Net/FixedSizeReader.cs | 80 -- .../src/System/Net/NTAuthentication.cs | 5 +- .../Net/Security/InternalNegotiateStream.cs | 446 ------- .../src/System/Net/Security/NegoState.cs | 840 ------------- .../System/Net/Security/NegotiateStream.cs | 1053 ++++++++++++----- .../Security/NegotiateStreamPal.Windows.cs | 21 +- .../System/Net/Security/ReadWriteAdapter.cs | 89 ++ .../SslStream.Implementation.Adapters.cs | 63 - .../Net/Security/SslStream.Implementation.cs | 22 +- .../src/System/Net/Security/SslStream.cs | 15 +- .../src/System/Net/SslStreamContext.cs | 19 +- .../src/System/Net/StreamFramer.cs | 549 +-------- .../NegotiateStreamInvalidOperationTest.cs | 52 - .../NegotiateStreamStreamToStreamTest.cs | 320 +++-- .../UnitTests/Fakes/FakeLazyAsyncResult.cs | 43 - .../Fakes/FakeSslStream.Implementation.cs | 2 +- .../System.Net.Security.Unit.Tests.csproj | 5 +- 25 files changed, 1165 insertions(+), 2571 deletions(-) delete mode 100644 src/libraries/System.Net.Security/src/System/Net/FixedSizeReader.cs delete mode 100644 src/libraries/System.Net.Security/src/System/Net/Security/InternalNegotiateStream.cs delete mode 100644 src/libraries/System.Net.Security/src/System/Net/Security/NegoState.cs create mode 100644 src/libraries/System.Net.Security/src/System/Net/Security/ReadWriteAdapter.cs delete mode 100644 src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.Adapters.cs delete mode 100644 src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeLazyAsyncResult.cs diff --git a/src/libraries/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs b/src/libraries/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs index c80283f5f218b..b86d5caaeb350 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs @@ -127,12 +127,11 @@ internal static partial class NetSecurityNative ref GssBuffer token); [DllImport(Interop.Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_Wrap")] - private static extern Status Wrap( + private static extern unsafe Status Wrap( out Status minorStatus, SafeGssContextHandle? contextHandle, bool isEncrypt, - byte[] inputBytes, - int offset, + byte* inputBytes, int count, ref GssBuffer outBuffer); @@ -145,20 +144,17 @@ internal static partial class NetSecurityNative int count, ref GssBuffer outBuffer); - internal static Status WrapBuffer( + internal static unsafe Status WrapBuffer( out Status minorStatus, SafeGssContextHandle? contextHandle, bool isEncrypt, - byte[] inputBytes, - int offset, - int count, + ReadOnlySpan inputBytes, ref GssBuffer outBuffer) { - Debug.Assert(inputBytes != null, "inputBytes must be valid value"); - Debug.Assert(offset >= 0 && offset <= inputBytes.Length, "offset must be valid"); - Debug.Assert(count >= 0 && count <= (inputBytes.Length - offset), "count must be valid"); - - return Wrap(out minorStatus, contextHandle, isEncrypt, inputBytes, offset, count, ref outBuffer); + fixed (byte* inputBytesPtr = inputBytes) + { + return Wrap(out minorStatus, contextHandle, isEncrypt, inputBytesPtr, inputBytes.Length, ref outBuffer); + } } internal static Status UnwrapBuffer( diff --git a/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs b/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs index 21edf85650544..8ba6978f874b7 100644 --- a/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs +++ b/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs @@ -43,19 +43,13 @@ internal static string QueryContextAuthenticationPackage(SafeDeleteContext secur private static byte[] GssWrap( SafeGssContextHandle? context, bool encrypt, - byte[] buffer, - int offset, - int count) + ReadOnlySpan buffer) { - Debug.Assert((buffer != null) && (buffer.Length > 0), "Invalid input buffer passed to Encrypt"); - Debug.Assert((offset >= 0) && (offset < buffer.Length), "Invalid input offset passed to Encrypt"); - Debug.Assert((count >= 0) && (count <= (buffer.Length - offset)), "Invalid input count passed to Encrypt"); - - Interop.NetSecurityNative.GssBuffer encryptedBuffer = default(Interop.NetSecurityNative.GssBuffer); + Interop.NetSecurityNative.GssBuffer encryptedBuffer = default; try { Interop.NetSecurityNative.Status minorStatus; - Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.WrapBuffer(out minorStatus, context, encrypt, buffer, offset, count, ref encryptedBuffer); + Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.WrapBuffer(out minorStatus, context, encrypt, buffer, ref encryptedBuffer); if (status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE) { throw new Interop.NetSecurityNative.GssApiException(status, minorStatus); @@ -555,16 +549,14 @@ internal static SafeFreeCredentials AcquireCredentialsHandle(string package, boo internal static int Encrypt( SafeDeleteContext securityContext, - byte[] buffer, - int offset, - int count, + ReadOnlySpan buffer, bool isConfidential, bool isNtlm, - ref byte[]? output, + [NotNull] ref byte[]? output, uint sequenceNumber) { SafeDeleteNegoContext gssContext = (SafeDeleteNegoContext) securityContext; - byte[] tempOutput = GssWrap(gssContext.GssContext, isConfidential, buffer, offset, count); + byte[] tempOutput = GssWrap(gssContext.GssContext, isConfidential, buffer); // Create space for prefixing with the length const int prefixLength = 4; @@ -628,7 +620,7 @@ internal static int VerifySignature(SafeDeleteContext securityContext, byte[] bu internal static int MakeSignature(SafeDeleteContext securityContext, byte[] buffer, int offset, int count, [AllowNull] ref byte[] output) { SafeDeleteNegoContext gssContext = (SafeDeleteNegoContext)securityContext; - byte[] tempOutput = GssWrap(gssContext.GssContext, false, buffer, offset, count); + byte[] tempOutput = GssWrap(gssContext.GssContext, false, new ReadOnlySpan(buffer, offset, count)); // Create space for prefixing with the length const int prefixLength = 4; output = new byte[tempOutput.Length + prefixLength]; diff --git a/src/libraries/Common/src/System/Threading/Tasks/TaskToApm.cs b/src/libraries/Common/src/System/Threading/Tasks/TaskToApm.cs index 96b41501f3407..7be4563cddecd 100644 --- a/src/libraries/Common/src/System/Threading/Tasks/TaskToApm.cs +++ b/src/libraries/Common/src/System/Threading/Tasks/TaskToApm.cs @@ -14,6 +14,7 @@ #nullable enable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Threading.Tasks { @@ -43,7 +44,7 @@ public static void End(IAsyncResult asyncResult) return; } - throw new ArgumentNullException(nameof(asyncResult)); + ThrowArgumentException(asyncResult); } /// Processes an IAsyncResult returned by Begin. @@ -55,9 +56,17 @@ public static TResult End(IAsyncResult asyncResult) return task.GetAwaiter().GetResult(); } - throw new ArgumentNullException(nameof(asyncResult)); + ThrowArgumentException(asyncResult); + return default!; // unreachable } + /// Throws an argument exception for the invalid . + [DoesNotReturn] + private static void ThrowArgumentException(IAsyncResult asyncResult) => + throw (asyncResult is null ? + new ArgumentNullException(nameof(asyncResult)) : + new ArgumentException(null, nameof(asyncResult))); + /// Provides a simple IAsyncResult that wraps a Task. /// /// We could use the Task as the IAsyncResult if the Task's AsyncState is the same as the object state, diff --git a/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkStream.cs b/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkStream.cs index 0f45acc9f80f0..daf5caf54a60d 100644 --- a/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkStream.cs +++ b/src/libraries/Common/tests/System/Net/VirtualNetwork/VirtualNetworkStream.cs @@ -22,6 +22,8 @@ public VirtualNetworkStream(VirtualNetwork network, bool isServer) _isServer = isServer; } + public int DelayMilliseconds { get; set; } + public bool Disposed { get; private set; } public override bool CanRead => true; @@ -87,6 +89,11 @@ public override async Task ReadAsync(byte[] buffer, int offset, int count, await _readStreamLock.WaitAsync(cancellationToken).ConfigureAwait(false); try { + if (DelayMilliseconds > 0) + { + await Task.Delay(DelayMilliseconds, cancellationToken); + } + if (_readStream == null || (_readStream.Position >= _readStream.Length)) { _readStream = new MemoryStream(await _network.ReadFrameAsync(_isServer, cancellationToken).ConfigureAwait(false)); @@ -105,22 +112,16 @@ public override void Write(byte[] buffer, int offset, int count) _network.WriteFrame(_isServer, buffer.AsSpan(offset, count).ToArray()); } - public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { - if (cancellationToken.IsCancellationRequested) - { - return Task.FromCanceled(cancellationToken); - } + cancellationToken.ThrowIfCancellationRequested(); - try + if (DelayMilliseconds > 0) { - Write(buffer, offset, count); - return Task.CompletedTask; - } - catch (Exception exc) - { - return Task.FromException(exc); + await Task.Delay(DelayMilliseconds, cancellationToken); } + + Write(buffer, offset, count); } public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) => diff --git a/src/libraries/Native/Unix/System.Net.Security.Native/pal_gssapi.c b/src/libraries/Native/Unix/System.Net.Security.Native/pal_gssapi.c index 0fbd518fa8bc0..03eef6231a930 100644 --- a/src/libraries/Native/Unix/System.Net.Security.Native/pal_gssapi.c +++ b/src/libraries/Native/Unix/System.Net.Security.Native/pal_gssapi.c @@ -417,7 +417,6 @@ uint32_t NetSecurityNative_Wrap(uint32_t* minorStatus, GssCtxId* contextHandle, int32_t isEncrypt, uint8_t* inputBytes, - int32_t offset, int32_t count, PAL_GssBuffer* outBuffer) { @@ -425,14 +424,13 @@ uint32_t NetSecurityNative_Wrap(uint32_t* minorStatus, assert(contextHandle != NULL); assert(isEncrypt == 1 || isEncrypt == 0); assert(inputBytes != NULL); - assert(offset >= 0); assert(count >= 0); assert(outBuffer != NULL); // count refers to the length of the input message. That is, number of bytes of inputBytes - // starting at offset that need to be wrapped. + // that need to be wrapped. int confState; - GssBuffer inputMessageBuffer = {.length = (size_t)count, .value = inputBytes + offset}; + GssBuffer inputMessageBuffer = {.length = (size_t)count, .value = inputBytes}; GssBuffer gssBuffer; uint32_t majorStatus = gss_wrap(minorStatus, contextHandle, isEncrypt, GSS_C_QOP_DEFAULT, &inputMessageBuffer, &confState, &gssBuffer); diff --git a/src/libraries/Native/Unix/System.Net.Security.Native/pal_gssapi.h b/src/libraries/Native/Unix/System.Net.Security.Native/pal_gssapi.h index 11e232d01501d..489b66b09290a 100644 --- a/src/libraries/Native/Unix/System.Net.Security.Native/pal_gssapi.h +++ b/src/libraries/Native/Unix/System.Net.Security.Native/pal_gssapi.h @@ -159,7 +159,6 @@ PALEXPORT uint32_t NetSecurityNative_Wrap(uint32_t* minorStatus, GssCtxId* contextHandle, int32_t isEncrypt, uint8_t* inputBytes, - int32_t offset, int32_t count, PAL_GssBuffer* outBuffer); diff --git a/src/libraries/System.Net.Security/ref/System.Net.Security.cs b/src/libraries/System.Net.Security/ref/System.Net.Security.cs index ff6cee15760f3..d657bb1fd59d7 100644 --- a/src/libraries/System.Net.Security/ref/System.Net.Security.cs +++ b/src/libraries/System.Net.Security/ref/System.Net.Security.cs @@ -91,9 +91,13 @@ public partial class NegotiateStream : System.Net.Security.AuthenticatedStream public override void Flush() { } public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; } public override int Read(byte[] buffer, int offset, int count) { throw null; } + public override System.Threading.Tasks.Task ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; } + public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken = default) { throw null; } public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; } public override void SetLength(long value) { } public override void Write(byte[] buffer, int offset, int count) { } + public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; } + public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default) { throw null; } } public enum ProtectionLevel { diff --git a/src/libraries/System.Net.Security/src/System.Net.Security.csproj b/src/libraries/System.Net.Security/src/System.Net.Security.csproj index f2daece20c633..73d613dfa729d 100644 --- a/src/libraries/System.Net.Security/src/System.Net.Security.csproj +++ b/src/libraries/System.Net.Security/src/System.Net.Security.csproj @@ -12,37 +12,32 @@ - - + + + + + + + - - - - - - - - - - @@ -65,8 +60,6 @@ - - /// The class is a simple wrapper on top of a read stream. It will read the exact number of bytes requested. - /// It will throw if EOF is reached before the expected number of bytes is returned. - /// - internal static class FixedSizeReader - { - /// - /// Returns 0 on legitimate EOF or if 0 bytes were requested, otherwise reads as directed or throws. - /// Returns count on success. - /// - public static int ReadPacket(Stream transport, byte[] buffer, int offset, int count) - { - int remainingCount = count; - do - { - int bytes = transport.Read(buffer, offset, remainingCount); - if (bytes == 0) - { - if (remainingCount != count) - { - throw new IOException(SR.net_io_eof); - } - - return 0; - } - - remainingCount -= bytes; - offset += bytes; - } while (remainingCount > 0); - - Debug.Assert(remainingCount == 0); - return count; - } - - /// - /// Completes "request" with 0 if 0 bytes was requested or legitimate EOF received. - /// Otherwise, reads as directed or completes "request" with an Exception. - /// - public static async Task ReadPacketAsync(Stream transport, AsyncProtocolRequest request) - { - try - { - int remainingCount = request.Count, offset = request.Offset; - do - { - int bytes = await transport.ReadAsync(new Memory(request.Buffer, offset, remainingCount), request.CancellationToken).ConfigureAwait(false); - if (bytes == 0) - { - if (remainingCount != request.Count) - { - throw new IOException(SR.net_io_eof); - } - request.CompleteRequest(0); - return; - } - - offset += bytes; - remainingCount -= bytes; - } while (remainingCount > 0); - - Debug.Assert(remainingCount == 0); - request.CompleteRequest(request.Count); - } - catch (Exception e) - { - request.CompleteUserWithError(e); - } - } - } -} diff --git a/src/libraries/System.Net.Security/src/System/Net/NTAuthentication.cs b/src/libraries/System.Net.Security/src/System/Net/NTAuthentication.cs index af931677016e7..0f4f7afef338d 100644 --- a/src/libraries/System.Net.Security/src/System/Net/NTAuthentication.cs +++ b/src/libraries/System.Net.Security/src/System/Net/NTAuthentication.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Net.Security; using System.Security.Authentication.ExtendedProtection; @@ -114,13 +115,11 @@ private static void InitializeCallback(object state) context.ThisPtr.Initialize(context.IsServer, context.Package, context.Credential, context.Spn, context.RequestedContextFlags, context.ChannelBinding); } - internal int Encrypt(byte[] buffer, int offset, int count, ref byte[]? output, uint sequenceNumber) + internal int Encrypt(ReadOnlySpan buffer, [NotNull] ref byte[]? output, uint sequenceNumber) { return NegotiateStreamPal.Encrypt( _securityContext!, buffer, - offset, - count, IsConfidentialityFlag, IsNTLM, ref output, diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/InternalNegotiateStream.cs b/src/libraries/System.Net.Security/src/System/Net/Security/InternalNegotiateStream.cs deleted file mode 100644 index 4c748bd307c29..0000000000000 --- a/src/libraries/System.Net.Security/src/System/Net/Security/InternalNegotiateStream.cs +++ /dev/null @@ -1,446 +0,0 @@ -// 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. - -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Security -{ - // - // This is a wrapping stream that does data encryption/decryption based on a successfully authenticated SSPI context. - // This file contains the private implementation. - // - public partial class NegotiateStream : AuthenticatedStream - { - private static readonly AsyncCallback s_writeCallback = new AsyncCallback(WriteCallback); - private static readonly AsyncProtocolCallback s_readCallback = new AsyncProtocolCallback(ReadCallback); - - private int _NestedWrite; - private int _NestedRead; - private byte[] _ReadHeader = null!; // will be initialized by ctor helper - - // Never updated directly, special properties are used. - private byte[]? _InternalBuffer; - private int _InternalOffset; - private int _InternalBufferCount; - - private void InitializeStreamPart() - { - _ReadHeader = new byte[4]; - } - - private byte[]? InternalBuffer - { - get - { - return _InternalBuffer; - } - } - - private int InternalOffset - { - get - { - return _InternalOffset; - } - } - - private int InternalBufferCount - { - get - { - return _InternalBufferCount; - } - } - - private void DecrementInternalBufferCount(int decrCount) - { - _InternalOffset += decrCount; - _InternalBufferCount -= decrCount; - } - - private void EnsureInternalBufferSize(int bytes) - { - _InternalBufferCount = bytes; - _InternalOffset = 0; - if (InternalBuffer == null || InternalBuffer.Length < bytes) - { - _InternalBuffer = new byte[bytes]; - } - } - - private void AdjustInternalBufferOffsetSize(int bytes, int offset) - { - _InternalBufferCount = bytes; - _InternalOffset = offset; - } - - // - // Validates user parameters for all Read/Write methods. - // - private void ValidateParameters(byte[] buffer, int offset, int count) - { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - - if (offset < 0) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } - - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count)); - } - - if (count > buffer.Length - offset) - { - throw new ArgumentOutOfRangeException(nameof(count), SR.net_offset_plus_count); - } - } - - // - // Combined sync/async write method. For sync request asyncRequest==null. - // - private void ProcessWrite(byte[] buffer, int offset, int count, AsyncProtocolRequest? asyncRequest) - { - ValidateParameters(buffer, offset, count); - - if (Interlocked.Exchange(ref _NestedWrite, 1) == 1) - { - throw new NotSupportedException(SR.Format(SR.net_io_invalidnestedcall, (asyncRequest != null ? "BeginWrite" : "Write"), "write")); - } - - bool failed = false; - try - { - StartWriting(buffer, offset, count, asyncRequest); - } - catch (Exception e) - { - failed = true; - if (e is IOException) - { - throw; - } - - throw new IOException(SR.net_io_write, e); - } - finally - { - if (asyncRequest == null || failed) - { - _NestedWrite = 0; - } - } - } - - private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolRequest? asyncRequest) - { - // We loop to this method from the callback. - // If the last chunk was just completed from async callback (count < 0), we complete user request. - if (count >= 0) - { - byte[]? outBuffer = null; - do - { - int chunkBytes = Math.Min(count, NegoState.MaxWriteDataSize); - int encryptedBytes; - - try - { - encryptedBytes = _negoState.EncryptData(buffer, offset, chunkBytes, ref outBuffer); - } - catch (Exception e) - { - throw new IOException(SR.net_io_encrypt, e); - } - - if (asyncRequest != null) - { - // prepare for the next request - asyncRequest.SetNextRequest(buffer, offset + chunkBytes, count - chunkBytes, null); - Task t = InnerStream.WriteAsync(outBuffer!, 0, encryptedBytes); - if (t.IsCompleted) - { - t.GetAwaiter().GetResult(); - } - else - { - IAsyncResult ar = TaskToApm.Begin(t, s_writeCallback, asyncRequest); - if (!ar.CompletedSynchronously) - { - return; - } - TaskToApm.End(ar); - } - } - else - { - InnerStream.Write(outBuffer!, 0, encryptedBytes); - } - - offset += chunkBytes; - count -= chunkBytes; - } while (count != 0); - } - - if (asyncRequest != null) - { - asyncRequest.CompleteUser(); - } - } - - // - // Combined sync/async read method. For sync request asyncRequest==null. - // There is a little overhead because we need to pass buffer/offset/count used only in sync. - // Still the benefit is that we have a common sync/async code path. - // - private int ProcessRead(byte[] buffer, int offset, int count, AsyncProtocolRequest? asyncRequest) - { - ValidateParameters(buffer, offset, count); - - if (Interlocked.Exchange(ref _NestedRead, 1) == 1) - { - throw new NotSupportedException(SR.Format(SR.net_io_invalidnestedcall, (asyncRequest != null ? "BeginRead" : "Read"), "read")); - } - - bool failed = false; - try - { - if (InternalBufferCount != 0) - { - int copyBytes = InternalBufferCount > count ? count : InternalBufferCount; - if (copyBytes != 0) - { - Buffer.BlockCopy(InternalBuffer!, InternalOffset, buffer, offset, copyBytes); - DecrementInternalBufferCount(copyBytes); - } - asyncRequest?.CompleteUser(copyBytes); - return copyBytes; - } - - // Performing actual I/O. - return StartReading(buffer, offset, count, asyncRequest); - } - catch (Exception e) - { - failed = true; - if (e is IOException) - { - throw; - } - throw new IOException(SR.net_io_read, e); - } - finally - { - if (asyncRequest == null || failed) - { - _NestedRead = 0; - } - } - } - - // - // To avoid recursion when 0 bytes have been decrypted, loop until decryption results in at least 1 byte. - // - private int StartReading(byte[] buffer, int offset, int count, AsyncProtocolRequest? asyncRequest) - { - int result; - // When we read -1 bytes means we have decrypted 0 bytes, need looping. - while ((result = StartFrameHeader(buffer, offset, count, asyncRequest)) == -1); - - return result; - } - - private int StartFrameHeader(byte[] buffer, int offset, int count, AsyncProtocolRequest? asyncRequest) - { - int readBytes = 0; - if (asyncRequest != null) - { - asyncRequest.SetNextRequest(_ReadHeader, 0, _ReadHeader.Length, s_readCallback); - _ = FixedSizeReader.ReadPacketAsync(InnerStream, asyncRequest); - if (!asyncRequest.MustCompleteSynchronously) - { - return 0; - } - - readBytes = asyncRequest.Result; - } - else - { - readBytes = FixedSizeReader.ReadPacket(InnerStream, _ReadHeader, 0, _ReadHeader.Length); - } - - return StartFrameBody(readBytes, buffer, offset, count, asyncRequest); - } - - private int StartFrameBody(int readBytes, byte[] buffer, int offset, int count, AsyncProtocolRequest? asyncRequest) - { - if (readBytes == 0) - { - //EOF - asyncRequest?.CompleteUser(0); - return 0; - } - - if (!(readBytes == _ReadHeader.Length)) - { - NetEventSource.Fail(this, $"Frame size must be 4 but received {readBytes} bytes."); - } - - // Replace readBytes with the body size recovered from the header content. - readBytes = _ReadHeader[3]; - readBytes = (readBytes << 8) | _ReadHeader[2]; - readBytes = (readBytes << 8) | _ReadHeader[1]; - readBytes = (readBytes << 8) | _ReadHeader[0]; - - // - // The body carries 4 bytes for trailer size slot plus trailer, hence <=4 frame size is always an error. - // Additionally we'd like to restrict the read frame size to 64k. - // - if (readBytes <= 4 || readBytes > NegoState.MaxReadFrameSize) - { - throw new IOException(SR.net_frame_read_size); - } - - // - // Always pass InternalBuffer for SSPI "in place" decryption. - // A user buffer can be shared by many threads in that case decryption/integrity check may fail cause of data corruption. - // - EnsureInternalBufferSize(readBytes); - if (asyncRequest != null) - { - asyncRequest.SetNextRequest(InternalBuffer, 0, readBytes, s_readCallback); - - _ = FixedSizeReader.ReadPacketAsync(InnerStream, asyncRequest); - - if (!asyncRequest.MustCompleteSynchronously) - { - return 0; - } - - readBytes = asyncRequest.Result; - } - else //Sync - { - readBytes = FixedSizeReader.ReadPacket(InnerStream, InternalBuffer!, 0, readBytes); - } - - return ProcessFrameBody(readBytes, buffer, offset, count, asyncRequest); - } - - private int ProcessFrameBody(int readBytes, byte[] buffer, int offset, int count, AsyncProtocolRequest? asyncRequest) - { - if (readBytes == 0) - { - // We already checked that the frame body is bigger than 0 bytes - // Hence, this is an EOF ... fire. - throw new IOException(SR.net_io_eof); - } - - // Decrypt into internal buffer, change "readBytes" to count now _Decrypted Bytes_ - int internalOffset; - readBytes = _negoState.DecryptData(InternalBuffer!, 0, readBytes, out internalOffset); - - // Decrypted data start from zero offset, the size can be shrunk after decryption. - AdjustInternalBufferOffsetSize(readBytes, internalOffset); - - if (readBytes == 0 && count != 0) - { - // Read again. - return -1; - } - - if (readBytes > count) - { - readBytes = count; - } - - Buffer.BlockCopy(InternalBuffer!, InternalOffset, buffer, offset, readBytes); - - // This will adjust both the remaining internal buffer count and the offset. - DecrementInternalBufferCount(readBytes); - - asyncRequest?.CompleteUser(readBytes); - - return readBytes; - } - - private static void WriteCallback(IAsyncResult transportResult) - { - if (transportResult.CompletedSynchronously) - { - return; - } - - if (!(transportResult.AsyncState is AsyncProtocolRequest)) - { - NetEventSource.Fail(transportResult, "State type is wrong, expected AsyncProtocolRequest."); - } - - AsyncProtocolRequest asyncRequest = (AsyncProtocolRequest)transportResult.AsyncState!; - - try - { - NegotiateStream negoStream = (NegotiateStream)asyncRequest.AsyncObject!; - TaskToApm.End(transportResult); - if (asyncRequest.Count == 0) - { - // This was the last chunk. - asyncRequest.Count = -1; - } - - negoStream.StartWriting(asyncRequest.Buffer!, asyncRequest.Offset, asyncRequest.Count, asyncRequest); - } - catch (Exception e) - { - if (asyncRequest.IsUserCompleted) - { - // This will throw on a worker thread. - throw; - } - - asyncRequest.CompleteUserWithError(e); - } - } - - private static void ReadCallback(AsyncProtocolRequest asyncRequest) - { - // Async ONLY completion. - try - { - NegotiateStream negoStream = (NegotiateStream)asyncRequest.AsyncObject!; - BufferAsyncResult bufferResult = (BufferAsyncResult)asyncRequest.UserAsyncResult; - - // This is an optimization to avoid an additional callback. - if ((object?)asyncRequest.Buffer == (object?)negoStream._ReadHeader) - { - negoStream.StartFrameBody(asyncRequest.Result, bufferResult.Buffer, bufferResult.Offset, bufferResult.Count, asyncRequest); - } - else - { - if (-1 == negoStream.ProcessFrameBody(asyncRequest.Result, bufferResult.Buffer, bufferResult.Offset, bufferResult.Count, asyncRequest)) - { - // In case we decrypted 0 bytes, start another reading. - negoStream.StartReading(bufferResult.Buffer, bufferResult.Offset, bufferResult.Count, asyncRequest); - } - } - } - catch (Exception e) - { - if (asyncRequest.IsUserCompleted) - { - // This will throw on a worker thread. - throw; - } - - asyncRequest.CompleteUserWithError(e); - } - } - } -} diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/NegoState.cs b/src/libraries/System.Net.Security/src/System/Net/Security/NegoState.cs deleted file mode 100644 index b59ffb97692ca..0000000000000 --- a/src/libraries/System.Net.Security/src/System/Net/Security/NegoState.cs +++ /dev/null @@ -1,840 +0,0 @@ -// 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. - -using System.Diagnostics; -using System.IO; -using System.Security.Principal; -using System.Threading; -using System.ComponentModel; -using System.Runtime.ExceptionServices; -using System.Security.Authentication; -using System.Security.Authentication.ExtendedProtection; - -namespace System.Net.Security -{ - // - // The class maintains the state of the authentication process and the security context. - // It encapsulates security context and does the real work in authentication and - // user data encryption - // - internal class NegoState - { -#pragma warning disable CA1825 // used in reference comparison, requires unique object identity - private static readonly byte[] s_emptyMessage = new byte[0]; -#pragma warning restore CA1825 - private static readonly AsyncCallback s_readCallback = new AsyncCallback(ReadCallback); - private static readonly AsyncCallback s_writeCallback = new AsyncCallback(WriteCallback); - - private readonly Stream _innerStream; - - private Exception? _exception; - - private StreamFramer? _framer; - private NTAuthentication? _context; - - private int _nestedAuth; - - internal const int ERROR_TRUST_FAILURE = 1790; // Used to serialize protectionLevel or impersonationLevel mismatch error to the remote side. - internal const int MaxReadFrameSize = 64 * 1024; - internal const int MaxWriteDataSize = 63 * 1024; // 1k for the framing and trailer that is always less as per SSPI. - - private bool _canRetryAuthentication; - private ProtectionLevel _expectedProtectionLevel; - private TokenImpersonationLevel _expectedImpersonationLevel; - private uint _writeSequenceNumber; - private uint _readSequenceNumber; - - private ExtendedProtectionPolicy? _extendedProtectionPolicy; - - // SSPI does not send a server ack on successful auth. - // This is a state variable used to gracefully handle auth confirmation. - private bool _remoteOk = false; - - internal NegoState(Stream innerStream) - { - Debug.Assert(innerStream != null); - - _innerStream = innerStream; - } - - internal static string DefaultPackage - { - get - { - return NegotiationInfoClass.Negotiate; - } - } - - internal IIdentity GetIdentity() - { - CheckThrow(true); - return NegotiateStreamPal.GetIdentity(_context!); - } - - internal void ValidateCreateContext( - string package, - NetworkCredential credential, - string servicePrincipalName, - ExtendedProtectionPolicy? policy, - ProtectionLevel protectionLevel, - TokenImpersonationLevel impersonationLevel) - { - if (policy != null) - { - // One of these must be set if EP is turned on - if (policy.CustomChannelBinding == null && policy.CustomServiceNames == null) - { - throw new ArgumentException(SR.net_auth_must_specify_extended_protection_scheme, nameof(policy)); - } - - _extendedProtectionPolicy = policy; - } - else - { - _extendedProtectionPolicy = new ExtendedProtectionPolicy(PolicyEnforcement.Never); - } - - ValidateCreateContext(package, true, credential, servicePrincipalName, _extendedProtectionPolicy!.CustomChannelBinding, protectionLevel, impersonationLevel); - } - - internal void ValidateCreateContext( - string package, - bool isServer, - NetworkCredential credential, - string? servicePrincipalName, - ChannelBinding? channelBinding, - ProtectionLevel protectionLevel, - TokenImpersonationLevel impersonationLevel) - { - if (_exception != null && !_canRetryAuthentication) - { - ExceptionDispatchInfo.Throw(_exception); - } - - if (_context != null && _context.IsValidContext) - { - throw new InvalidOperationException(SR.net_auth_reauth); - } - - if (credential == null) - { - throw new ArgumentNullException(nameof(credential)); - } - - if (servicePrincipalName == null) - { - throw new ArgumentNullException(nameof(servicePrincipalName)); - } - - NegotiateStreamPal.ValidateImpersonationLevel(impersonationLevel); - if (_context != null && IsServer != isServer) - { - throw new InvalidOperationException(SR.net_auth_client_server); - } - - _exception = null; - _remoteOk = false; - _framer = new StreamFramer(_innerStream); - _framer.WriteHeader.MessageId = FrameHeader.HandshakeId; - - _expectedProtectionLevel = protectionLevel; - _expectedImpersonationLevel = isServer ? impersonationLevel : TokenImpersonationLevel.None; - _writeSequenceNumber = 0; - _readSequenceNumber = 0; - - ContextFlagsPal flags = ContextFlagsPal.Connection; - - // A workaround for the client when talking to Win9x on the server side. - if (protectionLevel == ProtectionLevel.None && !isServer) - { - package = NegotiationInfoClass.NTLM; - } - else if (protectionLevel == ProtectionLevel.EncryptAndSign) - { - flags |= ContextFlagsPal.Confidentiality; - } - else if (protectionLevel == ProtectionLevel.Sign) - { - // Assuming user expects NT4 SP4 and above. - flags |= (ContextFlagsPal.ReplayDetect | ContextFlagsPal.SequenceDetect | ContextFlagsPal.InitIntegrity); - } - - if (isServer) - { - if (_extendedProtectionPolicy!.PolicyEnforcement == PolicyEnforcement.WhenSupported) - { - flags |= ContextFlagsPal.AllowMissingBindings; - } - - if (_extendedProtectionPolicy.PolicyEnforcement != PolicyEnforcement.Never && - _extendedProtectionPolicy.ProtectionScenario == ProtectionScenario.TrustedProxy) - { - flags |= ContextFlagsPal.ProxyBindings; - } - } - else - { - // Server side should not request any of these flags. - if (protectionLevel != ProtectionLevel.None) - { - flags |= ContextFlagsPal.MutualAuth; - } - - if (impersonationLevel == TokenImpersonationLevel.Identification) - { - flags |= ContextFlagsPal.InitIdentify; - } - - if (impersonationLevel == TokenImpersonationLevel.Delegation) - { - flags |= ContextFlagsPal.Delegate; - } - } - - _canRetryAuthentication = false; - - try - { - _context = new NTAuthentication(isServer, package, credential, servicePrincipalName, flags, channelBinding!); - } - catch (Win32Exception e) - { - throw new AuthenticationException(SR.net_auth_SSPI, e); - } - } - - private Exception SetException(Exception e) - { - if (_exception == null || !(_exception is ObjectDisposedException)) - { - _exception = e; - } - - if (_exception != null && _context != null) - { - _context.CloseContext(); - } - - return _exception!; - } - - internal bool IsAuthenticated - { - get - { - return _context != null && HandshakeComplete && _exception == null && _remoteOk; - } - } - - internal bool IsMutuallyAuthenticated - { - get - { - if (!IsAuthenticated) - { - return false; - } - - // Suppressing for NTLM since SSPI does not return correct value in the context flags. - if (_context!.IsNTLM) - { - return false; - } - - return _context.IsMutualAuthFlag; - } - } - - internal bool IsEncrypted - { - get - { - return IsAuthenticated && _context!.IsConfidentialityFlag; - } - } - - internal bool IsSigned - { - get - { - return IsAuthenticated && (_context!.IsIntegrityFlag || _context.IsConfidentialityFlag); - } - } - - internal bool IsServer - { - get - { - return _context != null && _context.IsServer; - } - } - - internal bool CanGetSecureStream - { - get - { - return (_context!.IsConfidentialityFlag || _context.IsIntegrityFlag); - } - } - - internal TokenImpersonationLevel AllowedImpersonation - { - get - { - CheckThrow(true); - return PrivateImpersonationLevel; - } - } - - private TokenImpersonationLevel PrivateImpersonationLevel - { - get - { - // We should suppress the delegate flag in NTLM case. - return (_context!.IsDelegationFlag && _context.ProtocolName != NegotiationInfoClass.NTLM) ? TokenImpersonationLevel.Delegation - : _context.IsIdentifyFlag ? TokenImpersonationLevel.Identification - : TokenImpersonationLevel.Impersonation; - } - } - - private bool HandshakeComplete - { - get - { - return _context!.IsCompleted && _context.IsValidContext; - } - } - - internal void CheckThrow(bool authSucessCheck) - { - if (_exception != null) - { - ExceptionDispatchInfo.Throw(_exception); - } - - if (authSucessCheck && !IsAuthenticated) - { - throw new InvalidOperationException(SR.net_auth_noauth); - } - } - - // - // This is to not depend on GC&SafeHandle class if the context is not needed anymore. - // - internal void Close() - { - // Mark this instance as disposed. - _exception = new ObjectDisposedException("NegotiateStream"); - if (_context != null) - { - _context.CloseContext(); - } - } - - internal void ProcessAuthentication(LazyAsyncResult? lazyResult) - { - CheckThrow(false); - if (Interlocked.Exchange(ref _nestedAuth, 1) == 1) - { - throw new InvalidOperationException(SR.Format(SR.net_io_invalidnestedcall, lazyResult == null ? "BeginAuthenticate" : "Authenticate", "authenticate")); - } - - try - { - if (_context!.IsServer) - { - // Listen for a client blob. - StartReceiveBlob(lazyResult); - } - else - { - // Start with the first blob. - StartSendBlob(null, lazyResult); - } - } - catch (Exception e) - { - // Round-trip it through SetException(). - e = SetException(e); - throw; - } - finally - { - if (lazyResult == null || _exception != null) - { - _nestedAuth = 0; - } - } - } - - internal void EndProcessAuthentication(IAsyncResult result) - { - if (result == null) - { - throw new ArgumentNullException("asyncResult"); - } - - LazyAsyncResult? lazyResult = result as LazyAsyncResult; - if (lazyResult == null) - { - throw new ArgumentException(SR.Format(SR.net_io_async_result, result.GetType().FullName), "asyncResult"); - } - - if (Interlocked.Exchange(ref _nestedAuth, 0) == 0) - { - throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndAuthenticate")); - } - - // No "artificial" timeouts implemented so far, InnerStream controls that. - lazyResult.InternalWaitForCompletion(); - - Exception? e = lazyResult.Result as Exception; - - if (e != null) - { - // Round-trip it through the SetException(). - e = SetException(e); - ExceptionDispatchInfo.Throw(e); - } - } - - private bool CheckSpn() - { - if (_context!.IsKerberos) - { - return true; - } - - if (_extendedProtectionPolicy!.PolicyEnforcement == PolicyEnforcement.Never || - _extendedProtectionPolicy.CustomServiceNames == null) - { - return true; - } - - string? clientSpn = _context.ClientSpecifiedSpn; - - if (string.IsNullOrEmpty(clientSpn)) - { - if (_extendedProtectionPolicy.PolicyEnforcement == PolicyEnforcement.WhenSupported) - { - return true; - } - } - else - { - return _extendedProtectionPolicy.CustomServiceNames.Contains(clientSpn); - } - - return false; - } - - // - // Client side starts here, but server also loops through this method. - // - private void StartSendBlob(byte[]? message, LazyAsyncResult? lazyResult) - { - Exception? exception = null; - if (message != s_emptyMessage) - { - message = GetOutgoingBlob(message, ref exception); - } - - if (exception != null) - { - // Signal remote side on a failed attempt. - StartSendAuthResetSignal(lazyResult, message!, exception); - return; - } - - if (HandshakeComplete) - { - if (_context!.IsServer && !CheckSpn()) - { - exception = new AuthenticationException(SR.net_auth_bad_client_creds_or_target_mismatch); - int statusCode = ERROR_TRUST_FAILURE; - message = new byte[8]; //sizeof(long) - - for (int i = message.Length - 1; i >= 0; --i) - { - message[i] = (byte)(statusCode & 0xFF); - statusCode = (int)((uint)statusCode >> 8); - } - - StartSendAuthResetSignal(lazyResult, message, exception); - return; - } - - if (PrivateImpersonationLevel < _expectedImpersonationLevel) - { - exception = new AuthenticationException(SR.Format(SR.net_auth_context_expectation, _expectedImpersonationLevel.ToString(), PrivateImpersonationLevel.ToString())); - int statusCode = ERROR_TRUST_FAILURE; - message = new byte[8]; //sizeof(long) - - for (int i = message.Length - 1; i >= 0; --i) - { - message[i] = (byte)(statusCode & 0xFF); - statusCode = (int)((uint)statusCode >> 8); - } - - StartSendAuthResetSignal(lazyResult, message, exception); - return; - } - - ProtectionLevel result = _context.IsConfidentialityFlag ? ProtectionLevel.EncryptAndSign : _context.IsIntegrityFlag ? ProtectionLevel.Sign : ProtectionLevel.None; - - if (result < _expectedProtectionLevel) - { - exception = new AuthenticationException(SR.Format(SR.net_auth_context_expectation, result.ToString(), _expectedProtectionLevel.ToString())); - int statusCode = ERROR_TRUST_FAILURE; - message = new byte[8]; //sizeof(long) - - for (int i = message.Length - 1; i >= 0; --i) - { - message[i] = (byte)(statusCode & 0xFF); - statusCode = (int)((uint)statusCode >> 8); - } - - StartSendAuthResetSignal(lazyResult, message, exception); - return; - } - - // Signal remote party that we are done - _framer!.WriteHeader.MessageId = FrameHeader.HandshakeDoneId; - if (_context.IsServer) - { - // Server may complete now because client SSPI would not complain at this point. - _remoteOk = true; - - // However the client will wait for server to send this ACK - //Force signaling server OK to the client - if (message == null) - { - message = s_emptyMessage; - } - } - } - else if (message == null || message == s_emptyMessage) - { - throw new InternalException(); - } - - if (message != null) - { - //even if we are completed, there could be a blob for sending. - if (lazyResult == null) - { - _framer!.WriteMessage(message); - } - else - { - IAsyncResult ar = _framer!.BeginWriteMessage(message, s_writeCallback, lazyResult); - if (!ar.CompletedSynchronously) - { - return; - } - _framer.EndWriteMessage(ar); - } - } - CheckCompletionBeforeNextReceive(lazyResult); - } - - // - // This will check and logically complete the auth handshake. - // - private void CheckCompletionBeforeNextReceive(LazyAsyncResult? lazyResult) - { - if (HandshakeComplete && _remoteOk) - { - // We are done with success. - if (lazyResult != null) - { - lazyResult.InvokeCallback(); - } - - return; - } - - StartReceiveBlob(lazyResult); - } - - // - // Server side starts here, but client also loops through this method. - // - private void StartReceiveBlob(LazyAsyncResult? lazyResult) - { - Debug.Assert(_framer != null); - - byte[]? message; - if (lazyResult == null) - { - message = _framer.ReadMessage(); - } - else - { - IAsyncResult ar = _framer.BeginReadMessage(s_readCallback, lazyResult); - if (!ar.CompletedSynchronously) - { - return; - } - - message = _framer.EndReadMessage(ar); - } - - ProcessReceivedBlob(message, lazyResult); - } - - private void ProcessReceivedBlob(byte[]? message, LazyAsyncResult? lazyResult) - { - // This is an EOF otherwise we would get at least *empty* message but not a null one. - if (message == null) - { - throw new AuthenticationException(SR.net_auth_eof, null); - } - - // Process Header information. - if (_framer!.ReadHeader.MessageId == FrameHeader.HandshakeErrId) - { - if (message.Length >= 8) // sizeof(long) - { - // Try to recover remote win32 Exception. - long error = 0; - for (int i = 0; i < 8; ++i) - { - error = (error << 8) + message[i]; - } - - ThrowCredentialException(error); - } - - throw new AuthenticationException(SR.net_auth_alert, null); - } - - if (_framer.ReadHeader.MessageId == FrameHeader.HandshakeDoneId) - { - _remoteOk = true; - } - else if (_framer.ReadHeader.MessageId != FrameHeader.HandshakeId) - { - throw new AuthenticationException(SR.Format(SR.net_io_header_id, "MessageId", _framer.ReadHeader.MessageId, FrameHeader.HandshakeId), null); - } - - CheckCompletionBeforeNextSend(message, lazyResult); - } - - // - // This will check and logically complete the auth handshake. - // - private void CheckCompletionBeforeNextSend(byte[] message, LazyAsyncResult? lazyResult) - { - //If we are done don't go into send. - if (HandshakeComplete) - { - if (!_remoteOk) - { - throw new AuthenticationException(SR.Format(SR.net_io_header_id, "MessageId", _framer!.ReadHeader.MessageId, FrameHeader.HandshakeDoneId), null); - } - if (lazyResult != null) - { - lazyResult.InvokeCallback(); - } - - return; - } - - // Not yet done, get a new blob and send it if any. - StartSendBlob(message, lazyResult); - } - - // - // This is to reset auth state on the remote side. - // If this write succeeds we will allow auth retrying. - // - private void StartSendAuthResetSignal(LazyAsyncResult? lazyResult, byte[] message, Exception exception) - { - _framer!.WriteHeader.MessageId = FrameHeader.HandshakeErrId; - - if (IsLogonDeniedException(exception)) - { - if (IsServer) - { - exception = new InvalidCredentialException(SR.net_auth_bad_client_creds, exception); - } - else - { - exception = new InvalidCredentialException(SR.net_auth_bad_client_creds_or_target_mismatch, exception); - } - } - - if (!(exception is AuthenticationException)) - { - exception = new AuthenticationException(SR.net_auth_SSPI, exception); - } - - if (lazyResult == null) - { - _framer.WriteMessage(message); - } - else - { - lazyResult.Result = exception; - IAsyncResult ar = _framer.BeginWriteMessage(message, s_writeCallback, lazyResult); - if (!ar.CompletedSynchronously) - { - return; - } - - _framer.EndWriteMessage(ar); - } - - _canRetryAuthentication = true; - ExceptionDispatchInfo.Throw(exception); - } - - private static void WriteCallback(IAsyncResult transportResult) - { - if (!(transportResult.AsyncState is LazyAsyncResult)) - { - NetEventSource.Fail(transportResult, "State type is wrong, expected LazyAsyncResult."); - } - - if (transportResult.CompletedSynchronously) - { - return; - } - - LazyAsyncResult lazyResult = (LazyAsyncResult)transportResult.AsyncState!; - - // Async completion. - try - { - NegoState authState = (NegoState)lazyResult.AsyncObject!; - authState._framer!.EndWriteMessage(transportResult); - - // Special case for an error notification. - if (lazyResult.Result is Exception e) - { - authState._canRetryAuthentication = true; - ExceptionDispatchInfo.Throw(e); - } - - authState.CheckCompletionBeforeNextReceive(lazyResult); - } - catch (Exception e) - { - if (lazyResult.InternalPeekCompleted) - { - // This will throw on a worker thread. - throw; - } - - lazyResult.InvokeCallback(e); - } - } - - private static void ReadCallback(IAsyncResult transportResult) - { - if (!(transportResult.AsyncState is LazyAsyncResult)) - { - NetEventSource.Fail(transportResult, "State type is wrong, expected LazyAsyncResult."); - } - - if (transportResult.CompletedSynchronously) - { - return; - } - - LazyAsyncResult lazyResult = (LazyAsyncResult)transportResult.AsyncState!; - - // Async completion. - try - { - NegoState authState = (NegoState)lazyResult.AsyncObject!; - byte[]? message = authState._framer!.EndReadMessage(transportResult); - authState.ProcessReceivedBlob(message, lazyResult); - } - catch (Exception e) - { - if (lazyResult.InternalPeekCompleted) - { - // This will throw on a worker thread. - throw; - } - - lazyResult.InvokeCallback(e); - } - } - - internal static bool IsError(SecurityStatusPal status) - { - return ((int)status.ErrorCode >= (int)SecurityStatusPalErrorCode.OutOfMemory); - } - - private unsafe byte[]? GetOutgoingBlob(byte[]? incomingBlob, ref Exception? e) - { - byte[]? message = _context!.GetOutgoingBlob(incomingBlob, false, out SecurityStatusPal statusCode); - - if (IsError(statusCode)) - { - e = NegotiateStreamPal.CreateExceptionFromError(statusCode); - uint error = (uint)e.HResult; - - message = new byte[sizeof(long)]; - for (int i = message.Length - 1; i >= 0; --i) - { - message[i] = (byte)(error & 0xFF); - error = (error >> 8); - } - } - - if (message != null && message.Length == 0) - { - message = s_emptyMessage; - } - - return message; - } - - internal int EncryptData(byte[] buffer, int offset, int count, ref byte[]? outBuffer) - { - CheckThrow(true); - - // SSPI seems to ignore this sequence number. - ++_writeSequenceNumber; - return _context!.Encrypt(buffer, offset, count, ref outBuffer, _writeSequenceNumber); - } - - internal int DecryptData(byte[] buffer, int offset, int count, out int newOffset) - { - CheckThrow(true); - - // SSPI seems to ignore this sequence number. - ++_readSequenceNumber; - return _context!.Decrypt(buffer, offset, count, out newOffset, _readSequenceNumber); - } - - internal static void ThrowCredentialException(long error) - { - Win32Exception e = new Win32Exception((int)error); - - if (e.NativeErrorCode == (int)SecurityStatusPalErrorCode.LogonDenied) - { - throw new InvalidCredentialException(SR.net_auth_bad_client_creds, e); - } - - if (e.NativeErrorCode == NegoState.ERROR_TRUST_FAILURE) - { - throw new AuthenticationException(SR.net_auth_context_expectation_remote, e); - } - - throw new AuthenticationException(SR.net_auth_alert, e); - } - - internal static bool IsLogonDeniedException(Exception exception) - { - Win32Exception? win32exception = exception as Win32Exception; - - return (win32exception != null) && (win32exception.NativeErrorCode == (int)SecurityStatusPalErrorCode.LogonDenied); - } - } -} diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStream.cs b/src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStream.cs index 0b221f41c84b3..8a420ed6a4baf 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStream.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStream.cs @@ -2,34 +2,59 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.ComponentModel; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Threading; -using System.Threading.Tasks; +using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; +using System.Security.Authentication; using System.Security.Authentication.ExtendedProtection; using System.Security.Principal; +using System.Threading; +using System.Threading.Tasks; namespace System.Net.Security { - /* - An authenticated stream based on NEGO SSP. - - The class that can be used by client and server side applications - - to transfer Identities across the stream - - to encrypt data based on NEGO SSP package - - In most cases the innerStream will be of type NetworkStream. - On Win9x data encryption is not available and both sides have - to explicitly drop SecurityLevel and MuatualAuth requirements. - - This is a simple wrapper class. - All real work is done by internal NegoState class and the other partial implementation files. - */ + /// + /// Provides a stream that uses the Negotiate security protocol to authenticate the client, and optionally the server, in client-server communication. + /// public partial class NegotiateStream : AuthenticatedStream { - private readonly NegoState _negoState; - private readonly string _package; + private const int ERROR_TRUST_FAILURE = 1790; // Used to serialize protectionLevel or impersonationLevel mismatch error to the remote side. + private const int MaxReadFrameSize = 64 * 1024; + private const int MaxWriteDataSize = 63 * 1024; // 1k for the framing and trailer that is always less as per SSPI. + private const string DefaultPackage = NegotiationInfoClass.Negotiate; + +#pragma warning disable CA1825 // used in reference comparison, requires unique object identity + private static readonly byte[] s_emptyMessage = new byte[0]; +#pragma warning restore CA1825 + + private readonly byte[] _readHeader; private IIdentity? _remoteIdentity; + private byte[] _buffer; + private int _bufferOffset; + private int _bufferCount; + + private volatile int _writeInProgress; + private volatile int _readInProgress; + private volatile int _authInProgress; + + private Exception? _exception; + private StreamFramer? _framer; + private NTAuthentication? _context; + private bool _canRetryAuthentication; + private ProtectionLevel _expectedProtectionLevel; + private TokenImpersonationLevel _expectedImpersonationLevel; + private uint _writeSequenceNumber; + private uint _readSequenceNumber; + private ExtendedProtectionPolicy? _extendedProtectionPolicy; + + /// + /// SSPI does not send a server ack on successful auth. + /// This is a state variable used to gracefully handle auth confirmation. + /// + private bool _remoteOk = false; public NegotiateStream(Stream innerStream) : this(innerStream, false) { @@ -37,530 +62,920 @@ public NegotiateStream(Stream innerStream) : this(innerStream, false) public NegotiateStream(Stream innerStream, bool leaveInnerStreamOpen) : base(innerStream, leaveInnerStreamOpen) { - _negoState = new NegoState(innerStream); - _package = NegoState.DefaultPackage; - InitializeStreamPart(); + _readHeader = new byte[4]; + _buffer = Array.Empty(); } - public virtual IAsyncResult BeginAuthenticateAsClient(AsyncCallback? asyncCallback, object? asyncState) + protected override void Dispose(bool disposing) { - return BeginAuthenticateAsClient((NetworkCredential)CredentialCache.DefaultCredentials, null, string.Empty, - ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, - asyncCallback, asyncState); + try + { + _exception = new ObjectDisposedException(nameof(NegotiateStream)); + _context?.CloseContext(); + } + finally + { + base.Dispose(disposing); + } } - public virtual IAsyncResult BeginAuthenticateAsClient(NetworkCredential credential, string targetName, AsyncCallback? asyncCallback, object? asyncState) + public override async ValueTask DisposeAsync() { - return BeginAuthenticateAsClient(credential, null, targetName, - ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, - asyncCallback, asyncState); + try + { + _exception = new ObjectDisposedException(nameof(NegotiateStream)); + _context?.CloseContext(); + } + finally + { + await base.DisposeAsync().ConfigureAwait(false); + } } - public virtual IAsyncResult BeginAuthenticateAsClient(NetworkCredential credential, ChannelBinding? binding, string targetName, AsyncCallback? asyncCallback, object? asyncState) - { - return BeginAuthenticateAsClient(credential, binding, targetName, - ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, - asyncCallback, asyncState); - } + public virtual IAsyncResult BeginAuthenticateAsClient(AsyncCallback? asyncCallback, object? asyncState) => + BeginAuthenticateAsClient((NetworkCredential)CredentialCache.DefaultCredentials, binding: null, string.Empty, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, + asyncCallback, asyncState); - public virtual IAsyncResult BeginAuthenticateAsClient( - NetworkCredential credential, - string targetName, - ProtectionLevel requiredProtectionLevel, - TokenImpersonationLevel allowedImpersonationLevel, - AsyncCallback? asyncCallback, - object? asyncState) - { - return BeginAuthenticateAsClient(credential, null, targetName, - requiredProtectionLevel, allowedImpersonationLevel, - asyncCallback, asyncState); - } + public virtual IAsyncResult BeginAuthenticateAsClient(NetworkCredential credential, string targetName, AsyncCallback? asyncCallback, object? asyncState) => + BeginAuthenticateAsClient(credential, binding: null, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, + asyncCallback, asyncState); + + public virtual IAsyncResult BeginAuthenticateAsClient(NetworkCredential credential, ChannelBinding? binding, string targetName, AsyncCallback? asyncCallback, object? asyncState) => + BeginAuthenticateAsClient(credential, binding, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, + asyncCallback, asyncState); public virtual IAsyncResult BeginAuthenticateAsClient( - NetworkCredential credential, - ChannelBinding? binding, - string targetName, - ProtectionLevel requiredProtectionLevel, - TokenImpersonationLevel allowedImpersonationLevel, - AsyncCallback? asyncCallback, - object? asyncState) - { - _negoState.ValidateCreateContext(_package, false, credential, targetName, binding, requiredProtectionLevel, allowedImpersonationLevel); + NetworkCredential credential, string targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel, + AsyncCallback? asyncCallback, object? asyncState) => + BeginAuthenticateAsClient(credential, binding: null, targetName, requiredProtectionLevel, allowedImpersonationLevel, + asyncCallback, asyncState); - LazyAsyncResult result = new LazyAsyncResult(_negoState, asyncState, asyncCallback); - _negoState.ProcessAuthentication(result); + public virtual IAsyncResult BeginAuthenticateAsClient( + NetworkCredential credential, ChannelBinding? binding, string targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel, + AsyncCallback? asyncCallback, object? asyncState) => + TaskToApm.Begin(AuthenticateAsClientAsync(credential, binding, targetName, requiredProtectionLevel, allowedImpersonationLevel), asyncCallback, asyncState); - return result; - } + public virtual void EndAuthenticateAsClient(IAsyncResult asyncResult) => TaskToApm.End(asyncResult); - public virtual void EndAuthenticateAsClient(IAsyncResult asyncResult) - { - _negoState.EndProcessAuthentication(asyncResult); - } + public virtual void AuthenticateAsServer() => + AuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, policy: null, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); - public virtual void AuthenticateAsServer() - { - AuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, null, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); - } - - public virtual void AuthenticateAsServer(ExtendedProtectionPolicy? policy) - { + public virtual void AuthenticateAsServer(ExtendedProtectionPolicy? policy) => AuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, policy, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); - } - public virtual void AuthenticateAsServer(NetworkCredential credential, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel requiredImpersonationLevel) - { - AuthenticateAsServer(credential, null, requiredProtectionLevel, requiredImpersonationLevel); - } + public virtual void AuthenticateAsServer(NetworkCredential credential, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel requiredImpersonationLevel) => + AuthenticateAsServer(credential, policy: null, requiredProtectionLevel, requiredImpersonationLevel); public virtual void AuthenticateAsServer(NetworkCredential credential, ExtendedProtectionPolicy? policy, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel requiredImpersonationLevel) { - _negoState.ValidateCreateContext(_package, credential, string.Empty, policy, requiredProtectionLevel, requiredImpersonationLevel); - _negoState.ProcessAuthentication(null); + ValidateCreateContext(DefaultPackage, credential, string.Empty, policy, requiredProtectionLevel, requiredImpersonationLevel); + AuthenticateAsync(new SyncReadWriteAdapter(InnerStream)).GetAwaiter().GetResult(); } - public virtual IAsyncResult BeginAuthenticateAsServer(AsyncCallback? asyncCallback, object? asyncState) - { - return BeginAuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, null, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, asyncCallback, asyncState); - } + public virtual IAsyncResult BeginAuthenticateAsServer(AsyncCallback? asyncCallback, object? asyncState) => + BeginAuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, policy: null, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, asyncCallback, asyncState); - public virtual IAsyncResult BeginAuthenticateAsServer(ExtendedProtectionPolicy? policy, AsyncCallback? asyncCallback, object? asyncState) - { - return BeginAuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, policy, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, asyncCallback, asyncState); - } + public virtual IAsyncResult BeginAuthenticateAsServer(ExtendedProtectionPolicy? policy, AsyncCallback? asyncCallback, object? asyncState) => + BeginAuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, policy, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, asyncCallback, asyncState); public virtual IAsyncResult BeginAuthenticateAsServer( - NetworkCredential credential, - ProtectionLevel requiredProtectionLevel, - TokenImpersonationLevel requiredImpersonationLevel, - AsyncCallback? asyncCallback, - object? asyncState) - { - return BeginAuthenticateAsServer(credential, null, requiredProtectionLevel, requiredImpersonationLevel, asyncCallback, asyncState); - } + NetworkCredential credential, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel requiredImpersonationLevel, + AsyncCallback? asyncCallback, object? asyncState) => + BeginAuthenticateAsServer(credential, policy: null, requiredProtectionLevel, requiredImpersonationLevel, asyncCallback, asyncState); public virtual IAsyncResult BeginAuthenticateAsServer( - NetworkCredential credential, - ExtendedProtectionPolicy? policy, - ProtectionLevel requiredProtectionLevel, - TokenImpersonationLevel requiredImpersonationLevel, - AsyncCallback? asyncCallback, - object? asyncState) - { - _negoState.ValidateCreateContext(_package, credential, string.Empty, policy, requiredProtectionLevel, requiredImpersonationLevel); + NetworkCredential credential, ExtendedProtectionPolicy? policy, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel requiredImpersonationLevel, + AsyncCallback? asyncCallback, object? asyncState) => + TaskToApm.Begin(AuthenticateAsServerAsync(credential, policy, requiredProtectionLevel, requiredImpersonationLevel), asyncCallback, asyncState); - LazyAsyncResult result = new LazyAsyncResult(_negoState, asyncState, asyncCallback); - _negoState.ProcessAuthentication(result); + public virtual void EndAuthenticateAsServer(IAsyncResult asyncResult) => TaskToApm.End(asyncResult); - return result; - } - // - public virtual void EndAuthenticateAsServer(IAsyncResult asyncResult) - { - _negoState.EndProcessAuthentication(asyncResult); - } + public virtual void AuthenticateAsClient() => + AuthenticateAsClient((NetworkCredential)CredentialCache.DefaultCredentials, binding: null, string.Empty, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); - public virtual void AuthenticateAsClient() - { - AuthenticateAsClient((NetworkCredential)CredentialCache.DefaultCredentials, null, string.Empty, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); - } + public virtual void AuthenticateAsClient(NetworkCredential credential, string targetName) => + AuthenticateAsClient(credential, binding: null, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); - public virtual void AuthenticateAsClient(NetworkCredential credential, string targetName) - { - AuthenticateAsClient(credential, null, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); - } - - public virtual void AuthenticateAsClient(NetworkCredential credential, ChannelBinding? binding, string targetName) - { + public virtual void AuthenticateAsClient(NetworkCredential credential, ChannelBinding? binding, string targetName) => AuthenticateAsClient(credential, binding, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); - } public virtual void AuthenticateAsClient( - NetworkCredential credential, string targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel) - { - AuthenticateAsClient(credential, null, targetName, requiredProtectionLevel, allowedImpersonationLevel); - } + NetworkCredential credential, string targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel) => + AuthenticateAsClient(credential, binding: null, targetName, requiredProtectionLevel, allowedImpersonationLevel); public virtual void AuthenticateAsClient( NetworkCredential credential, ChannelBinding? binding, string targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel) { - _negoState.ValidateCreateContext(_package, false, credential, targetName, binding, requiredProtectionLevel, allowedImpersonationLevel); - _negoState.ProcessAuthentication(null); + ValidateCreateContext(DefaultPackage, isServer: false, credential, targetName, binding, requiredProtectionLevel, allowedImpersonationLevel); + AuthenticateAsync(new SyncReadWriteAdapter(InnerStream)).GetAwaiter().GetResult(); } - public virtual Task AuthenticateAsClientAsync() - { - return Task.Factory.FromAsync(BeginAuthenticateAsClient, EndAuthenticateAsClient, null); - } + public virtual Task AuthenticateAsClientAsync() => + AuthenticateAsClientAsync((NetworkCredential)CredentialCache.DefaultCredentials, binding: null, string.Empty, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); - public virtual Task AuthenticateAsClientAsync(NetworkCredential credential, string targetName) - { - return Task.Factory.FromAsync(BeginAuthenticateAsClient, EndAuthenticateAsClient, credential, targetName, null); - } + public virtual Task AuthenticateAsClientAsync(NetworkCredential credential, string targetName) => + AuthenticateAsClientAsync(credential, binding: null, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); public virtual Task AuthenticateAsClientAsync( NetworkCredential credential, string targetName, ProtectionLevel requiredProtectionLevel, - TokenImpersonationLevel allowedImpersonationLevel) - { - return Task.Factory.FromAsync((callback, state) => BeginAuthenticateAsClient(credential, targetName, requiredProtectionLevel, allowedImpersonationLevel, callback, state), EndAuthenticateAsClient, null); - } + TokenImpersonationLevel allowedImpersonationLevel) => + AuthenticateAsClientAsync(credential, binding: null, targetName, requiredProtectionLevel, allowedImpersonationLevel); - public virtual Task AuthenticateAsClientAsync(NetworkCredential credential, ChannelBinding? binding, string targetName) - { - return Task.Factory.FromAsync(BeginAuthenticateAsClient, EndAuthenticateAsClient, credential, binding, targetName, null); - } + public virtual Task AuthenticateAsClientAsync(NetworkCredential credential, ChannelBinding? binding, string targetName) => + AuthenticateAsClientAsync(credential, binding, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); public virtual Task AuthenticateAsClientAsync( - NetworkCredential credential, ChannelBinding? binding, - string targetName, ProtectionLevel requiredProtectionLevel, + NetworkCredential credential, ChannelBinding? binding, string targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel) { - return Task.Factory.FromAsync((callback, state) => BeginAuthenticateAsClient(credential, binding, targetName, requiredProtectionLevel, allowedImpersonationLevel, callback, state), EndAuthenticateAsClient, null); + ValidateCreateContext(DefaultPackage, isServer: false, credential, targetName, binding, requiredProtectionLevel, allowedImpersonationLevel); + return AuthenticateAsync(new AsyncReadWriteAdapter(InnerStream, cancellationToken: default)); } - public virtual Task AuthenticateAsServerAsync() - { - return Task.Factory.FromAsync(BeginAuthenticateAsServer, EndAuthenticateAsServer, null); - } + public virtual Task AuthenticateAsServerAsync() => + AuthenticateAsServerAsync((NetworkCredential)CredentialCache.DefaultCredentials, policy: null, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); - public virtual Task AuthenticateAsServerAsync(ExtendedProtectionPolicy? policy) - { - return Task.Factory.FromAsync(BeginAuthenticateAsServer, EndAuthenticateAsServer, policy, null); - } + public virtual Task AuthenticateAsServerAsync(ExtendedProtectionPolicy? policy) => + AuthenticateAsServerAsync((NetworkCredential)CredentialCache.DefaultCredentials, policy, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); - public virtual Task AuthenticateAsServerAsync(NetworkCredential credential, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel requiredImpersonationLevel) - { - return Task.Factory.FromAsync(BeginAuthenticateAsServer, EndAuthenticateAsServer, credential, requiredProtectionLevel, requiredImpersonationLevel, null); - } + public virtual Task AuthenticateAsServerAsync(NetworkCredential credential, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel requiredImpersonationLevel) => + AuthenticateAsServerAsync(credential, policy: null, requiredProtectionLevel, requiredImpersonationLevel); public virtual Task AuthenticateAsServerAsync( - NetworkCredential credential, ExtendedProtectionPolicy? policy, - ProtectionLevel requiredProtectionLevel, - TokenImpersonationLevel requiredImpersonationLevel) + NetworkCredential credential, ExtendedProtectionPolicy? policy, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel requiredImpersonationLevel) { - return Task.Factory.FromAsync((callback, state) => BeginAuthenticateAsServer(credential, policy, requiredProtectionLevel, requiredImpersonationLevel, callback, state), EndAuthenticateAsClient, null); + ValidateCreateContext(DefaultPackage, credential, string.Empty, policy, requiredProtectionLevel, requiredImpersonationLevel); + return AuthenticateAsync(new AsyncReadWriteAdapter(InnerStream, cancellationToken: default)); } - public override bool IsAuthenticated + public override bool IsAuthenticated => IsAuthenticatedCore; + + [MemberNotNullWhen(true, nameof(_context))] + private bool IsAuthenticatedCore => _context != null && HandshakeComplete && _exception == null && _remoteOk; + + public override bool IsMutuallyAuthenticated => + IsAuthenticatedCore && + !_context.IsNTLM && // suppressing for NTLM since SSPI does not return correct value in the context flags. + _context.IsMutualAuthFlag; + + public override bool IsEncrypted => IsAuthenticatedCore && _context.IsConfidentialityFlag; + + public override bool IsSigned => IsAuthenticatedCore && (_context.IsIntegrityFlag || _context.IsConfidentialityFlag); + + public override bool IsServer => _context != null && _context.IsServer; + + public virtual TokenImpersonationLevel ImpersonationLevel { get { - return _negoState.IsAuthenticated; + ThrowIfFailed(authSuccessCheck: true); + return PrivateImpersonationLevel; } } - public override bool IsMutuallyAuthenticated + private TokenImpersonationLevel PrivateImpersonationLevel => + _context!.IsDelegationFlag && _context.ProtocolName != NegotiationInfoClass.NTLM ? TokenImpersonationLevel.Delegation : // We should suppress the delegate flag in NTLM case. + _context.IsIdentifyFlag ? TokenImpersonationLevel.Identification : + TokenImpersonationLevel.Impersonation; + + private bool HandshakeComplete => _context!.IsCompleted && _context.IsValidContext; + + private bool CanGetSecureStream => _context!.IsConfidentialityFlag || _context.IsIntegrityFlag; + + public virtual IIdentity RemoteIdentity { get { - return _negoState.IsMutuallyAuthenticated; + IIdentity? identity = _remoteIdentity; + if (identity is null) + { + ThrowIfFailed(authSuccessCheck: true); + _remoteIdentity = identity = NegotiateStreamPal.GetIdentity(_context!); + } + return identity; } } - public override bool IsEncrypted + public override bool CanSeek => false; + + public override bool CanRead => IsAuthenticated && InnerStream.CanRead; + + public override bool CanTimeout => InnerStream.CanTimeout; + + public override bool CanWrite => IsAuthenticated && InnerStream.CanWrite; + + public override int ReadTimeout + { + get => InnerStream.ReadTimeout; + set => InnerStream.ReadTimeout = value; + } + + public override int WriteTimeout { - get - { - return _negoState.IsEncrypted; - } + get => InnerStream.WriteTimeout; + set => InnerStream.WriteTimeout = value; } - public override bool IsSigned + public override long Length => InnerStream.Length; + + public override long Position { - get + get => InnerStream.Position; + set => throw new NotSupportedException(SR.net_noseek); + } + + public override void SetLength(long value) => + InnerStream.SetLength(value); + + public override long Seek(long offset, SeekOrigin origin) => + throw new NotSupportedException(SR.net_noseek); + + public override void Flush() => + InnerStream.Flush(); + + public override Task FlushAsync(CancellationToken cancellationToken) => + InnerStream.FlushAsync(cancellationToken); + + public override int Read(byte[] buffer, int offset, int count) + { + ValidateParameters(buffer, offset, count); + + ThrowIfFailed(authSuccessCheck: true); + if (!CanGetSecureStream) { - return _negoState.IsSigned; + return InnerStream.Read(buffer, offset, count); } + + ValueTask vt = ReadAsync(new SyncReadWriteAdapter(InnerStream), new Memory(buffer, offset, count)); + Debug.Assert(vt.IsCompleted, "Should have completed synchroously with sync adapter"); + return vt.GetAwaiter().GetResult(); } - public override bool IsServer + public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { - get + ValidateParameters(buffer, offset, count); + + ThrowIfFailed(authSuccessCheck: true); + if (!CanGetSecureStream) { - return _negoState.IsServer; + return InnerStream.ReadAsync(buffer, offset, count, cancellationToken); } + + return ReadAsync(new AsyncReadWriteAdapter(InnerStream, cancellationToken), new Memory(buffer, offset, count)).AsTask(); } - public virtual TokenImpersonationLevel ImpersonationLevel + public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) { - get + ThrowIfFailed(authSuccessCheck: true); + if (!CanGetSecureStream) { - return _negoState.AllowedImpersonation; + return InnerStream.ReadAsync(buffer, cancellationToken); } + + return ReadAsync(new AsyncReadWriteAdapter(InnerStream, cancellationToken), buffer); } - public virtual IIdentity RemoteIdentity + private async ValueTask ReadAsync(TAdapter adapter, Memory buffer, [CallerMemberName] string? callerName = null) where TAdapter : IReadWriteAdapter { - get + if (Interlocked.Exchange(ref _readInProgress, 1) == 1) + { + throw new NotSupportedException(SR.Format(SR.net_io_invalidnestedcall, callerName, "read")); + } + + try { - if (_remoteIdentity == null) + if (_bufferCount != 0) { - _remoteIdentity = _negoState.GetIdentity(); + int copyBytes = Math.Min(_bufferCount, buffer.Length); + if (copyBytes != 0) + { + _buffer.AsMemory(_bufferOffset, copyBytes).CopyTo(buffer); + _bufferOffset += copyBytes; + _bufferCount -= copyBytes; + } + return copyBytes; } - return _remoteIdentity; + while (true) + { + int readBytes = await adapter.ReadAllAsync(_readHeader).ConfigureAwait(false); + if (readBytes == 0) + { + return 0; + } + + // Replace readBytes with the body size recovered from the header content. + readBytes = BitConverter.ToInt32(_readHeader, 0); + + // The body carries 4 bytes for trailer size slot plus trailer, hence <= 4 frame size is always an error. + // Additionally we'd like to restrict the read frame size to 64k. + if (readBytes <= 4 || readBytes > MaxReadFrameSize) + { + throw new IOException(SR.net_frame_read_size); + } + + // Always pass InternalBuffer for SSPI "in place" decryption. + // A user buffer can be shared by many threads in that case decryption/integrity check may fail cause of data corruption. + _bufferCount = readBytes; + _bufferOffset = 0; + if (_buffer.Length < readBytes) + { + _buffer = new byte[readBytes]; + } + readBytes = await adapter.ReadAllAsync(new Memory(_buffer, 0, readBytes)).ConfigureAwait(false); + if (readBytes == 0) + { + // We already checked that the frame body is bigger than 0 bytes. Hence, this is an EOF. + throw new IOException(SR.net_io_eof); + } + + // Decrypt into internal buffer, change "readBytes" to count now _Decrypted Bytes_ + // Decrypted data start from zero offset, the size can be shrunk after decryption. + _bufferCount = readBytes = DecryptData(_buffer!, 0, readBytes, out _bufferOffset); + if (readBytes == 0 && buffer.Length != 0) + { + // Read again. + continue; + } + + if (readBytes > buffer.Length) + { + readBytes = buffer.Length; + } + + _buffer.AsMemory(_bufferOffset, readBytes).CopyTo(buffer); + _bufferOffset += readBytes; + _bufferCount -= readBytes; + + return readBytes; + } + } + catch (Exception e) when (!(e is IOException || e is OperationCanceledException)) + { + throw new IOException(SR.net_io_read, e); + } + finally + { + _readInProgress = 0; } } - // - // Stream contract implementation - // - public override bool CanSeek + public override void Write(byte[] buffer, int offset, int count) { - get + ValidateParameters(buffer, offset, count); + + ThrowIfFailed(authSuccessCheck: true); + if (!CanGetSecureStream) { - return false; + InnerStream.Write(buffer, offset, count); + return; } + + WriteAsync(new SyncReadWriteAdapter(InnerStream), new ReadOnlyMemory(buffer, offset, count)).GetAwaiter().GetResult(); } - public override bool CanRead + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { - get + ValidateParameters(buffer, offset, count); + + ThrowIfFailed(authSuccessCheck: true); + if (!CanGetSecureStream) { - return IsAuthenticated && InnerStream.CanRead; + return InnerStream.WriteAsync(buffer, offset, count, cancellationToken); } + + return WriteAsync(new AsyncReadWriteAdapter(InnerStream, cancellationToken), new ReadOnlyMemory(buffer, offset, count)); } - public override bool CanTimeout + public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { - get + ThrowIfFailed(authSuccessCheck: true); + if (!CanGetSecureStream) { - return InnerStream.CanTimeout; + return InnerStream.WriteAsync(buffer, cancellationToken); } + + return new ValueTask(WriteAsync(new AsyncReadWriteAdapter(InnerStream, cancellationToken), buffer)); } - public override bool CanWrite + private async Task WriteAsync(TAdapter adapter, ReadOnlyMemory buffer) where TAdapter : IReadWriteAdapter { - get + if (Interlocked.Exchange(ref _writeInProgress, 1) == 1) { - return IsAuthenticated && InnerStream.CanWrite; + throw new NotSupportedException(SR.Format(SR.net_io_invalidnestedcall, nameof(Write), "write")); } - } - public override int ReadTimeout - { - get + try { - return InnerStream.ReadTimeout; + byte[]? outBuffer = null; + while (!buffer.IsEmpty) + { + int chunkBytes = Math.Min(buffer.Length, MaxWriteDataSize); + int encryptedBytes; + try + { + encryptedBytes = EncryptData(buffer.Slice(0, chunkBytes).Span, ref outBuffer); + } + catch (Exception e) + { + throw new IOException(SR.net_io_encrypt, e); + } + + await adapter.WriteAsync(outBuffer, 0, encryptedBytes).ConfigureAwait(false); + buffer = buffer.Slice(chunkBytes); + } + } + catch (Exception e) when (!(e is IOException || e is OperationCanceledException)) + { + throw new IOException(SR.net_io_write, e); } - set + finally { - InnerStream.ReadTimeout = value; + _writeInProgress = 0; } } - public override int WriteTimeout + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) => + TaskToApm.Begin(ReadAsync(buffer, offset, count), asyncCallback, asyncState); + + public override int EndRead(IAsyncResult asyncResult) => + TaskToApm.End(asyncResult); + + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) => + TaskToApm.Begin(WriteAsync(buffer, offset, count), asyncCallback, asyncState); + + public override void EndWrite(IAsyncResult asyncResult) => + TaskToApm.End(asyncResult); + + /// Validates user parameters for all Read/Write methods. + private static void ValidateParameters(byte[] buffer, int offset, int count) { - get + if (buffer == null) { - return InnerStream.WriteTimeout; + throw new ArgumentNullException(nameof(buffer)); } - set + + if (offset < 0) { - InnerStream.WriteTimeout = value; + throw new ArgumentOutOfRangeException(nameof(offset)); } - } - public override long Length - { - get + if (count < 0) { - return InnerStream.Length; + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (count > buffer.Length - offset) + { + throw new ArgumentOutOfRangeException(nameof(count), SR.net_offset_plus_count); } } - public override long Position + private void ValidateCreateContext( + string package, + NetworkCredential credential, + string servicePrincipalName, + ExtendedProtectionPolicy? policy, + ProtectionLevel protectionLevel, + TokenImpersonationLevel impersonationLevel) { - get + if (policy != null) { - return InnerStream.Position; + // One of these must be set if EP is turned on + if (policy.CustomChannelBinding == null && policy.CustomServiceNames == null) + { + throw new ArgumentException(SR.net_auth_must_specify_extended_protection_scheme, nameof(policy)); + } + + _extendedProtectionPolicy = policy; } - set + else { - throw new NotSupportedException(SR.net_noseek); + _extendedProtectionPolicy = new ExtendedProtectionPolicy(PolicyEnforcement.Never); } - } - public override void SetLength(long value) - { - InnerStream.SetLength(value); + ValidateCreateContext(package, isServer: true, credential, servicePrincipalName, _extendedProtectionPolicy.CustomChannelBinding, protectionLevel, impersonationLevel); } - public override long Seek(long offset, SeekOrigin origin) + private void ValidateCreateContext( + string package, + bool isServer, + NetworkCredential credential, + string? servicePrincipalName, + ChannelBinding? channelBinding, + ProtectionLevel protectionLevel, + TokenImpersonationLevel impersonationLevel) { - throw new NotSupportedException(SR.net_noseek); - } + if (_exception != null && !_canRetryAuthentication) + { + ExceptionDispatchInfo.Throw(_exception); + } - public override void Flush() - { - InnerStream.Flush(); + if (_context != null && _context.IsValidContext) + { + throw new InvalidOperationException(SR.net_auth_reauth); + } + + if (credential == null) + { + throw new ArgumentNullException(nameof(credential)); + } + + if (servicePrincipalName == null) + { + throw new ArgumentNullException(nameof(servicePrincipalName)); + } + + NegotiateStreamPal.ValidateImpersonationLevel(impersonationLevel); + if (_context != null && IsServer != isServer) + { + throw new InvalidOperationException(SR.net_auth_client_server); + } + + _exception = null; + _remoteOk = false; + _framer = new StreamFramer(); + _framer.WriteHeader.MessageId = FrameHeader.HandshakeId; + + _expectedProtectionLevel = protectionLevel; + _expectedImpersonationLevel = isServer ? impersonationLevel : TokenImpersonationLevel.None; + _writeSequenceNumber = 0; + _readSequenceNumber = 0; + + ContextFlagsPal flags = ContextFlagsPal.Connection; + + // A workaround for the client when talking to Win9x on the server side. + if (protectionLevel == ProtectionLevel.None && !isServer) + { + package = NegotiationInfoClass.NTLM; + } + else if (protectionLevel == ProtectionLevel.EncryptAndSign) + { + flags |= ContextFlagsPal.Confidentiality; + } + else if (protectionLevel == ProtectionLevel.Sign) + { + // Assuming user expects NT4 SP4 and above. + flags |= ContextFlagsPal.ReplayDetect | ContextFlagsPal.SequenceDetect | ContextFlagsPal.InitIntegrity; + } + + if (isServer) + { + if (_extendedProtectionPolicy!.PolicyEnforcement == PolicyEnforcement.WhenSupported) + { + flags |= ContextFlagsPal.AllowMissingBindings; + } + + if (_extendedProtectionPolicy.PolicyEnforcement != PolicyEnforcement.Never && + _extendedProtectionPolicy.ProtectionScenario == ProtectionScenario.TrustedProxy) + { + flags |= ContextFlagsPal.ProxyBindings; + } + } + else + { + // Server side should not request any of these flags. + if (protectionLevel != ProtectionLevel.None) + { + flags |= ContextFlagsPal.MutualAuth; + } + + if (impersonationLevel == TokenImpersonationLevel.Identification) + { + flags |= ContextFlagsPal.InitIdentify; + } + + if (impersonationLevel == TokenImpersonationLevel.Delegation) + { + flags |= ContextFlagsPal.Delegate; + } + } + + _canRetryAuthentication = false; + + try + { + _context = new NTAuthentication(isServer, package, credential, servicePrincipalName, flags, channelBinding!); + } + catch (Win32Exception e) + { + throw new AuthenticationException(SR.net_auth_SSPI, e); + } } - public override Task FlushAsync(CancellationToken cancellationToken) + private void SetFailed(Exception e) { - return InnerStream.FlushAsync(cancellationToken); + if (!(_exception is ObjectDisposedException)) + { + _exception = e; + } + + _context?.CloseContext(); } - protected override void Dispose(bool disposing) + private void ThrowIfFailed(bool authSuccessCheck) { - try + if (_exception != null) { - _negoState.Close(); + ExceptionDispatchInfo.Throw(_exception); } - finally + + if (authSuccessCheck && !IsAuthenticatedCore) { - base.Dispose(disposing); + throw new InvalidOperationException(SR.net_auth_noauth); } } - public override async ValueTask DisposeAsync() + private async Task AuthenticateAsync(TAdapter adapter, [CallerMemberName] string? callerName = null) where TAdapter : IReadWriteAdapter { + Debug.Assert(_context != null); + + ThrowIfFailed(authSuccessCheck: false); + if (Interlocked.Exchange(ref _authInProgress, 1) == 1) + { + throw new InvalidOperationException(SR.Format(SR.net_io_invalidnestedcall, callerName, "authenticate")); + } + try { - _negoState.Close(); + await (_context.IsServer ? + ReceiveBlobAsync(adapter) : // server should listen for a client blob + SendBlobAsync(adapter, message: null)).ConfigureAwait(false); // client should send the first blob + } + catch (Exception e) + { + SetFailed(e); + throw; } finally { - await base.DisposeAsync().ConfigureAwait(false); + _authInProgress = 0; } } - public override int Read(byte[] buffer, int offset, int count) + private bool CheckSpn() { - _negoState.CheckThrow(true); + Debug.Assert(_context != null); - if (!_negoState.CanGetSecureStream) + if (_context.IsKerberos || + _extendedProtectionPolicy!.PolicyEnforcement == PolicyEnforcement.Never || + _extendedProtectionPolicy.CustomServiceNames == null) { - return InnerStream.Read(buffer, offset, count); + return true; + } + + string? clientSpn = _context.ClientSpecifiedSpn; + + if (string.IsNullOrEmpty(clientSpn)) + { + return _extendedProtectionPolicy.PolicyEnforcement == PolicyEnforcement.WhenSupported; } - return ProcessRead(buffer, offset, count, null); + return _extendedProtectionPolicy.CustomServiceNames.Contains(clientSpn); } - public override void Write(byte[] buffer, int offset, int count) + // Client authentication starts here, but server also loops through this method. + private async Task SendBlobAsync(TAdapter adapter, byte[]? message) where TAdapter : IReadWriteAdapter { - _negoState.CheckThrow(true); + Debug.Assert(_context != null); - if (!_negoState.CanGetSecureStream) + Exception? exception = null; + if (message != s_emptyMessage) { - InnerStream.Write(buffer, offset, count); - return; + message = GetOutgoingBlob(message, ref exception); } - ProcessWrite(buffer, offset, count, null); - } + if (exception != null) + { + // Signal remote side on a failed attempt. + await SendAuthResetSignalAndThrowAsync(adapter, message!, exception).ConfigureAwait(false); + Debug.Fail("Unreachable"); + } - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) - { - _negoState.CheckThrow(true); + if (HandshakeComplete) + { + if (_context.IsServer && !CheckSpn()) + { + exception = new AuthenticationException(SR.net_auth_bad_client_creds_or_target_mismatch); + int statusCode = ERROR_TRUST_FAILURE; + message = new byte[sizeof(long)]; + + for (int i = message.Length - 1; i >= 0; --i) + { + message[i] = (byte)(statusCode & 0xFF); + statusCode = (int)((uint)statusCode >> 8); + } + + await SendAuthResetSignalAndThrowAsync(adapter, message, exception).ConfigureAwait(false); + Debug.Fail("Unreachable"); + } - if (!_negoState.CanGetSecureStream) + if (PrivateImpersonationLevel < _expectedImpersonationLevel) + { + exception = new AuthenticationException(SR.Format(SR.net_auth_context_expectation, _expectedImpersonationLevel.ToString(), PrivateImpersonationLevel.ToString())); + int statusCode = ERROR_TRUST_FAILURE; + message = new byte[sizeof(long)]; + + for (int i = message.Length - 1; i >= 0; --i) + { + message[i] = (byte)(statusCode & 0xFF); + statusCode = (int)((uint)statusCode >> 8); + } + + await SendAuthResetSignalAndThrowAsync(adapter, message, exception).ConfigureAwait(false); + Debug.Fail("Unreachable"); + } + + ProtectionLevel result = _context.IsConfidentialityFlag ? ProtectionLevel.EncryptAndSign : _context.IsIntegrityFlag ? ProtectionLevel.Sign : ProtectionLevel.None; + + if (result < _expectedProtectionLevel) + { + exception = new AuthenticationException(SR.Format(SR.net_auth_context_expectation, result.ToString(), _expectedProtectionLevel.ToString())); + int statusCode = ERROR_TRUST_FAILURE; + message = new byte[sizeof(long)]; + + for (int i = message.Length - 1; i >= 0; --i) + { + message[i] = (byte)(statusCode & 0xFF); + statusCode = (int)((uint)statusCode >> 8); + } + + await SendAuthResetSignalAndThrowAsync(adapter, message, exception).ConfigureAwait(false); + Debug.Fail("Unreachable"); + } + + // Signal remote party that we are done + _framer!.WriteHeader.MessageId = FrameHeader.HandshakeDoneId; + if (_context.IsServer) + { + // Server may complete now because client SSPI would not complain at this point. + _remoteOk = true; + + // However the client will wait for server to send this ACK + // Force signaling server OK to the client + message ??= s_emptyMessage; + } + } + else if (message == null || message == s_emptyMessage) { - return TaskToApm.Begin(InnerStream.ReadAsync(buffer, offset, count), asyncCallback, asyncState); + throw new InternalException(); } - BufferAsyncResult bufferResult = new BufferAsyncResult(this, buffer, offset, count, asyncState, asyncCallback); - AsyncProtocolRequest asyncRequest = new AsyncProtocolRequest(bufferResult); - ProcessRead(buffer, offset, count, asyncRequest); - return bufferResult; + if (message != null) + { + //even if we are completed, there could be a blob for sending. + await _framer!.WriteMessageAsync(adapter, message).ConfigureAwait(false); + } + + if (HandshakeComplete && _remoteOk) + { + // We are done with success. + return; + } + + await ReceiveBlobAsync(adapter).ConfigureAwait(false); } - public override int EndRead(IAsyncResult asyncResult) + // Server authentication starts here, but client also loops through this method. + private async Task ReceiveBlobAsync(TAdapter adapter) where TAdapter : IReadWriteAdapter { - _negoState.CheckThrow(true); + Debug.Assert(_framer != null); - if (!_negoState.CanGetSecureStream) + byte[]? message = await _framer.ReadMessageAsync(adapter).ConfigureAwait(false); + if (message == null) { - return TaskToApm.End(asyncResult); + // This is an EOF otherwise we would get at least *empty* message but not a null one. + throw new AuthenticationException(SR.net_auth_eof); } - if (asyncResult == null) + // Process Header information. + if (_framer.ReadHeader.MessageId == FrameHeader.HandshakeErrId) { - throw new ArgumentNullException(nameof(asyncResult)); + if (message.Length >= sizeof(long)) + { + // Try to recover remote win32 Exception. + long error = 0; + for (int i = 0; i < 8; ++i) + { + error = (error << 8) + message[i]; + } + + ThrowCredentialException(error); + } + + throw new AuthenticationException(SR.net_auth_alert); } - BufferAsyncResult? bufferResult = asyncResult as BufferAsyncResult; - if (bufferResult == null) + if (_framer.ReadHeader.MessageId == FrameHeader.HandshakeDoneId) { - throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), nameof(asyncResult)); + _remoteOk = true; } - - if (Interlocked.Exchange(ref _NestedRead, 0) == 0) + else if (_framer.ReadHeader.MessageId != FrameHeader.HandshakeId) { - throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndRead")); + throw new AuthenticationException(SR.Format(SR.net_io_header_id, nameof(FrameHeader.MessageId), _framer.ReadHeader.MessageId, FrameHeader.HandshakeId)); } - // No "artificial" timeouts implemented so far, InnerStream controls timeout. - bufferResult.InternalWaitForCompletion(); - - if (bufferResult.Result is Exception e) + // If we are done don't go into send. + if (HandshakeComplete) { - if (e is IOException) + if (!_remoteOk) { - ExceptionDispatchInfo.Throw(e); + throw new AuthenticationException(SR.Format(SR.net_io_header_id, nameof(FrameHeader.MessageId), _framer.ReadHeader.MessageId, FrameHeader.HandshakeDoneId)); } - throw new IOException(SR.net_io_read, e); + return; } - return bufferResult.Int32Result; + // Not yet done, get a new blob and send it if any. + await SendBlobAsync(adapter, message).ConfigureAwait(false); } - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState) + // This is to reset auth state on the remote side. + // If this write succeeds we will allow auth retrying. + private async Task SendAuthResetSignalAndThrowAsync(TAdapter adapter, byte[] message, Exception exception) where TAdapter : IReadWriteAdapter { - _negoState.CheckThrow(true); + _framer!.WriteHeader.MessageId = FrameHeader.HandshakeErrId; + + if (IsLogonDeniedException(exception)) + { + exception = new InvalidCredentialException(IsServer ? SR.net_auth_bad_client_creds : SR.net_auth_bad_client_creds_or_target_mismatch, exception); + } - if (!_negoState.CanGetSecureStream) + if (!(exception is AuthenticationException)) { - return TaskToApm.Begin(InnerStream.WriteAsync(buffer, offset, count), asyncCallback, asyncState); + exception = new AuthenticationException(SR.net_auth_SSPI, exception); } - BufferAsyncResult bufferResult = new BufferAsyncResult(this, buffer, offset, count, asyncState, asyncCallback); - AsyncProtocolRequest asyncRequest = new AsyncProtocolRequest(bufferResult); + await _framer.WriteMessageAsync(adapter, message).ConfigureAwait(false); - ProcessWrite(buffer, offset, count, asyncRequest); - return bufferResult; + _canRetryAuthentication = true; + ExceptionDispatchInfo.Throw(exception); } - public override void EndWrite(IAsyncResult asyncResult) + private static bool IsError(SecurityStatusPal status) => + (int)status.ErrorCode >= (int)SecurityStatusPalErrorCode.OutOfMemory; + + private unsafe byte[]? GetOutgoingBlob(byte[]? incomingBlob, ref Exception? e) { - _negoState.CheckThrow(true); + Debug.Assert(_context != null); - if (!_negoState.CanGetSecureStream) - { - TaskToApm.End(asyncResult); - return; - } + byte[]? message = _context.GetOutgoingBlob(incomingBlob, false, out SecurityStatusPal statusCode); - if (asyncResult == null) + if (IsError(statusCode)) { - throw new ArgumentNullException(nameof(asyncResult)); - } + e = NegotiateStreamPal.CreateExceptionFromError(statusCode); + uint error = (uint)e.HResult; - BufferAsyncResult? bufferResult = asyncResult as BufferAsyncResult; - if (bufferResult == null) - { - throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), nameof(asyncResult)); + message = new byte[sizeof(long)]; + for (int i = message.Length - 1; i >= 0; --i) + { + message[i] = (byte)(error & 0xFF); + error >>= 8; + } } - if (Interlocked.Exchange(ref _NestedWrite, 0) == 0) + if (message != null && message.Length == 0) { - throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndWrite")); + message = s_emptyMessage; } - // No "artificial" timeouts implemented so far, InnerStream controls timeout. - bufferResult.InternalWaitForCompletion(); + return message; + } - if (bufferResult.Result is Exception e) - { - if (e is IOException) - { - ExceptionDispatchInfo.Throw(e); - } + private int EncryptData(ReadOnlySpan buffer, [NotNull] ref byte[]? outBuffer) + { + Debug.Assert(_context != null); + ThrowIfFailed(authSuccessCheck: true); - throw new IOException(SR.net_io_write, e); - } + // SSPI seems to ignore this sequence number. + ++_writeSequenceNumber; + return _context.Encrypt(buffer, ref outBuffer, _writeSequenceNumber); + } + + private int DecryptData(byte[] buffer, int offset, int count, out int newOffset) + { + Debug.Assert(_context != null); + ThrowIfFailed(authSuccessCheck: true); + + // SSPI seems to ignore this sequence number. + ++_readSequenceNumber; + return _context.Decrypt(buffer, offset, count, out newOffset, _readSequenceNumber); } + + private static void ThrowCredentialException(long error) + { + var e = new Win32Exception((int)error); + throw e.NativeErrorCode switch + { + (int)SecurityStatusPalErrorCode.LogonDenied => new InvalidCredentialException(SR.net_auth_bad_client_creds, e), + ERROR_TRUST_FAILURE => new AuthenticationException(SR.net_auth_context_expectation_remote, e), + _ => new AuthenticationException(SR.net_auth_alert, e) + }; + } + + private static bool IsLogonDeniedException(Exception exception) => + exception is Win32Exception win32exception && + win32exception.NativeErrorCode == (int)SecurityStatusPalErrorCode.LogonDenied; } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStreamPal.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStreamPal.Windows.cs index a03fe69151f6e..51d69634b36e5 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStreamPal.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/NegotiateStreamPal.Windows.cs @@ -4,6 +4,7 @@ using System.ComponentModel; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Security; using System.Security.Principal; @@ -85,12 +86,10 @@ internal static void ValidateImpersonationLevel(TokenImpersonationLevel imperson internal static int Encrypt( SafeDeleteContext securityContext, - byte[] buffer, - int offset, - int count, + ReadOnlySpan buffer, bool isConfidential, bool isNtlm, - ref byte[]? output, + [NotNull] ref byte[]? output, uint sequenceNumber) { SecPkgContext_Sizes sizes = default; @@ -101,9 +100,9 @@ internal static void ValidateImpersonationLevel(TokenImpersonationLevel imperson { int maxCount = checked(int.MaxValue - 4 - sizes.cbBlockSize - sizes.cbSecurityTrailer); - if (count > maxCount || count < 0) + if (buffer.Length > maxCount) { - throw new ArgumentOutOfRangeException(nameof(count), SR.Format(SR.net_io_out_range, maxCount)); + throw new ArgumentOutOfRangeException(nameof(buffer.Length), SR.Format(SR.net_io_out_range, maxCount)); } } catch (Exception e) when (!ExceptionCheck.IsFatal(e)) @@ -112,21 +111,21 @@ internal static void ValidateImpersonationLevel(TokenImpersonationLevel imperson throw; } - int resultSize = count + sizes.cbSecurityTrailer + sizes.cbBlockSize; + int resultSize = buffer.Length + sizes.cbSecurityTrailer + sizes.cbBlockSize; if (output == null || output.Length < resultSize + 4) { output = new byte[resultSize + 4]; } // Make a copy of user data for in-place encryption. - Buffer.BlockCopy(buffer, offset, output, 4 + sizes.cbSecurityTrailer, count); + buffer.CopyTo(output.AsSpan(4 + sizes.cbSecurityTrailer)); // Prepare buffers TOKEN(signature), DATA and Padding. ThreeSecurityBuffers buffers = default; var securityBuffer = MemoryMarshal.CreateSpan(ref buffers._item0, 3); securityBuffer[0] = new SecurityBuffer(output, 4, sizes.cbSecurityTrailer, SecurityBufferType.SECBUFFER_TOKEN); - securityBuffer[1] = new SecurityBuffer(output, 4 + sizes.cbSecurityTrailer, count, SecurityBufferType.SECBUFFER_DATA); - securityBuffer[2] = new SecurityBuffer(output, 4 + sizes.cbSecurityTrailer + count, sizes.cbBlockSize, SecurityBufferType.SECBUFFER_PADDING); + securityBuffer[1] = new SecurityBuffer(output, 4 + sizes.cbSecurityTrailer, buffer.Length, SecurityBufferType.SECBUFFER_DATA); + securityBuffer[2] = new SecurityBuffer(output, 4 + sizes.cbSecurityTrailer + buffer.Length, sizes.cbBlockSize, SecurityBufferType.SECBUFFER_PADDING); int errorCode; if (isConfidential) @@ -160,7 +159,7 @@ internal static void ValidateImpersonationLevel(TokenImpersonationLevel imperson } resultSize += securityBuffer[1].size; - if (securityBuffer[2].size != 0 && (forceCopy || resultSize != (count + sizes.cbSecurityTrailer))) + if (securityBuffer[2].size != 0 && (forceCopy || resultSize != (buffer.Length + sizes.cbSecurityTrailer))) { Buffer.BlockCopy(output, securityBuffer[2].offset, output, 4 + resultSize, securityBuffer[2].size); } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/ReadWriteAdapter.cs b/src/libraries/System.Net.Security/src/System/Net/Security/ReadWriteAdapter.cs new file mode 100644 index 0000000000000..497baeb4ccf6e --- /dev/null +++ b/src/libraries/System.Net.Security/src/System/Net/Security/ReadWriteAdapter.cs @@ -0,0 +1,89 @@ +// 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. + +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Security +{ + internal interface IReadWriteAdapter + { + ValueTask ReadAsync(Memory buffer); + + ValueTask WriteAsync(byte[] buffer, int offset, int count); + + Task WaitAsync(TaskCompletionSource waiter); + + CancellationToken CancellationToken { get; } + + public async ValueTask ReadAllAsync(Memory buffer) + { + int length = buffer.Length; + + do + { + int bytes = await ReadAsync(buffer).ConfigureAwait(false); + if (bytes == 0) + { + if (!buffer.IsEmpty) + { + throw new IOException(SR.net_io_eof); + } + break; + } + + buffer = buffer.Slice(bytes); + } + while (!buffer.IsEmpty); + + return length; + } + } + + internal readonly struct AsyncReadWriteAdapter : IReadWriteAdapter + { + private readonly Stream _stream; + + public AsyncReadWriteAdapter(Stream stream, CancellationToken cancellationToken) + { + _stream = stream; + CancellationToken = cancellationToken; + } + + public ValueTask ReadAsync(Memory buffer) => + _stream.ReadAsync(buffer, CancellationToken); + + public ValueTask WriteAsync(byte[] buffer, int offset, int count) => + _stream.WriteAsync(new ReadOnlyMemory(buffer, offset, count), CancellationToken); + + public Task WaitAsync(TaskCompletionSource waiter) => waiter.Task; + + public CancellationToken CancellationToken { get; } + } + + internal readonly struct SyncReadWriteAdapter : IReadWriteAdapter + { + private readonly Stream _stream; + + public SyncReadWriteAdapter(Stream stream) => _stream = stream; + + public ValueTask ReadAsync(Memory buffer) => + new ValueTask(_stream.Read(buffer.Span)); + + public ValueTask WriteAsync(byte[] buffer, int offset, int count) + { + _stream.Write(buffer, offset, count); + return default; + } + + public Task WaitAsync(TaskCompletionSource waiter) + { + waiter.Task.GetAwaiter().GetResult(); + return Task.CompletedTask; + } + + public CancellationToken CancellationToken => default; + } +} diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.Adapters.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.Adapters.cs deleted file mode 100644 index 4995f3fd09bf0..0000000000000 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.Adapters.cs +++ /dev/null @@ -1,63 +0,0 @@ -// 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. -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Security -{ - // This contains adapters to allow a single code path for sync/async logic - public partial class SslStream - { - private interface ISslIOAdapter - { - ValueTask ReadAsync(Memory buffer); - ValueTask WriteAsync(byte[] buffer, int offset, int count); - Task WaitAsync(TaskCompletionSource waiter); - CancellationToken CancellationToken { get; } - } - - private readonly struct AsyncSslIOAdapter : ISslIOAdapter - { - private readonly SslStream _sslStream; - private readonly CancellationToken _cancellationToken; - - public AsyncSslIOAdapter(SslStream sslStream, CancellationToken cancellationToken) - { - _cancellationToken = cancellationToken; - _sslStream = sslStream; - } - - public ValueTask ReadAsync(Memory buffer) => _sslStream.InnerStream.ReadAsync(buffer, _cancellationToken); - - public ValueTask WriteAsync(byte[] buffer, int offset, int count) => _sslStream.InnerStream.WriteAsync(new ReadOnlyMemory(buffer, offset, count), _cancellationToken); - - public Task WaitAsync(TaskCompletionSource waiter) => waiter.Task; - - public CancellationToken CancellationToken => _cancellationToken; - } - - private readonly struct SyncSslIOAdapter : ISslIOAdapter - { - private readonly SslStream _sslStream; - - public SyncSslIOAdapter(SslStream sslStream) => _sslStream = sslStream; - - public ValueTask ReadAsync(Memory buffer) => new ValueTask(_sslStream.InnerStream.Read(buffer.Span)); - - public ValueTask WriteAsync(byte[] buffer, int offset, int count) - { - _sslStream.InnerStream.Write(buffer, offset, count); - return default; - } - - public Task WaitAsync(TaskCompletionSource waiter) - { - waiter.Task.Wait(); - return Task.CompletedTask; - } - - public CancellationToken CancellationToken => default; - } - } -} diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs index d9ff52dfeba8f..68b142521d21c 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs @@ -196,11 +196,11 @@ private SecurityStatusPal PrivateDecryptData(byte[]? buffer, ref int offset, ref if (isAsync) { - result = ForceAuthenticationAsync(new AsyncSslIOAdapter(this, cancellationToken), _context!.IsServer, null, isApm); + result = ForceAuthenticationAsync(new AsyncReadWriteAdapter(InnerStream, cancellationToken), _context!.IsServer, null, isApm); } else { - ForceAuthenticationAsync(new SyncSslIOAdapter(this), _context!.IsServer, null).GetAwaiter().GetResult(); + ForceAuthenticationAsync(new SyncReadWriteAdapter(InnerStream), _context!.IsServer, null).GetAwaiter().GetResult(); result = null; } @@ -211,7 +211,7 @@ private SecurityStatusPal PrivateDecryptData(byte[]? buffer, ref int offset, ref // This is used to reply on re-handshake when received SEC_I_RENEGOTIATE on Read(). // private async Task ReplyOnReAuthenticationAsync(TIOAdapter adapter, byte[]? buffer) - where TIOAdapter : ISslIOAdapter + where TIOAdapter : IReadWriteAdapter { try { @@ -226,7 +226,7 @@ private async Task ReplyOnReAuthenticationAsync(TIOAdapter adapter, // reAuthenticationData is only used on Windows in case of renegotiation. private async Task ForceAuthenticationAsync(TIOAdapter adapter, bool receiveFirst, byte[]? reAuthenticationData, bool isApm = false) - where TIOAdapter : ISslIOAdapter + where TIOAdapter : IReadWriteAdapter { ProtocolToken message; bool handshakeCompleted = false; @@ -339,7 +339,7 @@ private async Task ForceAuthenticationAsync(TIOAdapter adapter, bool } private async ValueTask ReceiveBlobAsync(TIOAdapter adapter) - where TIOAdapter : ISslIOAdapter + where TIOAdapter : IReadWriteAdapter { int readBytes = await FillHandshakeBufferAsync(adapter, SecureChannel.ReadHeaderSize).ConfigureAwait(false); if (readBytes == 0) @@ -486,7 +486,7 @@ private bool CompleteHandshake(ref ProtocolToken? alertToken) } private async ValueTask WriteAsyncChunked(TIOAdapter writeAdapter, ReadOnlyMemory buffer) - where TIOAdapter : struct, ISslIOAdapter + where TIOAdapter : struct, IReadWriteAdapter { do { @@ -497,7 +497,7 @@ private async ValueTask WriteAsyncChunked(TIOAdapter writeAdapter, R } private ValueTask WriteSingleChunk(TIOAdapter writeAdapter, ReadOnlyMemory buffer) - where TIOAdapter : struct, ISslIOAdapter + where TIOAdapter : struct, IReadWriteAdapter { byte[] rentedBuffer = ArrayPool.Shared.Rent(buffer.Length + FrameOverhead); byte[] outBuffer = rentedBuffer; @@ -643,7 +643,7 @@ private void ReturnReadBufferIfEmpty() } private async ValueTask ReadAsyncInternal(TIOAdapter adapter, Memory buffer) - where TIOAdapter : ISslIOAdapter + where TIOAdapter : IReadWriteAdapter { if (Interlocked.Exchange(ref _nestedRead, 1) == 1) { @@ -790,7 +790,7 @@ private async ValueTask ReadAsyncInternal(TIOAdapter adapter, M // If we have enough data, it returns synchronously. If not, it will try to read // remaining bytes from given stream. private ValueTask FillHandshakeBufferAsync(TIOAdapter adapter, int minSize) - where TIOAdapter : ISslIOAdapter + where TIOAdapter : IReadWriteAdapter { if (_handshakeBuffer.ActiveLength >= minSize) { @@ -840,7 +840,7 @@ async ValueTask InternalFillHandshakeBufferAsync(TIOAdapter adap, ValueTas } private async ValueTask FillBufferAsync(TIOAdapter adapter, int numBytesRequired) - where TIOAdapter : ISslIOAdapter + where TIOAdapter : IReadWriteAdapter { Debug.Assert(_internalBufferCount > 0); Debug.Assert(_internalBufferCount < numBytesRequired); @@ -858,7 +858,7 @@ private async ValueTask FillBufferAsync(TIOAdapter adapter, int numB } private async ValueTask WriteAsyncInternal(TIOAdapter writeAdapter, ReadOnlyMemory buffer) - where TIOAdapter : struct, ISslIOAdapter + where TIOAdapter : struct, IReadWriteAdapter { ThrowIfExceptionalOrNotAuthenticatedOrShutdown(); diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs index 79c16bf043ed4..f3638799d7732 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.cs @@ -762,8 +762,7 @@ public override int Read(byte[] buffer, int offset, int count) { ThrowIfExceptionalOrNotAuthenticated(); ValidateParameters(buffer, offset, count); - SyncSslIOAdapter reader = new SyncSslIOAdapter(this); - ValueTask vt = ReadAsyncInternal(reader, new Memory(buffer, offset, count)); + ValueTask vt = ReadAsyncInternal(new SyncReadWriteAdapter(InnerStream), new Memory(buffer, offset, count)); Debug.Assert(vt.IsCompleted, "Sync operation must have completed synchronously"); return vt.GetAwaiter().GetResult(); } @@ -775,8 +774,7 @@ public override void Write(byte[] buffer, int offset, int count) ThrowIfExceptionalOrNotAuthenticated(); ValidateParameters(buffer, offset, count); - SyncSslIOAdapter writeAdapter = new SyncSslIOAdapter(this); - ValueTask vt = WriteAsyncInternal(writeAdapter, new ReadOnlyMemory(buffer, offset, count)); + ValueTask vt = WriteAsyncInternal(new SyncReadWriteAdapter(InnerStream), new ReadOnlyMemory(buffer, offset, count)); Debug.Assert(vt.IsCompleted, "Sync operation must have completed synchronously"); vt.GetAwaiter().GetResult(); } @@ -815,23 +813,20 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { ThrowIfExceptionalOrNotAuthenticated(); - AsyncSslIOAdapter writeAdapter = new AsyncSslIOAdapter(this, cancellationToken); - return WriteAsyncInternal(writeAdapter, buffer); + return WriteAsyncInternal(new AsyncReadWriteAdapter(InnerStream, cancellationToken), buffer); } public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { ThrowIfExceptionalOrNotAuthenticated(); ValidateParameters(buffer, offset, count); - AsyncSslIOAdapter read = new AsyncSslIOAdapter(this, cancellationToken); - return ReadAsyncInternal(read, new Memory(buffer, offset, count)).AsTask(); + return ReadAsyncInternal(new AsyncReadWriteAdapter(InnerStream, cancellationToken), new Memory(buffer, offset, count)).AsTask(); } public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) { ThrowIfExceptionalOrNotAuthenticated(); - AsyncSslIOAdapter read = new AsyncSslIOAdapter(this, cancellationToken); - return ReadAsyncInternal(read, buffer); + return ReadAsyncInternal(new AsyncReadWriteAdapter(InnerStream, cancellationToken), buffer); } private void ThrowIfExceptional() diff --git a/src/libraries/System.Net.Security/src/System/Net/SslStreamContext.cs b/src/libraries/System.Net.Security/src/System/Net/SslStreamContext.cs index eda52c9d784ef..338e3c84434b5 100644 --- a/src/libraries/System.Net.Security/src/System/Net/SslStreamContext.cs +++ b/src/libraries/System.Net.Security/src/System/Net/SslStreamContext.cs @@ -2,28 +2,23 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics; using System.Net.Security; using System.Security.Authentication.ExtendedProtection; namespace System.Net { - internal class SslStreamContext : TransportContext + internal sealed class SslStreamContext : TransportContext { + private readonly SslStream _sslStream; + internal SslStreamContext(SslStream sslStream) { - if (sslStream == null) - { - NetEventSource.Fail(this, "Not expecting a null sslStream!"); - } - + Debug.Assert(sslStream != null); _sslStream = sslStream!; } - public override ChannelBinding? GetChannelBinding(ChannelBindingKind kind) - { - return _sslStream.GetChannelBinding(kind); - } - - private readonly SslStream _sslStream; + public override ChannelBinding? GetChannelBinding(ChannelBindingKind kind) => + _sslStream.GetChannelBinding(kind); } } diff --git a/src/libraries/System.Net.Security/src/System/Net/StreamFramer.cs b/src/libraries/System.Net.Security/src/System/Net/StreamFramer.cs index dc494ca17e1b0..264fb4d6accfd 100644 --- a/src/libraries/System.Net.Security/src/System/Net/StreamFramer.cs +++ b/src/libraries/System.Net.Security/src/System/Net/StreamFramer.cs @@ -4,83 +4,37 @@ using System.IO; using System.Globalization; -using System.Runtime.ExceptionServices; +using System.Net.Security; using System.Threading.Tasks; namespace System.Net { - internal class StreamFramer + internal sealed class StreamFramer { - private readonly Stream _transport; - - private bool _eof; - private readonly FrameHeader _writeHeader = new FrameHeader(); private readonly FrameHeader _curReadHeader = new FrameHeader(); - private readonly FrameHeader _readVerifier = new FrameHeader( - FrameHeader.IgnoreValue, - FrameHeader.IgnoreValue, - FrameHeader.IgnoreValue); - - private readonly byte[] _readHeaderBuffer; - private readonly byte[] _writeHeaderBuffer; - private readonly AsyncCallback _readFrameCallback; - private readonly AsyncCallback _beginWriteCallback; - - public StreamFramer(Stream Transport) - { - if (Transport == null || Transport == Stream.Null) - { - throw new ArgumentNullException(nameof(Transport)); - } - - _transport = Transport; - _readHeaderBuffer = new byte[_curReadHeader.Size]; - _writeHeaderBuffer = new byte[_writeHeader.Size]; - - _readFrameCallback = new AsyncCallback(ReadFrameCallback); - _beginWriteCallback = new AsyncCallback(BeginWriteCallback); - } - - public FrameHeader ReadHeader - { - get - { - return _curReadHeader; - } - } - - public FrameHeader WriteHeader - { - get - { - return _writeHeader; - } - } + private readonly byte[] _readHeaderBuffer = new byte[FrameHeader.Size]; + private readonly byte[] _writeHeaderBuffer = new byte[FrameHeader.Size]; + private bool _eof; - public Stream Transport - { - get - { - return _transport; - } - } + public FrameHeader ReadHeader => _curReadHeader; + public FrameHeader WriteHeader => _writeHeader; - public byte[]? ReadMessage() + public async ValueTask ReadMessageAsync(TAdapter adapter) where TAdapter : IReadWriteAdapter { if (_eof) { return null; } - int offset = 0; byte[] buffer = _readHeaderBuffer; int bytesRead; + int offset = 0; while (offset < buffer.Length) { - bytesRead = Transport.Read(buffer, offset, buffer.Length - offset); + bytesRead = await adapter.ReadAsync(buffer.AsMemory(offset)).ConfigureAwait(false); if (bytesRead == 0) { if (offset == 0) @@ -89,20 +43,18 @@ public Stream Transport _eof = true; return null; } - else - { - throw new IOException(SR.Format(SR.net_io_readfailure, SR.net_io_connectionclosed)); - } + + throw new IOException(SR.Format(SR.net_io_readfailure, SR.net_io_connectionclosed)); } offset += bytesRead; } - _curReadHeader.CopyFrom(buffer, 0, _readVerifier); - if (_curReadHeader.PayloadSize > _curReadHeader.MaxMessageSize) + _curReadHeader.CopyFrom(buffer, 0); + if (_curReadHeader.PayloadSize > FrameHeader.MaxMessageSize) { throw new InvalidOperationException(SR.Format(SR.net_frame_size, - _curReadHeader.MaxMessageSize.ToString(NumberFormatInfo.InvariantInfo), + FrameHeader.MaxMessageSize, _curReadHeader.PayloadSize.ToString(NumberFormatInfo.InvariantInfo))); } @@ -111,7 +63,7 @@ public Stream Transport offset = 0; while (offset < buffer.Length) { - bytesRead = Transport.Read(buffer, offset, buffer.Length - offset); + bytesRead = await adapter.ReadAsync(buffer.AsMemory(offset)).ConfigureAwait(false); if (bytesRead == 0) { throw new IOException(SR.Format(SR.net_io_readfailure, SR.net_io_connectionclosed)); @@ -122,226 +74,7 @@ public Stream Transport return buffer; } - public IAsyncResult BeginReadMessage(AsyncCallback asyncCallback, object stateObject) - { - WorkerAsyncResult workerResult; - - if (_eof) - { - workerResult = new WorkerAsyncResult(this, stateObject, asyncCallback, null, 0, 0); - workerResult.InvokeCallback(-1); - return workerResult; - } - - workerResult = new WorkerAsyncResult(this, stateObject, asyncCallback, - _readHeaderBuffer, 0, - _readHeaderBuffer.Length); - - IAsyncResult result = TaskToApm.Begin(_transport.ReadAsync(_readHeaderBuffer, 0, _readHeaderBuffer.Length), - _readFrameCallback, workerResult); - - if (result.CompletedSynchronously) - { - ReadFrameComplete(result); - } - - return workerResult; - } - - private void ReadFrameCallback(IAsyncResult transportResult) - { - if (!(transportResult.AsyncState is WorkerAsyncResult)) - { - NetEventSource.Fail(this, $"The state expected to be WorkerAsyncResult, received {transportResult}."); - } - - if (transportResult.CompletedSynchronously) - { - return; - } - - WorkerAsyncResult workerResult = (WorkerAsyncResult)transportResult.AsyncState!; - - try - { - ReadFrameComplete(transportResult); - } - catch (Exception e) - { - if (e is OutOfMemoryException) - { - throw; - } - - if (!(e is IOException)) - { - e = new System.IO.IOException(SR.Format(SR.net_io_readfailure, e.Message), e); - } - - workerResult.InvokeCallback(e); - } - } - - // IO COMPLETION CALLBACK - // - // This callback is responsible for getting the complete protocol frame. - // 1. it reads the header. - // 2. it determines the frame size. - // 3. loops while not all frame received or an error. - // - private void ReadFrameComplete(IAsyncResult transportResult) - { - do - { - if (!(transportResult.AsyncState is WorkerAsyncResult)) - { - NetEventSource.Fail(this, $"The state expected to be WorkerAsyncResult, received {transportResult}."); - } - - WorkerAsyncResult workerResult = (WorkerAsyncResult)transportResult.AsyncState!; - - int bytesRead = TaskToApm.End(transportResult); - workerResult.Offset += bytesRead; - - if (!(workerResult.Offset <= workerResult.End)) - { - NetEventSource.Fail(this, $"WRONG: offset - end = {workerResult.Offset - workerResult.End}"); - } - - if (bytesRead <= 0) - { - // (by design) This indicates the stream has receives EOF - // If we are in the middle of a Frame - fail, otherwise - produce EOF - object? result = null; - if (!workerResult.HeaderDone && workerResult.Offset == 0) - { - result = (object)-1; - } - else - { - result = new System.IO.IOException(SR.net_frame_read_io); - } - - workerResult.InvokeCallback(result); - return; - } - - if (workerResult.Offset >= workerResult.End) - { - if (!workerResult.HeaderDone) - { - workerResult.HeaderDone = true; - // This indicates the header has been read successfully - _curReadHeader.CopyFrom(workerResult.Buffer!, 0, _readVerifier); - int payloadSize = _curReadHeader.PayloadSize; - if (payloadSize < 0) - { - // Let's call user callback and they call us back and we will throw - workerResult.InvokeCallback(new System.IO.IOException(SR.net_frame_read_size)); - } - - if (payloadSize == 0) - { - // report empty frame (NOT eof!) to the caller, he might be interested in - workerResult.InvokeCallback(0); - return; - } - - if (payloadSize > _curReadHeader.MaxMessageSize) - { - throw new InvalidOperationException(SR.Format(SR.net_frame_size, - _curReadHeader.MaxMessageSize.ToString(NumberFormatInfo.InvariantInfo), - payloadSize.ToString(NumberFormatInfo.InvariantInfo))); - } - - // Start reading the remaining frame data (note header does not count). - byte[] frame = new byte[payloadSize]; - // Save the ref of the data block - workerResult.Buffer = frame; - workerResult.End = frame.Length; - workerResult.Offset = 0; - - // Transport.ReadAsync below will pickup those changes. - } - else - { - workerResult.HeaderDone = false; // Reset for optional object reuse. - workerResult.InvokeCallback(workerResult.End); - return; - } - } - - // This means we need more data to complete the data block. - transportResult = TaskToApm.Begin(_transport.ReadAsync(workerResult.Buffer!, workerResult.Offset, workerResult.End - workerResult.Offset), - _readFrameCallback, workerResult); - } while (transportResult.CompletedSynchronously); - } - - // - // User code will call this when workerResult gets signaled. - // - // On BeginRead, the user always gets back our WorkerAsyncResult. - // The Result property represents either a number of bytes read or an - // exception put by our async state machine. - // - public byte[]? EndReadMessage(IAsyncResult asyncResult) - { - if (asyncResult == null) - { - throw new ArgumentNullException(nameof(asyncResult)); - } - WorkerAsyncResult? workerResult = asyncResult as WorkerAsyncResult; - - if (workerResult == null) - { - throw new ArgumentException(SR.Format(SR.net_io_async_result, typeof(WorkerAsyncResult).FullName), nameof(asyncResult)); - } - - if (!workerResult.InternalPeekCompleted) - { - workerResult.InternalWaitForCompletion(); - } - - if (workerResult.Result is Exception e) - { - ExceptionDispatchInfo.Throw(e); - } - - int size = (int)workerResult.Result!; - if (size == -1) - { - _eof = true; - return null; - } - else if (size == 0) - { - // Empty frame. - return Array.Empty(); - } - - return workerResult.Buffer; - } - - public void WriteMessage(byte[] message) - { - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } - - _writeHeader.PayloadSize = message.Length; - _writeHeader.CopyTo(_writeHeaderBuffer, 0); - - Transport.Write(_writeHeaderBuffer, 0, _writeHeaderBuffer.Length); - if (message.Length == 0) - { - return; - } - - Transport.Write(message, 0, message.Length); - } - - public IAsyncResult BeginWriteMessage(byte[] message, AsyncCallback asyncCallback, object stateObject) + public async Task WriteMessageAsync(TAdapter adapter, byte[] message) where TAdapter : IReadWriteAdapter { if (message == null) { @@ -351,141 +84,16 @@ public IAsyncResult BeginWriteMessage(byte[] message, AsyncCallback asyncCallbac _writeHeader.PayloadSize = message.Length; _writeHeader.CopyTo(_writeHeaderBuffer, 0); - if (message.Length == 0) - { - return TaskToApm.Begin(_transport.WriteAsync(_writeHeaderBuffer, 0, _writeHeaderBuffer.Length), - asyncCallback, stateObject); - } - - // Will need two async writes. Prepare the second: - WorkerAsyncResult workerResult = new WorkerAsyncResult(this, stateObject, asyncCallback, - message, 0, message.Length); - - // Charge the first: - IAsyncResult result = TaskToApm.Begin(_transport.WriteAsync(_writeHeaderBuffer, 0, _writeHeaderBuffer.Length), - _beginWriteCallback, workerResult); - - if (result.CompletedSynchronously) - { - BeginWriteComplete(result); - } - - return workerResult; - } - - private void BeginWriteCallback(IAsyncResult transportResult) - { - if (!(transportResult.AsyncState is WorkerAsyncResult)) - { - NetEventSource.Fail(this, $"The state expected to be WorkerAsyncResult, received {transportResult}."); - } - - if (transportResult.CompletedSynchronously) - { - return; - } - - var workerResult = (WorkerAsyncResult)transportResult.AsyncState!; - - try - { - BeginWriteComplete(transportResult); - } - catch (Exception e) - { - if (e is OutOfMemoryException) - { - throw; - } - - workerResult.InvokeCallback(e); - } - } - - // IO COMPLETION CALLBACK - // - // Called when user IO request was wrapped to do several underlined IO. - // - private void BeginWriteComplete(IAsyncResult transportResult) - { - do - { - WorkerAsyncResult workerResult = (WorkerAsyncResult)transportResult.AsyncState!; - - // First, complete the previous portion write. - TaskToApm.End(transportResult); - - // Check on exit criterion. - if (workerResult.Offset == workerResult.End) - { - workerResult.InvokeCallback(); - return; - } - - // Setup exit criterion. - workerResult.Offset = workerResult.End; - - // Write next portion (frame body) using Async IO. - transportResult = TaskToApm.Begin(_transport.WriteAsync(workerResult.Buffer!, 0, workerResult.End), - _beginWriteCallback, workerResult); - } - while (transportResult.CompletedSynchronously); - } - - public void EndWriteMessage(IAsyncResult asyncResult) - { - if (asyncResult == null) - { - throw new ArgumentNullException(nameof(asyncResult)); - } - - WorkerAsyncResult? workerResult = asyncResult as WorkerAsyncResult; - - if (workerResult != null) + await adapter.WriteAsync(_writeHeaderBuffer, 0, _writeHeaderBuffer.Length).ConfigureAwait(false); + if (message.Length != 0) { - if (!workerResult.InternalPeekCompleted) - { - workerResult.InternalWaitForCompletion(); - } - - if (workerResult.Result is Exception e) - { - ExceptionDispatchInfo.Throw(e); - } - } - else - { - TaskToApm.End(asyncResult); + await adapter.WriteAsync(message, 0, message.Length).ConfigureAwait(false); } } } - // - // This class wraps an Async IO request. It is based on our internal LazyAsyncResult helper. - // - If ParentResult is not null then the base class (LazyAsyncResult) methods must not be used. - // - If ParentResult == null, then real user IO request is wrapped. - // - - internal class WorkerAsyncResult : LazyAsyncResult - { - public byte[]? Buffer; - public int Offset; - public int End; - public bool HeaderDone; // This might be reworked so we read both header and frame in one chunk. - - public WorkerAsyncResult(object asyncObject, object asyncState, - AsyncCallback savedAsyncCallback, - byte[]? buffer, int offset, int end) - : base(asyncObject, asyncState, savedAsyncCallback) - { - Buffer = buffer; - Offset = offset; - End = end; - } - } - // Describes the header used in framing of the stream data. - internal class FrameHeader + internal sealed class FrameHeader { public const int IgnoreValue = -1; public const int HandshakeDoneId = 20; @@ -493,121 +101,44 @@ internal class FrameHeader public const int HandshakeId = 22; public const int DefaultMajorV = 1; public const int DefaultMinorV = 0; + public const int Size = 5; + public const int MaxMessageSize = 0xFFFF; - private int _MessageId; - private int _MajorV; - private int _MinorV; - private int _PayloadSize; - - public FrameHeader() - { - _MessageId = HandshakeId; - _MajorV = DefaultMajorV; - _MinorV = DefaultMinorV; - _PayloadSize = -1; - } - - public FrameHeader(int messageId, int majorV, int minorV) - { - _MessageId = messageId; - _MajorV = majorV; - _MinorV = minorV; - _PayloadSize = -1; - } - - public int Size - { - get - { - return 5; - } - } - - public int MaxMessageSize - { - get - { - return 0xFFFF; - } - } - - public int MessageId - { - get - { - return _MessageId; - } - set - { - _MessageId = value; - } - } + private int _payloadSize = -1; - public int MajorV - { - get - { - return _MajorV; - } - } - - public int MinorV - { - get - { - return _MinorV; - } - } + public int MessageId { get; set; } = HandshakeId; + public int MajorV { get; private set; } = DefaultMajorV; + public int MinorV { get; private set; } = DefaultMinorV; public int PayloadSize { - get - { - return _PayloadSize; - } + get => _payloadSize; set { if (value > MaxMessageSize) { - throw new ArgumentException(SR.Format(SR.net_frame_max_size, - MaxMessageSize.ToString(NumberFormatInfo.InvariantInfo), - value.ToString(NumberFormatInfo.InvariantInfo)), "PayloadSize"); + throw new ArgumentException(SR.Format(SR.net_frame_max_size, MaxMessageSize, value), nameof(PayloadSize)); } - _PayloadSize = value; + _payloadSize = value; } } public void CopyTo(byte[] dest, int start) { - dest[start++] = (byte)_MessageId; - dest[start++] = (byte)_MajorV; - dest[start++] = (byte)_MinorV; - dest[start++] = (byte)((_PayloadSize >> 8) & 0xFF); - dest[start] = (byte)(_PayloadSize & 0xFF); + dest[start++] = (byte)MessageId; + dest[start++] = (byte)MajorV; + dest[start++] = (byte)MinorV; + dest[start++] = (byte)((_payloadSize >> 8) & 0xFF); + dest[start] = (byte)(_payloadSize & 0xFF); } - public void CopyFrom(byte[] bytes, int start, FrameHeader verifier) + public void CopyFrom(byte[] bytes, int start) { - _MessageId = bytes[start++]; - _MajorV = bytes[start++]; - _MinorV = bytes[start++]; - _PayloadSize = (int)((bytes[start++] << 8) | bytes[start]); - - if (verifier.MessageId != FrameHeader.IgnoreValue && MessageId != verifier.MessageId) - { - throw new InvalidOperationException(SR.Format(SR.net_io_header_id, "MessageId", MessageId, verifier.MessageId)); - } - - if (verifier.MajorV != FrameHeader.IgnoreValue && MajorV != verifier.MajorV) - { - throw new InvalidOperationException(SR.Format(SR.net_io_header_id, "MajorV", MajorV, verifier.MajorV)); - } - - if (verifier.MinorV != FrameHeader.IgnoreValue && MinorV != verifier.MinorV) - { - throw new InvalidOperationException(SR.Format(SR.net_io_header_id, "MinorV", MinorV, verifier.MinorV)); - } + MessageId = bytes[start++]; + MajorV = bytes[start++]; + MinorV = bytes[start++]; + _payloadSize = (bytes[start++] << 8) | bytes[start]; } } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/NegotiateStreamInvalidOperationTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/NegotiateStreamInvalidOperationTest.cs index bdde8c6bded93..68c6368969902 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/NegotiateStreamInvalidOperationTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/NegotiateStreamInvalidOperationTest.cs @@ -98,56 +98,6 @@ public async Task NegotiateStream_EndReadEndWriteInvalidParameter_Throws() } } - [Fact] - public async Task NegotiateStream_ConcurrentAsyncReadOrWrite_ThrowsNotSupportedException() - { - byte[] recvBuf = new byte[s_sampleMsg.Length]; - var network = new VirtualNetwork(); - - using (var clientStream = new VirtualNetworkStream(network, isServer: false)) - using (var serverStream = new VirtualNetworkStream(network, isServer: true)) - using (var client = new NegotiateStream(clientStream)) - using (var server = new NegotiateStream(serverStream)) - { - await TestConfiguration.WhenAllOrAnyFailedWithTimeout( - client.AuthenticateAsClientAsync(CredentialCache.DefaultNetworkCredentials, string.Empty), - server.AuthenticateAsServerAsync()); - - // Custom EndWrite/Read will not reset the variable which monitors concurrent write/read. - await TestConfiguration.WhenAllOrAnyFailedWithTimeout( - Task.Factory.FromAsync(client.BeginWrite, (ar) => { Assert.NotNull(ar); }, s_sampleMsg, 0, s_sampleMsg.Length, client), - Task.Factory.FromAsync(server.BeginRead, (ar) => { Assert.NotNull(ar); }, recvBuf, 0, s_sampleMsg.Length, server)); - - Assert.Throws(() => client.BeginWrite(s_sampleMsg, 0, s_sampleMsg.Length, (ar) => { Assert.Null(ar); }, null)); - Assert.Throws(() => server.BeginRead(recvBuf, 0, s_sampleMsg.Length, (ar) => { Assert.Null(ar); }, null)); - } - } - - [Fact] - public async Task NegotiateStream_ConcurrentSyncReadOrWrite_ThrowsNotSupportedException() - { - byte[] recvBuf = new byte[s_sampleMsg.Length]; - var network = new VirtualNetwork(); - - using (var clientStream = new VirtualNetworkStream(network, isServer: false)) - using (var serverStream = new VirtualNetworkStream(network, isServer: true)) - using (var client = new NegotiateStream(clientStream)) - using (var server = new NegotiateStream(serverStream)) - { - await TestConfiguration.WhenAllOrAnyFailedWithTimeout( - client.AuthenticateAsClientAsync(CredentialCache.DefaultNetworkCredentials, string.Empty), - server.AuthenticateAsServerAsync()); - - // Custom EndWrite/Read will not reset the variable which monitors concurrent write/read. - await TestConfiguration.WhenAllOrAnyFailedWithTimeout( - Task.Factory.FromAsync(client.BeginWrite, (ar) => { Assert.NotNull(ar); }, s_sampleMsg, 0, s_sampleMsg.Length, client), - Task.Factory.FromAsync(server.BeginRead, (ar) => { Assert.NotNull(ar); }, recvBuf, 0, s_sampleMsg.Length, server)); - - Assert.Throws(() => client.Write(s_sampleMsg, 0, s_sampleMsg.Length)); - Assert.Throws(() => server.Read(recvBuf, 0, s_sampleMsg.Length)); - } - } - [Fact] public async Task NegotiateStream_DisposeTooEarly_Throws() { @@ -336,7 +286,6 @@ public async Task NegotiateStream_EndAuthenticateInvalidParameter_Throws() AssertExtensions.Throws(nameof(asyncResult), () => authStream.EndAuthenticateAsClient(result)); authStream.EndAuthenticateAsClient(asyncResult); - Assert.Throws(() => authStream.EndAuthenticateAsClient(asyncResult)); }, CredentialCache.DefaultNetworkCredentials, string.Empty, client), Task.Factory.FromAsync(server.BeginAuthenticateAsServer, (asyncResult) => @@ -348,7 +297,6 @@ public async Task NegotiateStream_EndAuthenticateInvalidParameter_Throws() AssertExtensions.Throws(nameof(asyncResult), () => authStream.EndAuthenticateAsServer(result)); authStream.EndAuthenticateAsServer(asyncResult); - Assert.Throws(() => authStream.EndAuthenticateAsServer(asyncResult)); }, server)); } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/NegotiateStreamStreamToStreamTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/NegotiateStreamStreamToStreamTest.cs index a507020420be9..1ffe2216a5a9e 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/NegotiateStreamStreamToStreamTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/NegotiateStreamStreamToStreamTest.cs @@ -2,11 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Diagnostics; +using System.IO; using System.Linq; using System.Net.Test.Common; +using System.Security.Authentication.ExtendedProtection; using System.Security.Principal; using System.Text; +using System.Threading; using System.Threading.Tasks; using Xunit; @@ -19,7 +21,7 @@ public abstract class NegotiateStreamStreamToStreamTest public static bool IsNtlmInstalled => Capability.IsNtlmInstalled(); private const int PartialBytesToRead = 5; - private static readonly byte[] s_sampleMsg = Encoding.UTF8.GetBytes("Sample Test Message"); + protected static readonly byte[] s_sampleMsg = Encoding.UTF8.GetBytes("Sample Test Message"); private const int MaxWriteDataSize = 63 * 1024; // NegoState.MaxWriteDataSize private static string s_longString = new string('A', MaxWriteDataSize) + 'Z'; @@ -27,14 +29,20 @@ public abstract class NegotiateStreamStreamToStreamTest protected abstract Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName); protected abstract Task AuthenticateAsServerAsync(NegotiateStream server); - - [ConditionalFact(nameof(IsNtlmInstalled))] - public async Task NegotiateStream_StreamToStream_Authentication_Success() + protected abstract Task ReadAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken = default); + protected abstract Task WriteAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken = default); + protected virtual bool SupportsCancelableReadsWrites => false; + protected virtual bool IsEncryptedAndSigned => true; + + [ConditionalTheory(nameof(IsNtlmInstalled))] + [InlineData(0)] + [InlineData(1)] + public async Task NegotiateStream_StreamToStream_Authentication_Success(int delay) { VirtualNetwork network = new VirtualNetwork(); - using (var clientStream = new VirtualNetworkStream(network, isServer: false)) - using (var serverStream = new VirtualNetworkStream(network, isServer: true)) + using (var clientStream = new VirtualNetworkStream(network, isServer: false) { DelayMilliseconds = delay }) + using (var serverStream = new VirtualNetworkStream(network, isServer: true) { DelayMilliseconds = delay }) using (var client = new NegotiateStream(clientStream)) using (var server = new NegotiateStream(serverStream)) { @@ -49,10 +57,10 @@ public async Task NegotiateStream_StreamToStream_Authentication_Success() // Expected Client property values: Assert.True(client.IsAuthenticated); Assert.Equal(TokenImpersonationLevel.Identification, client.ImpersonationLevel); - Assert.True(client.IsEncrypted); + Assert.Equal(IsEncryptedAndSigned, client.IsEncrypted); Assert.False(client.IsMutuallyAuthenticated); Assert.False(client.IsServer); - Assert.True(client.IsSigned); + Assert.Equal(IsEncryptedAndSigned, client.IsSigned); Assert.False(client.LeaveInnerStreamOpen); IIdentity serverIdentity = client.RemoteIdentity; @@ -63,10 +71,10 @@ public async Task NegotiateStream_StreamToStream_Authentication_Success() // Expected Server property values: Assert.True(server.IsAuthenticated); Assert.Equal(TokenImpersonationLevel.Identification, server.ImpersonationLevel); - Assert.True(server.IsEncrypted); + Assert.Equal(IsEncryptedAndSigned, server.IsEncrypted); Assert.False(server.IsMutuallyAuthenticated); Assert.True(server.IsServer); - Assert.True(server.IsSigned); + Assert.Equal(IsEncryptedAndSigned, server.IsSigned); Assert.False(server.LeaveInnerStreamOpen); IIdentity clientIdentity = server.RemoteIdentity; @@ -78,6 +86,43 @@ public async Task NegotiateStream_StreamToStream_Authentication_Success() } } + [ConditionalTheory(nameof(IsNtlmInstalled))] + [InlineData(0)] + [InlineData(1)] + public async Task NegotiateStream_StreamToStream_Authenticated_DisposeAsync(int delay) + { + var network = new VirtualNetwork(); + await using (var client = new NegotiateStream(new VirtualNetworkStream(network, isServer: false) { DelayMilliseconds = delay })) + await using (var server = new NegotiateStream(new VirtualNetworkStream(network, isServer: true) { DelayMilliseconds = delay })) + { + Assert.False(client.IsServer); + Assert.False(server.IsServer); + + Assert.False(client.IsAuthenticated); + Assert.False(server.IsAuthenticated); + + Assert.False(client.IsMutuallyAuthenticated); + Assert.False(server.IsMutuallyAuthenticated); + + Assert.False(client.IsEncrypted); + Assert.False(server.IsEncrypted); + + Assert.False(client.IsSigned); + Assert.False(server.IsSigned); + + await TestConfiguration.WhenAllOrAnyFailedWithTimeout( + AuthenticateAsClientAsync(client, CredentialCache.DefaultNetworkCredentials, string.Empty), + AuthenticateAsServerAsync(server)); + } + } + + [ConditionalFact(nameof(IsNtlmInstalled))] + public async Task NegotiateStream_StreamToStream_Unauthenticated_Dispose() + { + new NegotiateStream(new MemoryStream()).Dispose(); + await new NegotiateStream(new MemoryStream()).DisposeAsync(); + } + [ConditionalFact(nameof(IsNtlmInstalled))] public async Task NegotiateStream_StreamToStream_Authentication_TargetName_Success() { @@ -105,10 +150,10 @@ public async Task NegotiateStream_StreamToStream_Authentication_TargetName_Succe // Expected Client property values: Assert.True(client.IsAuthenticated); Assert.Equal(TokenImpersonationLevel.Identification, client.ImpersonationLevel); - Assert.True(client.IsEncrypted); + Assert.Equal(IsEncryptedAndSigned, client.IsEncrypted); Assert.False(client.IsMutuallyAuthenticated); Assert.False(client.IsServer); - Assert.True(client.IsSigned); + Assert.Equal(IsEncryptedAndSigned, client.IsSigned); Assert.False(client.LeaveInnerStreamOpen); IIdentity serverIdentity = client.RemoteIdentity; @@ -119,10 +164,10 @@ public async Task NegotiateStream_StreamToStream_Authentication_TargetName_Succe // Expected Server property values: Assert.True(server.IsAuthenticated); Assert.Equal(TokenImpersonationLevel.Identification, server.ImpersonationLevel); - Assert.True(server.IsEncrypted); + Assert.Equal(IsEncryptedAndSigned, server.IsEncrypted); Assert.False(server.IsMutuallyAuthenticated); Assert.True(server.IsServer); - Assert.True(server.IsSigned); + Assert.Equal(IsEncryptedAndSigned, server.IsSigned); Assert.False(server.LeaveInnerStreamOpen); IIdentity clientIdentity = server.RemoteIdentity; @@ -165,10 +210,10 @@ public async Task NegotiateStream_StreamToStream_Authentication_EmptyCredentials // Expected Client property values: Assert.True(client.IsAuthenticated); Assert.Equal(TokenImpersonationLevel.Identification, client.ImpersonationLevel); - Assert.True(client.IsEncrypted); + Assert.Equal(IsEncryptedAndSigned, client.IsEncrypted); Assert.False(client.IsMutuallyAuthenticated); Assert.False(client.IsServer); - Assert.True(client.IsSigned); + Assert.Equal(IsEncryptedAndSigned, client.IsSigned); Assert.False(client.LeaveInnerStreamOpen); IIdentity serverIdentity = client.RemoteIdentity; @@ -179,10 +224,10 @@ public async Task NegotiateStream_StreamToStream_Authentication_EmptyCredentials // Expected Server property values: Assert.True(server.IsAuthenticated); Assert.Equal(TokenImpersonationLevel.Identification, server.ImpersonationLevel); - Assert.True(server.IsEncrypted); + Assert.Equal(IsEncryptedAndSigned, server.IsEncrypted); Assert.False(server.IsMutuallyAuthenticated); Assert.True(server.IsServer); - Assert.True(server.IsSigned); + Assert.Equal(IsEncryptedAndSigned, server.IsSigned); Assert.False(server.LeaveInnerStreamOpen); IIdentity clientIdentity = server.RemoteIdentity; @@ -195,15 +240,17 @@ public async Task NegotiateStream_StreamToStream_Authentication_EmptyCredentials } } - [ConditionalFact(nameof(IsNtlmInstalled))] - public async Task NegotiateStream_StreamToStream_Successive_ClientWrite_Sync_Success() + [ConditionalTheory(nameof(IsNtlmInstalled))] + [InlineData(0)] + [InlineData(1)] + public async Task NegotiateStream_StreamToStream_Successive_ClientWrite_Success(int delay) { byte[] recvBuf = new byte[s_sampleMsg.Length]; VirtualNetwork network = new VirtualNetwork(); int bytesRead = 0; - using (var clientStream = new VirtualNetworkStream(network, isServer: false)) - using (var serverStream = new VirtualNetworkStream(network, isServer: true)) + using (var clientStream = new VirtualNetworkStream(network, isServer: false) { DelayMilliseconds = delay }) + using (var serverStream = new VirtualNetworkStream(network, isServer: true) { DelayMilliseconds = delay }) using (var client = new NegotiateStream(clientStream)) using (var server = new NegotiateStream(serverStream)) { @@ -216,99 +263,35 @@ public async Task NegotiateStream_StreamToStream_Successive_ClientWrite_Sync_Suc await TestConfiguration.WhenAllOrAnyFailedWithTimeout(auth); - client.Write(s_sampleMsg, 0, s_sampleMsg.Length); - server.Read(recvBuf, 0, s_sampleMsg.Length); - - Assert.True(s_sampleMsg.SequenceEqual(recvBuf)); - - client.Write(s_sampleMsg, 0, s_sampleMsg.Length); - - // Test partial sync read. - bytesRead = server.Read(recvBuf, 0, PartialBytesToRead); - Assert.Equal(PartialBytesToRead, bytesRead); - - bytesRead = server.Read(recvBuf, PartialBytesToRead, s_sampleMsg.Length - PartialBytesToRead); - Assert.Equal(s_sampleMsg.Length - PartialBytesToRead, bytesRead); - - Assert.True(s_sampleMsg.SequenceEqual(recvBuf)); - } - } - - [ConditionalFact(nameof(IsNtlmInstalled))] - public async Task NegotiateStream_StreamToStream_Successive_ClientWrite_Async_Success() - { - byte[] recvBuf = new byte[s_sampleMsg.Length]; - VirtualNetwork network = new VirtualNetwork(); - int bytesRead = 0; - - using (var clientStream = new VirtualNetworkStream(network, isServer: false)) - using (var serverStream = new VirtualNetworkStream(network, isServer: true)) - using (var client = new NegotiateStream(clientStream)) - using (var server = new NegotiateStream(serverStream)) - { - Assert.False(client.IsAuthenticated); - Assert.False(server.IsAuthenticated); - - Task[] auth = new Task[2]; - auth[0] = AuthenticateAsClientAsync(client, CredentialCache.DefaultNetworkCredentials, string.Empty); - auth[1] = AuthenticateAsServerAsync(server); - - await TestConfiguration.WhenAllOrAnyFailedWithTimeout(auth); - - auth[0] = client.WriteAsync(s_sampleMsg, 0, s_sampleMsg.Length); - auth[1] = server.ReadAsync(recvBuf, 0, s_sampleMsg.Length); + auth[0] = WriteAsync(client, s_sampleMsg, 0, s_sampleMsg.Length); + auth[1] = ReadAsync(server, recvBuf, 0, s_sampleMsg.Length); await TestConfiguration.WhenAllOrAnyFailedWithTimeout(auth); Assert.True(s_sampleMsg.SequenceEqual(recvBuf)); - await client.WriteAsync(s_sampleMsg, 0, s_sampleMsg.Length); + await WriteAsync(client, s_sampleMsg, 0, s_sampleMsg.Length); // Test partial async read. - bytesRead = await server.ReadAsync(recvBuf, 0, PartialBytesToRead); + bytesRead = await ReadAsync(server, recvBuf, 0, PartialBytesToRead); Assert.Equal(PartialBytesToRead, bytesRead); - bytesRead = await server.ReadAsync(recvBuf, PartialBytesToRead, s_sampleMsg.Length - PartialBytesToRead); + bytesRead = await ReadAsync(server, recvBuf, PartialBytesToRead, s_sampleMsg.Length - PartialBytesToRead); Assert.Equal(s_sampleMsg.Length - PartialBytesToRead, bytesRead); Assert.True(s_sampleMsg.SequenceEqual(recvBuf)); } } - [ConditionalFact(nameof(IsNtlmInstalled))] - public async Task NegotiateStream_ReadWriteLongMsgSync_Success() - { - byte[] recvBuf = new byte[s_longMsg.Length]; - var network = new VirtualNetwork(); - int bytesRead = 0; - - using (var clientStream = new VirtualNetworkStream(network, isServer: false)) - using (var serverStream = new VirtualNetworkStream(network, isServer: true)) - using (var client = new NegotiateStream(clientStream)) - using (var server = new NegotiateStream(serverStream)) - { - await TestConfiguration.WhenAllOrAnyFailedWithTimeout( - client.AuthenticateAsClientAsync(CredentialCache.DefaultNetworkCredentials, string.Empty), - server.AuthenticateAsServerAsync()); - - client.Write(s_longMsg, 0, s_longMsg.Length); - - while (bytesRead < s_longMsg.Length) - { - bytesRead += server.Read(recvBuf, bytesRead, s_longMsg.Length - bytesRead); - } - - Assert.True(s_longMsg.SequenceEqual(recvBuf)); - } - } - - [ConditionalFact(nameof(IsNtlmInstalled))] - public async Task NegotiateStream_ReadWriteLongMsgAsync_Success() + [ConditionalTheory(nameof(IsNtlmInstalled))] + [InlineData(0)] + [InlineData(1)] + public async Task NegotiateStream_ReadWriteLongMsg_Success(int delay) { byte[] recvBuf = new byte[s_longMsg.Length]; var network = new VirtualNetwork(); int bytesRead = 0; - using (var clientStream = new VirtualNetworkStream(network, isServer: false)) - using (var serverStream = new VirtualNetworkStream(network, isServer: true)) + using (var clientStream = new VirtualNetworkStream(network, isServer: false) { DelayMilliseconds = delay }) + using (var serverStream = new VirtualNetworkStream(network, isServer: true) { DelayMilliseconds = delay }) using (var client = new NegotiateStream(clientStream)) using (var server = new NegotiateStream(serverStream)) { @@ -316,11 +299,11 @@ public async Task NegotiateStream_ReadWriteLongMsgAsync_Success() client.AuthenticateAsClientAsync(CredentialCache.DefaultNetworkCredentials, string.Empty), server.AuthenticateAsServerAsync()); - await client.WriteAsync(s_longMsg, 0, s_longMsg.Length); + await WriteAsync(client, s_longMsg, 0, s_longMsg.Length); while (bytesRead < s_longMsg.Length) { - bytesRead += await server.ReadAsync(recvBuf, bytesRead, s_longMsg.Length - bytesRead); + bytesRead += await ReadAsync(server, recvBuf, bytesRead, s_longMsg.Length - bytesRead); } Assert.True(s_longMsg.SequenceEqual(recvBuf)); @@ -356,18 +339,91 @@ public void NegotiateStream_StreamToStream_FlushAsync_Propagated() Assert.True(task.IsCompleted); } } + + [ConditionalFact(nameof(IsNtlmInstalled))] + public async Task NegotiateStream_StreamToStream_Successive_CancelableReadsWrites() + { + if (!SupportsCancelableReadsWrites) + { + return; + } + + byte[] recvBuf = new byte[s_sampleMsg.Length]; + VirtualNetwork network = new VirtualNetwork(); + + using (var clientStream = new VirtualNetworkStream(network, isServer: false)) + using (var serverStream = new VirtualNetworkStream(network, isServer: true)) + using (var client = new NegotiateStream(clientStream)) + using (var server = new NegotiateStream(serverStream)) + { + await TestConfiguration.WhenAllOrAnyFailedWithTimeout( + AuthenticateAsClientAsync(client, CredentialCache.DefaultNetworkCredentials, string.Empty), + AuthenticateAsServerAsync(server)); + + clientStream.DelayMilliseconds = int.MaxValue; + serverStream.DelayMilliseconds = int.MaxValue; + + var cts = new CancellationTokenSource(); + Task t = WriteAsync(client, s_sampleMsg, 0, s_sampleMsg.Length, cts.Token); + Assert.False(t.IsCompleted); + cts.Cancel(); + await Assert.ThrowsAnyAsync(() => t); + + cts = new CancellationTokenSource(); + t = ReadAsync(server, s_sampleMsg, 0, s_sampleMsg.Length, cts.Token); + Assert.False(t.IsCompleted); + cts.Cancel(); + await Assert.ThrowsAnyAsync(() => t); + } + } } - public sealed class NegotiateStreamStreamToStreamTest_Async : NegotiateStreamStreamToStreamTest + public sealed class NegotiateStreamStreamToStreamTest_Async_Array : NegotiateStreamStreamToStreamTest { protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) => client.AuthenticateAsClientAsync(credential, targetName); protected override Task AuthenticateAsServerAsync(NegotiateStream server) => server.AuthenticateAsServerAsync(); + + protected override Task ReadAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + stream.ReadAsync(buffer, offset, count, cancellationToken); + + protected override Task WriteAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + stream.WriteAsync(buffer, offset, count, cancellationToken); + + protected override bool SupportsCancelableReadsWrites => true; } - public sealed class NegotiateStreamStreamToStreamTest_Async_TestOverloadNullBinding : NegotiateStreamStreamToStreamTest + public class NegotiateStreamStreamToStreamTest_Async_Memory : NegotiateStreamStreamToStreamTest + { + protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) => + client.AuthenticateAsClientAsync(credential, targetName); + + protected override Task AuthenticateAsServerAsync(NegotiateStream server) => + server.AuthenticateAsServerAsync(); + + protected override Task ReadAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + stream.ReadAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); + + protected override Task WriteAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + stream.WriteAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); + + protected override bool SupportsCancelableReadsWrites => true; + } + + public class NegotiateStreamStreamToStreamTest_Async_Memory_NotEncrypted : NegotiateStreamStreamToStreamTest_Async_Memory + { + protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) => + client.AuthenticateAsClientAsync(credential, targetName, ProtectionLevel.None, TokenImpersonationLevel.Identification); + + protected override Task AuthenticateAsServerAsync(NegotiateStream server) => + server.AuthenticateAsServerAsync(CredentialCache.DefaultNetworkCredentials, ProtectionLevel.None, TokenImpersonationLevel.Identification); + + protected override bool IsEncryptedAndSigned => false; + } + + public sealed class NegotiateStreamStreamToStreamTest_Async_TestOverloadNullBinding : NegotiateStreamStreamToStreamTest_Async_Memory { protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) => client.AuthenticateAsClientAsync(credential, null, targetName); @@ -376,7 +432,7 @@ public sealed class NegotiateStreamStreamToStreamTest_Async_TestOverloadNullBind server.AuthenticateAsServerAsync(null); } - public sealed class NegotiateStreamStreamToStreamTest_Async_TestOverloadProtectionLevel : NegotiateStreamStreamToStreamTest + public sealed class NegotiateStreamStreamToStreamTest_Async_TestOverloadProtectionLevel : NegotiateStreamStreamToStreamTest_Async_Memory { protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) => client.AuthenticateAsClientAsync(credential, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); @@ -385,7 +441,7 @@ public sealed class NegotiateStreamStreamToStreamTest_Async_TestOverloadProtecti server.AuthenticateAsServerAsync((NetworkCredential)CredentialCache.DefaultCredentials, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); } - public sealed class NegotiateStreamStreamToStreamTest_Async_TestOverloadAllParameters : NegotiateStreamStreamToStreamTest + public sealed class NegotiateStreamStreamToStreamTest_Async_TestOverloadAllParameters : NegotiateStreamStreamToStreamTest_Async_Memory { protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) => client.AuthenticateAsClientAsync(credential, null, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); @@ -394,25 +450,62 @@ public sealed class NegotiateStreamStreamToStreamTest_Async_TestOverloadAllParam server.AuthenticateAsServerAsync((NetworkCredential)CredentialCache.DefaultCredentials, null, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification); } - public sealed class NegotiateStreamStreamToStreamTest_BeginEnd : NegotiateStreamStreamToStreamTest + public class NegotiateStreamStreamToStreamTest_BeginEnd : NegotiateStreamStreamToStreamTest { protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) => Task.Factory.FromAsync(client.BeginAuthenticateAsClient, client.EndAuthenticateAsClient, credential, targetName, null); protected override Task AuthenticateAsServerAsync(NegotiateStream server) => Task.Factory.FromAsync(server.BeginAuthenticateAsServer, server.EndAuthenticateAsServer, null); + + protected override Task ReadAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + Task.Factory.FromAsync(stream.BeginRead, stream.EndRead, buffer, offset, count, null); + + protected override Task WriteAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + Task.Factory.FromAsync(stream.BeginWrite, stream.EndWrite, buffer, offset, count, null); } - public sealed class NegotiateStreamStreamToStreamTest_Sync : NegotiateStreamStreamToStreamTest + public sealed class NegotiateStreamStreamToStreamTest_BeginEnd_TestOverloadNullBinding : NegotiateStreamStreamToStreamTest_BeginEnd + { + protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) => + Task.Factory.FromAsync(client.BeginAuthenticateAsClient, client.EndAuthenticateAsClient, credential, (ChannelBinding)null, targetName, null); + + protected override Task AuthenticateAsServerAsync(NegotiateStream server) => + Task.Factory.FromAsync(server.BeginAuthenticateAsServer, server.EndAuthenticateAsServer, (ExtendedProtectionPolicy)null, null); + } + + public sealed class NegotiateStreamStreamToStreamTest_BeginEnd_TestOverloadProtectionLevel : NegotiateStreamStreamToStreamTest_BeginEnd + { + protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) => + Task.Factory.FromAsync( + (callback, state) => client.BeginAuthenticateAsClient(credential, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, callback, state), + client.EndAuthenticateAsClient, null); + + protected override Task AuthenticateAsServerAsync(NegotiateStream server) => + Task.Factory.FromAsync( + (callback, state) => server.BeginAuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification, callback, state), + server.EndAuthenticateAsServer, null); + } + + public class NegotiateStreamStreamToStreamTest_Sync : NegotiateStreamStreamToStreamTest { protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) => Task.Run(() => client.AuthenticateAsClient(credential, targetName)); protected override Task AuthenticateAsServerAsync(NegotiateStream server) => Task.Run(() => server.AuthenticateAsServer()); + + protected override Task ReadAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + Task.FromResult(stream.Read(buffer, offset, count)); + + protected override Task WriteAsync(NegotiateStream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + stream.Write(buffer, offset, count); + return Task.CompletedTask; + } } - public sealed class NegotiateStreamStreamToStreamTest_Sync_TestOverloadNullBinding : NegotiateStreamStreamToStreamTest + public sealed class NegotiateStreamStreamToStreamTest_Sync_TestOverloadNullBinding : NegotiateStreamStreamToStreamTest_Sync { protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) => Task.Run(() => client.AuthenticateAsClient(credential, null, targetName)); @@ -421,7 +514,7 @@ public sealed class NegotiateStreamStreamToStreamTest_Sync_TestOverloadNullBindi Task.Run(() => server.AuthenticateAsServer(null)); } - public sealed class NegotiateStreamStreamToStreamTest_Sync_TestOverloadAllParameters : NegotiateStreamStreamToStreamTest + public sealed class NegotiateStreamStreamToStreamTest_Sync_TestOverloadAllParameters : NegotiateStreamStreamToStreamTest_Sync { protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) => Task.Run(() => client.AuthenticateAsClient(credential, targetName, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification)); @@ -429,4 +522,15 @@ public sealed class NegotiateStreamStreamToStreamTest_Sync_TestOverloadAllParame protected override Task AuthenticateAsServerAsync(NegotiateStream server) => Task.Run(() => server.AuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, ProtectionLevel.EncryptAndSign, TokenImpersonationLevel.Identification)); } + + public class NegotiateStreamStreamToStreamTest_Sync_NotEncrypted : NegotiateStreamStreamToStreamTest_Sync + { + protected override Task AuthenticateAsClientAsync(NegotiateStream client, NetworkCredential credential, string targetName) => + Task.Run(() => client.AuthenticateAsClient(credential, targetName, ProtectionLevel.None, TokenImpersonationLevel.Identification)); + + protected override Task AuthenticateAsServerAsync(NegotiateStream server) => + Task.Run(() => server.AuthenticateAsServer((NetworkCredential)CredentialCache.DefaultCredentials, ProtectionLevel.None, TokenImpersonationLevel.Identification)); + + protected override bool IsEncryptedAndSigned => false; + } } diff --git a/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeLazyAsyncResult.cs b/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeLazyAsyncResult.cs deleted file mode 100644 index 709fc583536f2..0000000000000 --- a/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeLazyAsyncResult.cs +++ /dev/null @@ -1,43 +0,0 @@ -// 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. - -using System.Threading; - -namespace System.Net.Security -{ - internal class LazyAsyncResult : IAsyncResult - { - public LazyAsyncResult(SslStream sslState, object asyncState, AsyncCallback asyncCallback) - { - AsyncState = asyncState; - asyncCallback?.Invoke(this); - } - - public object AsyncState { get; } - - public WaitHandle AsyncWaitHandle - { - get - { - throw new NotImplementedException(); - } - } - - public bool CompletedSynchronously - { - get - { - return true; - } - } - - public bool IsCompleted - { - get - { - return true; - } - } - } -} diff --git a/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeSslStream.Implementation.cs b/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeSslStream.Implementation.cs index 3dffb86a4da38..ccd294beb54dd 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeSslStream.Implementation.cs +++ b/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeSslStream.Implementation.cs @@ -38,7 +38,7 @@ private void ValidateCreateContext(SslAuthenticationOptions sslAuthenticationOpt } private ValueTask WriteAsyncInternal(TWriteAdapter writeAdapter, ReadOnlyMemory buffer) - where TWriteAdapter : struct, ISslIOAdapter => default; + where TWriteAdapter : struct, IReadWriteAdapter => default; private ValueTask ReadAsyncInternal(TReadAdapter adapter, Memory buffer) => default; diff --git a/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj b/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj index 49823f8c08916..50d702a0b094c 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj +++ b/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj @@ -24,7 +24,6 @@ - @@ -45,8 +44,8 @@ Link="ProductionCode\System\Net\Security\SslApplicationProtocol.cs" /> - + Date: Tue, 19 May 2020 07:46:16 -0400 Subject: [PATCH 270/420] Libunwind1.5rc2 (#36027) * Add libunwind 1.5rc2 source Rename unused autoconfig dir aux -> aux_ consistent with original checkin * Delete files added by 1.3-rc1 * Update libunwind version in CMake * Add libunwind-version.txt * Add changes for SunOS from @am11 * Revert change to oop * Remove obsolete add_definition * Fix musl build * Fix comment * Be consistent and use HOST * Fix error in unw_sigcontext libunwind/libunwind#179 Introduced by libunwind/libunwind#71 __reseverved needs to be big enough to store a unw_fpsimd_context_t Which includes 32 128-bit registers, stored as 64 64-bit half registers. Fix off by 2 issue * Arm64 support !UNWIND_CONTEXT_IS_UCONTEXT_T Co-authored-by: Adeel --- .../src/pal/src/exception/seh-unwind.cpp | 16 + src/coreclr/src/pal/src/libunwind/.gitignore | 2 + src/coreclr/src/pal/src/libunwind/.travis.yml | 16 + .../src/pal/src/libunwind/CMakeLists.txt | 5 +- src/coreclr/src/pal/src/libunwind/Makefile.am | 5 + src/coreclr/src/pal/src/libunwind/README | 244 ++++++----- src/coreclr/src/pal/src/libunwind/autogen.sh | 2 +- .../src/pal/src/libunwind/configure.ac | 42 +- .../src/pal/src/libunwind/include/dwarf-eh.h | 1 + .../src/pal/src/libunwind/include/dwarf.h | 2 +- .../src/libunwind/include/libunwind-aarch64.h | 45 +- .../libunwind/include/libunwind-common.h.in | 15 +- .../src/libunwind/include/libunwind-mips.h | 2 +- .../src/libunwind/include/libunwind-s390x.h | 144 +++++++ .../pal/src/libunwind/include/libunwind.h.in | 2 + .../pal/src/libunwind/include/libunwind_i.h | 6 +- .../include/tdep-mips/dwarf-config.h | 3 - .../libunwind/include/tdep-mips/libunwind_i.h | 8 + .../include/tdep-s390x/dwarf-config.h | 52 +++ .../src/libunwind/include/tdep-s390x/jmpbuf.h | 35 ++ .../include/tdep-s390x/libunwind_i.h | 262 ++++++++++++ .../libunwind/include/tdep-x86_64/jmpbuf.h | 5 +- .../include/tdep-x86_64/libunwind_i.h | 5 + .../libunwind/include/tdep/libunwind_i.h.in | 2 + .../pal/src/libunwind/libunwind-version.txt | 2 + .../src/pal/src/libunwind/src/CMakeLists.txt | 21 +- .../src/pal/src/libunwind/src/Makefile.am | 55 ++- .../src/pal/src/libunwind/src/aarch64/Ginit.c | 23 +- .../src/libunwind/src/aarch64/Ginit_local.c | 2 +- .../pal/src/libunwind/src/aarch64/Gresume.c | 4 +- .../pal/src/libunwind/src/aarch64/unwind_i.h | 2 +- .../pal/src/libunwind/src/arm/Gex_tables.c | 5 +- .../src/pal/src/libunwind/src/arm/Ginit.c | 15 +- .../src/pal/src/libunwind/src/arm/Gresume.c | 4 +- .../src/pal/src/libunwind/src/arm/Gstep.c | 23 +- .../src/coredump/_UCD_access_reg_freebsd.c | 20 + .../src/coredump/_UCD_access_reg_linux.c | 3 + .../src/libunwind/src/coredump/_UCD_create.c | 13 +- .../src/coredump/_UCD_get_proc_name.c | 4 + .../coredump/_UPT_get_dyn_info_list_addr.c | 5 + .../src/pal/src/libunwind/src/dwarf/Gexpr.c | 16 +- .../libunwind/src/dwarf/Gfind_proc_info-lsb.c | 393 ++++++++++-------- .../libunwind/src/dwarf/Gfind_unwind_table.c | 3 + .../src/pal/src/libunwind/src/dwarf/Gparser.c | 38 +- src/coreclr/src/pal/src/libunwind/src/elfxx.c | 1 + .../src/pal/src/libunwind/src/hppa/Ginit.c | 15 +- .../src/pal/src/libunwind/src/ia64/Ginit.c | 1 + .../src/mi/Gfind_dynamic_proc_info.c | 1 + .../pal/src/libunwind/src/mi/Gget_proc_name.c | 10 +- .../src/pal/src/libunwind/src/mi/backtrace.c | 6 +- .../pal/src/libunwind/src/mi/flush_cache.c | 19 +- .../libunwind/src/mips/Gcreate_addr_space.c | 9 +- .../src/libunwind/src/mips/Gget_proc_info.c | 11 +- .../src/pal/src/libunwind/src/mips/Ginit.c | 15 +- .../src/pal/src/libunwind/src/mips/Gregs.c | 3 +- .../src/pal/src/libunwind/src/mips/Gstep.c | 98 ++++- .../src/pal/src/libunwind/src/os-solaris.c | 73 ++++ .../src/pal/src/libunwind/src/ppc32/Ginit.c | 11 +- .../src/pal/src/libunwind/src/ppc64/Ginit.c | 11 +- .../libunwind/src/ptrace/_UPT_access_fpreg.c | 7 + .../src/ptrace/_UPT_get_dyn_info_list_addr.c | 5 + .../libunwind/src/ptrace/_UPT_reg_offset.c | 34 ++ .../libunwind/src/s390x/Gapply_reg_state.c | 37 ++ .../libunwind/src/s390x/Gcreate_addr_space.c | 62 +++ .../src/libunwind/src/s390x/Gget_proc_info.c | 48 +++ .../src/libunwind/src/s390x/Gget_save_loc.c | 86 ++++ .../src/pal/src/libunwind/src/s390x/Gglobal.c | 101 +++++ .../src/pal/src/libunwind/src/s390x/Ginit.c | 365 ++++++++++++++++ .../pal/src/libunwind/src/s390x/Ginit_local.c | 81 ++++ .../src/libunwind/src/s390x/Ginit_remote.c | 57 +++ .../libunwind/src/s390x/Gis_signal_frame.c | 77 ++++ .../libunwind/src/s390x/Greg_states_iterate.c | 37 ++ .../src/pal/src/libunwind/src/s390x/Gregs.c | 116 ++++++ .../src/pal/src/libunwind/src/s390x/Gresume.c | 160 +++++++ .../src/pal/src/libunwind/src/s390x/Gstep.c | 146 +++++++ .../libunwind/src/s390x/Lapply_reg_state.c | 5 + .../libunwind/src/s390x/Lcreate_addr_space.c | 5 + .../src/libunwind/src/s390x/Lget_proc_info.c | 5 + .../src/libunwind/src/s390x/Lget_save_loc.c | 5 + .../src/pal/src/libunwind/src/s390x/Lglobal.c | 6 + .../src/pal/src/libunwind/src/s390x/Linit.c | 5 + .../pal/src/libunwind/src/s390x/Linit_local.c | 5 + .../src/libunwind/src/s390x/Linit_remote.c | 5 + .../libunwind/src/s390x/Lis_signal_frame.c | 5 + .../libunwind/src/s390x/Lreg_states_iterate.c | 5 + .../src/pal/src/libunwind/src/s390x/Lregs.c | 5 + .../src/pal/src/libunwind/src/s390x/Lresume.c | 5 + .../src/pal/src/libunwind/src/s390x/Lstep.c | 5 + .../pal/src/libunwind/src/s390x/getcontext.S | 74 ++++ .../src/pal/src/libunwind/src/s390x/init.h | 71 ++++ .../pal/src/libunwind/src/s390x/is_fpreg.c | 36 ++ .../src/pal/src/libunwind/src/s390x/regname.c | 57 +++ .../pal/src/libunwind/src/s390x/setcontext.S | 76 ++++ .../pal/src/libunwind/src/s390x/unwind_i.h | 48 +++ .../pal/src/libunwind/src/setjmp/siglongjmp.c | 10 +- .../src/pal/src/libunwind/src/sh/Ginit.c | 15 +- .../pal/src/libunwind/src/sh/Ginit_local.c | 2 +- .../src/pal/src/libunwind/src/sh/Gresume.c | 4 +- .../src/pal/src/libunwind/src/tilegx/Ginit.c | 15 +- .../src/libunwind/src/unwind/libunwind.pc.in | 2 +- .../src/pal/src/libunwind/src/x86/Ginit.c | 15 +- .../src/libunwind/src/x86_64/Gget_save_loc.c | 1 + .../pal/src/libunwind/src/x86_64/Gglobal.c | 21 +- .../src/pal/src/libunwind/src/x86_64/Ginit.c | 175 ++++++-- .../src/libunwind/src/x86_64/Ginit_local.c | 2 +- .../src/libunwind/src/x86_64/Ginit_remote.c | 2 +- .../src/libunwind/src/x86_64/Gos-solaris.c | 133 ++++++ .../src/libunwind/src/x86_64/Gstash_frame.c | 6 +- .../src/pal/src/libunwind/src/x86_64/Gstep.c | 121 ++++-- .../src/pal/src/libunwind/src/x86_64/Gtrace.c | 2 +- .../src/libunwind/src/x86_64/Los-solaris.c | 5 + .../pal/src/libunwind/src/x86_64/getcontext.S | 4 +- .../pal/src/libunwind/src/x86_64/setcontext.S | 6 +- .../pal/src/libunwind/src/x86_64/ucontext_i.h | 20 + .../src/pal/src/libunwind/tests/Gtest-bt.c | 6 +- .../src/pal/src/libunwind/tests/Gtest-trace.c | 2 +- .../tests/Gx64-test-dwarf-expressions.c | 68 +++ .../src/libunwind/tests/Ltest-mem-validate.c | 2 + .../tests/Lx64-test-dwarf-expressions.c | 5 + .../src/pal/src/libunwind/tests/Makefile.am | 19 +- .../src/libunwind/tests/check-namespace.sh.in | 22 +- .../src/pal/src/libunwind/tests/crasher.c | 7 +- .../libunwind/tests/test-coredump-unwind.c | 8 +- .../tests/x64-test-dwarf-expressions.S | 78 ++++ .../tests/x64-unwind-badjmp-signal-frame.c | 124 ++++++ 125 files changed, 4077 insertions(+), 528 deletions(-) create mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h create mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/libunwind-version.txt create mode 100644 src/coreclr/src/pal/src/libunwind/src/os-solaris.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/init.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/regname.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S create mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c create mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c create mode 100644 src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S create mode 100644 src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c diff --git a/src/coreclr/src/pal/src/exception/seh-unwind.cpp b/src/coreclr/src/pal/src/exception/seh-unwind.cpp index 53c86a0045384..654e385dec40a 100644 --- a/src/coreclr/src/pal/src/exception/seh-unwind.cpp +++ b/src/coreclr/src/pal/src/exception/seh-unwind.cpp @@ -111,6 +111,22 @@ static void WinContextToUnwindContext(CONTEXT *winContext, unw_context_t *unwCon unwContext->regs[13] = winContext->Sp; unwContext->regs[14] = winContext->Lr; unwContext->regs[15] = winContext->Pc; +#elif defined(HOST_ARM64) + unwContext->uc_mcontext.pc = winContext->Pc; + unwContext->uc_mcontext.sp = winContext->Sp; + unwContext->uc_mcontext.regs[29] = winContext->Fp; + unwContext->uc_mcontext.regs[30] = winContext->Lr; + + unwContext->uc_mcontext.regs[19] = winContext->X19; + unwContext->uc_mcontext.regs[20] = winContext->X20; + unwContext->uc_mcontext.regs[21] = winContext->X21; + unwContext->uc_mcontext.regs[22] = winContext->X22; + unwContext->uc_mcontext.regs[23] = winContext->X23; + unwContext->uc_mcontext.regs[24] = winContext->X24; + unwContext->uc_mcontext.regs[25] = winContext->X25; + unwContext->uc_mcontext.regs[26] = winContext->X26; + unwContext->uc_mcontext.regs[27] = winContext->X27; + unwContext->uc_mcontext.regs[28] = winContext->X28; #endif } diff --git a/src/coreclr/src/pal/src/libunwind/.gitignore b/src/coreclr/src/pal/src/libunwind/.gitignore index 7b7905f0d5981..724a1f4882e2c 100644 --- a/src/coreclr/src/pal/src/libunwind/.gitignore +++ b/src/coreclr/src/pal/src/libunwind/.gitignore @@ -75,5 +75,7 @@ tests/[GL]ia64-test-readonly tests/[GL]ia64-test-stack tests/ia64-test-dyn1 tests/ia64-test-sig +tests/[GL]x64-test-dwarf-expressions +tests/x64-unwind-badjmp-signal-frame tests/*.log tests/*.trs diff --git a/src/coreclr/src/pal/src/libunwind/.travis.yml b/src/coreclr/src/pal/src/libunwind/.travis.yml index 4a74b4a1bcb3e..7bf0f8d0638ef 100644 --- a/src/coreclr/src/pal/src/libunwind/.travis.yml +++ b/src/coreclr/src/pal/src/libunwind/.travis.yml @@ -9,6 +9,18 @@ env: - TARGET=mipsel-unknown-linux-gnu # Currently experiencing build failures here #- TARGET=powerpc64-linux-gnu + +linux-s390x: &linux-s390x + os: linux + arch: s390x + env: TARGET=s390x-linux-gnu + script: + - ./autogen.sh + - ./configure + - make -j32 + - ulimit -c unlimited + - make check -j32 + script: - ./autogen.sh - ./configure --target=$TARGET --host=$HOST @@ -16,3 +28,7 @@ script: - sudo bash -c 'echo core.%p.%p > /proc/sys/kernel/core_pattern' - ulimit -c unlimited - if [ $TARGET == 'x86_64-linux-gnu' ]; then make check -j32; fi + +jobs: + include: + - <<: *linux-s390x diff --git a/src/coreclr/src/pal/src/libunwind/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/CMakeLists.txt index 5c66b90fdb050..fc47c89f640cf 100644 --- a/src/coreclr/src/pal/src/libunwind/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/CMakeLists.txt @@ -13,10 +13,9 @@ elseif(CLR_CMAKE_HOST_ARCH_I386) endif() set(PKG_MAJOR "1") -set(PKG_MINOR "3") -set(PKG_EXTRA "-rc1") +set(PKG_MINOR "5") +set(PKG_EXTRA "-rc2") configure_file(include/libunwind-common.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind-common.h) configure_file(include/libunwind.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind.h) configure_file(include/tdep/libunwind_i.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/tdep/libunwind_i.h) - diff --git a/src/coreclr/src/pal/src/libunwind/Makefile.am b/src/coreclr/src/pal/src/libunwind/Makefile.am index 711d9100c7551..8132fa4cb952a 100644 --- a/src/coreclr/src/pal/src/libunwind/Makefile.am +++ b/src/coreclr/src/pal/src/libunwind/Makefile.am @@ -41,6 +41,9 @@ endif if ARCH_SH include_HEADERS += include/libunwind-sh.h endif +if ARCH_S390X +include_HEADERS += include/libunwind-s390x.h +endif if !REMOTE_ONLY include_HEADERS += include/libunwind.h include/unwind.h @@ -84,6 +87,8 @@ noinst_HEADERS = include/dwarf.h include/dwarf_i.h include/dwarf-eh.h \ include/tdep-ppc64/jmpbuf.h include/tdep-ppc64/libunwind_i.h \ include/tdep-sh/dwarf-config.h \ include/tdep-sh/jmpbuf.h include/tdep-sh/libunwind_i.h \ + include/tdep-s390x/dwarf-config.h \ + include/tdep-s390x/jmpbuf.h include/tdep-s390x/libunwind_i.h \ include/tdep/libunwind_i.h \ include/tdep/jmpbuf.h include/tdep/dwarf-config.h diff --git a/src/coreclr/src/pal/src/libunwind/README b/src/coreclr/src/pal/src/libunwind/README index 694f600b06dc9..b6d93ae4a6855 100644 --- a/src/coreclr/src/pal/src/libunwind/README +++ b/src/coreclr/src/pal/src/libunwind/README @@ -1,53 +1,83 @@ --*- mode: Outline -*- +# libunwind [![Build Status](https://travis-ci.org/libunwind/libunwind.svg?branch=master)](https://travis-ci.org/libunwind/libunwind) -This is version 1.3 of the unwind library. This library supports +This is version 1.5 of the unwind library. This library supports several architecture/operating-system combinations: - Linux/x86-64: Works well. - Linux/x86: Works well. - Linux/ARM: Works well. - Linux/IA-64: Works well. - Linux/PARISC: Works well, but C library missing unwind-info. - HP-UX/IA-64: Mostly works but known to have some serious limitations. - MIPS: Newly added. - Linux/AArch64: Works well. - Linux/PPC64: Newly added. - Linux/SuperH: Newly added. - FreeBSD/i386: Works well. - FreeBSD/x86-64: Newly added (FreeBSD architecture is known as amd64). - Linux/Tilegx: Newly added (64-bit mode only). - -* General Build Instructions +| System | Architecture | Status | +| :------ | :----------- | :----- | +| Linux | x86-64 | ✓ | +| Linux | x86 | ✓ | +| Linux | ARM | ✓ | +| Linux | AArch64 | ✓ | +| Linux | PPC64 | ✓ | +| Linux | SuperH | ✓ | +| Linux | IA-64 | ✓ | +| Linux | PARISC | Works well, but C library missing unwind-info | +| Linux | Tilegx | 64-bit mode only | +| Linux | MIPS | Newly added | +| HP-UX | IA-64 | Mostly works, but known to have serious limitations | +| FreeBSD | x86-64 | ✓ | +| FreeBSD | x86 | ✓ | +| FreeBSD | AArch64 | ✓ | +| Solaris | x86-64 | ✓ | + +## Libc Requirements + +libunwind depends on getcontext(), setcontext() functions which are missing +from C libraries like musl-libc because they are considered to be "obsolescent" +API by POSIX document. The following table tries to track current status of +such dependencies + + - r, requires + - p, provides its own implementation + - empty, no requirement + +| Archtecture | getcontext | setcontext | +|--------------|------------|------------| +| aarch64 | p | | +| arm | p | | +| hppa | p | p | +| ia64 | p | r | +| mips | p | | +| ppc32 | r | | +| ppc64 | r | r | +| s390x | p | p | +| sh | r | | +| tilegx | r | r | +| x86 | p | r | +| x86_64 | p | p | + +## General Build Instructions In general, this library can be built and installed with the following commands: - $ ./autogen.sh # Needed only for building from git. Depends on libtool. - $ ./configure - $ make - $ make install prefix=PREFIX + $ ./autogen.sh # Needed only for building from git. Depends on libtool. + $ ./configure + $ make + $ make install prefix=PREFIX -where PREFIX is the installation prefix. By default, a prefix of -/usr/local is used, such that libunwind.a is installed in -/usr/local/lib and unwind.h is installed in /usr/local/include. For -testing, you may want to use a prefix of /usr/local instead. +where `PREFIX` is the installation prefix. By default, a prefix of +`/usr/local` is used, such that `libunwind.a` is installed in +`/usr/local/lib` and `unwind.h` is installed in `/usr/local/include`. For +testing, you may want to use a prefix of `/usr/local` instead. -* Building with Intel compiler +### Building with Intel compiler -** Version 8 and later +#### Version 8 and later Starting with version 8, the preferred name for the IA-64 Intel -compiler is "icc" (same name as on x86). Thus, the configure-line +compiler is `icc` (same name as on x86). Thus, the configure-line should look like this: $ ./configure CC=icc CFLAGS="-g -O3 -ip" CXX=icc CCAS=gcc CCASFLAGS=-g \ - LDFLAGS="-L$PWD/src/.libs" + LDFLAGS="-L$PWD/src/.libs" -* Building on HP-UX +### Building on HP-UX For the time being, libunwind must be built with GCC on HP-UX. @@ -55,14 +85,13 @@ libunwind should be configured and installed on HP-UX like this: $ ./configure CFLAGS="-g -O2 -mlp64" CXXFLAGS="-g -O2 -mlp64" -Caveat: Unwinding of 32-bit (ILP32) binaries is not supported - at the moment. +Caveat: Unwinding of 32-bit (ILP32) binaries is not supported at the moment. -** Workaround for older versions of GCC +### Workaround for older versions of GCC -GCC v3.0 and GCC v3.2 ship with a bad version of sys/types.h. The +GCC v3.0 and GCC v3.2 ship with a bad version of `sys/types.h`. The workaround is to issue the following commands before running -"configure": +`configure`: $ mkdir $top_dir/include/sys $ cp /usr/include/sys/types.h $top_dir/include/sys @@ -70,138 +99,141 @@ workaround is to issue the following commands before running GCC v3.3.2 or later have been fixed and do not require this workaround. -* Building for PowerPC64 / Linux +### Building for PowerPC64 / Linux For building for power64 you should use: - $ ./configure CFLAGS="-g -O2 -m64" CXXFLAGS="-g -O2 -m64" + $ ./configure CFLAGS="-g -O2 -m64" CXXFLAGS="-g -O2 -m64" If your power support altivec registers: - $ ./configure CFLAGS="-g -O2 -m64 -maltivec" CXXFLAGS="-g -O2 -m64 -maltivec" + + $ ./configure CFLAGS="-g -O2 -m64 -maltivec" CXXFLAGS="-g -O2 -m64 -maltivec" To check if your processor has support for vector registers (altivec): + cat /proc/cpuinfo | grep altivec + and should have something like this: + cpu : PPC970, altivec supported If libunwind seems to not work (backtracing failing), try to compile -it with -O0, without optimizations. There are some compiler problems +it with `-O0`, without optimizations. There are some compiler problems depending on the version of your gcc. -* Building on FreeBSD - -General building instructions apply. To build and execute several tests, -you need libexecinfo library available in ports as devel/libexecinfo. +### Building on FreeBSD -Development of the port was done of FreeBSD 8.0-STABLE. The library -was build with the system compiler that is modified version of gcc 4.2.1, -as well as the gcc 4.4.3. +General building instructions apply. To build and execute several tests +on older versions of FreeBSD, you need libexecinfo library available in +ports as devel/libexecinfo. This port has been removed as of 2017 and is +indeed no longer needed. -* Regression Testing +## Regression Testing After building the library, you can run a set of regression tests with: - $ make check + $ make check -** Expected results on IA-64 Linux +### Expected results on IA-64 Linux Unless you have a very recent C library and compiler installed, it is currently expected to have the following tests fail on IA-64 Linux: - Gtest-init (should pass starting with glibc-2.3.x/gcc-3.4) - Ltest-init (should pass starting with glibc-2.3.x/gcc-3.4) - test-ptrace (should pass starting with glibc-2.3.x/gcc-3.4) - run-ia64-test-dyn1 (should pass starting with glibc-2.3.x) +* `Gtest-init` (should pass starting with glibc-2.3.x/gcc-3.4) +* `Ltest-init` (should pass starting with glibc-2.3.x/gcc-3.4) +* `test-ptrace` (should pass starting with glibc-2.3.x/gcc-3.4) +* `run-ia64-test-dyn1` (should pass starting with glibc-2.3.x) This does not mean that libunwind cannot be used with older compilers or C libraries, it just means that for certain corner cases, unwinding will fail. Since they're corner cases, it is not likely for applications to trigger them. -Note: If you get lots of errors in Gia64-test-nat and Lia64-test-nat, it's - almost certainly a sign of an old assembler. The GNU assembler used - to encode previous-stack-pointer-relative offsets incorrectly. - This bug was fixed on 21-Sep-2004 so any later assembler will be - fine. +Note: If you get lots of errors in `Gia64-test-nat` and `Lia64-test-nat`, it's +almost certainly a sign of an old assembler. The GNU assembler used +to encode previous-stack-pointer-relative offsets incorrectly. +This bug was fixed on 21-Sep-2004 so any later assembler will be +fine. -** Expected results on x86 Linux +### Expected results on x86 Linux The following tests are expected to fail on x86 Linux: - test-ptrace +* `test-ptrace` -** Expected results on x86-64 Linux +### Expected results on x86-64 Linux The following tests are expected to fail on x86-64 Linux: - run-ptrace-misc (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18748 - and http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18749) +* `run-ptrace-misc` (see + and ) -** Expected results on PARISC Linux +### Expected results on PARISC Linux Caveat: GCC v3.4 or newer is needed on PA-RISC Linux. Earlier versions of the compiler failed to generate the exception-handling -program header (GNU_EH_FRAME) needed for unwinding. +program header (`GNU_EH_FRAME`) needed for unwinding. The following tests are expected to fail on x86-64 Linux: - Gtest-bt (backtrace truncated at kill() due to lack of unwind-info) - Ltest-bt (likewise) - Gtest-resume-sig (Gresume.c:my_rt_sigreturn() is wrong somehow) - Ltest-resume-sig (likewise) - Gtest-init (likewise) - Ltest-init (likewise) - Gtest-dyn1 (no dynamic unwind info support yet) - Ltest-dyn1 (no dynamic unwind info support yet) - test-setjmp (longjmp() not implemented yet) - run-check-namespace (toolchain doesn't support HIDDEN yet) +* `Gtest-bt` (backtrace truncated at `kill()` due to lack of unwind-info) +* `Ltest-bt` (likewise) +* `Gtest-resume-sig` (`Gresume.c:my_rt_sigreturn()` is wrong somehow) +* `Ltest-resume-sig` (likewise) +* `Gtest-init` (likewise) +* `Ltest-init` (likewise) +* `Gtest-dyn1` (no dynamic unwind info support yet) +* `Ltest-dyn1` (no dynamic unwind info support yet) +* `test-setjmp` (`longjmp()` not implemented yet) +* `run-check-namespace` (toolchain doesn't support `HIDDEN` yet) -** Expected results on HP-UX +### Expected results on HP-UX -"make check" is currently unsupported for HP-UX. You can try to run +`make check` is currently unsupported for HP-UX. You can try to run it, but most tests will fail (and some may fail to terminate). The only test programs that are known to work at this time are: - tests/bt - tests/Gperf-simple - tests/test-proc-info - tests/test-static-link - tests/Gtest-init - tests/Ltest-init - tests/Gtest-resume-sig - tests/Ltest-resume-sig +* `tests/bt` +* `tests/Gperf-simple` +* `tests/test-proc-info` +* `tests/test-static-link` +* `tests/Gtest-init` +* `tests/Ltest-init` +* `tests/Gtest-resume-sig` +* `tests/Ltest-resume-sig` + +### Expected results on PPC64 Linux -** Expected results on PPC64 Linux +`make check` should run with no more than 10 out of 24 tests failed. -"make check" should run with no more than 10 out of 24 tests failed. +### Expected results on Solaris x86-64 +`make check` is passing 27 out of 33 tests. The following six tests are consistently +failing: -* Performance Testing +* `Gtest-concurrent` +* `Ltest-concurrent` +* `Ltest-init-local-signal` +* `Lrs-race` +* `test-setjmp` +* `x64-unwind-badjmp-signal-frame` + +## Performance Testing This distribution includes a few simple performance tests which give some idea of the basic cost of various libunwind operations. After building the library, you can run these tests with the following commands: - $ cd tests - $ make perf - -* Contacting the Developers - -Please direct all questions regarding this library to: - - libunwind-devel@nongnu.org - -You can do this by sending a mail to libunwind-request@nongnu.org with -a body of: - - subscribe libunwind-devel + $ cd tests + $ make perf -or you can subscribe and manage your subscription via the -web-interface at: +## Contacting the Developers - https://savannah.nongnu.org/mail/?group=libunwind +Please direct all questions regarding this library to . -Or interact at the gihub page: +You can do this by sending an email to with +a body of "subscribe libunwind-devel", or you can subscribe and manage your +subscription via the web-interface at . - https://github.com/libunwind/libunwind +You can also interact on our GitHub page: . diff --git a/src/coreclr/src/pal/src/libunwind/autogen.sh b/src/coreclr/src/pal/src/libunwind/autogen.sh index aad9de6615c22..b08bc831f6447 100755 --- a/src/coreclr/src/pal/src/libunwind/autogen.sh +++ b/src/coreclr/src/pal/src/libunwind/autogen.sh @@ -1,6 +1,6 @@ #!/bin/sh -test -n "$srcdir" || srcdir=`dirname "${BASH_SOURCE[0]}"` +test -n "$srcdir" || srcdir=`dirname "$0"` test -n "$srcdir" || srcdir=. ( cd "$srcdir" && diff --git a/src/coreclr/src/pal/src/libunwind/configure.ac b/src/coreclr/src/pal/src/libunwind/configure.ac index 0c5125971f7c6..226a10fb35047 100644 --- a/src/coreclr/src/pal/src/libunwind/configure.ac +++ b/src/coreclr/src/pal/src/libunwind/configure.ac @@ -1,5 +1,5 @@ define(pkg_major, 1) -define(pkg_minor, 3) +define(pkg_minor, 5) define(pkg_extra, -rc1) define(pkg_maintainer, libunwind-devel@nongnu.org) define(mkvers, $1.$2$3) @@ -70,7 +70,7 @@ PT_STEP, PT_SYSCALL], [], [], dnl Checks for library functions. AC_CHECK_FUNCS(dl_iterate_phdr dl_phdr_removals_counter dlmodinfo getunwind \ - ttrace mincore) + ttrace mincore pipe2) AC_MSG_CHECKING([if building with AltiVec]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ @@ -147,6 +147,10 @@ AC_ARG_ENABLE(tests, AS_HELP_STRING([--disable-tests],[Disable tests build]),, [enable_tests=yes]) +AC_ARG_ENABLE(weak-backtrace, + AS_HELP_STRING([--disable-weak-backtrace],[Do not provide the weak 'backtrace' symbol.]),, + [enable_weak_backtrace=yes]) + AC_MSG_CHECKING([if we should build libunwind-setjmp]) AC_MSG_RESULT([$enable_setjmp]) @@ -175,15 +179,17 @@ AM_CONDITIONAL(ARCH_PPC32, test x$target_arch = xppc32) AM_CONDITIONAL(ARCH_PPC64, test x$target_arch = xppc64) AM_CONDITIONAL(ARCH_SH, test x$target_arch = xsh) AM_CONDITIONAL(ARCH_TILEGX, test x$target_arch = xtilegx) +AM_CONDITIONAL(ARCH_S390X, test x$target_arch = xs390x) AM_CONDITIONAL(OS_LINUX, expr x$target_os : xlinux >/dev/null) AM_CONDITIONAL(OS_HPUX, expr x$target_os : xhpux >/dev/null) AM_CONDITIONAL(OS_FREEBSD, expr x$target_os : xfreebsd >/dev/null) AM_CONDITIONAL(OS_QNX, expr x$target_os : xnto-qnx >/dev/null) +AM_CONDITIONAL(OS_SOLARIS, expr x$target_os : xsolaris >/dev/null) AC_MSG_CHECKING([for ELF helper width]) case "${target_arch}" in (arm|hppa|ppc32|x86|sh) use_elf32=yes; AC_MSG_RESULT([32]);; -(aarch64|ia64|ppc64|x86_64|tilegx) use_elf64=yes; AC_MSG_RESULT([64]);; +(aarch64|ia64|ppc64|x86_64|s390x|tilegx) use_elf64=yes; AC_MSG_RESULT([64]);; (mips) use_elfxx=yes; AC_MSG_RESULT([xx]);; *) AC_MSG_ERROR([Unknown ELF target: ${target_arch}]) esac @@ -300,6 +306,23 @@ fi AC_SUBST([LIBLZMA]) AM_CONDITIONAL(HAVE_LZMA, test x$enable_minidebuginfo = xyes) +LIBZ= +AC_MSG_CHECKING([whether to support ZLIB-compressed symbol tables]) +AC_ARG_ENABLE(zlibdebuginfo, +AS_HELP_STRING([--enable-zlibdebuginfo], [Enables support for ZLIB-compressed symbol tables]),, [enable_zlibdebuginfo=auto]) +AC_MSG_RESULT([$enable_zlibdebuginfo]) +if test x$enable_zlibdebuginfo != xno; then + AC_CHECK_LIB([z], [uncompress], + [LIBZ=-lz + AC_DEFINE([HAVE_ZLIB], [1], [Define if you have libz]) + enable_zlibdebuginfo=yes], + [if test x$enable_zlibdebuginfo = xyes; then + AC_MSG_FAILURE([libz not found]) + fi]) +fi +AC_SUBST([LIBZ]) +AM_CONDITIONAL(HAVE_ZLIB, test x$enable_zlibdebuginfo = xyes) + AC_MSG_CHECKING([whether to support UNW_CACHE_PER_THREAD]) AC_ARG_ENABLE([per-thread-cache], AS_HELP_STRING([--enable-per-thread-cache], [build with support for UNW_CACHE_PER_THREAD (which imposes a hight TLS memory usage) (default: disabled)])) @@ -321,6 +344,14 @@ if test x$GCC = xyes -a x$intel_compiler != xyes; then fi AC_MSG_RESULT([$intel_compiler]) +AC_MSG_CHECKING([if building on Solaris then define __EXTENSIONS__ macro]) +if $OS_SOLARIS; then + CFLAGS="${CFLAGS} -D__EXTENSIONS__" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + AC_MSG_CHECKING([for QCC compiler]) AS_CASE([$CC], [qcc*|QCC*], [qcc_compiler=yes], [qcc_compiler=no]) AC_MSG_RESULT([$qcc_compiler]) @@ -436,6 +467,11 @@ if test "x$enable_tests" = "xyes"; then AC_CONFIG_FILES(tests/Makefile tests/check-namespace.sh) fi +AM_CONDITIONAL([CONFIG_WEAK_BACKTRACE], [test "x$enable_weak_backtrace" = xyes]) +AM_COND_IF([CONFIG_WEAK_BACKTRACE], [ + AC_DEFINE([CONFIG_WEAK_BACKTRACE], [1], [Define if the weak 'backtrace' symbol is provided.]) +]) + AC_CONFIG_FILES(Makefile src/Makefile include/libunwind-common.h include/libunwind.h include/tdep/libunwind_i.h) diff --git a/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h b/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h index e03750760c529..96002a1b9d2d2 100644 --- a/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h +++ b/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h @@ -27,6 +27,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define dwarf_eh_h #include "dwarf.h" +#include "libunwind_i.h" /* This header file defines the format of a DWARF exception-header section (.eh_frame_hdr, pointed to by program-header diff --git a/src/coreclr/src/pal/src/libunwind/include/dwarf.h b/src/coreclr/src/pal/src/libunwind/include/dwarf.h index fab93c614518e..764f6f20ac22b 100644 --- a/src/coreclr/src/pal/src/libunwind/include/dwarf.h +++ b/src/coreclr/src/pal/src/libunwind/include/dwarf.h @@ -419,7 +419,7 @@ extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t a unw_word_t ip); extern void dwarf_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg); -extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, +extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_word_t *addr, unw_word_t len, unw_word_t *valp, int *is_register); extern int diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h index 85812e151d782..2716afccb815b 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h @@ -44,9 +44,13 @@ extern "C" { leaving some slack for future expansion. Changing this value will require recompiling all users of this library. Stack allocation is relatively cheap and unwind-state copying is relatively rare, so we - want to err on making it rather too big than too small. */ + want to err on making it rather too big than too small. -#define UNW_TDEP_CURSOR_LEN 512 + Calculation is regs used (64 + 34) * 2 + 40 (bytes of rest of + cursor) + padding +*/ + +#define UNW_TDEP_CURSOR_LEN 250 typedef uint64_t unw_word_t; typedef int64_t unw_sword_t; @@ -169,15 +173,46 @@ typedef struct unw_tdep_save_loc unw_tdep_save_loc_t; -/* On AArch64, we can directly use ucontext_t as the unwind context. */ -typedef ucontext_t unw_tdep_context_t; +/* On AArch64, we can directly use ucontext_t as the unwind context, + * however, the __reserved struct is quite large: tune it down to only + * the necessary used fields. */ + +struct unw_sigcontext + { + uint64_t fault_address; + uint64_t regs[31]; + uint64_t sp; + uint64_t pc; + uint64_t pstate; + uint8_t __reserved[(66 * 8)] __attribute__((__aligned__(16))); +}; + +typedef struct + { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + __sigset_t uc_sigmask; + struct unw_sigcontext uc_mcontext; + } unw_tdep_context_t; + +typedef struct + { + uint32_t _ctx_magic; + uint32_t _ctx_size; + uint32_t fpsr; + uint32_t fpcr; + uint64_t vregs[64]; + } unw_fpsimd_context_t; + + #include "libunwind-common.h" #include "libunwind-dynamic.h" #define unw_tdep_getcontext(uc) (({ \ unw_tdep_context_t *unw_ctx = (uc); \ - register uint64_t *unw_base asm ("x0") = (uint64_t*) unw_ctx->uc_mcontext.regs; \ + register uint64_t *unw_base __asm__ ("x0") = (uint64_t*) unw_ctx->uc_mcontext.regs; \ __asm__ __volatile__ ( \ "stp x0, x1, [%[base], #0]\n" \ "stp x2, x3, [%[base], #16]\n" \ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in b/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in index 8d96ddca2abc3..9dbb415f50441 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in @@ -30,6 +30,19 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define UNW_VERSION_CODE(maj,min) (((maj) << 16) | (min)) #define UNW_VERSION UNW_VERSION_CODE(UNW_VERSION_MAJOR, UNW_VERSION_MINOR) +#ifdef __sun +// On SmartOS, gcc fails with the following error: +// +// ../include/libunwind-common.h:43:41: error: expected identifier or '(' before numeric constant +// # define UNW_PREFIX UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_) +// ^ +// +// workaround is to undefine _U explicitly. +// see https://github.com/libunwind/libunwind/issues/118 for more details. +// +#undef _U +#endif + #define UNW_PASTE2(x,y) x##y #define UNW_PASTE(x,y) UNW_PASTE2(x,y) #define UNW_OBJ(fn) UNW_PASTE(UNW_PREFIX, fn) @@ -240,7 +253,6 @@ unw_save_loc_t; #define unw_set_fpreg UNW_OBJ(set_fpreg) #define unw_get_save_loc UNW_OBJ(get_save_loc) #define unw_is_signal_frame UNW_OBJ(is_signal_frame) -#define unw_handle_signal_frame UNW_OBJ(handle_signal_frame) #define unw_get_proc_name UNW_OBJ(get_proc_name) #define unw_set_caching_policy UNW_OBJ(set_caching_policy) #define unw_set_cache_size UNW_OBJ(set_cache_size) @@ -273,7 +285,6 @@ extern int unw_get_fpreg (unw_cursor_t *, int, unw_fpreg_t *); extern int unw_set_fpreg (unw_cursor_t *, int, unw_fpreg_t); extern int unw_get_save_loc (unw_cursor_t *, int, unw_save_loc_t *); extern int unw_is_signal_frame (unw_cursor_t *); -extern int unw_handle_signal_frame (unw_cursor_t *); extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *); extern const char *unw_strerror (int); extern int unw_backtrace (void **, int); diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h index 97c95e2463ac1..ced34b2027af6 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h @@ -98,7 +98,7 @@ typedef enum UNW_MIPS_R30, UNW_MIPS_R31, - UNW_MIPS_PC = 34, + UNW_MIPS_PC = 64, /* FIXME: Other registers! */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h new file mode 100644 index 0000000000000..ebda40d57af9b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h @@ -0,0 +1,144 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBUNWIND_H +#define LIBUNWIND_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include +#include +#include + +#define UNW_TARGET s390x +#define UNW_TARGET_S390X 1 + +#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ + +/* This needs to be big enough to accommodate "struct cursor", while + leaving some slack for future expansion. Changing this value will + require recompiling all users of this library. Stack allocation is + relatively cheap and unwind-state copying is relatively rare, so we + want to err on making it rather too big than too small. */ +#define UNW_TDEP_CURSOR_LEN 384 + +typedef uint64_t unw_word_t; +typedef int64_t unw_sword_t; + +typedef double unw_tdep_fpreg_t; + +typedef enum + { + /* general purpose registers */ + UNW_S390X_R0, + UNW_S390X_R1, + UNW_S390X_R2, + UNW_S390X_R3, + UNW_S390X_R4, + UNW_S390X_R5, + UNW_S390X_R6, + UNW_S390X_R7, + UNW_S390X_R8, + UNW_S390X_R9, + UNW_S390X_R10, + UNW_S390X_R11, + UNW_S390X_R12, + UNW_S390X_R13, + UNW_S390X_R14, + UNW_S390X_R15, + + /* floating point registers */ + UNW_S390X_F0, + UNW_S390X_F1, + UNW_S390X_F2, + UNW_S390X_F3, + UNW_S390X_F4, + UNW_S390X_F5, + UNW_S390X_F6, + UNW_S390X_F7, + UNW_S390X_F8, + UNW_S390X_F9, + UNW_S390X_F10, + UNW_S390X_F11, + UNW_S390X_F12, + UNW_S390X_F13, + UNW_S390X_F14, + UNW_S390X_F15, + + /* PSW */ + UNW_S390X_IP, + + UNW_TDEP_LAST_REG = UNW_S390X_IP, + + /* TODO: access, vector registers */ + + /* frame info (read-only) */ + UNW_S390X_CFA, + + UNW_TDEP_IP = UNW_S390X_IP, + UNW_TDEP_SP = UNW_S390X_R15, + + /* TODO: placeholders */ + UNW_TDEP_EH = UNW_S390X_R0, + } +s390x_regnum_t; + +#define UNW_TDEP_NUM_EH_REGS 2 /* XXX Not sure what this means */ + +typedef struct unw_tdep_save_loc + { + /* Additional target-dependent info on a save location. */ + char unused; + } +unw_tdep_save_loc_t; + +/* On s390x, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; + +typedef struct + { + /* no s390x-specific auxiliary proc-info */ + char unused; + } +unw_tdep_proc_info_t; + +#include "libunwind-dynamic.h" +#include "libunwind-common.h" + +#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext) +#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) + +extern int unw_tdep_getcontext (unw_tdep_context_t *); +extern int unw_tdep_is_fpreg (int); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* LIBUNWIND_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in b/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in index 7a56168c8b272..a13e7767325df 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in @@ -25,6 +25,8 @@ # include "libunwind-x86_64.h" #elif defined __tilegx__ # include "libunwind-tilegx.h" +#elif defined __s390x__ +# include "libunwind-s390x.h" #else # error "Unsupported arch" #endif diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h index 0fcf32695e2ba..e0f4540144230 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h @@ -140,6 +140,7 @@ cmpxchg_ptr (void *addr, void *old, void *new) } # define fetch_and_add1(_ptr) AO_fetch_and_add1(_ptr) # define fetch_and_add(_ptr, value) AO_fetch_and_add(_ptr, value) +# define atomic_read(ptr) (AO_load(ptr)) /* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */ # if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2) # define HAVE_CMPXCHG @@ -164,10 +165,14 @@ cmpxchg_ptr (void *addr, void *old, void *new) } # define fetch_and_add1(_ptr) __sync_fetch_and_add(_ptr, 1) # define fetch_and_add(_ptr, value) __sync_fetch_and_add(_ptr, value) +# define atomic_read(ptr) (__atomic_load_n(ptr,__ATOMIC_RELAXED)) # define HAVE_CMPXCHG # define HAVE_FETCH_AND_ADD #endif + +#ifndef atomic_read #define atomic_read(ptr) (*(ptr)) +#endif #define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn)) #define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn) @@ -363,4 +368,3 @@ static inline void invalidate_edi (struct elf_dyn_info *edi) #define UNW_ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL)) #endif /* libunwind_i_h */ - diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h index 8006d0b8dd4fe..74b821f5c0d70 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h @@ -35,9 +35,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ #define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) -/* Return the size of an address, for DWARF purposes. */ -#define dwarf_addr_size(addr_space) ((addr_space)->addr_size) - /* Convert a pointer to a dwarf_cursor structure to a pointer to unw_cursor_t. */ #define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h index 3fe40c0c05319..0c0fd3cf47eb3 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h @@ -247,6 +247,14 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) 0, c->as_arg); else if (c->as->abi == UNW_MIPS_ABI_O32) return read_s32 (c, DWARF_GET_LOC (loc), val); + else if (c->as->abi == UNW_MIPS_ABI_N32) { + if (tdep_big_endian(c->as)) + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc) + 4, val, + 0, c->as_arg); + else + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + } else return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, 0, c->as_arg); diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h new file mode 100644 index 0000000000000..ca419bd52acdd --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h @@ -0,0 +1,52 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* copy of include/tdep-x86/dwarf-config.h, modified slightly for x86-64 + some consolidation is possible here */ + +#ifndef dwarf_config_h +#define dwarf_config_h + +/* derived from DWARF register mappings in Z ELF ABI */ +#define DWARF_NUM_PRESERVED_REGS 66 +#define DWARF_REGNUM_MAP_LENGTH DWARF_NUM_PRESERVED_REGS + +/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ +#define dwarf_is_big_endian(addr_space) 1 + +/* Convert a pointer to a dwarf_cursor structure to a pointer to + unw_cursor_t. */ +#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) + +typedef struct dwarf_loc + { + unw_word_t val; + unw_word_t type; /* see S390X_LOC_TYPE_* macros. */ + } +dwarf_loc_t; + +#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h new file mode 100644 index 0000000000000..509237525553a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h @@ -0,0 +1,35 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#if defined __linux__ + +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ + +#define JB_SP 9 // __gregs[9] +#define JB_RP 8 // __gregs[8] +#define JB_MASK_SAVED 18 // __mask_was_saved +#define JB_MASK 19 // __saved_mask + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h new file mode 100644 index 0000000000000..137a0b8a4f928 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h @@ -0,0 +1,262 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef S390X_LIBUNWIND_I_H +#define S390X_LIBUNWIND_I_H + +/* Target-dependent definitions that are internal to libunwind but need + to be shared with target-independent code. */ + +#include +#include + +#include "elf64.h" +#include "mempool.h" +#include "dwarf.h" + +struct unw_addr_space + { + struct unw_accessors acc; + unw_caching_policy_t caching_policy; +#ifdef HAVE_ATOMIC_OPS_H + AO_t cache_generation; +#else + uint32_t cache_generation; +#endif + unw_word_t dyn_generation; /* see dyn-common.h */ + unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ + struct dwarf_rs_cache global_cache; + struct unw_debug_frame_list *debug_frames; + }; + +struct cursor + { + struct dwarf_cursor dwarf; /* must be first */ + + /* Format of sigcontext structure and address at which it is + stored: */ + enum + { + S390X_SCF_NONE = 0, /* no signal frame encountered */ + S390X_SCF_LINUX_SIGFRAME = 1, /* Linux struct sigcontext */ + S390X_SCF_LINUX_RT_SIGFRAME = 2, /* Linux ucontext_t */ + } + sigcontext_format; + unw_word_t sigcontext_addr; + unw_word_t sigcontext_sp; + unw_word_t sigcontext_pc; + int validate; + ucontext_t *uc; + }; + +static inline ucontext_t * +dwarf_get_uc(const struct dwarf_cursor *cursor) +{ + const struct cursor *c = (struct cursor *) cursor->as_arg; + return c->uc; +} + +#define DWARF_GET_LOC(l) ((l).val) +# define DWARF_LOC_TYPE_MEM (0 << 0) +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_LOC_TYPE_VAL (1 << 2) + +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_IS_MEM_LOC(l) ((l).type == DWARF_LOC_TYPE_MEM) +# define DWARF_IS_VAL_LOC(l) (((l).type & DWARF_LOC_TYPE_VAL) != 0) + +# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +# define DWARF_VAL_LOC(c,v) DWARF_LOC ((v), DWARF_LOC_TYPE_VAL) +# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), DWARF_LOC_TYPE_MEM) + +#ifdef UNW_LOCAL_ONLY +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) +# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) + +#else /* !UNW_LOCAL_ONLY */ + +# define DWARF_NULL_LOC DWARF_LOC (0, 0) +# define DWARF_IS_NULL_LOC(l) \ + ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ + | DWARF_LOC_TYPE_FP)) + +#endif /* !UNW_LOCAL_ONLY */ + +static inline int +dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) +{ + assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_FP_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + /* FPRs may be saved in GPRs */ + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), (unw_word_t*)val, + 0, c->as_arg); + if (DWARF_IS_MEM_LOC (loc)) + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), (unw_word_t*)val, + 0, c->as_arg); + assert(DWARF_IS_VAL_LOC (loc)); + *val = *(unw_fpreg_t*) DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +{ + assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); + assert(!DWARF_IS_VAL_LOC (loc)); + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_FP_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + /* FPRs may be saved in GPRs */ + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), (unw_word_t*) &val, + 1, c->as_arg); + + assert(DWARF_IS_MEM_LOC (loc)); + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), (unw_word_t*) &val, + 1, c->as_arg); +} + +static inline int +dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +{ + assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + if (DWARF_IS_MEM_LOC (loc)) + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); + /* GPRs may be saved in FPRs */ + if (DWARF_IS_FP_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), (unw_fpreg_t*)val, + 0, c->as_arg); + assert(DWARF_IS_VAL_LOC (loc)); + *val = DWARF_GET_LOC (loc); + return 0; +} + +static inline int +dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +{ + assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); + assert(!DWARF_IS_VAL_LOC (loc)); + + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); + /* GPRs may be saved in FPRs */ + if (DWARF_IS_FP_LOC (loc)) + return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), (unw_fpreg_t*) &val, + 1, c->as_arg); + + assert(DWARF_IS_MEM_LOC (loc)); + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, + 1, c->as_arg); +} + +#define tdep_getcontext_trace unw_getcontext +#define tdep_init_done UNW_OBJ(init_done) +#define tdep_init_mem_validate UNW_OBJ(init_mem_validate) +#define tdep_init UNW_OBJ(init) +/* Platforms that support UNW_INFO_FORMAT_TABLE need to define + tdep_search_unwind_table. */ +#define tdep_search_unwind_table dwarf_search_unwind_table +#define tdep_find_unwind_table dwarf_find_unwind_table +#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) +#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) +#define tdep_access_reg UNW_OBJ(access_reg) +#define tdep_access_fpreg UNW_OBJ(access_fpreg) +#define tdep_fetch_frame(c,ip,n) do {} while(0) +#define tdep_cache_frame(c) 0 +#define tdep_reuse_frame(c,rs) do {} while(0) +#define tdep_stash_frame(cs,rs) do {} while(0) +#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) +#define tdep_uc_addr UNW_OBJ(uc_addr) + +#ifdef UNW_LOCAL_ONLY +# define tdep_find_proc_info(c,ip,n) \ + dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + dwarf_put_unwind_info((as), (pi), (arg)) +#else +# define tdep_find_proc_info(c,ip,n) \ + (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ + (c)->as_arg) +# define tdep_put_unwind_info(as,pi,arg) \ + (*(as)->acc.put_unwind_info)((as), (pi), (arg)) +#endif + +#define tdep_get_as(c) ((c)->dwarf.as) +#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) +#define tdep_get_ip(c) ((c)->dwarf.ip) +#define tdep_big_endian(as) 1 + +extern int tdep_init_done; + +extern void tdep_init (void); +extern void tdep_init_mem_validate (void); +extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, + unw_dyn_info_t *di, unw_proc_info_t *pi, + int need_unwind_info, void *arg); +extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); +extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen); +extern void tdep_get_exe_image_path (char *path); +extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, + unw_word_t *valp, int write); +extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, + unw_fpreg_t *valp, int write); + +#endif /* S390X_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h index d57196676db20..b2e5332b05966 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h @@ -23,9 +23,10 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if defined __linux__ +#if defined __linux__ || defined __sun -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ +/* Use glibc's jump-buffer indices; NPTL peeks at SP: + https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=sysdeps/x86_64/jmpbuf-offsets.h;h=ea94a1f90554deecceaf995ca5ee485ae8bffab7;hb=HEAD */ #define JB_SP 6 #define JB_RP 7 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h index 283525c16a38d..6b798c7115f3c 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h @@ -89,6 +89,7 @@ struct cursor X86_64_SCF_LINUX_RT_SIGFRAME, /* Linux ucontext_t */ X86_64_SCF_FREEBSD_SIGFRAME, /* FreeBSD signal frame */ X86_64_SCF_FREEBSD_SYSCALL, /* FreeBSD syscall */ + X86_64_SCF_SOLARIS_SIGFRAME, /* illumos/Solaris signal frame */ } sigcontext_format; unw_word_t sigcontext_addr; @@ -232,7 +233,11 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) #define tdep_get_ip(c) ((c)->dwarf.ip) #define tdep_big_endian(as) 0 +#ifdef HAVE_ATOMIC_OPS_H +extern AO_t tdep_init_done; +#else extern int tdep_init_done; +#endif extern void tdep_init (void); extern void tdep_init_mem_validate (void); diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in b/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in index af05a7fba24f9..c47299640e8e6 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in +++ b/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in @@ -25,6 +25,8 @@ # include "tdep-x86_64/libunwind_i.h" #elif defined __tilegx__ # include "tdep-tilegx/libunwind_i.h" +#elif defined __s390x__ +# include "tdep-s390x/libunwind_i.h" #else # error "Unsupported arch" #endif diff --git a/src/coreclr/src/pal/src/libunwind/libunwind-version.txt b/src/coreclr/src/pal/src/libunwind/libunwind-version.txt new file mode 100644 index 0000000000000..e96a102894ad4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/libunwind-version.txt @@ -0,0 +1,2 @@ +v1.5-rc2 +https://github.com/libunwind/libunwind/releases/tag/v1.5-rc2 diff --git a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt index 891eadd158fa5..386d8ba326030 100644 --- a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt @@ -14,8 +14,6 @@ add_definitions(-DPACKAGE_STRING="") add_definitions(-DPACKAGE_BUGREPORT="") add_definitions(-D_GNU_SOURCE) -# Ensure that the remote and local unwind code can reside in the same binary without name clashing -add_definitions("-Ddwarf_search_unwind_table_int=UNW_OBJ(dwarf_search_unwind_table_int)") # Disable warning due to incorrect format specifier in debugging printf via the Debug macro add_compile_options(-Wno-format -Wno-format-security) @@ -25,6 +23,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") else() add_compile_options(-Wno-unused-value) add_compile_options(-Wno-unused-result) + add_compile_options(-Wno-implicit-function-declaration) + add_compile_options(-Wno-incompatible-pointer-types) endif() if(CLR_CMAKE_HOST_ARCH_ARM) @@ -51,6 +51,10 @@ elseif(CLR_CMAKE_HOST_ARCH_ARM64) # Disable warning due to labs function called on unsigned argument add_compile_options(-Wno-absolute-value) endif() + # Issue https://github.com/libunwind/libunwind/issues/176 + if (CLR_CMAKE_HOST_ALPINE_LINUX) + add_definitions("-D__sigset_t=sigset_t") + endif() # We compile code with -std=c99 and the asm keyword is not recognized as it is a gnu extension add_definitions(-Dasm=__asm__) elseif(CLR_CMAKE_HOST_ARCH_I386) @@ -115,6 +119,14 @@ SET(libunwind_la_SOURCES_os_freebsd_local # Nothing ) +SET(libunwind_la_SOURCES_os_solaris + os-solaris.c +) + +SET(libunwind_la_SOURCES_os_solaris_local +# Nothing +) + if(CLR_CMAKE_HOST_LINUX) SET(libunwind_la_SOURCES_os ${libunwind_la_SOURCES_os_linux}) SET(libunwind_la_SOURCES_os_local ${libunwind_la_SOURCES_os_linux_local}) @@ -137,6 +149,11 @@ elseif(CLR_CMAKE_HOST_FREEBSD) SET(libunwind_la_SOURCES_arm_os arm/Gos-freebsd.c) SET(libunwind_la_SOURCES_arm_os_local arm/Los-freebsd.c) list(APPEND libunwind_coredump_la_SOURCES coredump/_UCD_access_reg_freebsd.c) +elseif(CLR_CMAKE_HOST_SUNOS) + SET(libunwind_la_SOURCES_os ${libunwind_la_SOURCES_os_solaris}) + SET(libunwind_la_SOURCES_os_local ${libunwind_la_SOURCES_os_solaris_local}) + SET(libunwind_la_SOURCES_x86_64_os x86_64/Gos-solaris.c) + SET(libunwind_la_SOURCES_x86_64_os_local x86_64/Los-solaris.c) endif() # List of arch-independent files needed by both local-only and generic diff --git a/src/coreclr/src/pal/src/libunwind/src/Makefile.am b/src/coreclr/src/pal/src/libunwind/src/Makefile.am index a557d8d1f4fb3..ff977446a7c2b 100644 --- a/src/coreclr/src/pal/src/libunwind/src/Makefile.am +++ b/src/coreclr/src/pal/src/libunwind/src/Makefile.am @@ -68,7 +68,7 @@ libunwind_coredump_la_SOURCES = \ coredump/_UPT_resume.c libunwind_coredump_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ -version-info $(COREDUMP_SO_VERSION) -libunwind_coredump_la_LIBADD = $(LIBLZMA) +libunwind_coredump_la_LIBADD = $(LIBLZMA) $(LIBZ) noinst_HEADERS += coredump/_UCD_internal.h coredump/_UCD_lib.h ### libunwind-setjmp: @@ -154,6 +154,8 @@ libunwind_la_SOURCES_os_freebsd = os-freebsd.c libunwind_la_SOURCES_os_qnx = os-qnx.c +libunwind_la_SOURCES_os_solaris = os-solaris.c + libunwind_dwarf_common_la_SOURCES = dwarf/global.c libunwind_dwarf_local_la_SOURCES = \ @@ -181,9 +183,9 @@ noinst_HEADERS += elf32.h elf64.h elfxx.h libunwind_elf32_la_SOURCES = elf32.c libunwind_elf64_la_SOURCES = elf64.c libunwind_elfxx_la_SOURCES = elfxx.c -libunwind_elf32_la_LIBADD = $(LIBLZMA) -libunwind_elf64_la_LIBADD = $(LIBLZMA) -libunwind_elfxx_la_LIBADD = $(LIBLZMA) +libunwind_elf32_la_LIBADD = $(LIBLZMA) $(LIBZ) +libunwind_elf64_la_LIBADD = $(LIBLZMA) $(LIBZ) +libunwind_elfxx_la_LIBADD = $(LIBLZMA) $(LIBZ) noinst_LTLIBRARIES += $(LIBUNWIND_ELF) libunwind_la_LIBADD += $(LIBUNWIND_ELF) @@ -463,6 +465,30 @@ libunwind_sh_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \ sh/Gglobal.c sh/Ginit.c sh/Ginit_local.c sh/Ginit_remote.c \ sh/Gis_signal_frame.c sh/Gregs.c sh/Gresume.c sh/Gstep.c +# The list of files that go both into libunwind and libunwind-s390x: +noinst_HEADERS += s390x/init.h s390x/unwind_i.h +libunwind_la_SOURCES_s390x_common = $(libunwind_la_SOURCES_common) \ + s390x/is_fpreg.c s390x/regname.c + +# The list of files that go into libunwind: +libunwind_la_SOURCES_s390x = $(libunwind_la_SOURCES_s390x_common) \ + $(libunwind_la_SOURCES_local) \ + s390x/Lapply_reg_state.c s390x/Lreg_states_iterate.c \ + s390x/Lcreate_addr_space.c s390x/Lget_save_loc.c s390x/Lglobal.c \ + s390x/Linit.c s390x/Linit_local.c s390x/Linit_remote.c \ + s390x/Lget_proc_info.c s390x/Lregs.c s390x/Lresume.c \ + s390x/Lis_signal_frame.c s390x/Lstep.c \ + s390x/getcontext.S s390x/setcontext.S + +# The list of files that go into libunwind-s390x: +libunwind_s390x_la_SOURCES_s390x = $(libunwind_la_SOURCES_s390x_common) \ + $(libunwind_la_SOURCES_generic) \ + s390x/Gapply_reg_state.c s390x/Greg_states_iterate.c \ + s390x/Gcreate_addr_space.c s390x/Gget_save_loc.c s390x/Gglobal.c \ + s390x/Ginit.c s390x/Ginit_local.c s390x/Ginit_remote.c \ + s390x/Gget_proc_info.c s390x/Gregs.c s390x/Gresume.c \ + s390x/Gis_signal_frame.c s390x/Gstep.c + if REMOTE_ONLY install-exec-hook: # Nothing to do here.... @@ -514,6 +540,12 @@ if OS_FREEBSD libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_freebsd.c endif +if OS_SOLARIS + libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_solaris) + libunwind_la_SOURCES_x86_64_os = x86_64/Gos-solaris.c + libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-solaris.c +endif + if OS_QNX libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_qnx) libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_qnx_local) @@ -662,7 +694,19 @@ if !REMOTE_ONLY libunwind_sh_la_LIBADD += libunwind.la -lc endif libunwind_setjmp_la_SOURCES += sh/siglongjmp.S +else +if ARCH_S390X + lib_LTLIBRARIES += libunwind-s390x.la + libunwind_la_SOURCES = $(libunwind_la_SOURCES_s390x) + libunwind_s390x_la_SOURCES = $(libunwind_s390x_la_SOURCES_s390x) + libunwind_s390x_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) + libunwind_s390x_la_LIBADD = libunwind-dwarf-generic.la + libunwind_s390x_la_LIBADD += libunwind-elf64.la +if !REMOTE_ONLY + libunwind_s390x_la_LIBADD += libunwind.la -lc +endif +endif # ARCH_S390X endif # ARCH_SH endif # ARCH_PPC64 endif # ARCH_PPC32 @@ -688,7 +732,7 @@ endif libunwind_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -XCClinker -nostdlib \ $(LDFLAGS_STATIC_LIBCXA) -version-info $(SOVERSION) libunwind_la_LIBADD += -lc $(LIBCRTS) -libunwind_la_LIBADD += $(LIBLZMA) +libunwind_la_LIBADD += $(LIBLZMA) $(LIBZ) AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/tdep-$(arch) -I. AM_CCASFLAGS = $(AM_CPPFLAGS) @@ -705,6 +749,7 @@ EXTRA_DIST = $(libunwind_la_SOURCES_aarch64) \ $(libunwind_la_SOURCES_os_linux) \ $(libunwind_la_SOURCES_os_hpux) \ $(libunwind_la_SOURCES_os_qnx) \ + $(libunwind_la_SOURCES_os_solaris) \ $(libunwind_la_SOURCES_common) \ $(libunwind_la_SOURCES_local) \ $(libunwind_la_SOURCES_generic) \ diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c index 9c4eae8298ee3..35389762f27ed 100644 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c @@ -41,7 +41,7 @@ static struct unw_addr_space local_addr_space; unw_addr_space_t unw_local_addr_space = &local_addr_space; static inline void * -uc_addr (ucontext_t *uc, int reg) +uc_addr (unw_tdep_context_t *uc, int reg) { if (reg >= UNW_AARCH64_X0 && reg < UNW_AARCH64_V0) return &uc->uc_mcontext.regs[reg]; @@ -54,20 +54,13 @@ uc_addr (ucontext_t *uc, int reg) # ifdef UNW_LOCAL_ONLY HIDDEN void * -tdep_uc_addr (ucontext_t *uc, int reg) +tdep_uc_addr (unw_tdep_context_t *uc, int reg) { return uc_addr (uc, reg); } # endif /* UNW_LOCAL_ONLY */ -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -78,7 +71,13 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); return 0; } @@ -104,7 +103,7 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, void *arg) { unw_word_t *addr; - ucontext_t *uc = arg; + unw_tdep_context_t *uc = arg; if (unw_is_fpreg (reg)) goto badreg; @@ -133,7 +132,7 @@ static int access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, int write, void *arg) { - ucontext_t *uc = arg; + unw_tdep_context_t *uc = arg; unw_fpreg_t *addr; if (!unw_is_fpreg (reg)) diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c index cd60ca840f508..69d4ed3861db9 100644 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c @@ -59,7 +59,7 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) } int -unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) +unw_init_local2 (unw_cursor_t *cursor, unw_tdep_context_t *uc, int flag) { if (!flag) { diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c index 3d82739293e11..2cc161360ef53 100644 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c @@ -71,7 +71,7 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) char x[sizeof(regs)]; }; - asm volatile ( + __asm__ __volatile__ ( "mov x4, %0\n" "mov x5, %1\n" "ldp x0, x1, [x4]\n" @@ -134,7 +134,7 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) sc->pc = uc->uc_mcontext.pc; sc->pstate = uc->uc_mcontext.pstate; - asm volatile ( + __asm__ __volatile__ ( "mov sp, %0\n" "ret %1\n" : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h index 3d324c2b08bd5..db7e29dd722e9 100644 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h @@ -59,6 +59,6 @@ extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, } while (0) #endif -#define GET_FPCTX(uc) ((struct fpsimd_context *)(&uc->uc_mcontext.__reserved)) +#define GET_FPCTX(uc) ((unw_fpsimd_context_t *)(&uc->uc_mcontext.__reserved)) #endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c index e79903cd87d3f..d6573a65e0c7d 100644 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c @@ -152,12 +152,13 @@ HIDDEN int arm_exidx_decode (const uint8_t *buf, uint8_t len, struct dwarf_cursor *c) { #define READ_OP() *buf++ - assert(buf != NULL); - assert(len > 0); const uint8_t *end = buf + len; int ret; struct arm_exbuf_data edata; + assert(buf != NULL); + assert(len > 0); + while (buf < end) { uint8_t op = READ_OP (); diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c index 2720d063a2424..0bac0d72da6fe 100644 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c @@ -57,18 +57,17 @@ tdep_uc_addr (unw_tdep_context_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c index a8288628a6cd6..3b9dfb33e60a7 100644 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c @@ -56,7 +56,7 @@ arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) char x[sizeof(regs)]; }; - asm __volatile__ ( + __asm__ __volatile__ ( "ldmia %0, {r4-r12, lr}\n" "mov sp, r12\n" "bx lr\n" @@ -90,7 +90,7 @@ arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) /* Set the SP and the PC in order to continue execution at the modified trampoline which restores the signal mask and the registers. */ - asm __volatile__ ( + __asm__ __volatile__ ( "mov sp, %0\n" "bx %1\n" : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c index 516c9f4d1837d..895e8a892afce 100644 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c @@ -46,7 +46,8 @@ arm_exidx_step (struct cursor *c) c->dwarf.loc[UNW_ARM_R15] = DWARF_NULL_LOC; unw_word_t ip = c->dwarf.ip; if (c->dwarf.use_prev_instr) - --ip; + /* The least bit denotes thumb/arm mode, clear it. */ + ip = (ip & ~(unw_word_t)0x1) - 1; /* check dynamic info first --- it overrides everything else */ ret = unwi_find_dynamic_proc_info (c->dwarf.as, ip, &c->dwarf.pi, 1, @@ -106,17 +107,20 @@ unw_step (unw_cursor_t *cursor) else if (unlikely (ret == -UNW_ESTOPUNWIND)) return ret; - if (ret < 0 && ret != -UNW_ENOINFO) - { - Debug (2, "returning %d\n", ret); - return ret; - } + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } } #endif /* CONFIG_DEBUG_FRAME */ /* Next, try extbl-based unwinding. */ if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)) { + Debug (13, "%s(ret=%d), trying extbl\n", + UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) ? "dwarf_step() failed " : "", + ret); ret = arm_exidx_step (c); if (ret > 0) return 1; @@ -134,7 +138,12 @@ unw_step (unw_cursor_t *cursor) { if (UNW_TRY_METHOD(UNW_ARM_METHOD_FRAME)) { - Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); + Debug (13, "%s%s%s%s(ret=%d), trying frame-chain\n", + UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) ? "dwarf_step() " : "", + (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) && UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX)) ? "and " : "", + UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX) ? "arm_exidx_step() " : "", + (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) || UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX)) ? "failed " : "", + ret); ret = UNW_ESUCCESS; /* DWARF unwinding failed, try to follow APCS/optimized APCS frame chain */ unw_word_t instr, i; diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c index 0e3a83bdc6ca3..930a1148e4f44 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c @@ -129,6 +129,26 @@ _UCD_access_reg (unw_addr_space_t as, return -UNW_EINVAL; } } +#elif defined(UNW_TARGET_AARCH64) + if (regnum >= UNW_AARCH64_X0 && regnum < UNW_AARCH64_X30) { + *valp = ui->prstatus->pr_reg.x[regnum]; + } else { + switch (regnum) { + case UNW_AARCH64_SP: + *valp = ui->prstatus->pr_reg.sp; + break; + case UNW_AARCH64_X30: + *valp = ui->prstatus->pr_reg.lr; + break; + case UNW_AARCH64_PC: + *valp = ui->prstatus->pr_reg.elr; + break; + default: + Debug(0, "bad regnum:%d\n", regnum); + return -UNW_EINVAL; + } + } + #else #error Port me #endif diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c index 208d8d27b6581..43792f849b3d7 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c @@ -54,6 +54,9 @@ _UCD_access_reg (unw_addr_space_t as, #elif defined(UNW_TARGET_TILEGX) if (regnum > UNW_TILEGX_CFA) goto badreg; +#elif defined(UNW_TARGET_S390X) + if (regnum > UNW_S390X_R15) + goto badreg; #else #if defined(UNW_TARGET_MIPS) static const uint8_t remap_regs[] = diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c index 62f6ee05c793b..4c430efb27b53 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c @@ -259,9 +259,13 @@ _UCD_create(const char *filename) cur->p_flags ); if (cur->p_filesz < cur->p_memsz) - Debug(2, " partial"); + { + Debug(2, " partial"); + } if (cur->p_flags & PF_X) - Debug(2, " executable"); + { + Debug(2, " executable"); + } } Debug(2, "\n"); i++; @@ -338,7 +342,10 @@ int _UCD_add_backing_file_at_segment(struct UCD_info *ui, int phdr_no, const cha phdr->backing_filesize = (uoff_t)statbuf.st_size; if (phdr->p_flags != (PF_X | PF_R)) - Debug(1, "Note: phdr[%u] is not r-x: flags are 0x%x\n", phdr_no, phdr->p_flags); + { + Debug(1, "Note: phdr[%u] is not r-x: flags are 0x%x\n", + phdr_no, phdr->p_flags); + } if (phdr->backing_filesize > phdr->p_memsz) { diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c index 00096c48d0770..3a4c9b8213c6d 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c @@ -36,6 +36,10 @@ elf_w (CD_get_proc_name) (struct UCD_info *ui, unw_addr_space_t as, unw_word_t i unsigned long segbase, mapoff; int ret; + /* We're about to map an elf image. If there is an elf image currently mapped, + then make sure to unmap it. */ + invalidate_edi(&ui->edi); + /* Used to be tdep_get_elf_image() in ptrace unwinding code */ coredump_phdr_t *cphdr = _UCD_get_elf_image(ui, ip); if (!cphdr) diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c index 0d11905566c30..739ed0569b9e6 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c @@ -74,6 +74,11 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, #else +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static inline int get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, int *countp) diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c index f63c3d220c6bd..2af454332dd82 100644 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c @@ -60,6 +60,8 @@ static const uint8_t operands[256] = [DW_OP_const4s] = OPND1 (VAL32), [DW_OP_const8u] = OPND1 (VAL64), [DW_OP_const8s] = OPND1 (VAL64), + [DW_OP_constu] = OPND1 (ULEB128), + [DW_OP_consts] = OPND1 (SLEB128), [DW_OP_pick] = OPND1 (VAL8), [DW_OP_plus_uconst] = OPND1 (ULEB128), [DW_OP_skip] = OPND1 (VAL16), @@ -235,8 +237,8 @@ dwarf_stack_aligned(struct dwarf_cursor *c, unw_word_t cfa_addr, } HIDDEN int -dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, unw_word_t len, - unw_word_t *valp, int *is_register) +dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_word_t *addr, + unw_word_t len, unw_word_t *valp, int *is_register) { unw_word_t operand1 = 0, operand2 = 0, tmp1, tmp2 = 0, tmp3, end_addr; uint8_t opcode, operands_signature, u8; @@ -285,10 +287,14 @@ do { \ end_addr = *addr + len; *is_register = 0; - Debug (14, "len=%lu, pushing cfa=0x%lx\n", - (unsigned long) len, (unsigned long) c->cfa); + Debug (14, "len=%lu, pushing initial value=0x%lx\n", + (unsigned long) len, (unsigned long) stack_val); - push (c->cfa); /* push current CFA as required by DWARF spec */ + /* The DWARF standard requires the current CFA to be pushed onto the stack */ + /* before evaluating DW_CFA_expression and DW_CFA_val_expression programs. */ + /* DW_CFA_def_cfa_expressions do not take an initial value, but we push on */ + /* a dummy value to keep this logic consistent. */ + push (stack_val); while (*addr < end_addr) { diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c index 509ceff47cbe3..0cfb4d4faea05 100644 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c @@ -34,6 +34,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "dwarf-eh.h" #include "libunwind_i.h" +#ifdef HAVE_ZLIB +#include +#endif /* HAVE_ZLIB */ + struct table_entry { int32_t start_ip_offset; @@ -46,12 +50,17 @@ struct table_entry #include "os-linux.h" #endif +#ifndef __clang__ static ALIAS(dwarf_search_unwind_table) int dwarf_search_unwind_table_int (unw_addr_space_t as, unw_word_t ip, unw_dyn_info_t *di, unw_proc_info_t *pi, int need_unwind_info, void *arg); +#else +#define dwarf_search_unwind_table_int dwarf_search_unwind_table +#endif + static int linear_search (unw_addr_space_t as, unw_word_t ip, unw_word_t eh_frame_start, unw_word_t eh_frame_end, @@ -118,14 +127,48 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local) return 1; } - *bufsize = shdr->sh_size; - *buf = malloc (*bufsize); - - memcpy(*buf, shdr->sh_offset + ei.image, *bufsize); + if (shdr->sh_flags & SHF_COMPRESSED) + { + unsigned long destSize; + Elf_W (Chdr) *chdr = (shdr->sh_offset + ei.image); +#ifdef HAVE_ZLIB + if (chdr->ch_type == ELFCOMPRESS_ZLIB) + { + *bufsize = destSize = chdr->ch_size; + GET_MEMORY(*buf, *bufsize); + ret = uncompress((unsigned char *)*buf, &destSize, + shdr->sh_offset + ei.image + sizeof(*chdr), + shdr->sh_size - sizeof(*chdr)); + if (ret != Z_OK) + { + Debug (2, "failed to decompress zlib .debug_frame, skipping\n"); + munmap(*buf, *bufsize); + munmap(ei.image, ei.size); + return 1; + } + + Debug (4, "read %zd->%zd bytes of .debug_frame from offset %zd\n", + shdr->sh_size, *bufsize, shdr->sh_offset); + } + else +#endif /* HAVE_ZLIB */ + { + Debug (2, "unknown compression type %d, skipping\n", + chdr->ch_type); + munmap(ei.image, ei.size); + return 1; + } + } + else + { + *bufsize = shdr->sh_size; + GET_MEMORY(*buf, *bufsize); - Debug (4, "read %zd bytes of .debug_frame from offset %zd\n", - *bufsize, shdr->sh_offset); + memcpy(*buf, shdr->sh_offset + ei.image, *bufsize); + Debug (4, "read %zd bytes of .debug_frame from offset %zd\n", + *bufsize, shdr->sh_offset); + } munmap(ei.image, ei.size); return 0; } @@ -208,7 +251,7 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, if (!err) { - fdesc = malloc (sizeof (struct unw_debug_frame_list)); + GET_MEMORY(fdesc, sizeof (struct unw_debug_frame_list)); fdesc->start = start; fdesc->end = end; @@ -223,66 +266,131 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, return fdesc; } -struct debug_frame_tab - { - struct table_entry *tab; - uint32_t length; - uint32_t size; - }; - -static void -debug_frame_tab_append (struct debug_frame_tab *tab, - unw_word_t fde_offset, unw_word_t start_ip) +static size_t +debug_frame_index_make (struct unw_debug_frame_list *fdesc) { - unsigned int length = tab->length; + unw_accessors_t *a = unw_get_accessors_int (unw_local_addr_space); + char *buf = fdesc->debug_frame; + size_t bufsize = fdesc->debug_frame_size; + unw_word_t addr = (unw_word_t) (uintptr_t) buf; + size_t count = 0; - if (length == tab->size) + while (addr < (unw_word_t) (uintptr_t) (buf + bufsize)) { - tab->size *= 2; - tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->size); - } + unw_word_t item_start = addr, item_end = 0; + uint32_t u32val = 0; + uint64_t cie_id = 0; + uint64_t id_for_cie; + + dwarf_readu32 (unw_local_addr_space, a, &addr, &u32val, NULL); + + if (u32val == 0) + break; + + if (u32val != 0xffffffff) + { + uint32_t cie_id32 = 0; + + item_end = addr + u32val; + dwarf_readu32 (unw_local_addr_space, a, &addr, &cie_id32, NULL); + cie_id = cie_id32; + id_for_cie = 0xffffffff; + } + else + { + uint64_t u64val = 0; + + /* Extended length. */ + dwarf_readu64 (unw_local_addr_space, a, &addr, &u64val, NULL); + item_end = addr + u64val; + + dwarf_readu64 (unw_local_addr_space, a, &addr, &cie_id, NULL); + id_for_cie = 0xffffffffffffffffull; + } + + /*Debug (1, "CIE/FDE id = %.8x\n", (int) cie_id);*/ + + if (cie_id == id_for_cie) + { + ; + /*Debug (1, "Found CIE at %.8x.\n", item_start);*/ + } + else + { + unw_word_t fde_addr = item_start; + unw_proc_info_t this_pi; + int err; + + /*Debug (1, "Found FDE at %.8x\n", item_start);*/ + + err = dwarf_extract_proc_info_from_fde (unw_local_addr_space, + a, &fde_addr, + &this_pi, + (uintptr_t) buf, 0, 1, + NULL); + + if (!err) + { + Debug (15, "start_ip = %lx, end_ip = %lx\n", + (long) this_pi.start_ip, (long) this_pi.end_ip); + + if (fdesc->index) + { + struct table_entry *e = &fdesc->index[count]; + + e->fde_offset = item_start - (unw_word_t) (uintptr_t) buf; + e->start_ip_offset = this_pi.start_ip; + } - tab->tab[length].fde_offset = fde_offset; - tab->tab[length].start_ip_offset = start_ip; + count++; + } + /*else + Debug (1, "FDE parse failed\n");*/ + } - tab->length = length + 1; + addr = item_end; + } + return count; } static void -debug_frame_tab_shrink (struct debug_frame_tab *tab) +debug_frame_index_sort (struct unw_debug_frame_list *fdesc) { - if (tab->size > tab->length) + size_t i, j, k, n = fdesc->index_size / sizeof (*fdesc->index); + struct table_entry *a = fdesc->index; + struct table_entry t; + + /* Use a simple Shell sort as it relatively fast and + * does not require additional memory. */ + + for (k = n / 2; k > 0; k /= 2) { - tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->length); - tab->size = tab->length; - } -} + for (i = k; i < n; i++) + { + t = a[i]; -static int -debug_frame_tab_compare (const void *a, const void *b) -{ - const struct table_entry *fa = a, *fb = b; + for (j = i; j >= k; j -= k) + { + if (t.start_ip_offset >= a[j - k].start_ip_offset) + break; - if (fa->start_ip_offset > fb->start_ip_offset) - return 1; - else if (fa->start_ip_offset < fb->start_ip_offset) - return -1; - else - return 0; + a[j] = a[j - k]; + } + + a[j] = t; + } + } } -HIDDEN int +int dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip, unw_word_t segbase, const char* obj_name, unw_word_t start, unw_word_t end) { - unw_dyn_info_t *di; - struct unw_debug_frame_list *fdesc = 0; - unw_accessors_t *a; - unw_word_t addr; + unw_dyn_info_t *di = di_debug; + struct unw_debug_frame_list *fdesc; Debug (15, "Trying to find .debug_frame for %s\n", obj_name); - di = di_debug; fdesc = locate_debug_info (unw_local_addr_space, ip, obj_name, start, end); @@ -291,130 +399,69 @@ dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip, Debug (15, "couldn't load .debug_frame\n"); return found; } - else + + Debug (15, "loaded .debug_frame\n"); + + if (fdesc->debug_frame_size == 0) { - char *buf; - size_t bufsize; - unw_word_t item_start, item_end = 0; - uint32_t u32val = 0; - uint64_t cie_id = 0; - struct debug_frame_tab tab; + Debug (15, "zero-length .debug_frame\n"); + return found; + } + + /* Now create a binary-search table, if it does not already exist. */ + + if (!fdesc->index) + { + /* Find all FDE entries in debug_frame, and make into a sorted + index. First determine an index element count. */ - Debug (15, "loaded .debug_frame\n"); + size_t count = debug_frame_index_make (fdesc); - buf = fdesc->debug_frame; - bufsize = fdesc->debug_frame_size; + if (!count) + { + Debug (15, "no CIE/FDE found in .debug_frame\n"); + return found; + } - if (bufsize == 0) - { - Debug (15, "zero-length .debug_frame\n"); - return found; - } + fdesc->index_size = count * sizeof (*fdesc->index); + GET_MEMORY (fdesc->index, fdesc->index_size); - /* Now create a binary-search table, if it does not already exist. */ if (!fdesc->index) - { - addr = (unw_word_t) (uintptr_t) buf; - - a = unw_get_accessors_int (unw_local_addr_space); - - /* Find all FDE entries in debug_frame, and make into a sorted - index. */ - - tab.length = 0; - tab.size = 16; - tab.tab = calloc (tab.size, sizeof (struct table_entry)); - - while (addr < (unw_word_t) (uintptr_t) (buf + bufsize)) - { - uint64_t id_for_cie; - item_start = addr; - - dwarf_readu32 (unw_local_addr_space, a, &addr, &u32val, NULL); - - if (u32val == 0) - break; - else if (u32val != 0xffffffff) - { - uint32_t cie_id32 = 0; - item_end = addr + u32val; - dwarf_readu32 (unw_local_addr_space, a, &addr, &cie_id32, - NULL); - cie_id = cie_id32; - id_for_cie = 0xffffffff; - } - else - { - uint64_t u64val = 0; - /* Extended length. */ - dwarf_readu64 (unw_local_addr_space, a, &addr, &u64val, NULL); - item_end = addr + u64val; - - dwarf_readu64 (unw_local_addr_space, a, &addr, &cie_id, NULL); - id_for_cie = 0xffffffffffffffffull; - } - - /*Debug (1, "CIE/FDE id = %.8x\n", (int) cie_id);*/ - - if (cie_id == id_for_cie) - ; - /*Debug (1, "Found CIE at %.8x.\n", item_start);*/ - else - { - unw_word_t fde_addr = item_start; - unw_proc_info_t this_pi; - int err; - - /*Debug (1, "Found FDE at %.8x\n", item_start);*/ - - err = dwarf_extract_proc_info_from_fde (unw_local_addr_space, - a, &fde_addr, - &this_pi, - (uintptr_t) buf, 0, 1, - NULL); - if (err == 0) - { - Debug (15, "start_ip = %lx, end_ip = %lx\n", - (long) this_pi.start_ip, (long) this_pi.end_ip); - debug_frame_tab_append (&tab, - item_start - (unw_word_t) (uintptr_t) buf, - this_pi.start_ip); - } - /*else - Debug (1, "FDE parse failed\n");*/ - } - - addr = item_end; - } - - debug_frame_tab_shrink (&tab); - qsort (tab.tab, tab.length, sizeof (struct table_entry), - debug_frame_tab_compare); - /* for (i = 0; i < tab.length; i++) - { - fprintf (stderr, "ip %x, fde offset %x\n", - (int) tab.tab[i].start_ip_offset, - (int) tab.tab[i].fde_offset); - }*/ - fdesc->index = tab.tab; - fdesc->index_size = tab.length; - } - - di->format = UNW_INFO_FORMAT_TABLE; - di->start_ip = fdesc->start; - di->end_ip = fdesc->end; - di->u.ti.name_ptr = (unw_word_t) (uintptr_t) obj_name; - di->u.ti.table_data = (unw_word_t *) fdesc; - di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t); - di->u.ti.segbase = segbase; - - found = 1; - Debug (15, "found debug_frame table `%s': segbase=0x%lx, len=%lu, " - "gp=0x%lx, table_data=0x%lx\n", - (char *) (uintptr_t) di->u.ti.name_ptr, - (long) di->u.ti.segbase, (long) di->u.ti.table_len, - (long) di->gp, (long) di->u.ti.table_data); + { + Debug (15, "couldn't allocate a frame index table\n"); + fdesc->index_size = 0; + return found; + } + + /* Then fill and sort the index. */ + + debug_frame_index_make (fdesc); + debug_frame_index_sort (fdesc); + + /*for (i = 0; i < count; i++) + { + const struct table_entry *e = &fdesc->index[i]; + + Debug (15, "ip %x, FDE offset %x\n", + e->start_ip_offset, e->fde_offset); + }*/ } + + di->format = UNW_INFO_FORMAT_TABLE; + di->start_ip = fdesc->start; + di->end_ip = fdesc->end; + di->u.ti.name_ptr = (unw_word_t) (uintptr_t) obj_name; + di->u.ti.table_data = (unw_word_t *) fdesc; + di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t); + di->u.ti.segbase = segbase; + + found = 1; + Debug (15, "found debug_frame table `%s': segbase=0x%lx, len=%lu, " + "gp=0x%lx, table_data=0x%lx\n", + (char *) (uintptr_t) di->u.ti.name_ptr, + (long) di->u.ti.segbase, (long) di->u.ti.table_len, + (long) di->gp, (long) di->u.ti.table_data); + return found; } @@ -525,6 +572,10 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) } else if (phdr->p_type == PT_GNU_EH_FRAME) p_eh_hdr = phdr; +#if defined __sun + else if (phdr->p_type == PT_SUNW_UNWIND) + p_eh_hdr = phdr; +#endif else if (phdr->p_type == PT_DYNAMIC) p_dynamic = phdr; } @@ -606,11 +657,15 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) /* If there is no search table or it has an unsupported encoding, fall back on linear search. */ if (hdr->table_enc == DW_EH_PE_omit) - Debug (4, "table `%s' lacks search table; doing linear search\n", - info->dlpi_name); + { + Debug (4, "table `%s' lacks search table; doing linear search\n", + info->dlpi_name); + } else - Debug (4, "table `%s' has encoding 0x%x; doing linear search\n", - info->dlpi_name, hdr->table_enc); + { + Debug (4, "table `%s' has encoding 0x%x; doing linear search\n", + info->dlpi_name, hdr->table_enc); + } eh_frame_end = max_load_addr; /* XXX can we do better? */ @@ -843,7 +898,7 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip, endianness is the target one. */ as = unw_local_addr_space; table = fdesc->index; - table_len = fdesc->index_size * sizeof (struct table_entry); + table_len = fdesc->index_size; debug_frame_base = (uintptr_t) fdesc->debug_frame; #endif } diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c index 6a2ad504078af..f5f7ad06c3b67 100644 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c @@ -80,6 +80,9 @@ dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, break; case PT_GNU_EH_FRAME: +#if defined __sun + case PT_SUNW_UNWIND: +#endif peh_hdr = phdr + i; break; diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c index 7d255aeeaf3c9..28fd73c6b0f7f 100644 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c @@ -440,8 +440,15 @@ fetch_proc_info (struct dwarf_cursor *c, unw_word_t ip) continue, and it's important we get this right, as 'ip' could be right at the function entry and hence FDE edge, or at instruction that manipulates CFA (push/pop). */ + if (c->use_prev_instr) - --ip; + { +#if defined(__arm__) + /* On arm, the least bit denotes thumb/arm mode, clear it. */ + ip &= ~(unw_word_t)0x1; +#endif + --ip; + } memset (&c->pi, 0, sizeof (c->pi)); @@ -734,7 +741,7 @@ create_state_record_for (struct dwarf_cursor *c, dwarf_state_record_t *sr, } static inline int -eval_location_expr (struct dwarf_cursor *c, unw_addr_space_t as, +eval_location_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr, dwarf_loc_t *locp, void *arg) { @@ -746,7 +753,7 @@ eval_location_expr (struct dwarf_cursor *c, unw_addr_space_t as, return ret; /* evaluate the expression: */ - if ((ret = dwarf_eval_expr (c, &addr, len, &val, &is_register)) < 0) + if ((ret = dwarf_eval_expr (c, stack_val, &addr, len, &val, &is_register)) < 0) return ret; if (is_register) @@ -804,7 +811,10 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) assert (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_EXPR); addr = rs->reg.val[DWARF_CFA_REG_COLUMN]; - if ((ret = eval_location_expr (c, as, a, addr, &cfa_loc, arg)) < 0) + /* The dwarf standard doesn't specify an initial value to be pushed on */ + /* the stack before DW_CFA_def_cfa_expression evaluation. We push on a */ + /* dummy value (0) to keep the eval_location_expr function consistent. */ + if ((ret = eval_location_expr (c, 0, as, a, addr, &cfa_loc, arg)) < 0) return ret; /* the returned location better be a memory location... */ if (DWARF_IS_REG_LOC (cfa_loc)) @@ -831,18 +841,30 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) break; case DWARF_WHERE_REG: - new_loc[i] = DWARF_REG_LOC (c, dwarf_to_unw_regnum (rs->reg.val[i])); +#ifdef __s390x__ + /* GPRs can be saved in FPRs on s390x */ + if (unw_is_fpreg (dwarf_to_unw_regnum (rs->reg.val[i]))) + { + new_loc[i] = DWARF_FPREG_LOC (c, dwarf_to_unw_regnum (rs->reg.val[i])); + break; + } +#endif + new_loc[i] = new_loc[rs->reg.val[i]]; break; case DWARF_WHERE_EXPR: addr = rs->reg.val[i]; - if ((ret = eval_location_expr (c, as, a, addr, new_loc + i, arg)) < 0) + /* The dwarf standard requires the current CFA to be pushed on the */ + /* stack before DW_CFA_expression evaluation. */ + if ((ret = eval_location_expr (c, cfa, as, a, addr, new_loc + i, arg)) < 0) return ret; break; case DWARF_WHERE_VAL_EXPR: addr = rs->reg.val[i]; - if ((ret = eval_location_expr (c, as, a, addr, new_loc + i, arg)) < 0) + /* The dwarf standard requires the current CFA to be pushed on the */ + /* stack before DW_CFA_val_expression evaluation. */ + if ((ret = eval_location_expr (c, cfa, as, a, addr, new_loc + i, arg)) < 0) return ret; new_loc[i] = DWARF_VAL_LOC (c, DWARF_GET_LOC (new_loc[i])); break; @@ -924,7 +946,6 @@ find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr) unsigned short index = -1; if (cache) { - put_rs_cache (c->as, cache, &saved_mask); if (rs) { index = rs - cache->buckets; @@ -932,6 +953,7 @@ find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr) cache->links[c->prev_rs].hint = index + 1; c->prev_rs = index; } + put_rs_cache (c->as, cache, &saved_mask); } if (ret < 0) return ret; diff --git a/src/coreclr/src/pal/src/libunwind/src/elfxx.c b/src/coreclr/src/pal/src/libunwind/src/elfxx.c index b03dfcb734cda..2589a3d43b628 100644 --- a/src/coreclr/src/pal/src/libunwind/src/elfxx.c +++ b/src/coreclr/src/pal/src/libunwind/src/elfxx.c @@ -28,6 +28,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include +#include #ifdef HAVE_LZMA #include diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c index 461e4b93da65f..265455a68c82a 100644 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c @@ -64,13 +64,6 @@ _Uhppa_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -81,7 +74,13 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c index b09a2ad57c7a7..8601bb3ca885f 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c @@ -68,6 +68,7 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, if (!_U_dyn_info_list_addr) return -UNW_ENOINFO; #endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. *dyn_info_list_addr = _U_dyn_info_list_addr (); return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c index 98d35012861cf..2e7c62e5e8623 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c @@ -49,6 +49,7 @@ local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, return -UNW_ENOINFO; #endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. list = (unw_dyn_info_list_t *) (uintptr_t) _U_dyn_info_list_addr (); for (di = list->first; di; di = di->next) if (ip >= di->start_ip && ip < di->end_ip) diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c index 840d9007f4c1d..0b77fa59523cd 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c @@ -106,7 +106,15 @@ unw_get_proc_name (unw_cursor_t *cursor, char *buf, size_t buf_len, ip = tdep_get_ip (c); #if !defined(__ia64__) if (c->dwarf.use_prev_instr) - --ip; + { +#if defined(__arm__) + /* On arm, the least bit denotes thumb/arm mode, clear it. */ + ip &= ~(unw_word_t)0x1; +#endif + --ip; + } + + #endif error = get_proc_name (tdep_get_as (c), ip, buf, buf_len, offp, tdep_get_as_arg (c)); diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c b/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c index c7aa2bdcdcbf0..b28151370cdcc 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c +++ b/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c @@ -23,9 +23,9 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef UNW_REMOTE_ONLY - +#if !defined(UNW_REMOTE_ONLY) && !defined(UNW_LOCAL_ONLY) #define UNW_LOCAL_ONLY + #include #include #include @@ -75,7 +75,9 @@ unw_backtrace (void **buffer, int size) return n; } +#ifdef CONFIG_WEAK_BACKTRACE extern int backtrace (void **buffer, int size) WEAK ALIAS(unw_backtrace); +#endif #endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c b/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c index cbd93e1a11cff..f2b01158a0ec7 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c +++ b/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c @@ -30,21 +30,24 @@ unw_flush_cache (unw_addr_space_t as, unw_word_t lo, unw_word_t hi) { #if !UNW_TARGET_IA64 struct unw_debug_frame_list *w = as->debug_frames; -#endif - /* clear dyn_info_list_addr cache: */ - as->dyn_info_list_addr = 0; - -#if !UNW_TARGET_IA64 - for (; w; w = w->next) + while (w) { + struct unw_debug_frame_list *n = w->next; + if (w->index) - free (w->index); - free (w->debug_frame); + munmap (w->index, w->index_size); + + munmap (w->debug_frame, w->debug_frame_size); + munmap (w, sizeof (*w)); + w = n; } as->debug_frames = NULL; #endif + /* clear dyn_info_list_addr cache: */ + as->dyn_info_list_addr = 0; + /* This lets us flush caches lazily. The implementation currently ignores the flush range arguments (lo-hi). This is OK because unw_flush_cache() is allowed to flush more than the requested diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c index 493d03db662b9..24e0d3b1536a2 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c @@ -58,8 +58,15 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order) as->big_endian = (byte_order == __BIG_ENDIAN); /* FIXME! There is no way to specify the ABI. */ +#if _MIPS_SIM == _ABIO32 as->abi = UNW_MIPS_ABI_O32; - as->addr_size = 4; +#elif _MIPS_SIM == _ABIN32 + as->abi = UNW_MIPS_ABI_N32; +#elif _MIPS_SIM == _ABI64 + as->abi = UNW_MIPS_ABI_N64; +#else +# error Unsupported ABI +#endif return as; #endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c index 7b84be87b917d..04c4326d45c69 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c @@ -30,11 +30,14 @@ unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) struct cursor *c = (struct cursor *) cursor; int ret; - /* We can only unwind using Dwarf into on MIPS: return failure code - if it's not present. */ ret = dwarf_make_proc_info (&c->dwarf); - if (ret < 0) - return ret; + if (ret < 0) { + /* Construct a dummy proc info if Dwarf failed */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = c->dwarf.ip; + pi->end_ip = c->dwarf.ip + 4; + return 0; + } *pi = c->dwarf.pi; return 0; diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c index 3df170c754934..bf7a8f5a8f444 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c @@ -69,13 +69,6 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -86,7 +79,13 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { - *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list; +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c index 95194022d2be1..e967324d67d6e 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c @@ -63,7 +63,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, case UNW_MIPS_R26: case UNW_MIPS_R27: case UNW_MIPS_R28: - case UNW_MIPS_R29: + case UNW_MIPS_R30: case UNW_MIPS_R31: loc = c->dwarf.loc[reg - UNW_MIPS_R0]; @@ -75,6 +75,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, loc = c->dwarf.loc[reg]; break; + case UNW_MIPS_R29: case UNW_MIPS_CFA: if (write) return -UNW_EREADONLYREG; diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c index 937136aef1f76..0235d523f0399 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c @@ -110,6 +110,96 @@ mips_handle_signal_frame (unw_cursor_t *cursor) return 1; } + + +static inline +int is_valid_fp_val(unw_word_t cfa_val, unw_word_t fp_val) +{ + return fp_val > 0 && cfa_val > 0 && fp_val >cfa_val && (fp_val - cfa_val < 0x4000); +} + +static int _step_n64(struct cursor *c) +{ + #define FP_REG UNW_MIPS_R30 + #define SP_REG UNW_MIPS_R29 + #define RA_REG UNW_MIPS_R31 + + //TODO:handle plt entry + int ret; + unw_word_t current_fp_val = 0; + unw_word_t current_ra_val = 0; + unw_word_t current_sp_val = 0; + struct dwarf_loc up_fp_loc = DWARF_NULL_LOC; + struct dwarf_loc up_ra_loc = DWARF_NULL_LOC; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[SP_REG], ¤t_sp_val); + if (ret < 0) + { + Debug (2, "returning %d [SP=0x%lx]\n", ret, + DWARF_GET_LOC (c->dwarf.loc[FP_REG])); + return ret; + } + ret = dwarf_get (&c->dwarf, c->dwarf.loc[FP_REG], ¤t_fp_val); + if (ret < 0) + { + Debug (2, "returning %d [FP=0x%lx]\n", ret, + DWARF_GET_LOC (c->dwarf.loc[FP_REG])); + return ret; + } + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RA_REG], ¤t_ra_val); + if (ret < 0) + { + Debug (2, "returning %d [RA=0x%lx]\n", ret, + DWARF_GET_LOC (c->dwarf.loc[RA_REG])); + return ret; + } + + Debug(2, "BEGIN GUESSING WITH SP:%p FP:%p CFA:%p at %p, RA:%p\n", + current_sp_val, current_fp_val, c->dwarf.cfa, + c->dwarf.ip, current_ra_val + ); + + if (current_fp_val == current_sp_val) { + // Don't adjust FP + up_fp_loc = c->dwarf.loc[FP_REG]; + up_ra_loc = c->dwarf.loc[RA_REG]; + } else if (is_valid_fp_val(c->dwarf.cfa, current_fp_val)) { + /* Heuristic to determine incorrect guess. For FP to be a + valid frame it needs to be above current CFA, but don't + let it go more than a little. Note that we can't deduce + anything about new FP (fp1) since it may not be a frame + pointer in the frame above. Just check we get the value. */ + up_fp_loc = DWARF_MEM_LOC (c, current_fp_val+16); + up_ra_loc = DWARF_MEM_LOC (c, current_fp_val+24); + unw_word_t up_fp_val = 0; + ret = dwarf_get (&c->dwarf, up_fp_loc, &up_fp_val); + if (ret > 0 && is_valid_fp_val(current_fp_val, up_fp_val)) { + c->dwarf.loc[FP_REG] = up_fp_loc; + } + } + + if (DWARF_IS_NULL_LOC (up_fp_loc)) + { + ret = 0; + Debug (2, "NULL %%fp loc, returning %d\n", ret); + return ret; + } + + c->dwarf.loc[UNW_MIPS_PC] = c->dwarf.loc[RA_REG]; + c->dwarf.loc[RA_REG] = up_ra_loc; + c->dwarf.loc[SP_REG] = up_fp_loc; + c->dwarf.loc[FP_REG] = up_fp_loc; + c->dwarf.use_prev_instr = 1; + + if (c->dwarf.ip == current_ra_val && current_fp_val == current_sp_val) { + // Backtrace stopped: frame did not save the PC + c->dwarf.ip = 0; + } else { + c->dwarf.ip = current_ra_val; + } + return (c->dwarf.ip == 0) ? 0 : 1; +} + int unw_step (unw_cursor_t *cursor) { @@ -124,9 +214,11 @@ unw_step (unw_cursor_t *cursor) if (unlikely (ret == -UNW_ESTOPUNWIND)) return ret; - /* Dwarf unwinding didn't work, stop. */ +#if _MIPS_SIM == _ABI64 if (unlikely (ret < 0)) - return 0; - + { + return _step_n64(c); + } +#endif return (c->dwarf.ip == 0) ? 0 : 1; } diff --git a/src/coreclr/src/pal/src/libunwind/src/os-solaris.c b/src/coreclr/src/pal/src/libunwind/src/os-solaris.c new file mode 100644 index 0000000000000..3c140ef29c93e --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/os-solaris.c @@ -0,0 +1,73 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003-2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include + +#include "libunwind_i.h" +#include "os-linux.h" // using linux header for map_iterator implementation + +int +tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, + unsigned long *segbase, unsigned long *mapoff, + char *path, size_t pathlen) +{ + struct map_iterator mi; + int found = 0, rc; + unsigned long hi; + + if (maps_init (&mi, pid) < 0) + return -1; + + while (maps_next (&mi, segbase, &hi, mapoff)) + if (ip >= *segbase && ip < hi) + { + found = 1; + break; + } + + if (!found) + { + maps_close (&mi); + return -1; + } + if (path) + { + strncpy(path, mi.path, pathlen); + } + rc = elf_map_image (ei, mi.path); + maps_close (&mi); + return rc; +} + +#ifndef UNW_REMOTE_ONLY + +void +tdep_get_exe_image_path (char *path) +{ + strcpy(path, getexecname()); +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c index ba302448a314b..7b45455807c89 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c @@ -91,9 +91,6 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - - static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -104,7 +101,13 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c index 4c88cd6e77ff0..7bfb395a7923c 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c @@ -95,9 +95,6 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - - static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -108,7 +105,13 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c index 2b92462fa927f..37cd4ffe1c2f7 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c @@ -84,6 +84,9 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, #elif defined(__arm__) if ((unsigned) reg < UNW_ARM_F0 || (unsigned) reg > UNW_ARM_F7) return -UNW_EBADREG; +#elif defined(__aarch64__) + if ((unsigned) reg < UNW_AARCH64_V0 || (unsigned) reg > UNW_AARCH64_V31) + return -UNW_EBADREG; #else #error Fix me #endif @@ -99,6 +102,8 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, memcpy(&fpreg.fpr_acc[reg], val, sizeof(unw_fpreg_t)); #elif defined(__arm__) memcpy(&fpreg.fpr[reg], val, sizeof(unw_fpreg_t)); +#elif defined(__aarch64__) + memcpy(&fpreg.fp_q[reg], val, sizeof(unw_fpreg_t)); #else #error Fix me #endif @@ -111,6 +116,8 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, memcpy(val, &fpreg.fpr_acc[reg], sizeof(unw_fpreg_t)); #elif defined(__arm__) memcpy(val, &fpreg.fpr[reg], sizeof(unw_fpreg_t)); +#elif defined(__aarch64__) + memcpy(val, &fpreg.fp_q[reg], sizeof(unw_fpreg_t)); #else #error Fix me #endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c index cc5ed0441865e..16671d453e1f2 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c @@ -71,6 +71,11 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, #else +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static inline int get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, int *countp) diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c index c82d1c9887295..52be799980db3 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c @@ -632,6 +632,40 @@ const int _UPT_reg_offset[UNW_REG_LAST + 1] = [UNW_TILEGX_R54] = 0x1b0, [UNW_TILEGX_R55] = 0x1b8, [UNW_TILEGX_PC] = 0x1a0 +#elif defined(UNW_TARGET_S390X) + [UNW_S390X_R0] = 0x10, + [UNW_S390X_R1] = 0x18, + [UNW_S390X_R2] = 0x20, + [UNW_S390X_R3] = 0x28, + [UNW_S390X_R4] = 0x30, + [UNW_S390X_R5] = 0x38, + [UNW_S390X_R6] = 0x40, + [UNW_S390X_R7] = 0x48, + [UNW_S390X_R8] = 0x50, + [UNW_S390X_R9] = 0x58, + [UNW_S390X_R10] = 0x60, + [UNW_S390X_R11] = 0x68, + [UNW_S390X_R12] = 0x70, + [UNW_S390X_R13] = 0x78, + [UNW_S390X_R14] = 0x80, + [UNW_S390X_R15] = 0x88, + [UNW_S390X_F0] = 0xe0, + [UNW_S390X_F1] = 0xe8, + [UNW_S390X_F2] = 0xf0, + [UNW_S390X_F3] = 0xf8, + [UNW_S390X_F4] = 0x100, + [UNW_S390X_F5] = 0x108, + [UNW_S390X_F6] = 0x110, + [UNW_S390X_F7] = 0x118, + [UNW_S390X_F8] = 0x120, + [UNW_S390X_F9] = 0x128, + [UNW_S390X_F10] = 0x130, + [UNW_S390X_F11] = 0x138, + [UNW_S390X_F12] = 0x140, + [UNW_S390X_F13] = 0x148, + [UNW_S390X_F14] = 0x150, + [UNW_S390X_F15] = 0x150, + [UNW_S390X_IP] = 0x08 #else # error Fix me. #endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c new file mode 100644 index 0000000000000..82f056da67ebf --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_apply_reg_state (unw_cursor_t *cursor, + void *reg_states_data) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c new file mode 100644 index 0000000000000..d411454932bc4 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c @@ -0,0 +1,62 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Copyright (C) 2012 Tommi Rantala + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#if defined(_BIG_ENDIAN) && !defined(__BIG_ENDIAN) +#define __BIG_ENDIAN _BIG_ENDIAN +#endif + +unw_addr_space_t +unw_create_addr_space (unw_accessors_t *a, int byte_order) +{ +#ifdef UNW_LOCAL_ONLY + return NULL; +#else + unw_addr_space_t as; + + /* + * s390x supports only big-endian. + */ + if (byte_order != 0 && byte_order != __BIG_ENDIAN) + return NULL; + + as = malloc (sizeof (*as)); + if (!as) + return NULL; + + memset (as, 0, sizeof (*as)); + + as->acc = *a; + + return as; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c new file mode 100644 index 0000000000000..50de1e423c2c9 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c @@ -0,0 +1,48 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) +{ + struct cursor *c = (struct cursor *) cursor; + + if (dwarf_make_proc_info (&c->dwarf) < 0) + { + /* On x86-64, some key routines such as _start() and _dl_start() + are missing DWARF unwind info. We don't want to fail in that + case, because those frames are uninteresting and just mark + the end of the frame-chain anyhow. */ + memset (pi, 0, sizeof (*pi)); + pi->start_ip = c->dwarf.ip; + pi->end_ip = c->dwarf.ip + 1; + return 0; + } + *pi = c->dwarf.pi; + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c new file mode 100644 index 0000000000000..dc462c966e567 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c @@ -0,0 +1,86 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + + switch (reg) + { + case UNW_S390X_R6: + case UNW_S390X_R7: + case UNW_S390X_R8: + case UNW_S390X_R9: + case UNW_S390X_R10: + case UNW_S390X_R11: + case UNW_S390X_R12: + case UNW_S390X_R13: + case UNW_S390X_R15: + case UNW_S390X_F8: + case UNW_S390X_F9: + case UNW_S390X_F10: + case UNW_S390X_F11: + case UNW_S390X_F12: + case UNW_S390X_F13: + case UNW_S390X_F14: + case UNW_S390X_F15: + loc = c->dwarf.loc[reg]; + break; + + default: + break; + } + + memset (sloc, 0, sizeof (*sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c new file mode 100644 index 0000000000000..e2abe89d30743 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c @@ -0,0 +1,101 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "config.h" +#include "unwind_i.h" +#include "dwarf_i.h" + +HIDDEN define_lock (s390x_lock); +HIDDEN int tdep_init_done; + +/* The API register numbers are exactly the same as the .eh_frame + registers, for now at least. */ +HIDDEN const uint8_t dwarf_to_unw_regnum_map[DWARF_NUM_PRESERVED_REGS] = + { + UNW_S390X_R0, + UNW_S390X_R1, + UNW_S390X_R2, + UNW_S390X_R3, + UNW_S390X_R4, + UNW_S390X_R5, + UNW_S390X_R6, + UNW_S390X_R7, + UNW_S390X_R8, + UNW_S390X_R9, + UNW_S390X_R10, + UNW_S390X_R11, + UNW_S390X_R12, + UNW_S390X_R13, + UNW_S390X_R14, + UNW_S390X_R15, + + UNW_S390X_F0, + UNW_S390X_F2, + UNW_S390X_F4, + UNW_S390X_F6, + UNW_S390X_F1, + UNW_S390X_F3, + UNW_S390X_F5, + UNW_S390X_F7, + UNW_S390X_F8, + UNW_S390X_F10, + UNW_S390X_F12, + UNW_S390X_F14, + UNW_S390X_F9, + UNW_S390X_F11, + UNW_S390X_F13, + UNW_S390X_F15, + }; + +HIDDEN void +tdep_init (void) +{ + intrmask_t saved_mask; + + sigfillset (&unwi_full_mask); + + lock_acquire (&s390x_lock, saved_mask); + { + if (tdep_init_done) + /* another thread else beat us to it... */ + goto out; + + mi_init (); + + dwarf_init (); + + tdep_init_mem_validate (); + +#ifndef UNW_REMOTE_ONLY + s390x_local_addr_space_init (); +#endif + tdep_init_done = 1; /* signal that we're initialized... */ + } + out: + lock_release (&s390x_lock, saved_mask); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c new file mode 100644 index 0000000000000..db01743c06276 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c @@ -0,0 +1,365 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Copyright (C) 2007 David Mosberger-Tang + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "unwind_i.h" + +#ifdef UNW_REMOTE_ONLY + +/* unw_local_addr_space is a NULL pointer in this case. */ +unw_addr_space_t unw_local_addr_space; + +#else /* !UNW_REMOTE_ONLY */ + +static struct unw_addr_space local_addr_space; + +unw_addr_space_t unw_local_addr_space = &local_addr_space; + +static inline void * +uc_addr (ucontext_t *uc, int reg) +{ + if (reg >= UNW_S390X_R0 && reg <= UNW_S390X_R15) + return &uc->uc_mcontext.gregs[reg - UNW_S390X_R0]; + if (reg >= UNW_S390X_F0 && reg <= UNW_S390X_F15) + return &uc->uc_mcontext.fpregs.fprs[reg - UNW_S390X_F0]; + if (reg == UNW_S390X_IP) + return &uc->uc_mcontext.psw.addr; + + return NULL; +} + +# ifdef UNW_LOCAL_ONLY + +HIDDEN void * +tdep_uc_addr (ucontext_t *uc, int reg) +{ + return uc_addr (uc, reg); +} + +# endif /* UNW_LOCAL_ONLY */ + +static void +put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) +{ + /* it's a no-op */ +} + +static int +get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, + void *arg) +{ +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); + return 0; +} + +#define PAGE_SIZE 4096 +#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) + +static int mem_validate_pipe[2] = {-1, -1}; + +static inline void +open_pipe (void) +{ + /* ignore errors for closing invalid fd's */ + close (mem_validate_pipe[0]); + close (mem_validate_pipe[1]); + + pipe2 (mem_validate_pipe, O_CLOEXEC | O_NONBLOCK); +} + +ALWAYS_INLINE +static int +write_validate (void *addr) +{ + int ret = -1; + ssize_t bytes = 0; + + do + { + char buf; + bytes = read (mem_validate_pipe[0], &buf, 1); + } + while ( errno == EINTR ); + + int valid_read = (bytes > 0 || errno == EAGAIN || errno == EWOULDBLOCK); + if (!valid_read) + { + // re-open closed pipe + open_pipe (); + } + + do + { + /* use syscall insteadof write() so that ASAN does not complain */ + ret = syscall (SYS_write, mem_validate_pipe[1], addr, 1); + } + while ( errno == EINTR ); + + return ret; +} + +static int (*mem_validate_func) (void *addr, size_t len); +static int msync_validate (void *addr, size_t len) +{ + if (msync (addr, len, MS_ASYNC) != 0) + { + return -1; + } + + return write_validate (addr); +} + +#ifdef HAVE_MINCORE +static int mincore_validate (void *addr, size_t len) +{ + unsigned char mvec[2]; /* Unaligned access may cross page boundary */ + size_t i; + + /* mincore could fail with EAGAIN but we conservatively return -1 + instead of looping. */ + if (mincore (addr, len, mvec) != 0) + { + return -1; + } + + for (i = 0; i < (len + PAGE_SIZE - 1) / PAGE_SIZE; i++) + { + if (!(mvec[i] & 1)) return -1; + } + + return write_validate (addr); +} +#endif + +/* Initialise memory validation method. On linux kernels <2.6.21, + mincore() returns incorrect value for MAP_PRIVATE mappings, + such as stacks. If mincore() was available at compile time, + check if we can actually use it. If not, use msync() instead. */ +HIDDEN void +tdep_init_mem_validate (void) +{ + open_pipe (); + +#ifdef HAVE_MINCORE + unsigned char present = 1; + unw_word_t addr = PAGE_START((unw_word_t)&present); + unsigned char mvec[1]; + int ret; + while ((ret = mincore ((void*)addr, PAGE_SIZE, mvec)) == -1 && + errno == EAGAIN) {} + if (ret == 0 && (mvec[0] & 1)) + { + Debug(1, "using mincore to validate memory\n"); + mem_validate_func = mincore_validate; + } + else +#endif + { + Debug(1, "using msync to validate memory\n"); + mem_validate_func = msync_validate; + } +} + +/* Cache of already validated addresses */ +#define NLGA 4 +static unw_word_t last_good_addr[NLGA]; +static int lga_victim; + +static int +validate_mem (unw_word_t addr) +{ + int i, victim; + size_t len; + + if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) + len = PAGE_SIZE; + else + len = PAGE_SIZE * 2; + + addr = PAGE_START(addr); + + if (addr == 0) + return -1; + + for (i = 0; i < NLGA; i++) + { + if (last_good_addr[i] && (addr == last_good_addr[i])) + return 0; + } + + if (mem_validate_func ((void *) addr, len) == -1) + return -1; + + victim = lga_victim; + for (i = 0; i < NLGA; i++) { + if (!last_good_addr[victim]) { + last_good_addr[victim++] = addr; + return 0; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + last_good_addr[victim] = addr; + victim = (victim + 1) % NLGA; + lga_victim = victim; + + return 0; +} + +static int +access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, + void *arg) +{ + if (unlikely (write)) + { + Debug (16, "mem[%016lx] <- %lx\n", addr, *val); + *(unw_word_t *) addr = *val; + } + else + { + /* validate address */ + const struct cursor *c = (const struct cursor *)arg; + if (likely (c != NULL) && unlikely (c->validate) + && unlikely (validate_mem (addr))) { + Debug (16, "mem[%016lx] -> invalid\n", addr); + return -1; + } + *val = *(unw_word_t *) addr; + Debug (16, "mem[%016lx] -> %lx\n", addr, *val); + } + return 0; +} + +static int +access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, + void *arg) +{ + unw_word_t *addr; + ucontext_t *uc = ((struct cursor *)arg)->uc; + + if (unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + *(unw_word_t *) addr = *val; + Debug (12, "%s <- 0x%016lx\n", unw_regname (reg), *val); + } + else + { + *val = *(unw_word_t *) addr; + Debug (12, "%s -> 0x%016lx\n", unw_regname (reg), *val); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; +} + +static int +access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, + int write, void *arg) +{ + ucontext_t *uc = ((struct cursor *)arg)->uc; + unw_fpreg_t *addr; + + if (!unw_is_fpreg (reg)) + goto badreg; + + if (!(addr = uc_addr (uc, reg))) + goto badreg; + + if (write) + { + Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + *(unw_fpreg_t *) addr = *val; + } + else + { + *val = *(unw_fpreg_t *) addr; + Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), + ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); + } + return 0; + + badreg: + Debug (1, "bad register number %u\n", reg); + /* attempt to access a non-preserved register */ + return -UNW_EBADREG; +} + +static int +get_static_proc_name (unw_addr_space_t as, unw_word_t ip, + char *buf, size_t buf_len, unw_word_t *offp, + void *arg) +{ + return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); +} + +HIDDEN void +s390x_local_addr_space_init (void) +{ + memset (&local_addr_space, 0, sizeof (local_addr_space)); + local_addr_space.caching_policy = UNW_CACHE_GLOBAL; + local_addr_space.acc.find_proc_info = dwarf_find_proc_info; + local_addr_space.acc.put_unwind_info = put_unwind_info; + local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; + local_addr_space.acc.access_mem = access_mem; + local_addr_space.acc.access_reg = access_reg; + local_addr_space.acc.access_fpreg = access_fpreg; + local_addr_space.acc.resume = s390x_local_resume; + local_addr_space.acc.get_proc_name = get_static_proc_name; + unw_flush_cache (&local_addr_space, 0, 0); + + memset (last_good_addr, 0, sizeof (unw_word_t) * NLGA); + lga_victim = 0; +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c new file mode 100644 index 0000000000000..5eaead0f840bb --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c @@ -0,0 +1,81 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "init.h" + +#ifdef UNW_REMOTE_ONLY + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return -UNW_EINVAL; +} + +#else /* !UNW_REMOTE_ONLY */ + +static int +unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) +{ + struct cursor *c = (struct cursor *) cursor; + + if (unlikely (!tdep_init_done)) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = unw_local_addr_space; + c->dwarf.as_arg = c; + c->uc = uc; + c->validate = 0; + return common_init (c, use_prev_instr); +} + +int +unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) +{ + return unw_init_local_common(cursor, uc, 1); +} + +int +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) +{ + if (!flag) + { + return unw_init_local_common(cursor, uc, 1); + } + else if (flag == UNW_INIT_SIGNAL_FRAME) + { + return unw_init_local_common(cursor, uc, 0); + } + else + { + return -UNW_EINVAL; + } +} + +#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c new file mode 100644 index 0000000000000..efd61d64d4b8f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c @@ -0,0 +1,57 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "init.h" +#include "unwind_i.h" + +int +unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) +{ +#ifdef UNW_LOCAL_ONLY + return -UNW_EINVAL; +#else /* !UNW_LOCAL_ONLY */ + struct cursor *c = (struct cursor *) cursor; + + if (!tdep_init_done) + tdep_init (); + + Debug (1, "(cursor=%p)\n", c); + + c->dwarf.as = as; + if (as == unw_local_addr_space) + { + c->dwarf.as_arg = c; + c->uc = as_arg; + } + else + { + c->dwarf.as_arg = as_arg; + c->uc = NULL; + } + return common_init (c, 0); +#endif /* !UNW_LOCAL_ONLY */ +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c new file mode 100644 index 0000000000000..7ed91e3ccfc02 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c @@ -0,0 +1,77 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2012 Tommi Rantala + Copyright (C) 2013 Linaro Limited + Copyright (C) 2017 IBM + + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +/* The restorer stub will be a system call: + - rt_sigreturn: svc 173 (0x0aad) + - sigreturn: svc 119 (0x0a77) +*/ + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ +#ifdef __linux__ + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret, shift = 48; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + /* Align the instruction pointer to 8 bytes so that we guarantee + an 8 byte read from it won't cross a page boundary. + Instructions on s390x are 2 byte aligned. */ + ip = c->dwarf.ip & ~7; + shift -= (c->dwarf.ip - ip) * 8; + + ret = (*a->access_mem) (as, ip, &w0, 0, arg); + if (ret < 0) + return ret; + + /* extract first 2 bytes of the next instruction */ + w0 = (w0 >> shift) & 0xffff; + + /* sigreturn */ + if (w0 == 0x0a77) + return 1; + + /* rt_sigreturn */ + if (w0 == 0x0aad) + return 2; + + return 0; + +#else + return -UNW_ENOINFO; +#endif +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c new file mode 100644 index 0000000000000..a17dc1b561d6f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c @@ -0,0 +1,37 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +int +unw_reg_states_iterate (unw_cursor_t *cursor, + unw_reg_states_callback cb, void *token) +{ + struct cursor *c = (struct cursor *) cursor; + + return dwarf_reg_states_iterate (&c->dwarf, cb, token); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c new file mode 100644 index 0000000000000..1a48833d56e73 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c @@ -0,0 +1,116 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +HIDDEN int +tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + + switch (reg) + { + case UNW_S390X_CFA: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; + return 0; + + case UNW_S390X_R0: + case UNW_S390X_R1: + case UNW_S390X_R2: + case UNW_S390X_R3: + case UNW_S390X_R4: + case UNW_S390X_R5: + case UNW_S390X_R6: + case UNW_S390X_R7: + case UNW_S390X_R8: + case UNW_S390X_R9: + case UNW_S390X_R10: + case UNW_S390X_R11: + case UNW_S390X_R12: + case UNW_S390X_R13: + case UNW_S390X_R14: + case UNW_S390X_IP: + loc = c->dwarf.loc[reg]; + break; + + case UNW_S390X_R15: + if (write) + return -UNW_EREADONLYREG; + loc = c->dwarf.loc[reg]; + break; + + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_put (&c->dwarf, loc, *valp); + else + return dwarf_get (&c->dwarf, loc, valp); +} + +HIDDEN int +tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, + int write) +{ + dwarf_loc_t loc = DWARF_NULL_LOC; + + switch (reg) + { + case UNW_S390X_F0: + case UNW_S390X_F1: + case UNW_S390X_F2: + case UNW_S390X_F3: + case UNW_S390X_F4: + case UNW_S390X_F5: + case UNW_S390X_F6: + case UNW_S390X_F7: + case UNW_S390X_F8: + case UNW_S390X_F9: + case UNW_S390X_F10: + case UNW_S390X_F11: + case UNW_S390X_F12: + case UNW_S390X_F13: + case UNW_S390X_F14: + case UNW_S390X_F15: + loc = c->dwarf.loc[reg]; + break; + default: + Debug (1, "bad register number %u\n", reg); + return -UNW_EBADREG; + } + + if (write) + return dwarf_putfp (&c->dwarf, loc, *valp); + else + return dwarf_getfp (&c->dwarf, loc, valp); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c new file mode 100644 index 0000000000000..fd9d13027e2a8 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c @@ -0,0 +1,160 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include "unwind_i.h" + +#ifndef UNW_REMOTE_ONLY + +HIDDEN inline int +s390x_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) +{ + struct cursor *c = (struct cursor *) cursor; + ucontext_t uc = *c->uc; + ucontext_t *rt = NULL; + struct sigcontext *sc = NULL; + int i; + unw_word_t sp, ip; + uc.uc_mcontext.psw.addr = c->dwarf.ip; + + /* Ensure c->pi is up-to-date. On x86-64, it's relatively common to + be missing DWARF unwind info. We don't want to fail in that + case, because the frame-chain still would let us do a backtrace + at least. */ + dwarf_make_proc_info (&c->dwarf); + + switch (c->sigcontext_format) + { + case S390X_SCF_NONE: + Debug (8, "resuming at ip=%llx via setcontext()\n", + (unsigned long long) c->dwarf.ip); + setcontext (&uc); + abort(); /* unreachable */ + case S390X_SCF_LINUX_SIGFRAME: + Debug (8, "resuming at ip=%llx via signal trampoline\n", + (unsigned long long) c->dwarf.ip); + sc = (struct sigcontext*)c->sigcontext_addr; + for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) + sc->sregs->regs.gprs[i-UNW_S390X_R0] = uc.uc_mcontext.gregs[i-UNW_S390X_R0]; + for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) + sc->sregs->fpregs.fprs[i-UNW_S390X_F0] = uc.uc_mcontext.fpregs.fprs[i-UNW_S390X_F0].d; + sc->sregs->regs.psw.addr = uc.uc_mcontext.psw.addr; + + sp = c->sigcontext_sp; + ip = c->sigcontext_pc; + __asm__ __volatile__ ( + "lgr 15, %[sp]\n" + "br %[ip]\n" + : : [sp] "r" (sp), [ip] "r" (ip) + ); + abort(); /* unreachable */ + case S390X_SCF_LINUX_RT_SIGFRAME: + Debug (8, "resuming at ip=%llx via signal trampoline\n", + (unsigned long long) c->dwarf.ip); + rt = (ucontext_t*)c->sigcontext_addr; + for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) + rt->uc_mcontext.gregs[i-UNW_S390X_R0] = uc.uc_mcontext.gregs[i-UNW_S390X_R0]; + for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) + rt->uc_mcontext.fpregs.fprs[i-UNW_S390X_F0] = uc.uc_mcontext.fpregs.fprs[i-UNW_S390X_F0]; + rt->uc_mcontext.psw.addr = uc.uc_mcontext.psw.addr; + + sp = c->sigcontext_sp; + ip = c->sigcontext_pc; + __asm__ __volatile__ ( + "lgr 15, %[sp]\n" + "br %[ip]\n" + : : [sp] "r" (sp), [ip] "r" (ip) + ); + abort(); /* unreachable */ + } + return -UNW_EINVAL; +} + +#endif /* !UNW_REMOTE_ONLY */ + +/* This routine is responsible for copying the register values in + cursor C and establishing them as the current machine state. */ + +static inline int +establish_machine_state (struct cursor *c) +{ + int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, + int write, void *); + int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, + int write, void *); + unw_addr_space_t as = c->dwarf.as; + void *arg = c->dwarf.as_arg; + unw_fpreg_t fpval; + unw_word_t val; + int reg; + + access_reg = as->acc.access_reg; + access_fpreg = as->acc.access_fpreg; + + Debug (8, "copying out cursor state\n"); + + for (reg = 0; reg <= UNW_REG_LAST; ++reg) + { + Debug (16, "copying %s %d\n", unw_regname (reg), reg); + if (unw_is_fpreg (reg)) + { + if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) + (*access_fpreg) (as, reg, &fpval, 1, arg); + } + else + { + if (tdep_access_reg (c, reg, &val, 0) >= 0) + (*access_reg) (as, reg, &val, 1, arg); + } + } + + if (c->dwarf.args_size) + { + if (tdep_access_reg (c, UNW_S390X_R15, &val, 0) >= 0) + { + val += c->dwarf.args_size; + (*access_reg) (as, UNW_S390X_R15, &val, 1, arg); + } + } + return 0; +} + +int +unw_resume (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret; + + Debug (1, "(cursor=%p)\n", c); + + if ((ret = establish_machine_state (c)) < 0) + return ret; + + return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, + c->dwarf.as_arg); +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c new file mode 100644 index 0000000000000..0b79580b256bc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c @@ -0,0 +1,146 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include + +static int +s390x_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret, i; + unw_word_t sc_addr, sp, *gprs, *fprs, *psw; + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_R15], &sp); + if (ret < 0) + return ret; + + /* Save the SP and PC to be able to return execution at this point + later in time (unw_resume). */ + c->sigcontext_sp = sp; + c->sigcontext_pc = c->dwarf.ip; + switch (c->sigcontext_format) + { + case S390X_SCF_LINUX_SIGFRAME: /* sigreturn */ + sc_addr = sp + 160; + gprs = ((struct sigcontext*)sc_addr)->sregs->regs.gprs; + fprs = (unw_word_t*)((struct sigcontext*)sc_addr)->sregs->fpregs.fprs; + psw = &((struct sigcontext*)sc_addr)->sregs->regs.psw.addr; + break; + case S390X_SCF_LINUX_RT_SIGFRAME: /* rt_sigreturn */ + sc_addr = sp + sizeof(siginfo_t) + 8 + 160; + gprs = ((ucontext_t*)sc_addr)->uc_mcontext.gregs; + fprs = (unw_word_t*)((ucontext_t*)sc_addr)->uc_mcontext.fpregs.fprs; + psw = &((ucontext_t*)sc_addr)->uc_mcontext.psw.addr; + break; + default: + return -UNW_EUNSPEC; + } + + c->sigcontext_addr = sc_addr; + + /* Update the dwarf cursor. + Set the location of the registers to the corresponding addresses of the + uc_mcontext / sigcontext structure contents. */ + for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) + c->dwarf.loc[i] = DWARF_MEM_LOC (c, (unw_word_t) &gprs[i-UNW_S390X_R0]); + for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) + c->dwarf.loc[i] = DWARF_MEM_LOC (c, (unw_word_t) &fprs[i-UNW_S390X_F0]); + + c->dwarf.loc[UNW_S390X_IP] = DWARF_MEM_LOC (c, (unw_word_t) psw); + + /* Set SP/CFA and PC/IP. + Normally the default CFA on s390x is r15+160. We do not add that offset + here because dwarf_step will add the offset. */ + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_R15], &c->dwarf.cfa); + dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_IP], &c->dwarf.ip); + + c->dwarf.pi_valid = 0; + c->dwarf.use_prev_instr = 0; + + return 1; +} + +int +unw_step (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + int ret = 0, val = c->validate, sig; + +#if CONSERVATIVE_CHECKS + c->validate = 1; +#endif + + Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx)\n", + c, c->dwarf.ip, c->dwarf.cfa); + + /* Try DWARF-based unwinding... */ + c->sigcontext_format = S390X_SCF_NONE; + ret = dwarf_step (&c->dwarf); + +#if CONSERVATIVE_CHECKS + c->validate = val; +#endif + + if (unlikely (ret == -UNW_ENOINFO)) + { + /* GCC doesn't currently emit debug information for signal + trampolines on s390x so we check for them explicitly. + + If there isn't debug information available we could also + try using the backchain (if available). + + Other platforms also detect PLT entries here. That's + tricky to do reliably on s390x so I've left it out for + now. */ + + /* Memory accesses here are quite likely to be unsafe. */ + c->validate = 1; + + /* Check if this is a signal frame. */ + sig = unw_is_signal_frame (cursor); + if (sig > 0) + { + c->sigcontext_format = sig; + ret = s390x_handle_signal_frame (cursor); + } + else + { + c->dwarf.ip = 0; + ret = 0; + } + + c->validate = val; + return ret; + } + + if (unlikely (ret > 0 && c->dwarf.ip == 0)) + return 0; + + return ret; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c new file mode 100644 index 0000000000000..7ebada480e564 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gapply_reg_state.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c new file mode 100644 index 0000000000000..0f2dc6be90145 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gcreate_addr_space.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c new file mode 100644 index 0000000000000..69028b019fcd5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_proc_info.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c new file mode 100644 index 0000000000000..9ea048a9076ba --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c new file mode 100644 index 0000000000000..8c43a67c0fff2 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c @@ -0,0 +1,6 @@ +#define UNW_LOCAL_ONLY +#include "config.h" +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gglobal.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c new file mode 100644 index 0000000000000..e9abfdd46a3e0 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c new file mode 100644 index 0000000000000..68a1687e85444 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_local.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c new file mode 100644 index 0000000000000..58cb04ab7cd1f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Ginit_remote.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c new file mode 100644 index 0000000000000..b9a7c4f51ad9f --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gis_signal_frame.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c new file mode 100644 index 0000000000000..f1eb1e79dcdcc --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Greg_states_iterate.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c new file mode 100644 index 0000000000000..2c9c75cd7d9a1 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gregs.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c new file mode 100644 index 0000000000000..41a8cf003de4a --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gresume.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c new file mode 100644 index 0000000000000..c1ac3c7547f00 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gstep.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S new file mode 100644 index 0000000000000..d35a3cf3a953d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S @@ -0,0 +1,74 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 Google, Inc + Contributed by Paul Pluzhnikov + Copyright (C) 2010 Konstantin Belousov + Copyright (C) 2017 IBM + + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +// int _Us390x_getcontext (unw_tdep_context_t *ucp) + + .global _Us390x_getcontext + .type _Us390x_getcontext, @function +_Us390x_getcontext: + .cfi_startproc + + // Save the minimal set of registers required to restore the + // context. Generally speaking this is just the preserved + // registers but we've also saved the parameter registers + // so that return values can be modified too. + + // save PSW address + // (not strictly needed but makes other code simpler) + stg %r14,0x30(%r2) + + // floating point parameters (not strictly needed) + std %f0,0x100(%r2) + std %f2,0x110(%r2) + std %f4,0x120(%r2) + std %f6,0x130(%r2) + + // floating point preserved registers + stfpc 0xf8(%r2) + std %f8,0x140(%r2) + std %f9,0x148(%r2) + std %f10,0x150(%r2) + std %f11,0x158(%r2) + std %f12,0x160(%r2) + std %f13,0x168(%r2) + std %f14,0x170(%r2) + std %f15,0x178(%r2) + + // preserved registers and parameters + lgr %r1,%r2 + lghi %r2,0 + stmg %r2,%r15,0x48(%r1) + + br %r14 + + .cfi_endproc + .size _Us390x_getcontext, . - _Us390x_getcontext + + // We do not need executable stack. + .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/init.h b/src/coreclr/src/pal/src/libunwind/src/s390x/init.h new file mode 100644 index 0000000000000..86ced38f66ca5 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/init.h @@ -0,0 +1,71 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static inline int +common_init (struct cursor *c, unsigned use_prev_instr) +{ + int ret; + int i; + + for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) { + c->dwarf.loc[i] = DWARF_REG_LOC(&c->dwarf, i); + } + for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) { + c->dwarf.loc[i] = DWARF_FPREG_LOC(&c->dwarf, i); + } + /* IP isn't a real register, it is encoded in the PSW */ + c->dwarf.loc[UNW_S390X_IP] = DWARF_REG_LOC(&c->dwarf, UNW_S390X_IP); + + ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_IP], &c->dwarf.ip); + if (ret < 0) + return ret; + + /* Normally the CFA offset on s390x is biased, however this is taken + into account by the CFA offset in dwarf_step, so here we just mark + make it equal to the stack pointer. */ + ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_S390X_R15), + &c->dwarf.cfa); + if (ret < 0) + return ret; + + c->sigcontext_format = S390X_SCF_NONE; + c->sigcontext_addr = 0; + + c->dwarf.args_size = 0; + c->dwarf.stash_frames = 0; + c->dwarf.use_prev_instr = use_prev_instr; + c->dwarf.pi_valid = 0; + c->dwarf.pi_is_dynamic = 0; + c->dwarf.hint = 0; + c->dwarf.prev_rs = 0; + c->dwarf.eh_valid_mask = 0; + + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c new file mode 100644 index 0000000000000..bc31f3e917011 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c @@ -0,0 +1,36 @@ +/* libunwind - a platform-independent unwind library + Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "libunwind_i.h" + +int +unw_is_fpreg (int regnum) +{ + /* vector registers? */ + return regnum >= UNW_S390X_F0 && regnum <= UNW_S390X_F15; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/regname.c b/src/coreclr/src/pal/src/libunwind/src/s390x/regname.c new file mode 100644 index 0000000000000..2421b37ebb0d3 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/regname.c @@ -0,0 +1,57 @@ +/* libunwind - a platform-independent unwind library + + Contributed by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +static const char *regname[] = + { + [UNW_S390X_R0]="R0", + [UNW_S390X_R1]="R1", + [UNW_S390X_R2]="R2", + [UNW_S390X_R3]="R3", + [UNW_S390X_R4]="R4", + [UNW_S390X_R5]="R5", + [UNW_S390X_R6]="R6", + [UNW_S390X_R7]="R7", + [UNW_S390X_R8]="R8", + [UNW_S390X_R9]="R9", + [UNW_S390X_R10]="R10", + [UNW_S390X_R11]="R11", + [UNW_S390X_R12]="R12", + [UNW_S390X_R13]="R13", + [UNW_S390X_R14]="R14", + [UNW_S390X_R15]="R15", + + [UNW_S390X_IP]="IP" + }; + +const char * +unw_regname (unw_regnum_t reg) +{ + if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) + return regname[reg]; + else + return "???"; +} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S new file mode 100644 index 0000000000000..6cf55688aa436 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S @@ -0,0 +1,76 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 Google, Inc + Contributed by Paul Pluzhnikov + Copyright (C) 2010 Konstantin Belousov + Copyright (C) 2017 IBM + + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +// int _Us390x_setcontext (const ucontext_t *ucp) + + .global _Us390x_setcontext + .type _Us390x_setcontext, @function +_Us390x_setcontext: + .cfi_startproc + + // Must only restore registers saved by getcontext, other fields + // in the ucontext_t might be uninitialised. + + // Stop this function being unwound. We are clobbering callee-save + // registers in this function so unwinding it is unsafe. + // Ideally we'd save callee-save registers, update the CFI for them + // and then switch to the new CFI once the context switch is + // complete. + .cfi_undefined %r14 + + // floating point parameters + ld %f0,0x100(%r2) + ld %f2,0x110(%r2) + ld %f4,0x120(%r2) + ld %f6,0x130(%r2) + + // floating point preserved registers + lfpc 0xf8(%r2) + ld %f8,0x140(%r2) + ld %f9,0x148(%r2) + ld %f10,0x150(%r2) + ld %f11,0x158(%r2) + ld %f12,0x160(%r2) + ld %f13,0x168(%r2) + ld %f14,0x170(%r2) + ld %f15,0x178(%r2) + + // preserved registers and parameters + lgr %r1,%r2 + lmg %r2,%r15,0x48(%r1) + + // restore PSW address + lg %r1,0x30(%r1) + br %r1 + + .cfi_endproc + .size _Us390x_setcontext, . - _Us390x_setcontext + + // We do not need executable stack. + .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h new file mode 100644 index 0000000000000..6e4b99baaa8da --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h @@ -0,0 +1,48 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002, 2005 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + Modified for s390x by Michael Munday + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef unwind_i_h +#define unwind_i_h + +#include + +#include + +#include "libunwind_i.h" +#include + +#define s390x_lock UNW_OBJ(lock) +#define s390x_local_resume UNW_OBJ(local_resume) +#define s390x_local_addr_space_init UNW_OBJ(local_addr_space_init) +#define setcontext UNW_ARCH_OBJ(setcontext) + +extern void s390x_local_addr_space_init (void); +extern int s390x_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg); +extern int setcontext (const ucontext_t *ucp); + +#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c b/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c index 0e286f6f0851c..dd330ce9e19db 100644 --- a/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c +++ b/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c @@ -31,8 +31,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "jmpbuf.h" #include "setjmp_i.h" -#if !defined(_NSIG) && defined(_SIG_MAXSIG) -# define _NSIG (_SIG_MAXSIG - 1) +#if !defined(_NSIG) +# if defined(_SIG_MAXSIG) +# define _NSIG (_SIG_MAXSIG - 1) +# elif defined(NSIG) +# define _NSIG NSIG +# endif #endif #if defined(__GLIBC__) @@ -92,7 +96,7 @@ siglongjmp (sigjmp_buf env, int val) if (!resume_restores_sigmask (&c, wp) && wp[JB_MASK_SAVED]) { /* sigmask was saved */ -#if defined(__linux__) +#if defined(__linux__) || defined(__sun) if (UNW_NUM_EH_REGS < 4 || _NSIG > 16 * sizeof (unw_word_t)) /* signal mask doesn't fit into EH arguments and we can't put it on the stack without overwriting something diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c index 52988a721e9d7..9fe96d2bd4d8e 100644 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c @@ -58,13 +58,6 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -75,7 +68,13 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c index 99ddb36fb3e33..45631306bcd81 100644 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c @@ -37,7 +37,7 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) #else /* !UNW_REMOTE_ONLY */ static int -unw_init_local (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr) +unw_init_local_common (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr) { struct cursor *c = (struct cursor *) cursor; diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c index a263c92718a0b..5590bafa61242 100644 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c @@ -55,7 +55,7 @@ sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) char x[sizeof(regs)]; }; - asm volatile ( + __asm__ __volatile__ ( "mov.l @%0+, r8\n" "mov.l @%0+, r9\n" "mov.l @%0+, r10\n" @@ -99,7 +99,7 @@ sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) /* Set the SP and the PC in order to continue execution at the modified trampoline which restores the signal mask and the registers. */ - asm __volatile__ ( + __asm__ __volatile__ ( "mov %0, r15\n" "lds %1, pr\n" "rts\n" diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c index 7564a558be436..925e6413246be 100644 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c @@ -64,13 +64,6 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -81,7 +74,13 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { - *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list; +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in b/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in index 1505c5d6f67d3..9a65faf39e125 100644 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in @@ -7,5 +7,5 @@ Name: libunwind Description: libunwind base library Version: @VERSION@ Libs: -L${libdir} -lunwind -Libs.private: @LIBLZMA@ +Libs.private: @LIBLZMA@ @LIBZ@ Cflags: -I${includedir} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c index f6b8dc27d4934..3cec74a216b1f 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c @@ -54,13 +54,6 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -71,7 +64,13 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c index 0057c62d648bf..40568700e0e40 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c @@ -44,6 +44,7 @@ unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) case UNW_X86_64_R13: loc = c->dwarf.loc[R13]; break; case UNW_X86_64_R14: loc = c->dwarf.loc[R14]; break; case UNW_X86_64_R15: loc = c->dwarf.loc[R15]; break; + case UNW_X86_64_RIP: loc = c->dwarf.loc[RIP]; break; default: break; diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c index 8d1fbb4b0a991..9a7b1957eb8d9 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c @@ -30,7 +30,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "dwarf_i.h" HIDDEN define_lock (x86_64_lock); -HIDDEN int tdep_init_done; +#ifdef HAVE_ATOMIC_OPS_H + HIDDEN AO_t tdep_init_done; +#else + HIDDEN int tdep_init_done; +#endif /* See comments for svr4_dbx_register_map[] in gcc/config/i386/i386.c. */ @@ -77,15 +81,17 @@ HIDDEN void tdep_init (void) { intrmask_t saved_mask; + intrmask_t full_mask; + sigfillset (&full_mask); - sigfillset (&unwi_full_mask); - - lock_acquire (&x86_64_lock, saved_mask); + SIGPROCMASK (SIG_SETMASK, &full_mask, &saved_mask); + mutex_lock (&x86_64_lock); { - if (tdep_init_done) + if (atomic_read(&tdep_init_done)) /* another thread else beat us to it... */ goto out; + sigfillset (&unwi_full_mask); mi_init (); dwarf_init (); @@ -95,8 +101,9 @@ tdep_init (void) #ifndef UNW_REMOTE_ONLY x86_64_local_addr_space_init (); #endif - tdep_init_done = 1; /* signal that we're initialized... */ + fetch_and_add1(&tdep_init_done); /* signal that we're initialized... */ } out: - lock_release (&x86_64_lock, saved_mask); + mutex_unlock(&x86_64_lock); + SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); } diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c index 2a84a1eec75e7..fd8d418b1a576 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c @@ -49,13 +49,6 @@ static struct unw_addr_space local_addr_space; unw_addr_space_t unw_local_addr_space = &local_addr_space; -HIDDEN unw_dyn_info_list_t _U_dyn_info_list; - -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -66,7 +59,13 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { - *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; +#ifndef UNW_LOCAL_ONLY +# pragma weak _U_dyn_info_list_addr + if (!_U_dyn_info_list_addr) + return -UNW_ENOINFO; +#endif + // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. + *dyn_info_list_addr = _U_dyn_info_list_addr (); return 0; } @@ -75,14 +74,44 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, static int mem_validate_pipe[2] = {-1, -1}; +#ifdef HAVE_PIPE2 +static inline void +do_pipe2 (int pipefd[2]) +{ + pipe2 (pipefd, O_CLOEXEC | O_NONBLOCK); +} +#else +static inline void +set_pipe_flags (int fd) +{ + int fd_flags = fcntl (fd, F_GETFD, 0); + int status_flags = fcntl (fd, F_GETFL, 0); + + fd_flags |= FD_CLOEXEC; + fcntl (fd, F_SETFD, fd_flags); + + status_flags |= O_NONBLOCK; + fcntl (fd, F_SETFL, status_flags); +} + +static inline void +do_pipe2 (int pipefd[2]) +{ + pipe (pipefd); + set_pipe_flags(pipefd[0]); + set_pipe_flags(pipefd[1]); +} +#endif + static inline void open_pipe (void) { - /* ignore errors for closing invalid fd's */ - close (mem_validate_pipe[0]); - close (mem_validate_pipe[1]); + if (mem_validate_pipe[0] != -1) + close (mem_validate_pipe[0]); + if (mem_validate_pipe[1] != -1) + close (mem_validate_pipe[1]); - pipe2 (mem_validate_pipe, O_CLOEXEC | O_NONBLOCK); + do_pipe2 (mem_validate_pipe); } ALWAYS_INLINE @@ -131,20 +160,14 @@ static int msync_validate (void *addr, size_t len) static int mincore_validate (void *addr, size_t len) { unsigned char mvec[2]; /* Unaligned access may cross page boundary */ - size_t i; /* mincore could fail with EAGAIN but we conservatively return -1 instead of looping. */ - if (mincore (addr, len, mvec) != 0) + if (mincore (addr, len, (char *)mvec) != 0) { return -1; } - for (i = 0; i < (len + PAGE_SIZE - 1) / PAGE_SIZE; i++) - { - if (!(mvec[i] & 1)) return -1; - } - return write_validate (addr); } #endif @@ -163,9 +186,9 @@ tdep_init_mem_validate (void) unw_word_t addr = PAGE_START((unw_word_t)&present); unsigned char mvec[1]; int ret; - while ((ret = mincore ((void*)addr, PAGE_SIZE, mvec)) == -1 && + while ((ret = mincore ((void*)addr, PAGE_SIZE, (char *)mvec)) == -1 && errno == EAGAIN) {} - if (ret == 0 && (mvec[0] & 1)) + if (ret == 0) { Debug(1, "using mincore to validate memory\n"); mem_validate_func = mincore_validate; @@ -180,13 +203,93 @@ tdep_init_mem_validate (void) /* Cache of already validated addresses */ #define NLGA 4 -static unw_word_t last_good_addr[NLGA]; -static int lga_victim; +#if defined(HAVE___THREAD) && HAVE___THREAD +// thread-local variant +static __thread unw_word_t last_good_addr[NLGA]; +static __thread int lga_victim; static int -validate_mem (unw_word_t addr) +is_cached_valid_mem(unw_word_t addr) +{ + int i; + for (i = 0; i < NLGA; i++) + { + if (addr == last_good_addr[i]) + return 1; + } + return 0; +} + +static void +cache_valid_mem(unw_word_t addr) +{ + int i, victim; + victim = lga_victim; + for (i = 0; i < NLGA; i++) { + if (last_good_addr[victim] == 0) { + last_good_addr[victim] = addr; + return; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + last_good_addr[victim] = addr; + victim = (victim + 1) % NLGA; + lga_victim = victim; +} + +#elif HAVE_ATOMIC_OPS_H +// global, thread safe variant +static AO_T last_good_addr[NLGA]; +static AO_T lga_victim; + +static int +is_cached_valid_mem(unw_word_t addr) +{ + int i; + for (i = 0; i < NLGA; i++) + { + if (addr == AO_load(&last_good_addr[i])) + return 1; + } + return 0; +} + +static void +cache_valid_mem(unw_word_t addr) { int i, victim; + victim = AO_load(&lga_victim); + for (i = 0; i < NLGA; i++) { + if (AO_compare_and_swap(&last_good_addr[victim], 0, addr)) { + return; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + AO_store(&last_good_addr[victim], addr); + victim = (victim + 1) % NLGA; + AO_store(&lga_victim, victim); +} +#else +// disabled, no cache +static int +is_cached_valid_mem(unw_word_t addr UNUSED) +{ + return 0; +} + +static void +cache_valid_mem(unw_word_t addr UNUSED) +{ +} +#endif + +static int +validate_mem (unw_word_t addr) +{ size_t len; if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) @@ -199,28 +302,13 @@ validate_mem (unw_word_t addr) if (addr == 0) return -1; - for (i = 0; i < NLGA; i++) - { - if (last_good_addr[i] && (addr == last_good_addr[i])) - return 0; - } + if (is_cached_valid_mem(addr)) + return 0; if (mem_validate_func ((void *) addr, len) == -1) return -1; - victim = lga_victim; - for (i = 0; i < NLGA; i++) { - if (!last_good_addr[victim]) { - last_good_addr[victim++] = addr; - return 0; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - last_good_addr[victim] = addr; - victim = (victim + 1) % NLGA; - lga_victim = victim; + cache_valid_mem(addr); return 0; } @@ -334,9 +422,6 @@ x86_64_local_addr_space_init (void) local_addr_space.acc.resume = x86_64_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; unw_flush_cache (&local_addr_space, 0, 0); - - memset (last_good_addr, 0, sizeof (unw_word_t) * NLGA); - lga_victim = 0; } #endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c index 5eaead0f840bb..12a9e3e4c96aa 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c @@ -43,7 +43,7 @@ unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_i { struct cursor *c = (struct cursor *) cursor; - if (unlikely (!tdep_init_done)) + if (unlikely (!atomic_read(&tdep_init_done))) tdep_init (); Debug (1, "(cursor=%p)\n", c); diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c index efd61d64d4b8f..f411b23331782 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c @@ -36,7 +36,7 @@ unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) #else /* !UNW_LOCAL_ONLY */ struct cursor *c = (struct cursor *) cursor; - if (!tdep_init_done) + if (!atomic_read(&tdep_init_done)) tdep_init (); Debug (1, "(cursor=%p)\n", c); diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c new file mode 100644 index 0000000000000..75258d61d8755 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c @@ -0,0 +1,133 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2002-2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + + Modified for x86_64 by Max Asbock + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" +#include "ucontext_i.h" + +#include + +struct sigframe { + uint64_t signo; + uint64_t sip; +}; + +int +unw_is_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + + c->sigcontext_format = (c->dwarf.ip == (unw_word_t)-1) ? + X86_64_SCF_SOLARIS_SIGFRAME : X86_64_SCF_NONE; + + return (c->sigcontext_format); +} + +HIDDEN int +x86_64_handle_signal_frame (unw_cursor_t *cursor) +{ + struct cursor *c = (struct cursor *) cursor; + unw_word_t ucontext = c->dwarf.cfa + sizeof (struct sigframe); + + if (c->sigcontext_format != X86_64_SCF_SOLARIS_SIGFRAME) + return -UNW_EBADFRAME; + + c->sigcontext_addr = c->dwarf.cfa; + + Debug(1, "signal frame cfa = %lx ucontext = %lx\n", + (uint64_t)c->dwarf.cfa, (uint64_t)ucontext); + + struct dwarf_loc rsp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); + int ret = dwarf_get (&c->dwarf, rsp_loc, &c->dwarf.cfa); + + if (ret < 0) + { + Debug (2, "return %d\n", ret); + return ret; + } + + c->dwarf.loc[RAX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RAX, 0); + c->dwarf.loc[RDX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDX, 0); + c->dwarf.loc[RCX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RCX, 0); + c->dwarf.loc[RBX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBX, 0); + c->dwarf.loc[RSI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSI, 0); + c->dwarf.loc[RDI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDI, 0); + c->dwarf.loc[RBP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0); + c->dwarf.loc[RSP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); + c->dwarf.loc[ R8] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); + c->dwarf.loc[ R9] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); + c->dwarf.loc[R10] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); + c->dwarf.loc[R11] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); + c->dwarf.loc[R12] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); + c->dwarf.loc[R13] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); + c->dwarf.loc[R14] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); + c->dwarf.loc[R15] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); + c->dwarf.loc[RIP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0); + + c->dwarf.use_prev_instr = 1; + return 0; +} + +#ifndef UNW_REMOTE_ONLY +HIDDEN void * +x86_64_r_uc_addr (ucontext_t *uc, int reg) +{ + /* NOTE: common_init() in init.h inlines these for fast path access. */ + void *addr; + + switch (reg) + { + case UNW_X86_64_R8: addr = &uc->uc_mcontext.gregs[REG_R8]; break; + case UNW_X86_64_R9: addr = &uc->uc_mcontext.gregs[REG_R9]; break; + case UNW_X86_64_R10: addr = &uc->uc_mcontext.gregs[REG_R10]; break; + case UNW_X86_64_R11: addr = &uc->uc_mcontext.gregs[REG_R11]; break; + case UNW_X86_64_R12: addr = &uc->uc_mcontext.gregs[REG_R12]; break; + case UNW_X86_64_R13: addr = &uc->uc_mcontext.gregs[REG_R13]; break; + case UNW_X86_64_R14: addr = &uc->uc_mcontext.gregs[REG_R14]; break; + case UNW_X86_64_R15: addr = &uc->uc_mcontext.gregs[REG_R15]; break; + case UNW_X86_64_RDI: addr = &uc->uc_mcontext.gregs[REG_RDI]; break; + case UNW_X86_64_RSI: addr = &uc->uc_mcontext.gregs[REG_RSI]; break; + case UNW_X86_64_RBP: addr = &uc->uc_mcontext.gregs[REG_RBP]; break; + case UNW_X86_64_RBX: addr = &uc->uc_mcontext.gregs[REG_RBX]; break; + case UNW_X86_64_RDX: addr = &uc->uc_mcontext.gregs[REG_RDX]; break; + case UNW_X86_64_RAX: addr = &uc->uc_mcontext.gregs[REG_RAX]; break; + case UNW_X86_64_RCX: addr = &uc->uc_mcontext.gregs[REG_RCX]; break; + case UNW_X86_64_RSP: addr = &uc->uc_mcontext.gregs[REG_RSP]; break; + case UNW_X86_64_RIP: addr = &uc->uc_mcontext.gregs[REG_RIP]; break; + + default: + addr = NULL; + } + return addr; +} + +HIDDEN NORETURN void +x86_64_sigreturn (unw_cursor_t *cursor) +{ + abort(); +} + +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c index 2c7bc312e28c0..2a44f873e9edf 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c @@ -110,10 +110,10 @@ tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) } else if (f->frame_type == UNW_X86_64_FRAME_ALIGNED) { - Debug (4, " aligned frame, offset %li\n", f->cfa_reg_offset); + Debug (4, " aligned frame, offset %i\n", f->cfa_reg_offset); } - /* PLT and guessed RBP-walked frames are handled in unw_step(). */ - else + else { Debug (4, " unusual frame\n"); + } } diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c index 10498170ac76d..d4831197cb39e 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c @@ -104,6 +104,7 @@ unw_step (unw_cursor_t *cursor) via CALLQ. Try this for all non-signal trampoline code. */ + unw_word_t invalid_prev_rip = 0; unw_word_t prev_ip = c->dwarf.ip, prev_cfa = c->dwarf.cfa; struct dwarf_loc rbp_loc, rsp_loc, rip_loc; @@ -149,7 +150,10 @@ unw_step (unw_cursor_t *cursor) return ret; } - if (!rbp) + unw_word_t not_used; + invalid_prev_rip = dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, prev_ip), ¬_used); + + if (!rbp && invalid_prev_rip == 0) { /* Looks like we may have reached the end of the call-chain. */ rbp_loc = DWARF_NULL_LOC; @@ -158,38 +162,90 @@ unw_step (unw_cursor_t *cursor) } else { - unw_word_t rbp1 = 0; - rbp_loc = DWARF_LOC(rbp, 0); - rsp_loc = DWARF_NULL_LOC; - rip_loc = DWARF_LOC (rbp + 8, 0); - ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1); - Debug (1, "[RBP=0x%lx] = 0x%lx (cfa = 0x%lx) -> 0x%lx\n", - (unsigned long) DWARF_GET_LOC (c->dwarf.loc[RBP]), - rbp, c->dwarf.cfa, rbp1); - - /* Heuristic to determine incorrect guess. For RBP to be a - valid frame it needs to be above current CFA, but don't - let it go more than a little. Note that we can't deduce - anything about new RBP (rbp1) since it may not be a frame - pointer in the frame above. Just check we get the value. */ - if (ret < 0 - || rbp < c->dwarf.cfa - || (rbp - c->dwarf.cfa) > 0x4000) + /* + * Check if previous RIP was invalid + * This could happen if a bad function pointer was + * followed and so the stack wasn't updated by the + * preamble + */ + int rip_fixup_success = 0; + if (invalid_prev_rip != 0) { - rip_loc = DWARF_NULL_LOC; - rbp_loc = DWARF_NULL_LOC; - } + Debug (2, "Previous RIP 0x%lx was invalid, attempting fixup\n", prev_ip); + unw_word_t rsp; + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RSP], &rsp); - c->frame_info.frame_type = UNW_X86_64_FRAME_GUESSED; - c->frame_info.cfa_reg_rsp = 0; - c->frame_info.cfa_reg_offset = 16; - c->frame_info.rbp_cfa_offset = -16; - c->dwarf.cfa += 16; - } + /*Test to see if what we think is the previous RIP is valid*/ + unw_word_t new_ip = 0; + if (dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, rsp), &new_ip) == 0) + { + Debug (2, "RSP 0x%lx looks valid\n", rsp); + if ((ret = dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip), ¬_used)) == 0) + { + Debug (2, "new_ip 0x%lx looks valid\n", new_ip); + rip_fixup_success = 1; + c->frame_info.cfa_reg_offset = 8; + c->frame_info.cfa_reg_rsp = 1; + c->frame_info.rbp_cfa_offset = -1; + c->frame_info.rsp_cfa_offset = -1; + c->frame_info.frame_type = UNW_X86_64_FRAME_OTHER; + /* + * The call should have pushed RIP to the stack + * and since there was no preamble RSP hasn't been + * touched so RIP should be at RSP. + */ + c->dwarf.cfa += 8; + /* Optimised x64 binaries don't use RBP it seems? */ + rbp_loc = DWARF_LOC (rbp, 0); + rsp_loc = DWARF_LOC (rsp, 0); + rip_loc = DWARF_LOC (rsp, 0); + } + else + Debug (2, "new_ip 0x%lx dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip), ¬_used) != 0\n", new_ip); + } + else + Debug (2, "rsp 0x%lx dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, rsp), &new_ip) != 0\n", rsp); + } + /* + * If the previous rip we found on the stack didn't look valid fall back + * to the previous method for finding a valid stack frame + */ + if (!rip_fixup_success) + { + Debug (2, "RIP fixup didn't work, falling back\n"); + unw_word_t rbp1 = 0; + rbp_loc = DWARF_LOC(rbp, 0); + rsp_loc = DWARF_NULL_LOC; + rip_loc = DWARF_LOC (rbp + 8, 0); + ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1); + Debug (1, "[RBP=0x%lx] = 0x%lx (cfa = 0x%lx) -> 0x%lx\n", + (unsigned long) DWARF_GET_LOC (c->dwarf.loc[RBP]), + rbp, c->dwarf.cfa, rbp1); + + /* Heuristic to determine incorrect guess. For RBP to be a + valid frame it needs to be above current CFA, but don't + let it go more than a little. Note that we can't deduce + anything about new RBP (rbp1) since it may not be a frame + pointer in the frame above. Just check we get the value. */ + if (ret < 0 + || rbp < c->dwarf.cfa + || (rbp - c->dwarf.cfa) > 0x4000) + { + rip_loc = DWARF_NULL_LOC; + rbp_loc = DWARF_NULL_LOC; + } + c->frame_info.frame_type = UNW_X86_64_FRAME_GUESSED; + c->frame_info.cfa_reg_rsp = 0; + c->frame_info.cfa_reg_offset = 16; + c->frame_info.rbp_cfa_offset = -16; + c->dwarf.cfa += 16; + + } + } /* Mark all registers unsaved */ for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; + c->dwarf.loc[i] = DWARF_NULL_LOC; c->dwarf.loc[RBP] = rbp_loc; c->dwarf.loc[RSP] = rsp_loc; @@ -197,7 +253,7 @@ unw_step (unw_cursor_t *cursor) c->dwarf.use_prev_instr = 1; } - if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) + if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP]) && invalid_prev_rip == 0) { ret = 0; Debug (2, "NULL %%rbp loc, returning %d\n", ret); @@ -214,6 +270,13 @@ unw_step (unw_cursor_t *cursor) Debug (2, "returning %d\n", ret); return ret; } +#if __sun + if (c->dwarf.ip == 0) + { + Debug (2, "returning 0\n"); + return ret; + } +#endif ret = 1; } else diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c index 741227105e184..824527f9beaac 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c @@ -540,7 +540,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) break; /* Record this address in stack trace. We skipped the first address. */ - buffer[depth++] = (void *) (rip - d->use_prev_instr); + buffer[depth++] = (void *) rip; } #if UNW_DEBUG diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c new file mode 100644 index 0000000000000..be64b2c695b89 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gos-solaris.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S index 7a8b5664bdaeb..e1450719b7da1 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S @@ -57,11 +57,13 @@ _Ux86_64_getcontext: movq %rax, UC_MCONTEXT_GREGS_RAX(%rdi) movq %rcx, UC_MCONTEXT_GREGS_RCX(%rdi) -#if defined __linux__ +#if defined __linux__ || defined __sun /* Save fp state (not needed, except for setcontext not restoring garbage). */ leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8 +#ifdef UC_MCONTEXT_FPREGS_PTR movq %r8, UC_MCONTEXT_FPREGS_PTR(%rdi) +#endif // UC_MCONTEXT_FPREGS_PTR fnstenv (%r8) stmxcsr FPREGS_OFFSET_MXCSR(%r8) #elif defined __FreeBSD__ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S index 358217defbaf3..17e5ae12032aa 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S @@ -37,9 +37,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ _Ux86_64_setcontext: -#if defined __linux__ +#if defined __linux__ || defined __sun /* restore fp state */ +#ifdef UC_MCONTEXT_FPREGS_PTR mov UC_MCONTEXT_FPREGS_PTR(%rdi),%r8 +#else // UC_MCONTEXT_FPREGS_PTR + leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8 +#endif // UC_MCONTEXT_FPREGS_PTR fldenv (%r8) ldmxcsr FPREGS_OFFSET_MXCSR(%r8) #elif defined __FreeBSD__ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h b/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h index aded941d053f7..e886c948453ce 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h @@ -78,5 +78,25 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define UC_MCONTEXT_FPOWNED_FPU 0x20001 #define UC_MCONTEXT_FPFMT_XMM 0x10002 #define UC_MCONTEXT_MC_LEN_VAL 0x320 +#elif defined __sun +#define UC_MCONTEXT_GREGS_R8 0x78 +#define UC_MCONTEXT_GREGS_R9 0x70 +#define UC_MCONTEXT_GREGS_R10 0x68 +#define UC_MCONTEXT_GREGS_R11 0x60 +#define UC_MCONTEXT_GREGS_R12 0x58 +#define UC_MCONTEXT_GREGS_R13 0x50 +#define UC_MCONTEXT_GREGS_R14 0x48 +#define UC_MCONTEXT_GREGS_R15 0x40 +#define UC_MCONTEXT_GREGS_RDI 0x80 +#define UC_MCONTEXT_GREGS_RSI 0x88 +#define UC_MCONTEXT_GREGS_RBP 0x90 +#define UC_MCONTEXT_GREGS_RBX 0x98 +#define UC_MCONTEXT_GREGS_RDX 0xa0 +#define UC_MCONTEXT_GREGS_RAX 0xb0 +#define UC_MCONTEXT_GREGS_RCX 0xa8 +#define UC_MCONTEXT_GREGS_RSP 0xe0 +#define UC_MCONTEXT_GREGS_RIP 0xc8 +#define UC_MCONTEXT_FPREGS_MEM 0x120 +#define FPREGS_OFFSET_MXCSR 0x18 #endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c index beae2a3ccd9b9..d5b484478705c 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c @@ -176,7 +176,7 @@ sighandler (int signal, void *siginfo UNUSED, void *context) { printf ("sighandler: got signal %d, sp=%p", signal, &sp); #if UNW_TARGET_IA64 -# if defined(__linux__) +# if defined(__linux__) || defined __sun printf (" @ %lx", uc->uc_mcontext.sc_ip); # else { @@ -189,13 +189,13 @@ sighandler (int signal, void *siginfo UNUSED, void *context) } # endif #elif UNW_TARGET_X86 -#if defined __linux__ +#if defined __linux__ || defined __sun printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_EIP]); #elif defined __FreeBSD__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip); #endif #elif UNW_TARGET_X86_64 -#if defined __linux__ +#if defined __linux__ || defined __sun printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]); #elif defined __FreeBSD__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip); diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c index fc1f646eac6d0..48667bb9f4df3 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c @@ -207,7 +207,7 @@ sighandler (int signal, void *siginfo UNUSED, void *context) printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip); #endif #elif UNW_TARGET_X86_64 -#if defined __linux__ +#if defined __linux__ || defined __sun printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]); #elif defined __FreeBSD__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip); diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c b/src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c new file mode 100644 index 0000000000000..209f87131248d --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c @@ -0,0 +1,68 @@ +#include +#include +#include + +#include + +static int verbose; +static int nerrors; + +#define panic(args...) \ + do { printf (args); ++nerrors; } while (0) + +// Assembly routine which sets up the stack for the test then calls another one +// which clobbers the stack, and which in turn calls recover_register below +extern int64_t DW_CFA_expression_testcase(int64_t regnum, int64_t height); + +// recover_register is called by the assembly routines. It returns the value of +// a register at a specified height from the inner-most frame. The return value +// is propagated back through the assembly routines to the testcase. +extern int64_t recover_register(int64_t regnum, int64_t height) +{ + // Initialize cursor to current frame + int rc, i; + unw_cursor_t cursor; + unw_context_t context; + unw_getcontext(&context); + unw_init_local(&cursor, &context); + // Unwind frames until required height from inner-most frame (i.e. this one) + for (i = 0; i < height; ++i) + { + rc = unw_step(&cursor); + if (rc < 0) + panic("%s: unw_step failed on step %d with return code %d", __FUNCTION__, i, rc); + else if (rc == 0) + panic("%s: unw_step failed to reach the end of the stack", __FUNCTION__); + unw_word_t pc; + rc = unw_get_reg(&cursor, UNW_REG_IP, &pc); + if (rc < 0 || pc == 0) + panic("%s: unw_get_reg failed to locate the program counter", __FUNCTION__); + } + // We're now at the required height, extract register + uint64_t value; + if ((rc = unw_get_reg(&cursor, (unw_regnum_t) regnum, &value)) != 0) + panic("%s: unw_get_reg failed to retrieve register %lu", __FUNCTION__, regnum); + return value; +} + +int +main (int argc, char **argv) +{ + if (argc > 1) + verbose = 1; + + if (DW_CFA_expression_testcase(12, 1) != 0) + panic("r12 should be clobbered at height 1 (DW_CFA_expression_inner)"); + if (DW_CFA_expression_testcase(12, 2) != 111222333) + panic("r12 should be restored at height 2 (DW_CFA_expression_testcase)"); + + if (nerrors > 0) + { + fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); + exit (-1); + } + + if (verbose) + printf ("SUCCESS.\n"); + return 0; +} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c index 1cacb9f028f15..e5127b90628fc 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c @@ -35,6 +35,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include +#include +#include #define panic(args...) \ { fprintf (stderr, args); exit (-1); } diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c b/src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c new file mode 100644 index 0000000000000..07e916e60a6ac --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if !defined(UNW_REMOTE_ONLY) +#include "Gx64-test-dwarf-expressions.c" +#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Makefile.am b/src/coreclr/src/pal/src/libunwind/tests/Makefile.am index 4b0b9db7d1699..61d1bf875a8c8 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/Makefile.am +++ b/src/coreclr/src/pal/src/libunwind/tests/Makefile.am @@ -37,7 +37,11 @@ if ARCH_PPC64 if USE_ALTIVEC noinst_PROGRAMS_arch += ppc64-test-altivec endif #USE_ALTIVEC -endif #ARCH_PPC64 +else #!ARCH_PPC64 +if ARCH_X86_64 + check_PROGRAMS_arch += Gx64-test-dwarf-expressions Lx64-test-dwarf-expressions x64-unwind-badjmp-signal-frame +endif #ARCH X86_64 +endif #!ARCH_PPC64 endif #!ARCH_IA64 check_PROGRAMS_cdep += Gtest-bt Ltest-bt Gtest-exc Ltest-exc \ Gtest-init Ltest-init \ @@ -139,12 +143,21 @@ Gia64_test_nat_SOURCES = Gia64-test-nat.c ia64-test-nat-asm.S ia64_test_dyn1_SOURCES = ia64-test-dyn1.c ia64-dyn-asm.S flush-cache.S \ flush-cache.h ppc64_test_altivec_SOURCES = ppc64-test-altivec.c ppc64-test-altivec-utils.c + + +Gx64_test_dwarf_expressions_SOURCES = Gx64-test-dwarf-expressions.c \ + x64-test-dwarf-expressions.S +Lx64_test_dwarf_expressions_SOURCES = Lx64-test-dwarf-expressions.c \ + x64-test-dwarf-expressions.S + + Gtest_init_SOURCES = Gtest-init.cxx Ltest_init_SOURCES = Ltest-init.cxx Ltest_cxx_exceptions_SOURCES = Ltest-cxx-exceptions.cxx Ltest_init_local_signal_SOURCES = Ltest-init-local-signal.c Ltest-init-local-signal-lib.c +x64_unwind_badjmp_signal_frame_SOURCES = x64-unwind-badjmp-signal-frame.c Gtest_dyn1_SOURCES = Gtest-dyn1.c flush-cache.S flush-cache.h Ltest_dyn1_SOURCES = Ltest-dyn1.c flush-cache.S flush-cache.h test_static_link_SOURCES = test-static-link-loc.c test-static-link-gen.c @@ -191,6 +204,7 @@ Ltest_init_local_signal_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_bt_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_concurrent_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -lpthread +x64_unwind_badjmp_signal_frame_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_dyn1_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_exc_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_init_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) @BACKTRACELIB@ @@ -232,3 +246,6 @@ Lia64_test_readonly_LDADD = $(LIBUNWIND_local) ia64_test_dyn1_LDADD = $(LIBUNWIND) ia64_test_sig_LDADD = $(LIBUNWIND) ppc64_test_altivec_LDADD = $(LIBUNWIND) + +Gx64_test_dwarf_expressions_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) +Lx64_test_dwarf_expressions_LDADD = $(LIBUNWIND_local) diff --git a/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in b/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in index 6d0081732da00..f43bca263bc35 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in +++ b/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in @@ -85,6 +85,11 @@ filter_misc () { ignore _ftext ignore _gp fi + + if [ ${os} == "solaris2.11" ]; then + ignore _PROCEDURE_LINKAGE_TABLE_ + ignore _etext + fi } check_local_unw_abi () { @@ -121,7 +126,7 @@ check_local_unw_abi () { match _U_dyn_register match unw_backtrace - match backtrace + @CONFIG_WEAK_BACKTRACE_TRUE@match backtrace case ${plat} in arm) @@ -176,6 +181,14 @@ check_local_unw_abi () { match _U${plat}_get_exe_image_path match ${plat}_lock ;; + s390x) + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_is_fpreg + match _UL${plat}_dwarf_search_unwind_table + match _UL${plat}_dwarf_find_unwind_table + match _U${plat}_setcontext + ;; *) match _U${plat}_is_fpreg @@ -276,6 +289,13 @@ check_generic_unw_abi () { match _U${plat}_local_addr_space_init match ${plat}_lock ;; + s390x) + match _U${plat}_is_fpreg + match _U${plat}_get_elf_image + match _U${plat}_get_exe_image_path + match _U${plat}_dwarf_search_unwind_table + match _U${plat}_dwarf_find_unwind_table + ;; *) match _U${plat}_is_fpreg match _U${plat}_dwarf_search_unwind_table diff --git a/src/coreclr/src/pal/src/libunwind/tests/crasher.c b/src/coreclr/src/pal/src/libunwind/tests/crasher.c index 24c78054c9478..bb99e339c2639 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/crasher.c +++ b/src/coreclr/src/pal/src/libunwind/tests/crasher.c @@ -87,8 +87,13 @@ write_maps(char *fname) #endif #ifdef __GNUC__ +#ifndef __clang__ +// Gcc >= 8 became too good at inlining aliase c into b when using -O2 or -O3, +// so force -O1 in all cases, otherwise a frame will be missing in the tests. +#pragma GCC optimize "-O1" +#endif int c(int x) NOINLINE ALIAS(b); -#define compiler_barrier() asm volatile(""); +#define compiler_barrier() __asm__ __volatile__ (""); #else int c(int x); #define compiler_barrier() diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c b/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c index 53498237c2fd0..fb06a38effa10 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c +++ b/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c @@ -57,7 +57,11 @@ #include /* For SIGSEGV handler code */ -#include +#if HAVE_EXECINFO_H +# include +#else + extern int backtrace (void **, int); +#endif #include #include @@ -242,7 +246,7 @@ void handle_sigsegv(int sig, siginfo_t *info, void *ucontext) void *array[50]; int size; size = backtrace(array, 50); -#ifdef __linux__ +#if defined __linux__ && HAVE_EXECINFO_H backtrace_symbols_fd(array, size, 2); #endif } diff --git a/src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S b/src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S new file mode 100644 index 0000000000000..f275625df1006 --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S @@ -0,0 +1,78 @@ +.global DW_CFA_expression_testcase + +.extern recover_register + +.text + +# CFI expressions were added in DWARF v3 to allow compilers to specify memory +# locations or register values using DWARF programs. These programs are simple +# stack-based operations which allow the compiler to encode integer mathematics +# and other complex logic. CFI expressions are therefore more powerful than the +# conventional register + offset schemes. +# +# These tests capture a bug we have fixed in libunwind. CFI expression programs +# always start with the current CFA pushed onto the stack. This file contains a +# pair of routines which test CFI expression parsing. Specifically they test +# DW_CFA_expression logic, which uses DWARF expressions to compute the address +# where a non-volatile register was stored. +# +# Main calls DW_CFA_expression_testcase, which sets up known state in a +# non-volatile (caller-saved) register. We use r12 for this purpose. After this +# DW_CFA_expression_testcase then calls DW_CFA_expression_inner, which clobbers +# r12 after stashing its value on the stack. This routine contains a DWARF3 CFI +# expression to restore the value of r12 on unwind which should allow libunwind +# to recover clobbered state. DW_CFA_expression_inner calls recover_register to +# retrieve the cached register value. This function recovers the register value +# by using libunwind to unwind the stack through DW_CFA_expression_inner and up +# to the call site in DW_CFA_expression_testcase. If our expression is correct, +# libunwind will be able to restore r12 from the stack. +# +# BE CAREFUL WITH rdi, rsi, rax HERE! The arguments to recover_register are +# passed in via rdi, rsi and I just let them flow through unchanged. Similarly +# RAX flows back unchanged. Adding any function calls to the below may clobber +# these registers and cause this test to fail mysteriously. + + +######################################################## +# Test: Restoring a register using a DW_CFA_expression # +# which uses implicit CFA pushed onto stack. # +######################################################## + +.type DW_CFA_expression_testcase STT_FUNC +DW_CFA_expression_testcase: + .cfi_startproc + push %r12 + .cfi_adjust_cfa_offset 8 + # Move our sentinel (known) value into non-volatile (Callee-saved) r12 + mov $111222333, %r12 + .cfi_rel_offset %r12, 0 + call DW_CFA_expression_inner + pop %r12 + .cfi_restore %r12 + .cfi_adjust_cfa_offset -8 + ret + .cfi_endproc +.size DW_CFA_expression_testcase,.-DW_CFA_expression_testcase + +.type DW_CFA_expression_inner STT_FUNC +DW_CFA_expression_inner: + .cfi_startproc + push %r12 + .cfi_adjust_cfa_offset 8 + # !! IMPORTANT BIT !! The test is all about how we parse the following bytes. + # Now we use an expression to describe where our sentinel value is stored: + # DW_CFA_expression(0x10), r12(0x0c), Length(0x02), (preamble) + # DW_OP_lit16(0x40), DW_OP_minus(0x1c) (instructions) + # Parsing starts with the CFA on the stack, then pushes 16, then does a minus + # which is eqivalent to a=pop(), b=pop(), push(b-a), leaving us with a value + # of cfa-16 (cfa points at old rsp, cfa-8 is our rip, so we stored r12 at + # cfa-16). + xor %r12, %r12 # Trash r12 + .cfi_escape 0x10, 0x0c, 0x2, 0x40, 0x1c # DW_CFA_expression for recovery + call recover_register + pop %r12 + .cfi_restore %r12 + .cfi_adjust_cfa_offset -8 + ret + .cfi_endproc +.size DW_CFA_expression_inner,.-DW_CFA_expression_inner diff --git a/src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c b/src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c new file mode 100644 index 0000000000000..c7b7cf7335a8b --- /dev/null +++ b/src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c @@ -0,0 +1,124 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2019 Brock York + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_SYS_PTRACE_H +#include +#endif + +#define UNW_LOCAL_ONLY +#include + +/* + * unwind in the signal handler checking the backtrace is correct + * after a bad jump. + */ +void handle_sigsegv(int signal, siginfo_t *info, void *ucontext) +{ + /* + * 0 = success + * !0 = general failure + * 77 = test skipped + * 99 = complete failure + */ + int test_status = 0; + unw_cursor_t cursor; unw_context_t uc; + unw_word_t ip, sp, offset; + char name[1000]; + int found_signal_frame = 0; + int i = 0; + char *names[] = { + "", + "main", + }; + int names_count = sizeof(names) / sizeof(*names); + + unw_getcontext(&uc); + unw_init_local(&cursor, &uc); + + while (unw_step(&cursor) > 0 && !test_status) + { + if (unw_is_signal_frame(&cursor)) + { + found_signal_frame = 1; + } + if (found_signal_frame) + { + unw_get_reg(&cursor, UNW_REG_IP, &ip); + unw_get_reg(&cursor, UNW_REG_SP, &sp); + memset(name, 0, sizeof(char) * 1000); + unw_get_proc_name(&cursor, name, sizeof(char) * 1000, &offset); + printf("ip = %lx, sp = %lx offset = %lx name = %s\n", (long) ip, (long) sp, (long) offset, name); + if (i < names_count) + { + if (strcmp(names[i], name) != 0) + { + test_status = 1; + printf("frame %s doesn't match expected frame %s\n", name, names[i]); + } + else + { + i += 1; + } + } + } + } + + if (i != names_count) //Make sure we found all the frames! + { + printf("Failed to find all frames i:%d != names_count:%d\n", i, names_count); + test_status = 1; + } + + /*return test_status to test harness*/ + exit(test_status); +} + +void (*invalid_function)() = (void*)1; + +int main(int argc, char *argv[]) +{ + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handle_sigsegv; + sa.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &sa, NULL); + + invalid_function(); + + /* + * 99 is the hard error exit status for automake tests: + * https://www.gnu.org/software/automake/manual/html_node/Scripts_002dbased-Testsuites.html#Scripts_002dbased-Testsuites + * If we dont end up in the signal handler something went horribly wrong. + */ + return 99; +} From 1c048bdfc7b7e4dc9b6d8170b63052695b1d8459 Mon Sep 17 00:00:00 2001 From: Youssef Victor <31348972+Youssef1313@users.noreply.github.com> Date: Tue, 19 May 2020 15:39:51 +0200 Subject: [PATCH 271/420] Checking strings against length seem to have better perf (#36443) * Chckecing strings against length seem to have better perf * Apply suggestions from code review Co-authored-by: Miha Zupan Co-authored-by: Ben Adams * Apply suggestions from code review Co-authored-by: Ben Adams * Update src/libraries/System.Drawing.Common/src/System/Drawing/BitmapSelector.cs Co-authored-by: Ben Adams * Apply suggestions from code review * Update src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameFormatter.cs * fix build error * Update SmtpClient.cs * Update AssemblyNameFormatter.cs * Update LoggingEventSource.cs * Fix build error * Apply suggestions from code review * Update src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/SyndicationContent.cs * Fix build error * Apply suggestions from code review Co-authored-by: Miha Zupan Co-authored-by: Ben Adams --- .../Interop/Linux/cgroups/Interop.cgroups.cs | 2 +- .../System/Diagnostics/PerformanceCounter.cs | 4 ++-- .../Diagnostics/PerformanceCounterLib.cs | 2 +- .../src/System/Diagnostics/Process.Windows.cs | 2 +- .../src/System/Drawing/BitmapSelector.cs | 2 +- .../IO/IsolatedStorage/IsolatedStorageFile.cs | 22 +++++++++---------- .../InternalRelationshipCollection.cs | 2 +- .../Packaging/PackUriHelper.PackUriScheme.cs | 4 ++-- .../src/System/IO/Packaging/PackUriHelper.cs | 6 ++--- .../src/System/IO/Packaging/ZipPackage.cs | 2 +- .../src/System/Net/Mail/Attachment.cs | 8 +++---- .../src/System/Net/Mail/MailAddress.cs | 2 +- .../System/Net/Mail/MailAddressCollection.cs | 2 +- .../src/System/Net/Mail/MailMessage.cs | 4 ++-- .../src/System/Net/Mail/MailPriority.cs | 4 ++-- .../src/System/Net/Mail/SmtpClient.cs | 2 +- .../src/System/Net/Mime/ContentDisposition.cs | 2 +- .../src/System/Net/Mime/ContentType.cs | 8 +++---- .../src/System/Net/Mime/HeaderCollection.cs | 14 ++++++------ .../src/System/Net/FtpControlStream.cs | 2 +- .../Reflection/AssemblyNameFormatter.cs | 2 +- .../Serialization/Json/XmlJsonWriter.cs | 2 +- .../src/System/Xml/Dom/XmlNodeReader.cs | 2 +- .../src/System/Xml/Schema/XmlSchemaSet.cs | 2 +- .../src/System/Runtime/Caching/MemoryCache.cs | 4 ++-- .../Reflection/Emit/ModuleBuilder.Mono.cs | 2 +- .../src/System/Reflection/RuntimeModule.cs | 2 +- .../src/System/RuntimeTypeHandle.cs | 2 +- 28 files changed, 57 insertions(+), 57 deletions(-) diff --git a/src/libraries/Common/src/Interop/Linux/cgroups/Interop.cgroups.cs b/src/libraries/Common/src/Interop/Linux/cgroups/Interop.cgroups.cs index abb7baa63a673..f2417e20881bd 100644 --- a/src/libraries/Common/src/Interop/Linux/cgroups/Interop.cgroups.cs +++ b/src/libraries/Common/src/Interop/Linux/cgroups/Interop.cgroups.cs @@ -348,7 +348,7 @@ internal static bool TryFindCGroupPathForSubsystem(CGroupVersion cgroupVersion, // cgroup v2: Find the first entry that matches the cgroup v2 hierarchy: // 0::$PATH - if ((lineParts[0] == "0") && (lineParts[1] == string.Empty)) + if ((lineParts[0] == "0") && (lineParts[1].Length == 0)) { path = lineParts[2]; return true; diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounter.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounter.cs index f1637f4998c36..37e4b41d98a4f 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounter.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounter.cs @@ -470,9 +470,9 @@ private void InitializeImpl() string currentCategoryName = _categoryName; string currentMachineName = _machineName; - if (currentCategoryName == string.Empty) + if (currentCategoryName.Length == 0) throw new InvalidOperationException(SR.CategoryNameMissing); - if (_counterName == string.Empty) + if (_counterName.Length == 0) throw new InvalidOperationException(SR.CounterNameMissing); if (ReadOnly) diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs index 93ad673af15cb..7facea0fcdd6c 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs @@ -455,7 +455,7 @@ private static void CreateIniFile(string categoryName, string categoryHelp, Coun iniWriter.Write(languageId); iniWriter.Write(HelpSufix); iniWriter.Write("="); - if (categoryHelp == null || categoryHelp == string.Empty) + if (string.IsNullOrEmpty(categoryHelp)) iniWriter.WriteLine(SR.HelpNotAvailable); else iniWriter.WriteLine(categoryHelp); diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs index 998ec9fa03f5c..af85258d6a9ea 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs @@ -536,7 +536,7 @@ private unsafe bool StartWithCreateProcess(ProcessStartInfo startInfo) environmentBlock = GetEnvironmentVariablesBlock(startInfo._environmentVariables!); } string workingDirectory = startInfo.WorkingDirectory; - if (workingDirectory == string.Empty) + if (workingDirectory.Length == 0) workingDirectory = Directory.GetCurrentDirectory(); bool retVal; diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/BitmapSelector.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/BitmapSelector.cs index 06ccdf8e3c9c5..ae11c6e29d640 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/BitmapSelector.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/BitmapSelector.cs @@ -64,7 +64,7 @@ internal static string AppendSuffix(string filePath) /// public static string GetFileName(string originalPath) { - if (Suffix == string.Empty) + if (string.IsNullOrEmpty(Suffix)) return originalPath; string newPath = AppendSuffix(originalPath); diff --git a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs index d7d09f9bf3ff6..1d13427bb6659 100644 --- a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs +++ b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs @@ -262,7 +262,7 @@ public DateTimeOffset GetCreationTime(string path) if (path == null) throw new ArgumentNullException(nameof(path)); - if (path == string.Empty) + if (path.Length == 0) { throw new ArgumentException(SR.Argument_EmptyPath, nameof(path)); } @@ -284,7 +284,7 @@ public DateTimeOffset GetLastAccessTime(string path) if (path == null) throw new ArgumentNullException(nameof(path)); - if (path == string.Empty) + if (path.Length == 0) { throw new ArgumentException(SR.Argument_EmptyPath, nameof(path)); } @@ -306,7 +306,7 @@ public DateTimeOffset GetLastWriteTime(string path) if (path == null) throw new ArgumentNullException(nameof(path)); - if (path == string.Empty) + if (path.Length == 0) { throw new ArgumentException(SR.Argument_EmptyPath, nameof(path)); } @@ -331,12 +331,12 @@ public void CopyFile(string sourceFileName, string destinationFileName) if (destinationFileName == null) throw new ArgumentNullException(nameof(destinationFileName)); - if (sourceFileName == string.Empty) + if (sourceFileName.Length == 0) { throw new ArgumentException(SR.Argument_EmptyPath, nameof(sourceFileName)); } - if (destinationFileName == string.Empty) + if (destinationFileName.Length == 0) { throw new ArgumentException(SR.Argument_EmptyPath, nameof(destinationFileName)); } @@ -352,12 +352,12 @@ public void CopyFile(string sourceFileName, string destinationFileName, bool ove if (destinationFileName == null) throw new ArgumentNullException(nameof(destinationFileName)); - if (sourceFileName == string.Empty) + if (sourceFileName.Length == 0) { throw new ArgumentException(SR.Argument_EmptyPath, nameof(sourceFileName)); } - if (destinationFileName == string.Empty) + if (destinationFileName.Length == 0) { throw new ArgumentException(SR.Argument_EmptyPath, nameof(destinationFileName)); } @@ -393,12 +393,12 @@ public void MoveFile(string sourceFileName, string destinationFileName) if (destinationFileName == null) throw new ArgumentNullException(nameof(destinationFileName)); - if (sourceFileName == string.Empty) + if (sourceFileName.Length == 0) { throw new ArgumentException(SR.Argument_EmptyPath, nameof(sourceFileName)); } - if (destinationFileName == string.Empty) + if (destinationFileName.Length == 0) { throw new ArgumentException(SR.Argument_EmptyPath, nameof(destinationFileName)); } @@ -434,12 +434,12 @@ public void MoveDirectory(string sourceDirectoryName, string destinationDirector if (destinationDirectoryName == null) throw new ArgumentNullException(nameof(destinationDirectoryName)); - if (sourceDirectoryName == string.Empty) + if (sourceDirectoryName.Length == 0) { throw new ArgumentException(SR.Argument_EmptyPath, nameof(sourceDirectoryName)); } - if (destinationDirectoryName == string.Empty) + if (destinationDirectoryName.Length == 0) { throw new ArgumentException(SR.Argument_EmptyPath, nameof(destinationDirectoryName)); } diff --git a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/InternalRelationshipCollection.cs b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/InternalRelationshipCollection.cs index 09413c8a38444..db8cdf81d8b8e 100644 --- a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/InternalRelationshipCollection.cs +++ b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/InternalRelationshipCollection.cs @@ -161,7 +161,7 @@ internal void Flush() internal static void ThrowIfInvalidRelationshipType(string relationshipType) { // Look for empty string or string with just spaces - if (relationshipType.Trim() == string.Empty) + if (string.IsNullOrWhiteSpace(relationshipType)) throw new ArgumentException(SR.InvalidRelationshipType); } diff --git a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.PackUriScheme.cs b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.PackUriScheme.cs index c2c79ee231837..c43ca1ac61cd6 100644 --- a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.PackUriScheme.cs +++ b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.PackUriScheme.cs @@ -79,7 +79,7 @@ public static Uri Create(Uri packageUri, Uri partUri, string fragment) if (fragment != null) { - if (fragment == string.Empty || fragment[0] != '#') + if (fragment.Length == 0 || fragment[0] != '#') throw new ArgumentException(SR.Format(SR.FragmentMustStartWithHash, nameof(fragment))); } @@ -323,7 +323,7 @@ private static PackUriHelper.ValidatedPartUri GetPartUriComponent(Uri packUri) string partName = GetStringForPartUriFromAnyUri(packUri); - if (partName == string.Empty) + if (partName.Length == 0) return null; else return ValidatePartUri(new Uri(partName, UriKind.Relative)); diff --git a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.cs b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.cs index 2b50ad0791ffa..404e5e6fe9e24 100644 --- a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.cs +++ b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/PackUriHelper.cs @@ -49,7 +49,7 @@ public static Uri CreatePartUri(Uri partUri) string partName = GetStringForPartUriFromAnyUri(resolvedUri); - if (partName == string.Empty) + if (partName.Length == 0) throw new ArgumentException(SR.PartUriIsEmpty); ThrowIfPartNameEndsWithSlash(partName); @@ -399,7 +399,7 @@ private static Exception GetExceptionIfPartUriInvalid(Uri partUri, out string pa //We need to make sure that the URI passed to us is not just "/" //"/" is a valid relative uri, but is not a valid partname - if (partName == string.Empty) + if (partName.Length == 0) return new ArgumentException(SR.PartUriIsEmpty); if (partName[0] != ForwardSlashChar) @@ -804,7 +804,7 @@ private bool IsRelationshipUri() // String.Split, will always return an empty string as the // first member in the array as the string starts with a "/" - Debug.Assert(segments.Length > 0 && segments[0] == string.Empty); + Debug.Assert(segments.Length > 0 && segments[0].Length == 0); //If the extension was not equal to .rels, we would have exited early. Debug.Assert(string.CompareOrdinal((Path.GetExtension(segments[segments.Length - 1])), RelationshipPartUpperCaseExtension) == 0); diff --git a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/ZipPackage.cs b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/ZipPackage.cs index f044bf76c1682..f44daf64e07a0 100644 --- a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/ZipPackage.cs +++ b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/ZipPackage.cs @@ -964,7 +964,7 @@ private void ValidateXmlAttribute(string attributeName, string attributeValue, s ThrowIfXmlAttributeMissing(attributeName, attributeValue, tagName, reader); //Checking for empty attribute - if (attributeValue == string.Empty) + if (attributeValue.Length == 0) throw new XmlException(SR.Format(SR.RequiredAttributeEmpty, tagName, attributeName), null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition); } diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/Attachment.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/Attachment.cs index 44e48f7fc9e3e..91ffd95551706 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/Attachment.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/Attachment.cs @@ -75,7 +75,7 @@ internal void SetContentFromFile(string fileName, ContentType? contentType) throw new ArgumentNullException(nameof(fileName)); } - if (fileName == string.Empty) + if (fileName.Length == 0) { throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(fileName)), nameof(fileName)); } @@ -91,7 +91,7 @@ internal void SetContentFromFile(string fileName, string? mediaType) throw new ArgumentNullException(nameof(fileName)); } - if (fileName == string.Empty) + if (fileName.Length == 0) { throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(fileName)), nameof(fileName)); } @@ -154,7 +154,7 @@ internal void SetContentFromString(string content, Encoding? encoding, string? m _part.Stream.Close(); } - if (mediaType == null || mediaType == string.Empty) + if (string.IsNullOrEmpty(mediaType)) { mediaType = MediaTypeNames.Text.Plain; } @@ -340,7 +340,7 @@ public Attachment(string fileName) : base(fileName) public Attachment(string fileName, ContentType contentType) : base(fileName, contentType) { - if (contentType.Name == null || contentType.Name == string.Empty) + if (string.IsNullOrEmpty(contentType.Name)) { Name = Path.GetFileName(fileName); } diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddress.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddress.cs index 9519b3f80d87c..76d97dd95f4e5 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddress.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddress.cs @@ -124,7 +124,7 @@ private static bool TryParse(string address, string? displayName, Encoding? disp { throw new ArgumentNullException(nameof(address)); } - if (address == string.Empty) + if (address.Length == 0) { throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(address)), nameof(address)); } diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddressCollection.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddressCollection.cs index 5b1b687e30179..bc63f116fcea9 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddressCollection.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailAddressCollection.cs @@ -23,7 +23,7 @@ public void Add(string addresses) { throw new ArgumentNullException(nameof(addresses)); } - if (addresses == string.Empty) + if (addresses.Length == 0) { throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(addresses)), nameof(addresses)); } diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailMessage.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailMessage.cs index 83eddcd9f755f..4bb5e9e8663d2 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailMessage.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailMessage.cs @@ -44,10 +44,10 @@ public MailMessage(string from, string to) if (to == null) throw new ArgumentNullException(nameof(to)); - if (from == string.Empty) + if (from.Length == 0) throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(from)), nameof(from)); - if (to == string.Empty) + if (to.Length == 0) throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(to)), nameof(to)); _message = new Message(from, to); diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailPriority.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailPriority.cs index 6c912e3239c25..ee4618cdd83c3 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailPriority.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailPriority.cs @@ -51,10 +51,10 @@ internal Message(string from, string to) : this() if (to == null) throw new ArgumentNullException(nameof(to)); - if (from == string.Empty) + if (from.Length == 0) throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(from)), nameof(from)); - if (to == string.Empty) + if (to.Length == 0) throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(to)), nameof(to)); _from = new MailAddress(from); diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpClient.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpClient.cs index 834b5ba0b8081..0def5723b3064 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpClient.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpClient.cs @@ -187,7 +187,7 @@ private void Initialize() throw new ArgumentNullException(nameof(value)); } - if (value == string.Empty) + if (value.Length == 0) { throw new ArgumentException(SR.net_emptystringset, nameof(value)); } diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentDisposition.cs b/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentDisposition.cs index be078ae7edcdf..891d17ef06882 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentDisposition.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentDisposition.cs @@ -83,7 +83,7 @@ public string DispositionType { throw new ArgumentNullException(nameof(value)); } - if (value == string.Empty) + if (value.Length == 0) { throw new ArgumentException(SR.net_emptystringset, nameof(value)); } diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentType.cs b/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentType.cs index d3a183fb3b31f..7394cfdd20c5e 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentType.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentType.cs @@ -50,7 +50,7 @@ public ContentType(string contentType) { throw new ArgumentNullException(nameof(contentType)); } - if (contentType == string.Empty) + if (contentType.Length == 0) { throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(contentType)), nameof(contentType)); } @@ -65,7 +65,7 @@ public ContentType(string contentType) get { return Parameters["boundary"]; } set { - if (value == null || value == string.Empty) + if (string.IsNullOrEmpty(value)) { Parameters.Remove("boundary"); } @@ -81,7 +81,7 @@ public ContentType(string contentType) get { return Parameters["charset"]; } set { - if (value == null || value == string.Empty) + if (string.IsNullOrEmpty(value)) { Parameters.Remove("charset"); } @@ -105,7 +105,7 @@ public string MediaType throw new ArgumentNullException(nameof(value)); } - if (value == string.Empty) + if (value.Length == 0) { throw new ArgumentException(SR.net_emptystringset, nameof(value)); } diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mime/HeaderCollection.cs b/src/libraries/System.Net.Mail/src/System/Net/Mime/HeaderCollection.cs index 1162b0138015f..1b468f725477f 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mime/HeaderCollection.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mime/HeaderCollection.cs @@ -31,7 +31,7 @@ public override void Remove(string name) throw new ArgumentNullException(nameof(name)); } - if (name == string.Empty) + if (name.Length == 0) { throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(name)), nameof(name)); } @@ -60,7 +60,7 @@ public override void Remove(string name) throw new ArgumentNullException(nameof(name)); } - if (name == string.Empty) + if (name.Length == 0) { throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(name)), nameof(name)); } @@ -87,7 +87,7 @@ public override void Remove(string name) throw new ArgumentNullException(nameof(name)); } - if (name == string.Empty) + if (name.Length == 0) { throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(name)), nameof(name)); } @@ -138,12 +138,12 @@ public override void Set(string name, string value) throw new ArgumentNullException(nameof(value)); } - if (name == string.Empty) + if (name.Length == 0) { throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(name)), nameof(name)); } - if (value == string.Empty) + if (value.Length == 0) { throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(value)), nameof(value)); } @@ -187,11 +187,11 @@ public override void Add(string name, string value) { throw new ArgumentNullException(nameof(value)); } - if (name == string.Empty) + if (name.Length == 0) { throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(name)), nameof(name)); } - if (value == string.Empty) + if (value.Length == 0) { throw new ArgumentException(SR.Format(SR.net_emptystringcall, nameof(value)), nameof(value)); } diff --git a/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs b/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs index f36b48483d54a..3cd68e4ad068b 100644 --- a/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs +++ b/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs @@ -595,7 +595,7 @@ protected override PipelineEntry[] BuildCommandsList(WebRequest req) if (request.MethodInfo.Operation == FtpOperation.Rename) { - string baseDir = (requestDirectory == string.Empty) + string baseDir = (requestDirectory.Length == 0) ? string.Empty : requestDirectory + "/"; commandList.Add(new PipelineEntry(FormatFtpCommand("RNFR", baseDir + requestFilename), flags)); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameFormatter.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameFormatter.cs index 09585f8d58f19..3ead4ce8e87f3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameFormatter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameFormatter.cs @@ -54,7 +54,7 @@ public static string ComputeDisplayName(string? name, Version? version, string? if (cultureName != null) { - if (cultureName == string.Empty) + if (cultureName.Length == 0) cultureName = "neutral"; sb.Append(", Culture="); sb.AppendQuoted(cultureName); diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/XmlJsonWriter.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/XmlJsonWriter.cs index 6f09bd393b63b..2f0194b2334b6 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/XmlJsonWriter.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/XmlJsonWriter.cs @@ -245,7 +245,7 @@ public override string LookupPrefix(string ns) { return JsonGlobals.xmlPrefix; } - if (ns == string.Empty) + if (ns.Length == 0) { return string.Empty; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs index e8290112ad098..9d73bfa51103a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs @@ -919,7 +919,7 @@ internal string LookupPrefix(string namespaceName) { return _nameTable.Add("xml"); } - if (namespaceName == string.Empty) + if (namespaceName.Length == 0) { return string.Empty; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs index c071cdaf6a699..e9d9f7e9ad91f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs @@ -958,7 +958,7 @@ internal XmlSchema FindSchemaByNSAndUrl(Uri schemaUri, string ns, DictionaryEntr { return schema; } - else if (tns == string.Empty) + else if (tns.Length == 0) { //There could be a chameleon for same ns // It is OK to pass in the schema we have found so far, since it must have the schemaUri we're looking for // (we found it that way above) and it must be the original chameleon schema (the one without target ns) diff --git a/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/MemoryCache.cs b/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/MemoryCache.cs index 3dcbf43fecb9c..ffb420c4f7238 100644 --- a/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/MemoryCache.cs +++ b/src/libraries/System.Runtime.Caching/src/System/Runtime/Caching/MemoryCache.cs @@ -344,7 +344,7 @@ public MemoryCache(string name, NameValueCollection config = null) { throw new ArgumentNullException(nameof(name)); } - if (name == string.Empty) + if (name.Length == 0) { throw new ArgumentException(SR.Empty_string_invalid, nameof(name)); } @@ -364,7 +364,7 @@ public MemoryCache(string name, NameValueCollection config, bool ignoreConfigSec { throw new ArgumentNullException(nameof(name)); } - if (name == string.Empty) + if (name.Length == 0) { throw new ArgumentException(SR.Empty_string_invalid, nameof(name)); } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.Mono.cs index 0c9f12ad193aa..5f6e79e580c33 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.Mono.cs @@ -154,7 +154,7 @@ private FieldBuilder DefineDataImpl(string name, int size, FieldAttributes attri { if (name == null) throw new ArgumentNullException(nameof(name)); - if (name == string.Empty) + if (name.Length == 0) throw new ArgumentException("name cannot be empty", nameof(name)); if (global_type_created != null) throw new InvalidOperationException("global fields already created"); diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs index 5d110fefdaebb..d4efac98e0a4e 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs @@ -197,7 +197,7 @@ Type GetType(string className, bool throwOnError, bool ignoreCase) { if (className == null) throw new ArgumentNullException(nameof(className)); - if (className == string.Empty) + if (className.Length == 0) throw new ArgumentException("Type name can't be empty"); return assembly.InternalGetType(this, className, throwOnError, ignoreCase); } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs b/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs index 7df75e09b9178..90a36a0230f5c 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs @@ -289,7 +289,7 @@ internal static bool IsTypeDefinition(RuntimeType type) if (typeName == null) throw new ArgumentNullException(nameof(typeName)); - if (typeName == string.Empty) + if (typeName.Length == 0) if (throwOnError) throw new TypeLoadException("A null or zero length string does not represent a valid Type."); else From 89b68cc3434b58cac3404493c5bfafc6c0457cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 19 May 2020 15:57:20 +0200 Subject: [PATCH 272/420] Fix RuntimeInformation.IsOSPlatform for Browser/WASM (#36665) The native code was still using the previous `WEBASSEMBLY` name instead of `BROWSER` as decided in https://github.com/dotnet/runtime/issues/33328. --- eng/native/configureplatform.cmake | 5 +++-- eng/native/configuretools.cmake | 2 +- src/libraries/Native/Unix/CMakeLists.txt | 17 ++++++++--------- .../System.IO.Compression.Native/CMakeLists.txt | 2 +- .../Native/Unix/System.Native/CMakeLists.txt | 2 +- .../Native/Unix/System.Native/pal_io.c | 2 +- .../Native/Unix/System.Native/pal_process.c | 2 +- .../Native/Unix/System.Native/pal_sysctl.c | 2 +- src/libraries/Native/Unix/configure.cmake | 6 +++--- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index 9dfd3cff36ac4..04fdfaed45a99 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -170,6 +170,7 @@ endif(CLR_CMAKE_HOST_OS STREQUAL Windows) if(CLR_CMAKE_HOST_OS STREQUAL Emscripten) #set(CLR_CMAKE_HOST_UNIX 1) # TODO: this should be reenabled but it activates a bunch of additional compiler flags in configurecompiler.cmake set(CLR_CMAKE_HOST_UNIX_WASM 1) + set(CLR_CMAKE_HOST_BROWSER 1) endif(CLR_CMAKE_HOST_OS STREQUAL Emscripten) #-------------------------------------------- @@ -317,7 +318,7 @@ endif(CLR_CMAKE_TARGET_OS STREQUAL SunOS) if(CLR_CMAKE_TARGET_OS STREQUAL Emscripten) set(CLR_CMAKE_TARGET_UNIX 1) set(CLR_CMAKE_TARGET_LINUX 1) - set(CLR_CMAKE_TARGET_EMSCRIPTEN 1) + set(CLR_CMAKE_TARGET_BROWSER 1) endif(CLR_CMAKE_TARGET_OS STREQUAL Emscripten) if(CLR_CMAKE_TARGET_UNIX) @@ -359,7 +360,7 @@ else() endif() endif() -if(NOT CLR_CMAKE_TARGET_EMSCRIPTEN) +if(NOT CLR_CMAKE_TARGET_BROWSER) # Skip check_pie_supported call on Android as ld from llvm toolchain with NDK API level 21 # complains about missing linker flag `-no-pie` (while level 28's ld does support this flag, # but since we know that PIE is supported, we can safely skip this redundant check). diff --git a/eng/native/configuretools.cmake b/eng/native/configuretools.cmake index b63ab0f1a66d5..4fb94531d7698 100644 --- a/eng/native/configuretools.cmake +++ b/eng/native/configuretools.cmake @@ -6,7 +6,7 @@ if (CMAKE_C_COMPILER MATCHES "-?[0-9]+(\.[0-9]+)?$") set(CLR_CMAKE_COMPILER_FILE_NAME_VERSION "${CMAKE_MATCH_0}") endif() -if(NOT WIN32 AND NOT CLR_CMAKE_TARGET_ARCH_WASM) +if(NOT WIN32 AND NOT CLR_CMAKE_TARGET_BROWSER) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") if(APPLE) set(TOOLSET_PREFIX "") diff --git a/src/libraries/Native/Unix/CMakeLists.txt b/src/libraries/Native/Unix/CMakeLists.txt index 6d6ca05dc3d94..1d1db4873abfe 100644 --- a/src/libraries/Native/Unix/CMakeLists.txt +++ b/src/libraries/Native/Unix/CMakeLists.txt @@ -10,9 +10,9 @@ if(CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) cmake_minimum_required(VERSION 3.14.5) endif() -if(NOT CLR_CMAKE_TARGET_ARCH_WASM) +if(NOT CLR_CMAKE_TARGET_BROWSER) cmake_policy(SET CMP0083 NEW) -endif(NOT CLR_CMAKE_TARGET_ARCH_WASM) +endif(NOT CLR_CMAKE_TARGET_BROWSER) set(CMAKE_MACOSX_RPATH ON) set(CMAKE_INSTALL_PREFIX $ENV{__CMakeBinDir}) @@ -46,8 +46,7 @@ if (PRERELEASE) add_compile_options(-Werror) endif() -if(CLR_CMAKE_TARGET_ARCH_WASM) - add_definitions(-D_WASM_) +if(CLR_CMAKE_TARGET_BROWSER) # The emscripten build has additional warnings so -Werror breaks add_compile_options(-Wno-unused-parameter) add_compile_options(-Wno-unused-function) @@ -55,7 +54,7 @@ if(CLR_CMAKE_TARGET_ARCH_WASM) add_compile_options(-Wno-implicit-int-float-conversion) else() set(GEN_SHARED_LIB 1) -endif(CLR_CMAKE_TARGET_ARCH_WASM) +endif(CLR_CMAKE_TARGET_BROWSER) if (CLR_CMAKE_TARGET_ARCH_AMD64) add_definitions(-DTARGET_64BIT=1) @@ -139,7 +138,7 @@ else () message(FATAL_ERROR "Unknown build type. Set CMAKE_BUILD_TYPE to DEBUG or RELEASE.") endif () -if(CLR_CMAKE_TARGET_ARCH_WASM) +if(CLR_CMAKE_TARGET_BROWSER) elseif (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) add_definitions(-D__APPLE_USE_RFC_3542) @@ -164,7 +163,7 @@ endif(CLR_CMAKE_TARGET_FREEBSD) # ./build-native.sh cmakeargs -DCLR_ADDITIONAL_COMPILER_OPTIONS=<...> cmakeargs -DCLR_ADDITIONAL_LINKER_FLAGS=<...> # if(CLR_CMAKE_TARGET_UNIX) - if(NOT CLR_CMAKE_TARGET_ARCH_WASM AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS) + if(NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS) if(CLR_CMAKE_TARGET_OSX) add_definitions(-DTARGET_OSX) add_link_options(-Wl,-bind_at_load) @@ -190,7 +189,7 @@ include(configure.cmake) add_subdirectory(System.IO.Compression.Native) -if (NOT CLR_CMAKE_TARGET_ARCH_WASM AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID) +if (NOT CLR_CMAKE_TARGET_BROWSER AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID) add_subdirectory(System.IO.Ports.Native) endif() @@ -200,7 +199,7 @@ endif() add_subdirectory(System.Native) -if(CLR_CMAKE_TARGET_ARCH_WASM) +if(CLR_CMAKE_TARGET_BROWSER) # skip for now elseif(CLR_CMAKE_TARGET_IOS) add_subdirectory(System.Net.Security.Native) diff --git a/src/libraries/Native/Unix/System.IO.Compression.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.IO.Compression.Native/CMakeLists.txt index 3315941e1aceb..d1bfa9f4b8490 100644 --- a/src/libraries/Native/Unix/System.IO.Compression.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.IO.Compression.Native/CMakeLists.txt @@ -1,6 +1,6 @@ project(System.IO.Compression.Native C) -if (CLR_CMAKE_TARGET_ARCH_WASM) +if (CLR_CMAKE_TARGET_BROWSER) add_definitions(-s USE_ZLIB) elseif (CLR_CMAKE_TARGET_ANDROID) # need special case here since we want to link against libz.so but find_package() would resolve libz.a diff --git a/src/libraries/Native/Unix/System.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Native/CMakeLists.txt index e3bf2532b3ae5..884e1b065814e 100644 --- a/src/libraries/Native/Unix/System.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.Native/CMakeLists.txt @@ -30,7 +30,7 @@ else () set(NATIVE_SOURCES ${NATIVE_SOURCES} pal_console.c) endif () -if (CLR_CMAKE_TARGET_LINUX AND NOT CLR_CMAKE_TARGET_ARCH_WASM) +if (CLR_CMAKE_TARGET_LINUX AND NOT CLR_CMAKE_TARGET_BROWSER) set(NATIVE_SOURCES ${NATIVE_SOURCES} pal_networkchange.c) if (!HAVE_LINUX_RTNETLINK_H) diff --git a/src/libraries/Native/Unix/System.Native/pal_io.c b/src/libraries/Native/Unix/System.Native/pal_io.c index 2e441c3efe1e5..ccae4e87c9756 100644 --- a/src/libraries/Native/Unix/System.Native/pal_io.c +++ b/src/libraries/Native/Unix/System.Native/pal_io.c @@ -1280,7 +1280,7 @@ int32_t SystemNative_GetPeerID(intptr_t socket, uid_t* euid) // ucred causes Emscripten to fail even though it's defined, // but getting peer credentials won't work for WebAssembly anyway -#if defined(SO_PEERCRED) && !defined(_WASM_) +#if defined(SO_PEERCRED) && !defined(TARGET_WASM) struct ucred creds; socklen_t len = sizeof(creds); if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &creds, &len) == 0) diff --git a/src/libraries/Native/Unix/System.Native/pal_process.c b/src/libraries/Native/Unix/System.Native/pal_process.c index 2a5028558446a..2824eb05073e3 100644 --- a/src/libraries/Native/Unix/System.Native/pal_process.c +++ b/src/libraries/Native/Unix/System.Native/pal_process.c @@ -134,7 +134,7 @@ static int compare_groups(const void * a, const void * b) static int SetGroups(uint32_t* userGroups, int32_t userGroupsLength, uint32_t* processGroups) { -#if defined(__linux__) || defined(_WASM_) +#if defined(__linux__) || defined(TARGET_WASM) size_t platformGroupsLength = Int32ToSizeT(userGroupsLength); #else // BSD int platformGroupsLength = userGroupsLength; diff --git a/src/libraries/Native/Unix/System.Native/pal_sysctl.c b/src/libraries/Native/Unix/System.Native/pal_sysctl.c index 0adf8ac57d33a..0d3b7f1e9a16f 100644 --- a/src/libraries/Native/Unix/System.Native/pal_sysctl.c +++ b/src/libraries/Native/Unix/System.Native/pal_sysctl.c @@ -24,7 +24,7 @@ int32_t SystemNative_Sysctl(int* name, unsigned int namelen, void* value, size_t void* newp = NULL; size_t newlen = 0; -#if defined(__linux__) || defined(_WASM_) +#if defined(__linux__) || defined(TARGET_WASM) return sysctl(name, (int)(namelen), value, len, newp, newlen); #else return sysctl(name, namelen, value, len, newp, newlen); diff --git a/src/libraries/Native/Unix/configure.cmake b/src/libraries/Native/Unix/configure.cmake index 96f8f7857c3dc..4dc8b93c36de8 100644 --- a/src/libraries/Native/Unix/configure.cmake +++ b/src/libraries/Native/Unix/configure.cmake @@ -9,8 +9,8 @@ include(CheckTypeSize) if (CLR_CMAKE_TARGET_ANDROID) set(PAL_UNIX_NAME \"ANDROID\") -elseif (CLR_CMAKE_TARGET_ARCH_WASM) - set(PAL_UNIX_NAME \"WEBASSEMBLY\") +elseif (CLR_CMAKE_TARGET_BROWSER) + set(PAL_UNIX_NAME \"BROWSER\") elseif (CLR_CMAKE_TARGET_LINUX) set(PAL_UNIX_NAME \"LINUX\") elseif (CLR_CMAKE_TARGET_OSX) @@ -879,7 +879,7 @@ set (CMAKE_REQUIRED_LIBRARIES ${PREVIOUS_CMAKE_REQUIRED_LIBRARIES}) set (HAVE_INOTIFY 0) if (HAVE_INOTIFY_INIT AND HAVE_INOTIFY_ADD_WATCH AND HAVE_INOTIFY_RM_WATCH) set (HAVE_INOTIFY 1) -elseif (CLR_CMAKE_TARGET_LINUX AND NOT CLR_CMAKE_TARGET_ARCH_WASM) +elseif (CLR_CMAKE_TARGET_LINUX AND NOT CLR_CMAKE_TARGET_BROWSER) message(FATAL_ERROR "Cannot find inotify functions on a Linux platform.") endif() From 1529b44a5d43959df4e58d6ad3f6d3dab1ff3033 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 19 May 2020 14:09:05 +0000 Subject: [PATCH 273/420] [master] Update dependencies from mono/linker Microsoft/vstest (#36692) * Update dependencies from https://github.com/mono/linker build 20200518.5 Microsoft.NET.ILLink.Tasks From Version 5.0.0-preview.3.20268.2 -> To Version 5.0.0-preview.3.20268.5 * Update dependencies from https://github.com/microsoft/vstest build 20200518-01 Microsoft.NET.Test.Sdk From Version 16.7.0-preview-20200515-03 -> To Version 16.7.0-preview-20200518-01 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 510009e4b4833..a0025342df1b3 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -82,9 +82,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization d0bb63d2ec7060714e63ee4082fac48f2e57f3e2 - + https://github.com/microsoft/vstest - 59354e1f9c366b40d06ecf62372fc455d7f1ba18 + 3f18c870db1776dab9c94e7b819c0dad90ff9686 https://github.com/dotnet/runtime-assets @@ -170,9 +170,9 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - 0f1b1a569fcd16bd9e7c180d3c8bef1080348d9d + 45730defebfff077bff4991d4884e0ff32f78913 https://github.com/dotnet/xharness diff --git a/eng/Versions.props b/eng/Versions.props index 2ef1900170fd3..23082297d6ab9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -108,7 +108,7 @@ 4.8.0 - 16.7.0-preview-20200515-03 + 16.7.0-preview-20200518-01 1.0.0-prerelease.20265.8 2.4.1 1.2.1 @@ -118,7 +118,7 @@ 3.1.0-preview-20200129.1 - 5.0.0-preview.3.20268.2 + 5.0.0-preview.3.20268.5 9.0.1-alpha.1.20262.1 9.0.1-alpha.1.20262.1 From d734c7ee32add0fbdd9fedcacc3cadd03b369de2 Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Tue, 19 May 2020 16:26:01 +0200 Subject: [PATCH 274/420] Remove duplicated code from SR.cs (#36277) --- src/libraries/Common/src/System/SR.cs | 7 +- .../System.Private.CoreLib.Shared.projitems | 3 + .../System.Private.CoreLib/src/System/SR.cs | 106 ++---------------- 3 files changed, 18 insertions(+), 98 deletions(-) diff --git a/src/libraries/Common/src/System/SR.cs b/src/libraries/Common/src/System/SR.cs index 357492065e502..69a233ed668e3 100644 --- a/src/libraries/Common/src/System/SR.cs +++ b/src/libraries/Common/src/System/SR.cs @@ -29,7 +29,12 @@ internal static string GetResourceString(string resourceKey, string? defaultStri string? resourceString = null; try { - resourceString = ResourceManager.GetString(resourceKey); + resourceString = +#if SYSTEM_PRIVATE_CORELIB + InternalGetResourceString(resourceKey); +#else + ResourceManager.GetString(resourceKey); +#endif } catch (MissingManifestResourceException) { } diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 23fd990bfb42c..3ee0049c240d7 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -1055,6 +1055,9 @@ Common\System\HResults.cs + + Common\System\SR.cs + Common\System\Collections\Generic\ReferenceEqualityComparer.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/SR.cs b/src/libraries/System.Private.CoreLib/src/System/SR.cs index e70d6187507a7..017ce551e8b16 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SR.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SR.cs @@ -13,53 +13,24 @@ namespace System { internal static partial class SR { - // This method is used to decide if we need to append the exception message parameters to the message when calling SR.Format. - // by default it returns false. - // Native code generators can replace the value this returns based on user input at the time of native code generation. - // Marked as NoInlining because if this is used in an AoT compiled app that is not compiled into a single file, the user - // could compile each module with a different setting for this. We want to make sure there's a consistent behavior - // that doesn't depend on which native module this method got inlined into. - [MethodImpl(MethodImplOptions.NoInlining)] - private static bool UsingResourceKeys() - { - return false; - } + private static readonly object _lock = new object(); + private static List? _currentlyLoading; + private static int _infinitelyRecursingCount; + private static bool _resourceManagerInited; // Needed for debugger integration - internal static string? GetResourceString(string resourceKey) + internal static string GetResourceString(string resourceKey) { return GetResourceString(resourceKey, string.Empty); } - internal static string GetResourceString(string resourceKey, string? defaultString) - { - if (UsingResourceKeys()) - return defaultString ?? resourceKey; - - string? resourceString = null; - try { resourceString = InternalGetResourceString(resourceKey); } - catch (MissingManifestResourceException) { } - - if (defaultString != null && resourceKey.Equals(resourceString, StringComparison.Ordinal)) - { - return defaultString; - } - - return resourceString!; // only null if missing resource - } - - private static readonly object _lock = new object(); - private static List? _currentlyLoading; - private static int _infinitelyRecursingCount; - private static bool _resourceManagerInited = false; - [PreserveDependency(".cctor()", "System.Resources.ResourceManager")] - private static string? InternalGetResourceString(string? key) + private static string InternalGetResourceString(string key) { - if (string.IsNullOrEmpty(key)) + if (key.Length == 0) { - Debug.Fail("SR::GetResourceString with null or empty key. Bug in caller, or weird recursive loading problem?"); - return key!; + Debug.Fail("SR::GetResourceString with empty resourceKey. Bug in caller, or weird recursive loading problem?"); + return key; } // We have a somewhat common potential for infinite @@ -146,64 +117,5 @@ internal static string GetResourceString(string resourceKey, string? defaultStri } } } - - internal static string Format(IFormatProvider? provider, string resourceFormat, params object?[]? args) - { - if (args != null) - { - if (UsingResourceKeys()) - { - return resourceFormat + ", " + string.Join(", ", args); - } - - return string.Format(provider, resourceFormat, args); - } - - return resourceFormat; - } - - internal static string Format(string resourceFormat, params object?[]? args) - { - if (args != null) - { - if (UsingResourceKeys()) - { - return resourceFormat + ", " + string.Join(", ", args); - } - - return string.Format(resourceFormat, args); - } - - return resourceFormat; - } - - internal static string Format(string resourceFormat, object? p1) - { - if (UsingResourceKeys()) - { - return string.Join(", ", resourceFormat, p1); - } - - return string.Format(resourceFormat, p1); - } - - internal static string Format(string resourceFormat, object? p1, object? p2) - { - if (UsingResourceKeys()) - { - return string.Join(", ", resourceFormat, p1, p2); - } - - return string.Format(resourceFormat, p1, p2); - } - - internal static string Format(string resourceFormat, object? p1, object? p2, object? p3) - { - if (UsingResourceKeys()) - { - return string.Join(", ", resourceFormat, p1, p2, p3); - } - return string.Format(resourceFormat, p1, p2, p3); - } } } From 714fbbc71c271244ca469c5b6af0839cf374ef99 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 19 May 2020 10:29:15 -0500 Subject: [PATCH 275/420] Add RequiresUnreferencedCodeAttribute (#36674) This attribute is used by the linker to know which methods are unsafe to use when an application is trimmed. Fix #33862 --- .../System.Private.CoreLib.Shared.projitems | 1 + .../RequiresUnreferencedCodeAttribute.cs | 41 +++++++++++++++++++ .../System.Runtime/ref/System.Runtime.cs | 7 ++++ .../tests/System.Runtime.Tests.csproj | 1 + .../DynamicDependencyAttributeTests.cs | 2 +- .../RequiresUnreferencedCodeAttributeTests.cs | 35 ++++++++++++++++ 6 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttribute.cs create mode 100644 src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttributeTests.cs diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 3ee0049c240d7..8857b33b6f8dd 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -194,6 +194,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttribute.cs new file mode 100644 index 0000000000000..5ab29034e1a8b --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttribute.cs @@ -0,0 +1,41 @@ +// 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. + +namespace System.Diagnostics.CodeAnalysis +{ + /// + /// Indicates that the specified method requires dynamic access to code that is not referenced + /// statically, for example through . + /// + /// + /// This allows tools to understand which methods are unsafe to call when removing unreferenced + /// code from an application. + /// + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)] + public sealed class RequiresUnreferencedCodeAttribute : Attribute + { + /// + /// Initializes a new instance of the class + /// with the specified message. + /// + /// + /// A message that contains information about the usage of unreferenced code. + /// + public RequiresUnreferencedCodeAttribute(string message) + { + Message = message; + } + + /// + /// Gets a message that contains information about the usage of unreferenced code. + /// + public string Message { get; } + + /// + /// Gets or sets an optional URL that contains more information about the method, + /// why it requries unreferenced code, and what options a consumer has to deal with it. + /// + public string? Url { get; set; } + } +} diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 0ff7018d9f5d1..50ef98b9c7930 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -5698,6 +5698,13 @@ public sealed class MemberNotNullWhenAttribute : System.Attribute public bool ReturnValue { get { throw null; } } public string[] Members { get { throw null; } } } + [System.AttributeUsageAttribute(System.AttributeTargets.Method | System.AttributeTargets.Constructor, Inherited = false)] + public sealed class RequiresUnreferencedCodeAttribute : System.Attribute + { + public RequiresUnreferencedCodeAttribute(string message) { } + public string Message { get { throw null; } } + public string? Url { get { throw null; } set { } } + } [System.AttributeUsageAttribute(System.AttributeTargets.All, Inherited=false, AllowMultiple=true)] [System.Diagnostics.ConditionalAttribute("CODE_ANALYSIS")] public sealed partial class SuppressMessageAttribute : System.Attribute diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj index e9dd22e302f7a..69f4de93591a8 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj @@ -156,6 +156,7 @@ + diff --git a/src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/DynamicDependencyAttributeTests.cs b/src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/DynamicDependencyAttributeTests.cs index 2b475906acfc5..337af64fdd342 100644 --- a/src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/DynamicDependencyAttributeTests.cs +++ b/src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/DynamicDependencyAttributeTests.cs @@ -6,7 +6,7 @@ namespace System.Diagnostics.CodeAnalysis.Tests { - public class DynamicDependencyAttributeTestsTests + public class DynamicDependencyAttributeTests { [Theory] [InlineData("Foo()")] diff --git a/src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttributeTests.cs b/src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttributeTests.cs new file mode 100644 index 0000000000000..044fc78deec0b --- /dev/null +++ b/src/libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/RequiresUnreferencedCodeAttributeTests.cs @@ -0,0 +1,35 @@ +// 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. + +using Xunit; + +namespace System.Diagnostics.CodeAnalysis.Tests +{ + public class RequiresUnreferencedCodeAttributeTests + { + [Fact] + public void TestConstructor() + { + var attr = new RequiresUnreferencedCodeAttribute("User Message"); + + Assert.Equal("User Message", attr.Message); + Assert.Null(attr.Url); + } + + [Theory] + [InlineData("https://dot.net")] + [InlineData("")] + [InlineData(null)] + public void TestSetUrl(string url) + { + var attr = new RequiresUnreferencedCodeAttribute("User Message") + { + Url = url + }; + + Assert.Equal("User Message", attr.Message); + Assert.Equal(url, attr.Url); + } + } +} From b934bc02abe2bf03e8efd027a2d3bc14ba011acf Mon Sep 17 00:00:00 2001 From: Anton Lapounov Date: Tue, 19 May 2020 10:09:08 -0700 Subject: [PATCH 276/420] Revert unintentional alignment change for Vector256 (#36673) Addresses https://github.com/dotnet/runtime/pull/35864#issuecomment-629803015. In an earlier change I also added the `type.Instantiation[0].IsPrimitive` condition to the `IsVectorType` predicate. Revert that part as well and allow only primitive numeric types for HFA/HVA purpose. The same list of 10 types is recognized in `MethodTable::GetVectorSize` and `Compiler::getBaseTypeAndSizeOfSIMDType`. --- .../Compiler/VectorFieldLayoutAlgorithm.cs | 8 +++-- .../tools/Common/JitInterface/CorInfoImpl.cs | 19 ++---------- .../Common/TypeSystem/Common/TypeDesc.cs | 30 ++++++++++++++++++- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/coreclr/src/tools/Common/Compiler/VectorFieldLayoutAlgorithm.cs b/src/coreclr/src/tools/Common/Compiler/VectorFieldLayoutAlgorithm.cs index 4720ea427b709..12ded51464c64 100644 --- a/src/coreclr/src/tools/Common/Compiler/VectorFieldLayoutAlgorithm.cs +++ b/src/coreclr/src/tools/Common/Compiler/VectorFieldLayoutAlgorithm.cs @@ -90,7 +90,8 @@ public override bool ComputeContainsGCPointers(DefType type) public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type) { - if (type.Context.Target.Architecture == TargetArchitecture.ARM64) + if (type.Context.Target.Architecture == TargetArchitecture.ARM64 && + type.Instantiation[0].IsPrimitiveNumeric) { return type.InstanceFieldSize.AsInt switch { @@ -106,8 +107,9 @@ public static bool IsVectorType(DefType type) { return type.IsIntrinsic && type.Namespace == "System.Runtime.Intrinsics" && - ((type.Name == "Vector64`1") || (type.Name == "Vector128`1")) && - type.Instantiation[0].IsPrimitive; + (type.Name == "Vector64`1" || + type.Name == "Vector128`1" || + type.Name == "Vector256`1"); } } } diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs index 175becc964a34..205304c49a36b 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs @@ -1759,23 +1759,10 @@ private CorInfoType getTypeForPrimitiveNumericClass(CORINFO_CLASS_STRUCT_* cls) { var type = HandleToObject(cls); - switch (type.Category) - { - case TypeFlags.Byte: - case TypeFlags.SByte: - case TypeFlags.UInt16: - case TypeFlags.Int16: - case TypeFlags.UInt32: - case TypeFlags.Int32: - case TypeFlags.UInt64: - case TypeFlags.Int64: - case TypeFlags.Single: - case TypeFlags.Double: - return asCorInfoType(type); + if (type.IsPrimitiveNumeric) + return asCorInfoType(type); - default: - return CorInfoType.CORINFO_TYPE_UNDEF; - } + return CorInfoType.CORINFO_TYPE_UNDEF; } private bool canCast(CORINFO_CLASS_STRUCT_* child, CORINFO_CLASS_STRUCT_* parent) diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeDesc.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeDesc.cs index d9110d148e1d1..cf266f0c0990f 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeDesc.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeDesc.cs @@ -188,7 +188,7 @@ public bool IsValueType /// /// Gets a value indicating whether this is one of the primitive types (boolean, char, void, - /// a floating point, or an integer type). + /// a floating-point, or an integer type). /// public bool IsPrimitive { @@ -198,6 +198,34 @@ public bool IsPrimitive } } + /// + /// Gets a value indicating whether this is one of the primitive numeric types + /// (a floating-point or an integer type). + /// + public bool IsPrimitiveNumeric + { + get + { + switch (GetTypeFlags(TypeFlags.CategoryMask)) + { + case TypeFlags.SByte: + case TypeFlags.Byte: + case TypeFlags.Int16: + case TypeFlags.UInt16: + case TypeFlags.Int32: + case TypeFlags.UInt32: + case TypeFlags.Int64: + case TypeFlags.UInt64: + case TypeFlags.Single: + case TypeFlags.Double: + return true; + + default: + return false; + } + } + } + /// /// Gets a value indicating whether this is an enum type. /// Access to retrieve the underlying integral type. From fdd9b9fc819500ed8476ae1779e1e9f30d44eafd Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Tue, 19 May 2020 11:12:20 -0700 Subject: [PATCH 277/420] Improve sort function in crossgen2 (#36676) - Increase memory locality substantially in composite images - Sort non-generic methods with module together - Sort generic methods near other generic methods with similar instantiations Json benchmark showed improvement from 237,827 RPS to 270,306 RPS, and reduced working set by about 10MB --- .../TypeSystem/Ecma/EcmaMethod.Sorting.cs | 8 ++++-- .../TypeSystem/Ecma/EcmaType.Sorting.cs | 6 ++-- .../Sorting/InstantiatedMethod.Sorting.cs | 24 ++++++++++------ .../Sorting/InstantiatedType.Sorting.cs | 28 ++++++++++++------- 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/coreclr/src/tools/Common/TypeSystem/Ecma/EcmaMethod.Sorting.cs b/src/coreclr/src/tools/Common/TypeSystem/Ecma/EcmaMethod.Sorting.cs index b9cfbda285923..c5e20b5362b95 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Ecma/EcmaMethod.Sorting.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Ecma/EcmaMethod.Sorting.cs @@ -17,12 +17,14 @@ protected internal override int CompareToImpl(MethodDesc other, TypeSystemCompar EcmaModule module = _type.EcmaModule; EcmaModule otherModule = otherMethod._type.EcmaModule; - - int result = module.MetadataReader.GetToken(_handle) - otherModule.MetadataReader.GetToken(otherMethod._handle); + + // Sort by module in preference to by token. This will place methods of the same type near each other + // even when working with several modules + int result = module.CompareTo(otherModule); if (result != 0) return result; - return module.CompareTo(otherModule); + return module.MetadataReader.GetToken(_handle) - otherModule.MetadataReader.GetToken(otherMethod._handle); } } } diff --git a/src/coreclr/src/tools/Common/TypeSystem/Ecma/EcmaType.Sorting.cs b/src/coreclr/src/tools/Common/TypeSystem/Ecma/EcmaType.Sorting.cs index 246f36aa3f02a..77a3fbe46a762 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Ecma/EcmaType.Sorting.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Ecma/EcmaType.Sorting.cs @@ -13,12 +13,14 @@ partial class EcmaType protected internal override int CompareToImpl(TypeDesc other, TypeSystemComparer comparer) { + // Sort by module in preference to by token. This will place types from the same module near each other + // even when working with several modules. var otherType = (EcmaType)other; - int result = _module.MetadataReader.GetToken(_handle) - otherType._module.MetadataReader.GetToken(otherType._handle); + int result = _module.CompareTo(otherType._module); if (result != 0) return result; - return _module.CompareTo(otherType._module); + return _module.MetadataReader.GetToken(_handle) - otherType._module.MetadataReader.GetToken(otherType._handle); } } } diff --git a/src/coreclr/src/tools/Common/TypeSystem/Sorting/InstantiatedMethod.Sorting.cs b/src/coreclr/src/tools/Common/TypeSystem/Sorting/InstantiatedMethod.Sorting.cs index 17b270780ce79..065c122721360 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Sorting/InstantiatedMethod.Sorting.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Sorting/InstantiatedMethod.Sorting.cs @@ -12,21 +12,27 @@ partial class InstantiatedMethod protected internal override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer) { var otherMethod = (InstantiatedMethod)other; - int result = _instantiation.Length - otherMethod._instantiation.Length; - if (result != 0) - return result; - - result = comparer.Compare(_methodDef, otherMethod._methodDef); - if (result != 0) - return result; - + // Sort by instantiation before sorting by associated method definition + // The goal of this is to keep methods which work with the same types near + // to each other. This is a better heuristic than sorting by method definition + // then by instantiation. + // + // The goal is to sort methods like SomeClass.SomeMethod, + // near SomeOtherClass.SomeOtherMethod + int result = 0; + // Sort instantiations of the same type together for (int i = 0; i < _instantiation.Length; i++) { + if (i >= otherMethod._instantiation.Length) + return 1; result = comparer.Compare(_instantiation[i], otherMethod._instantiation[i]); if (result != 0) - break; + return result; } + if (_instantiation.Length < otherMethod._instantiation.Length) + return -1; + result = comparer.Compare(_methodDef, otherMethod._methodDef); return result; } } diff --git a/src/coreclr/src/tools/Common/TypeSystem/Sorting/InstantiatedType.Sorting.cs b/src/coreclr/src/tools/Common/TypeSystem/Sorting/InstantiatedType.Sorting.cs index f749b4559406a..b983382f6268c 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Sorting/InstantiatedType.Sorting.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Sorting/InstantiatedType.Sorting.cs @@ -14,20 +14,28 @@ partial class InstantiatedType protected internal override int CompareToImpl(TypeDesc other, TypeSystemComparer comparer) { var otherType = (InstantiatedType)other; + // Sort by instantiation before sorting by associated method definition + // The goal of this is to keep methods which work with the same types near + // to each other. This is a better heuristic than sorting by method definition + // then by instantiation. + // + // The goal is to sort classes like SomeClass, + // near SomeOtherClass - int result = comparer.Compare(_typeDef, otherType._typeDef); - if (result == 0) + int result = 0; + // Sort instantiations of the same type together + for (int i = 0; i < _instantiation.Length; i++) { - Debug.Assert(_instantiation.Length == otherType._instantiation.Length); - for (int i = 0; i < _instantiation.Length; i++) - { - result = comparer.Compare(_instantiation[i], otherType._instantiation[i]); - if (result != 0) - break; - } + if (i >= otherType._instantiation.Length) + return 1; + result = comparer.Compare(_instantiation[i], otherType._instantiation[i]); + if (result != 0) + return result; } + if (_instantiation.Length < otherType._instantiation.Length) + return -1; - return result; + return comparer.Compare(_typeDef, otherType._typeDef); } } } From 20ee02bda38a50a370ff18b794f39e2fe43e3943 Mon Sep 17 00:00:00 2001 From: AraHaan <15173749+AraHaan@users.noreply.github.com> Date: Tue, 19 May 2020 14:35:01 -0400 Subject: [PATCH 278/420] Fixed Incorrectly named function arguments in TryGetPlatformSocketOption. (#36694) Fixes #36686. --- .../Native/Unix/System.Native/pal_networking.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libraries/Native/Unix/System.Native/pal_networking.c b/src/libraries/Native/Unix/System.Native/pal_networking.c index 319b5000c46a0..ba58024472b8e 100644 --- a/src/libraries/Native/Unix/System.Native/pal_networking.c +++ b/src/libraries/Native/Unix/System.Native/pal_networking.c @@ -1592,14 +1592,14 @@ int32_t SystemNative_GetSocketErrorOption(intptr_t socket, int32_t* error) return Error_SUCCESS; } -static bool TryGetPlatformSocketOption(int32_t socketOptionName, int32_t socketOptionLevel, int* optLevel, int* optName) +static bool TryGetPlatformSocketOption(int32_t socketOptionLevel, int32_t socketOptionName, int* optLevel, int* optName) { - switch (socketOptionName) + switch (socketOptionLevel) { case SocketOptionLevel_SOL_SOCKET: *optLevel = SOL_SOCKET; - switch (socketOptionLevel) + switch (socketOptionName) { case SocketOptionName_SO_DEBUG: *optName = SO_DEBUG; @@ -1680,7 +1680,7 @@ static bool TryGetPlatformSocketOption(int32_t socketOptionName, int32_t socketO case SocketOptionLevel_SOL_IP: *optLevel = IPPROTO_IP; - switch (socketOptionLevel) + switch (socketOptionName) { case SocketOptionName_SO_IP_OPTIONS: *optName = IP_OPTIONS; @@ -1759,7 +1759,7 @@ static bool TryGetPlatformSocketOption(int32_t socketOptionName, int32_t socketO case SocketOptionLevel_SOL_IPV6: *optLevel = IPPROTO_IPV6; - switch (socketOptionLevel) + switch (socketOptionName) { case SocketOptionName_SO_IPV6_HOPLIMIT: *optName = IPV6_HOPLIMIT; @@ -1793,7 +1793,7 @@ static bool TryGetPlatformSocketOption(int32_t socketOptionName, int32_t socketO case SocketOptionLevel_SOL_TCP: *optLevel = IPPROTO_TCP; - switch (socketOptionLevel) + switch (socketOptionName) { case SocketOptionName_SO_TCP_NODELAY: *optName = TCP_NODELAY; @@ -1825,7 +1825,7 @@ static bool TryGetPlatformSocketOption(int32_t socketOptionName, int32_t socketO case SocketOptionLevel_SOL_UDP: *optLevel = IPPROTO_UDP; - switch (socketOptionLevel) + switch (socketOptionName) { // case SocketOptionName_SO_UDP_NOCHECKSUM: From cf1390cbb7262fbedbbfc677f49a7fb3ed0df336 Mon Sep 17 00:00:00 2001 From: Tom Deseyn Date: Tue, 19 May 2020 20:43:24 +0200 Subject: [PATCH 279/420] Try using socket syscalls that accepts a single buffer to improve performance (#36371) * Try using socket syscalls that accepts a single buffer to improve performance * Remove ref from Receive calls * Prefix Pal methods invoking methods with Sys * Also use single-buffer syscalls for sync Socket Receive methods * Improve comment * PR feedback * Assert SocketAddress null instead of checking --- .../Unix/System.Native/Interop.Receive.cs | 16 ++ .../Unix/System.Native/Interop.Send.cs | 16 ++ .../Unix/System.Native/pal_networking.c | 62 +++++++- .../Unix/System.Native/pal_networking.h | 4 + .../src/System.Net.Sockets.csproj | 4 + .../src/System/Net/Sockets/Socket.cs | 2 +- .../Net/Sockets/SocketAsyncContext.Unix.cs | 53 ++++++- .../Net/Sockets/SocketAsyncEventArgs.Unix.cs | 12 +- .../src/System/Net/Sockets/SocketPal.Unix.cs | 140 +++++++++++++++--- .../System/Net/Sockets/SocketPal.Windows.cs | 2 +- 10 files changed, 282 insertions(+), 29 deletions(-) create mode 100644 src/libraries/Common/src/Interop/Unix/System.Native/Interop.Receive.cs create mode 100644 src/libraries/Common/src/Interop/Unix/System.Native/Interop.Send.cs diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Receive.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Receive.cs new file mode 100644 index 0000000000000..8f3cdbf9db07a --- /dev/null +++ b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Receive.cs @@ -0,0 +1,16 @@ +// 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. + +using System; +using System.Net.Sockets; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Sys + { + [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Receive")] + internal static extern unsafe Error Receive(SafeHandle socket, byte* buffer, int bufferLen, SocketFlags flags, int* received); + } +} diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Send.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Send.cs new file mode 100644 index 0000000000000..b4a7e1c9bc832 --- /dev/null +++ b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.Send.cs @@ -0,0 +1,16 @@ +// 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. + +using System; +using System.Net.Sockets; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Sys + { + [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Send")] + internal static extern unsafe Error Send(SafeHandle socket, byte* buffer, int bufferLen, SocketFlags flags, int* sent); + } +} diff --git a/src/libraries/Native/Unix/System.Native/pal_networking.c b/src/libraries/Native/Unix/System.Native/pal_networking.c index ba58024472b8e..9aabac040abe7 100644 --- a/src/libraries/Native/Unix/System.Native/pal_networking.c +++ b/src/libraries/Native/Unix/System.Native/pal_networking.c @@ -1348,6 +1348,34 @@ static int32_t ConvertSocketFlagsPlatformToPal(int platformFlags) ((platformFlags & MSG_CTRUNC) == 0 ? 0 : SocketFlags_MSG_CTRUNC); } +int32_t SystemNative_Receive(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* received) +{ + if (buffer == NULL || bufferLen < 0 || received == NULL) + { + return Error_EFAULT; + } + + int fd = ToFileDescriptor(socket); + + int socketFlags; + if (!ConvertSocketFlagsPalToPlatform(flags, &socketFlags)) + { + return Error_ENOTSUP; + } + + ssize_t res; + while ((res = recv(fd, buffer, (size_t)bufferLen, socketFlags)) < 0 && errno == EINTR); + + if (res != -1) + { + *received = (int32_t)res; + return Error_SUCCESS; + } + + *received = 0; + return SystemNative_ConvertErrorPlatformToPal(errno); +} + int32_t SystemNative_ReceiveMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* received) { if (messageHeader == NULL || received == NULL || messageHeader->SocketAddressLen < 0 || @@ -1391,6 +1419,38 @@ int32_t SystemNative_ReceiveMessage(intptr_t socket, MessageHeader* messageHeade return SystemNative_ConvertErrorPlatformToPal(errno); } +int32_t SystemNative_Send(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* sent) +{ + if (buffer == NULL || bufferLen < 0 || sent == NULL) + { + return Error_EFAULT; + } + + int fd = ToFileDescriptor(socket); + + int socketFlags; + if (!ConvertSocketFlagsPalToPlatform(flags, &socketFlags)) + { + return Error_ENOTSUP; + } + + ssize_t res; +#if defined(__APPLE__) && __APPLE__ + // possible OSX kernel bug: https://github.com/dotnet/runtime/issues/27221 + while ((res = send(fd, buffer, (size_t)bufferLen, socketFlags)) < 0 && (errno == EINTR || errno == EPROTOTYPE)); +#else + while ((res = send(fd, buffer, (size_t)bufferLen, socketFlags)) < 0 && errno == EINTR); +#endif + if (res != -1) + { + *sent = (int32_t)res; + return Error_SUCCESS; + } + + *sent = 0; + return SystemNative_ConvertErrorPlatformToPal(errno); +} + int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* sent) { if (messageHeader == NULL || sent == NULL || messageHeader->SocketAddressLen < 0 || @@ -1412,7 +1472,7 @@ int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, ssize_t res; #if defined(__APPLE__) && __APPLE__ - // possible OSX kernel bug: #31927 + // possible OSX kernel bug: https://github.com/dotnet/runtime/issues/27221 while ((res = sendmsg(fd, &header, socketFlags)) < 0 && (errno == EINTR || errno == EPROTOTYPE)); #else while ((res = sendmsg(fd, &header, socketFlags)) < 0 && errno == EINTR); diff --git a/src/libraries/Native/Unix/System.Native/pal_networking.h b/src/libraries/Native/Unix/System.Native/pal_networking.h index 4cd3ca922ea52..04f26eb6650d1 100644 --- a/src/libraries/Native/Unix/System.Native/pal_networking.h +++ b/src/libraries/Native/Unix/System.Native/pal_networking.h @@ -360,8 +360,12 @@ PALEXPORT int32_t SystemNative_SetReceiveTimeout(intptr_t socket, int32_t millis PALEXPORT int32_t SystemNative_SetSendTimeout(intptr_t socket, int32_t millisecondsTimeout); +PALEXPORT int32_t SystemNative_Receive(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* received); + PALEXPORT int32_t SystemNative_ReceiveMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* received); +PALEXPORT int32_t SystemNative_Send(intptr_t socket, void* buffer, int32_t bufferLen, int32_t flags, int32_t* sent); + PALEXPORT int32_t SystemNative_SendMessage(intptr_t socket, MessageHeader* messageHeader, int32_t flags, int64_t* sent); PALEXPORT int32_t SystemNative_Accept(intptr_t socket, uint8_t* socketAddress, int32_t* socketAddressLen, intptr_t* acceptedSocket); diff --git a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj index 3661f2bfafeda..8cda15170f21e 100644 --- a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj +++ b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj @@ -274,8 +274,12 @@ Link="Common\Interop\Unix\Interop.Poll.Structs.cs" /> + + > buffers, SocketFlags socketFlags, o if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"SRC:{LocalEndPoint} DST:{RemoteEndPoint}"); int bytesTransferred; - errorCode = SocketPal.Receive(_handle, buffers, ref socketFlags, out bytesTransferred); + errorCode = SocketPal.Receive(_handle, buffers, socketFlags, out bytesTransferred); #if TRACE_VERBOSE if (NetEventSource.IsEnabled) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs index a0479bfc33629..9934e5c97f656 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs @@ -463,6 +463,7 @@ private abstract class ReceiveOperation : ReadOperation private sealed class BufferMemoryReceiveOperation : ReceiveOperation { public Memory Buffer; + public bool SetReceivedFlags; public BufferMemoryReceiveOperation(SocketAsyncContext context) : base(context) { } @@ -479,7 +480,17 @@ protected override bool DoTryComplete(SocketAsyncContext context) } else { - return SocketPal.TryCompleteReceiveFrom(context._socket, Buffer.Span, null, Flags, SocketAddress, ref SocketAddressLen, out BytesTransferred, out ReceivedFlags, out ErrorCode); + if (!SetReceivedFlags) + { + Debug.Assert(SocketAddress == null); + + ReceivedFlags = SocketFlags.None; + return SocketPal.TryCompleteReceive(context._socket, Buffer.Span, Flags, out BytesTransferred, out ErrorCode); + } + else + { + return SocketPal.TryCompleteReceiveFrom(context._socket, Buffer.Span, null, Flags, SocketAddress, ref SocketAddressLen, out BytesTransferred, out ReceivedFlags, out ErrorCode); + } } } @@ -1465,13 +1476,13 @@ public SocketError ConnectAsync(byte[] socketAddress, int socketAddressLen, Acti return SocketError.IOPending; } - public SocketError Receive(Memory buffer, ref SocketFlags flags, int timeout, out int bytesReceived) + public SocketError Receive(Memory buffer, SocketFlags flags, int timeout, out int bytesReceived) { int socketAddressLen = 0; return ReceiveFrom(buffer, ref flags, null, ref socketAddressLen, timeout, out bytesReceived); } - public SocketError Receive(Span buffer, ref SocketFlags flags, int timeout, out int bytesReceived) + public SocketError Receive(Span buffer, SocketFlags flags, int timeout, out int bytesReceived) { int socketAddressLen = 0; return ReceiveFrom(buffer, ref flags, null, ref socketAddressLen, timeout, out bytesReceived); @@ -1545,6 +1556,39 @@ public unsafe SocketError ReceiveFrom(Span buffer, ref SocketFlags flags, } } + public SocketError ReceiveAsync(Memory buffer, SocketFlags flags, out int bytesReceived, Action callback, CancellationToken cancellationToken = default) + { + SetNonBlocking(); + + SocketError errorCode; + int observedSequenceNumber; + if (_receiveQueue.IsReady(this, out observedSequenceNumber) && + SocketPal.TryCompleteReceive(_socket, buffer.Span, flags, out bytesReceived, out errorCode)) + { + return errorCode; + } + + BufferMemoryReceiveOperation operation = RentBufferMemoryReceiveOperation(); + operation.SetReceivedFlags = false; + operation.Callback = callback; + operation.Buffer = buffer; + operation.Flags = flags; + operation.SocketAddress = null; + operation.SocketAddressLen = 0; + + if (!_receiveQueue.StartAsyncOperation(this, operation, observedSequenceNumber, cancellationToken)) + { + bytesReceived = operation.BytesTransferred; + errorCode = operation.ErrorCode; + + ReturnOperation(operation); + return errorCode; + } + + bytesReceived = 0; + return SocketError.IOPending; + } + public SocketError ReceiveFromAsync(Memory buffer, SocketFlags flags, byte[]? socketAddress, ref int socketAddressLen, out int bytesReceived, out SocketFlags receivedFlags, Action callback, CancellationToken cancellationToken = default) { SetNonBlocking(); @@ -1558,6 +1602,7 @@ public SocketError ReceiveFromAsync(Memory buffer, SocketFlags flags, byt } BufferMemoryReceiveOperation operation = RentBufferMemoryReceiveOperation(); + operation.SetReceivedFlags = true; operation.Callback = callback; operation.Buffer = buffer; operation.Flags = flags; @@ -1579,7 +1624,7 @@ public SocketError ReceiveFromAsync(Memory buffer, SocketFlags flags, byt return SocketError.IOPending; } - public SocketError Receive(IList> buffers, ref SocketFlags flags, int timeout, out int bytesReceived) + public SocketError Receive(IList> buffers, SocketFlags flags, int timeout, out int bytesReceived) { return ReceiveFrom(buffers, ref flags, null, 0, timeout, out bytesReceived); } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs index d2ca491a52ae9..99147f05a429c 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Unix.cs @@ -128,7 +128,17 @@ internal unsafe SocketError DoOperationReceive(SafeSocketHandle handle, Cancella SocketError errorCode; if (_bufferList == null) { - errorCode = handle.AsyncContext.ReceiveAsync(_buffer.Slice(_offset, _count), _socketFlags, out bytesReceived, out flags, TransferCompletionCallback, cancellationToken); + // TCP has no out-going receive flags. We can use different syscalls which give better performance. + bool noReceivedFlags = _currentSocket!.ProtocolType == ProtocolType.Tcp; + if (noReceivedFlags) + { + errorCode = handle.AsyncContext.ReceiveAsync(_buffer.Slice(_offset, _count), _socketFlags, out bytesReceived, TransferCompletionCallback, cancellationToken); + flags = SocketFlags.None; + } + else + { + errorCode = handle.AsyncContext.ReceiveAsync(_buffer.Slice(_offset, _count), _socketFlags, out bytesReceived, out flags, TransferCompletionCallback, cancellationToken); + } } else { diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs index 2c3fd57c279af..f174b732c2552 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Unix.cs @@ -96,7 +96,29 @@ public static unsafe SocketError CreateSocket(AddressFamily addressFamily, Socke return errorCode; } - private static unsafe int Receive(SafeSocketHandle socket, SocketFlags flags, Span buffer, byte[]? socketAddress, ref int socketAddressLen, out SocketFlags receivedFlags, out Interop.Error errno) + private static unsafe int SysReceive(SafeSocketHandle socket, SocketFlags flags, Span buffer, out Interop.Error errno) + { + int received = 0; + + fixed (byte* b = &MemoryMarshal.GetReference(buffer)) + { + errno = Interop.Sys.Receive( + socket, + b, + buffer.Length, + flags, + &received); + } + + if (errno != Interop.Error.SUCCESS) + { + return -1; + } + + return received; + } + + private static unsafe int SysReceive(SafeSocketHandle socket, SocketFlags flags, Span buffer, byte[]? socketAddress, ref int socketAddressLen, out SocketFlags receivedFlags, out Interop.Error errno) { Debug.Assert(socketAddress != null || socketAddressLen == 0, $"Unexpected values: socketAddress={socketAddress}, socketAddressLen={socketAddressLen}"); @@ -137,7 +159,30 @@ private static unsafe int Receive(SafeSocketHandle socket, SocketFlags flags, Sp return checked((int)received); } - private static unsafe int Send(SafeSocketHandle socket, SocketFlags flags, ReadOnlySpan buffer, ref int offset, ref int count, byte[]? socketAddress, int socketAddressLen, out Interop.Error errno) + private static unsafe int SysSend(SafeSocketHandle socket, SocketFlags flags, ReadOnlySpan buffer, ref int offset, ref int count, out Interop.Error errno) + { + int sent; + fixed (byte* b = &MemoryMarshal.GetReference(buffer)) + { + errno = Interop.Sys.Send( + socket, + &b[offset], + count, + flags, + &sent); + } + + if (errno != Interop.Error.SUCCESS) + { + return -1; + } + + offset += sent; + count -= sent; + return sent; + } + + private static unsafe int SysSend(SafeSocketHandle socket, SocketFlags flags, ReadOnlySpan buffer, ref int offset, ref int count, byte[] socketAddress, int socketAddressLen, out Interop.Error errno) { int sent; fixed (byte* sockAddr = socketAddress) @@ -177,7 +222,7 @@ private static unsafe int Send(SafeSocketHandle socket, SocketFlags flags, ReadO return sent; } - private static unsafe int Send(SafeSocketHandle socket, SocketFlags flags, IList> buffers, ref int bufferIndex, ref int offset, byte[]? socketAddress, int socketAddressLen, out Interop.Error errno) + private static unsafe int SysSend(SafeSocketHandle socket, SocketFlags flags, IList> buffers, ref int bufferIndex, ref int offset, byte[]? socketAddress, int socketAddressLen, out Interop.Error errno) { // Pin buffers and set up iovecs. int startIndex = bufferIndex, startOffset = offset; @@ -274,7 +319,7 @@ private static unsafe long SendFile(SafeSocketHandle socket, SafeFileHandle file return bytesSent; } - private static unsafe int Receive(SafeSocketHandle socket, SocketFlags flags, IList> buffers, byte[]? socketAddress, ref int socketAddressLen, out SocketFlags receivedFlags, out Interop.Error errno) + private static unsafe int SysReceive(SafeSocketHandle socket, SocketFlags flags, IList> buffers, byte[]? socketAddress, ref int socketAddressLen, out SocketFlags receivedFlags, out Interop.Error errno) { int available = 0; errno = Interop.Sys.GetBytesAvailable(socket, &available); @@ -373,7 +418,7 @@ private static unsafe int Receive(SafeSocketHandle socket, SocketFlags flags, IL return checked((int)received); } - private static unsafe int ReceiveMessageFrom(SafeSocketHandle socket, SocketFlags flags, Span buffer, byte[] socketAddress, ref int socketAddressLen, bool isIPv4, bool isIPv6, out SocketFlags receivedFlags, out IPPacketInformation ipPacketInformation, out Interop.Error errno) + private static unsafe int SysReceiveMessageFrom(SafeSocketHandle socket, SocketFlags flags, Span buffer, byte[] socketAddress, ref int socketAddressLen, bool isIPv4, bool isIPv6, out SocketFlags receivedFlags, out IPPacketInformation ipPacketInformation, out Interop.Error errno) { Debug.Assert(socketAddress != null, "Expected non-null socketAddress"); @@ -423,7 +468,7 @@ private static unsafe int ReceiveMessageFrom(SafeSocketHandle socket, SocketFlag return checked((int)received); } - private static unsafe int ReceiveMessageFrom( + private static unsafe int SysReceiveMessageFrom( SafeSocketHandle socket, SocketFlags flags, IList> buffers, byte[] socketAddress, ref int socketAddressLen, bool isIPv4, bool isIPv6, out SocketFlags receivedFlags, out IPPacketInformation ipPacketInformation, out Interop.Error errno) @@ -617,6 +662,60 @@ public static unsafe bool TryCompleteConnect(SafeSocketHandle socket, int socket public static bool TryCompleteReceiveFrom(SafeSocketHandle socket, IList> buffers, SocketFlags flags, byte[]? socketAddress, ref int socketAddressLen, out int bytesReceived, out SocketFlags receivedFlags, out SocketError errorCode) => TryCompleteReceiveFrom(socket, default(Span), buffers, flags, socketAddress, ref socketAddressLen, out bytesReceived, out receivedFlags, out errorCode); + public static unsafe bool TryCompleteReceive(SafeSocketHandle socket, Span buffer, SocketFlags flags, out int bytesReceived, out SocketError errorCode) + { + try + { + Interop.Error errno; + int received; + + if (buffer.Length == 0) + { + // Special case a receive of 0 bytes into a single buffer. A common pattern is to ReceiveAsync 0 bytes in order + // to be asynchronously notified when data is available, without needing to dedicate a buffer. Some platforms (e.g. macOS), + // however complete a 0-byte read successfully when data isn't available, as the request can logically be satisfied + // synchronously. As such, we treat 0 specially, and perform a 1-byte peek. + byte oneBytePeekBuffer; + received = SysReceive(socket, flags | SocketFlags.Peek, new Span(&oneBytePeekBuffer, 1), out errno); + if (received > 0) + { + // Peeked for 1-byte, but the actual request was for 0. + received = 0; + } + } + else + { + // Receive > 0 bytes into a single buffer + received = SysReceive(socket, flags, buffer, out errno); + } + + if (received != -1) + { + bytesReceived = received; + errorCode = SocketError.Success; + return true; + } + + bytesReceived = 0; + + if (errno != Interop.Error.EAGAIN && errno != Interop.Error.EWOULDBLOCK) + { + errorCode = GetSocketErrorForErrorCode(errno); + return true; + } + + errorCode = SocketError.Success; + return false; + } + catch (ObjectDisposedException) + { + // The socket was closed, or is closing. + bytesReceived = 0; + errorCode = SocketError.OperationAborted; + return true; + } + } + public static unsafe bool TryCompleteReceiveFrom(SafeSocketHandle socket, Span buffer, IList>? buffers, SocketFlags flags, byte[]? socketAddress, ref int socketAddressLen, out int bytesReceived, out SocketFlags receivedFlags, out SocketError errorCode) { try @@ -627,7 +726,7 @@ public static unsafe bool TryCompleteReceiveFrom(SafeSocketHandle socket, Span(&oneBytePeekBuffer, 1), socketAddress, ref socketAddressLen, out receivedFlags, out errno); + received = SysReceive(socket, flags | SocketFlags.Peek, new Span(&oneBytePeekBuffer, 1), socketAddress, ref socketAddressLen, out receivedFlags, out errno); if (received > 0) { // Peeked for 1-byte, but the actual request was for 0. @@ -646,7 +745,7 @@ public static unsafe bool TryCompleteReceiveFrom(SafeSocketHandle socket, Span 0 bytes into a single buffer - received = Receive(socket, flags, buffer, socketAddress, ref socketAddressLen, out receivedFlags, out errno); + received = SysReceive(socket, flags, buffer, socketAddress, ref socketAddressLen, out receivedFlags, out errno); } if (received != -1) @@ -684,8 +783,8 @@ public static unsafe bool TryCompleteReceiveMessageFrom(SafeSocketHandle socket, Interop.Error errno; int received = buffers == null ? - ReceiveMessageFrom(socket, flags, buffer, socketAddress, ref socketAddressLen, isIPv4, isIPv6, out receivedFlags, out ipPacketInformation, out errno) : - ReceiveMessageFrom(socket, flags, buffers, socketAddress, ref socketAddressLen, isIPv4, isIPv6, out receivedFlags, out ipPacketInformation, out errno); + SysReceiveMessageFrom(socket, flags, buffer, socketAddress, ref socketAddressLen, isIPv4, isIPv6, out receivedFlags, out ipPacketInformation, out errno) : + SysReceiveMessageFrom(socket, flags, buffers, socketAddress, ref socketAddressLen, isIPv4, isIPv6, out receivedFlags, out ipPacketInformation, out errno); if (received != -1) { @@ -746,8 +845,9 @@ public static bool TryCompleteSendTo(SafeSocketHandle socket, ReadOnlySpan try { sent = buffers != null ? - Send(socket, flags, buffers, ref bufferIndex, ref offset, socketAddress, socketAddressLen, out errno) : - Send(socket, flags, buffer, ref offset, ref count, socketAddress, socketAddressLen, out errno); + SysSend(socket, flags, buffers, ref bufferIndex, ref offset, socketAddress, socketAddressLen, out errno) : + socketAddress == null ? SysSend(socket, flags, buffer, ref offset, ref count, out errno) : + SysSend(socket, flags, buffer, ref offset, ref count, socketAddress, socketAddressLen, out errno); } catch (ObjectDisposedException) { @@ -1009,12 +1109,12 @@ public static SocketError SendTo(SafeSocketHandle handle, byte[] buffer, int off return errorCode; } - public static SocketError Receive(SafeSocketHandle handle, IList> buffers, ref SocketFlags socketFlags, out int bytesTransferred) + public static SocketError Receive(SafeSocketHandle handle, IList> buffers, SocketFlags socketFlags, out int bytesTransferred) { SocketError errorCode; if (!handle.IsNonBlocking) { - errorCode = handle.AsyncContext.Receive(buffers, ref socketFlags, handle.ReceiveTimeout, out bytesTransferred); + errorCode = handle.AsyncContext.Receive(buffers, socketFlags, handle.ReceiveTimeout, out bytesTransferred); } else { @@ -1032,12 +1132,11 @@ public static SocketError Receive(SafeSocketHandle handle, byte[] buffer, int of { if (!handle.IsNonBlocking) { - return handle.AsyncContext.Receive(new Memory(buffer, offset, count), ref socketFlags, handle.ReceiveTimeout, out bytesTransferred); + return handle.AsyncContext.Receive(new Memory(buffer, offset, count), socketFlags, handle.ReceiveTimeout, out bytesTransferred); } - int socketAddressLen = 0; SocketError errorCode; - bool completed = TryCompleteReceiveFrom(handle, new Span(buffer, offset, count), socketFlags, null, ref socketAddressLen, out bytesTransferred, out socketFlags, out errorCode); + bool completed = TryCompleteReceive(handle, new Span(buffer, offset, count), socketFlags, out bytesTransferred, out errorCode); return completed ? errorCode : SocketError.WouldBlock; } @@ -1045,12 +1144,11 @@ public static SocketError Receive(SafeSocketHandle handle, Span buffer, So { if (!handle.IsNonBlocking) { - return handle.AsyncContext.Receive(buffer, ref socketFlags, handle.ReceiveTimeout, out bytesTransferred); + return handle.AsyncContext.Receive(buffer, socketFlags, handle.ReceiveTimeout, out bytesTransferred); } - int socketAddressLen = 0; SocketError errorCode; - bool completed = TryCompleteReceiveFrom(handle, buffer, socketFlags, null, ref socketAddressLen, out bytesTransferred, out socketFlags, out errorCode); + bool completed = TryCompleteReceive(handle, buffer, socketFlags, out bytesTransferred, out errorCode); return completed ? errorCode : SocketError.WouldBlock; } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs index ed39e9be08b67..6ea3e1cc03aa2 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketPal.Windows.cs @@ -338,7 +338,7 @@ public static unsafe SocketError SendTo(SafeSocketHandle handle, byte[] buffer, return SocketError.Success; } - public static SocketError Receive(SafeSocketHandle handle, IList> buffers, ref SocketFlags socketFlags, out int bytesTransferred) + public static SocketError Receive(SafeSocketHandle handle, IList> buffers, SocketFlags socketFlags, out int bytesTransferred) { const int StackThreshold = 16; // arbitrary limit to avoid too much space on stack (note: may be over-sized, that's OK - length passed separately) int count = buffers.Count; From ebc55e399bda0347dd187bf004ccebc77fb778d7 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Tue, 19 May 2020 13:42:11 -0700 Subject: [PATCH 280/420] fix handling of Ssl2 and enable disabled tests (#36098) * attempt to fix ssl2 * adjust length calculation * enable tests * fix ReadAsyncInternal * use PlatformDetection.SupportsSsl2 * feedback from review Co-authored-by: Tomas Weinfurt --- .../HttpClientHandlerTest.SslProtocols.cs | 4 +- .../Net/Security/SslStream.Implementation.cs | 49 ++++++++++--------- .../ClientAsyncAuthenticateTest.cs | 3 +- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs index 9c9ad3fc8b16a..735642702cded 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs @@ -113,7 +113,6 @@ public static IEnumerable GetAsync_AllowedSSLVersion_Succeeds_MemberDa [Theory] [MemberData(nameof(GetAsync_AllowedSSLVersion_Succeeds_MemberData))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/36100", TestPlatforms.Windows)] public async Task GetAsync_AllowedSSLVersion_Succeeds(SslProtocols acceptedProtocol, bool requestOnlyThisProtocol) { using (HttpClientHandler handler = CreateHttpClientHandler()) @@ -196,7 +195,7 @@ public async Task GetAsync_SupportedSSLVersion_Succeeds(SslProtocols sslProtocol public static IEnumerable NotSupportedSSLVersionServers() { #pragma warning disable 0618 - if (PlatformDetection.IsWindows10Version1607OrGreater) + if (PlatformDetection.SupportsSsl2) { yield return new object[] { SslProtocols.Ssl2, Configuration.Http.SSLv2RemoteServer }; } @@ -249,7 +248,6 @@ public async Task GetAsync_NoSpecifiedProtocol_DefaultsToTls12() [InlineData(SslProtocols.Tls11 | SslProtocols.Tls12, SslProtocols.Tls)] // Skip this on WinHttpHandler. [InlineData(SslProtocols.Tls12, SslProtocols.Tls11)] [InlineData(SslProtocols.Tls, SslProtocols.Tls12)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/36100", TestPlatforms.Windows)] public async Task GetAsync_AllowedClientSslVersionDiffersFromServer_ThrowsException( SslProtocols allowedClientProtocols, SslProtocols acceptedServerProtocols) { diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs index 68b142521d21c..7b9dd62870c4e 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs @@ -24,11 +24,11 @@ public partial class SslStream private enum Framing { - Unknown = 0, - BeforeSSL3, - SinceSSL3, - Unified, - Invalid + Unknown = 0, // Initial before any frame is processd. + BeforeSSL3, // SSlv2 + SinceSSL3, // SSlv3 & TLS + Unified, // Intermediate on first frame until response is processes. + Invalid // Somthing is wrong. } // This is set on the first packet to figure out the framing style. @@ -352,12 +352,12 @@ private async ValueTask ReceiveBlobAsync(TIOAdapter a _framing = DetectFraming(_handshakeBuffer.ActiveReadOnlySpan); } - if (_framing == Framing.BeforeSSL3) + if (_framing != Framing.SinceSSL3) { #pragma warning disable 0618 _lastFrame.Header.Version = SslProtocols.Ssl2; #pragma warning restore 0618 - _lastFrame.Header.Length = GetFrameSize(_handshakeBuffer.ActiveReadOnlySpan); + _lastFrame.Header.Length = GetFrameSize(_handshakeBuffer.ActiveReadOnlySpan) - TlsFrameHelper.HeaderSize; } else { @@ -409,25 +409,28 @@ private ProtocolToken ProcessBlob(int frameSize) // ActiveSpan will exclude the "discarded" data. _handshakeBuffer.Discard(frameSize); - // Often more TLS messages fit into same packet. Get as many complete frames as we can. - while (_handshakeBuffer.ActiveLength > TlsFrameHelper.HeaderSize) + if (_framing == Framing.SinceSSL3) { - TlsFrameHeader nextHeader = default; - - if (!TlsFrameHelper.TryGetFrameHeader(_handshakeBuffer.ActiveReadOnlySpan, ref nextHeader)) + // Often more TLS messages fit into same packet. Get as many complete frames as we can. + while (_handshakeBuffer.ActiveLength > TlsFrameHelper.HeaderSize) { - break; - } + TlsFrameHeader nextHeader = default; - frameSize = nextHeader.Length + TlsFrameHelper.HeaderSize; - if (nextHeader.Type == TlsContentType.AppData || frameSize > _handshakeBuffer.ActiveLength) - { - // We don't have full frame left or we already have app data which needs to be processed by decrypt. - break; - } + if (!TlsFrameHelper.TryGetFrameHeader(_handshakeBuffer.ActiveReadOnlySpan, ref nextHeader)) + { + break; + } + + frameSize = nextHeader.Length + TlsFrameHelper.HeaderSize; + if (nextHeader.Type == TlsContentType.AppData || frameSize > _handshakeBuffer.ActiveLength) + { + // We don't have full frame left or we already have app data which needs to be processed by decrypt. + break; + } - chunkSize += frameSize; - _handshakeBuffer.Discard(frameSize); + chunkSize += frameSize; + _handshakeBuffer.Discard(frameSize); + } } return _context!.NextMessage(availableData.Slice(0, chunkSize)); @@ -684,7 +687,7 @@ private async ValueTask ReadAsyncInternal(TIOAdapter adapter, M Debug.Assert(_internalBufferCount >= SecureChannel.ReadHeaderSize); // Parse the frame header to determine the payload size (which includes the header size). - int payloadBytes = TlsFrameHelper.GetFrameSize(_internalBuffer.AsSpan(_internalOffset)); + int payloadBytes = GetFrameSize(_internalBuffer.AsSpan(_internalOffset)); if (payloadBytes < 0) { throw new IOException(SR.net_frame_read_size); diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs index 2ea89a4148b94..a8dba5b6b0b6b 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs @@ -59,12 +59,11 @@ public async Task ClientAsyncAuthenticate_EachSupportedProtocol_Success(SslProto [Fact] [PlatformSpecific(TestPlatforms.Windows)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/36100")] public async Task ClientAsyncAuthenticate_Ssl2WithSelf_Success() { // Test Ssl2 against itself. This is a standalone test as even on versions where Windows supports Ssl2, // it appears to have rules around not using it when other protocols are mentioned. - if (!PlatformDetection.IsWindows10Version1607OrGreater) + if (PlatformDetection.SupportsSsl2) { #pragma warning disable 0618 await ClientAsyncSslHelper(SslProtocols.Ssl2, SslProtocols.Ssl2); From 8f929a123fcd9b9c8d7841a26ff87e4843c8ffa5 Mon Sep 17 00:00:00 2001 From: Nathan Ricci Date: Tue, 19 May 2020 17:28:54 -0400 Subject: [PATCH 281/420] Removed extra slash. (#36722) Remove extra / from path on runtimetests. --- eng/pipelines/runtime.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index d73ebcdee2594..c340890b49388 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -107,8 +107,8 @@ jobs: - eng/pipelines/installer/* - subset: runtimetests include: - - /src/coreclr/tests/* - - /src/coreclr/build-test.sh + - src/coreclr/tests/* + - src/coreclr/build-test.sh - subset: installer include: - docs/manpages/* From 5685928450d6cce9e794afcd242bd1d67c02854f Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Tue, 19 May 2020 14:38:28 -0700 Subject: [PATCH 282/420] Contain non-candidate regOptional lclVars (#36601) --- src/coreclr/src/jit/lsraarm.cpp | 17 +++++++++---- src/coreclr/src/jit/lsraarm64.cpp | 16 ++++++++++--- src/coreclr/src/jit/lsraxarch.cpp | 40 ++++++++++++++----------------- 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/coreclr/src/jit/lsraarm.cpp b/src/coreclr/src/jit/lsraarm.cpp index b28e295443b69..165ad929fbc05 100644 --- a/src/coreclr/src/jit/lsraarm.cpp +++ b/src/coreclr/src/jit/lsraarm.cpp @@ -219,7 +219,6 @@ int LinearScan::BuildNode(GenTree* tree) switch (tree->OperGet()) { case GT_LCL_VAR: - case GT_LCL_FLD: { // We handle tracked variables differently from non-tracked ones. If it is tracked, // we will simply add a use of the tracked variable at its parent/consumer. @@ -230,13 +229,23 @@ int LinearScan::BuildNode(GenTree* tree) // is processed, unless this is marked "isLocalDefUse" because it is a stack-based argument // to a call or an orphaned dead node. // - GenTreeLclVarCommon* const lclVar = tree->AsLclVarCommon(); - LclVarDsc* const varDsc = compiler->lvaGetDesc(lclVar); - if (isCandidateVar(varDsc)) + bool isCandidate = compiler->lvaGetDesc(tree->AsLclVar())->lvLRACandidate; + if (tree->IsRegOptional() && !isCandidate) + { + tree->ClearRegOptional(); + tree->SetContained(); + return 0; + } + if (isCandidate) { return 0; } + } + __fallthrough; + case GT_LCL_FLD: + { + GenTreeLclVarCommon* const lclVar = tree->AsLclVarCommon(); if (lclVar->OperIs(GT_LCL_FLD) && lclVar->AsLclFld()->IsOffsetMisaligned()) { buildInternalIntRegisterDefForNode(lclVar); // to generate address. diff --git a/src/coreclr/src/jit/lsraarm64.cpp b/src/coreclr/src/jit/lsraarm64.cpp index c69a6cfab03cd..60084a8e65f3e 100644 --- a/src/coreclr/src/jit/lsraarm64.cpp +++ b/src/coreclr/src/jit/lsraarm64.cpp @@ -76,7 +76,6 @@ int LinearScan::BuildNode(GenTree* tree) break; case GT_LCL_VAR: - case GT_LCL_FLD: { // We handle tracked variables differently from non-tracked ones. If it is tracked, // we will simply add a use of the tracked variable at its parent/consumer. @@ -87,11 +86,22 @@ int LinearScan::BuildNode(GenTree* tree) // is processed, unless this is marked "isLocalDefUse" because it is a stack-based argument // to a call or an orphaned dead node. // - LclVarDsc* const varDsc = &compiler->lvaTable[tree->AsLclVarCommon()->GetLclNum()]; - if (isCandidateVar(varDsc)) + bool isCandidate = compiler->lvaGetDesc(tree->AsLclVar())->lvLRACandidate; + if (tree->IsRegOptional() && !isCandidate) { + tree->ClearRegOptional(); + tree->SetContained(); return 0; } + if (isCandidate) + { + return 0; + } + } + __fallthrough; + + case GT_LCL_FLD: + { srcCount = 0; #ifdef FEATURE_SIMD // Need an additional register to read upper 4 bytes of Vector3. diff --git a/src/coreclr/src/jit/lsraxarch.cpp b/src/coreclr/src/jit/lsraxarch.cpp index 772ab8c12c208..1bc0f36bfb26d 100644 --- a/src/coreclr/src/jit/lsraxarch.cpp +++ b/src/coreclr/src/jit/lsraxarch.cpp @@ -83,26 +83,6 @@ int LinearScan::BuildNode(GenTree* tree) break; case GT_LCL_VAR: - // Because we do containment analysis before we redo dataflow and identify register - // candidates, the containment analysis only uses !lvDoNotEnregister to estimate register - // candidates. - // If there is a lclVar that is estimated to be register candidate but - // is not, if they were marked regOptional they should now be marked contained instead. - // TODO-XArch-CQ: When this is being called while RefPositions are being created, - // use lvLRACandidate here instead. - if (tree->IsRegOptional()) - { - if (!compiler->lvaTable[tree->AsLclVarCommon()->GetLclNum()].lvTracked || - compiler->lvaTable[tree->AsLclVarCommon()->GetLclNum()].lvDoNotEnregister) - { - tree->ClearRegOptional(); - tree->SetContained(); - return 0; - } - } - __fallthrough; - - case GT_LCL_FLD: { // We handle tracked variables differently from non-tracked ones. If it is tracked, // we will simply add a use of the tracked variable at its parent/consumer. @@ -113,11 +93,27 @@ int LinearScan::BuildNode(GenTree* tree) // is processed, unless this is marked "isLocalDefUse" because it is a stack-based argument // to a call or an orphaned dead node. // - LclVarDsc* const varDsc = &compiler->lvaTable[tree->AsLclVarCommon()->GetLclNum()]; - if (isCandidateVar(varDsc)) + // Because we do containment analysis before we redo dataflow and identify register + // candidates, the containment analysis only uses !lvDoNotEnregister to estimate register + // candidates. + // If there is a lclVar that is estimated to be register candidate but + // is not, if they were marked regOptional they should now be marked contained instead. + bool isCandidate = compiler->lvaGetDesc(tree->AsLclVar())->lvLRACandidate; + if (tree->IsRegOptional() && !isCandidate) + { + tree->ClearRegOptional(); + tree->SetContained(); + return 0; + } + if (isCandidate) { return 0; } + } + __fallthrough; + + case GT_LCL_FLD: + { srcCount = 0; #ifdef FEATURE_SIMD // Need an additional register to read upper 4 bytes of Vector3. From a01c3abe20834479eca06e9c0590f1508d26a3ec Mon Sep 17 00:00:00 2001 From: Anirudh Agnihotry Date: Tue, 19 May 2020 14:44:01 -0700 Subject: [PATCH 283/420] Adding a ci leg for Source build (#36141) * successfullsource build * adding a new source build leg. * remove yy * add default vlaue * addressing feedback * use boolean value * addind comment and other feedback * adding colon and removing unintentional change * adding default value of isSourceBUild --- eng/notSupported.SourceBuild.targets | 6 +++++- eng/pipelines/libraries/base-job.yml | 12 ++++++++++-- eng/pipelines/libraries/build-job.yml | 4 +++- eng/pipelines/runtime.yml | 18 ++++++++++++++++++ 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/eng/notSupported.SourceBuild.targets b/eng/notSupported.SourceBuild.targets index afbbdd32de404..743c4a3ace00b 100644 --- a/eng/notSupported.SourceBuild.targets +++ b/eng/notSupported.SourceBuild.targets @@ -3,7 +3,11 @@ BeforeTargets="BeforeCompile" Condition="'$(DotNetBuildFromSource)' == 'true' and ('$(GeneratePlatformNotSupportedAssembly)' == 'true' or '$(GeneratePlatformNotSupportedAssemblyMessage)' != '')"> - + + + $(IntermediateOutputPath) + + diff --git a/eng/pipelines/libraries/base-job.yml b/eng/pipelines/libraries/base-job.yml index 53305711a23b5..575f23f31bc4c 100644 --- a/eng/pipelines/libraries/base-job.yml +++ b/eng/pipelines/libraries/base-job.yml @@ -7,6 +7,7 @@ parameters: framework: '' isOfficialBuild: false isOfficialAllConfigurations: false + isSourceBuild: false liveRuntimeBuildConfig: '' runtimeFlavor: 'coreclr' timeoutInMinutes: 150 @@ -24,8 +25,12 @@ jobs: - template: /eng/common/templates/job/job.yml parameters: ${{ if notIn(parameters.framework, 'allConfigurations', 'net472') }}: - displayName: ${{ format('Libraries {0} {1}{2} {3} {4}', parameters.displayName, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - name: ${{ format('libraries_{0}_{1}{2}_{3}_{4}', parameters.name, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + ${{ if eq(parameters.isSourceBuild, false) }}: + displayName: ${{ format('Libraries {0} {1}{2} {3} {4}', parameters.displayName, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + name: ${{ format('libraries_{0}_{1}{2}_{3}_{4}', parameters.name, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + ${{ if eq(parameters.isSourceBuild, true) }}: + displayName: ${{ format('Libraries {0} {1}{2} {3} {4}', 'Source Build', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + name: ${{ format('libraries_{0}_{1}{2}_{3}_{4}', 'sourcebuild', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} ${{ if in(parameters.framework, 'allConfigurations', 'net472') }}: displayName: ${{ format('Libraries {0} {1} {2} {3} {4}', parameters.displayName, parameters.osGroup, parameters.framework, parameters.archType, parameters.buildConfig) }} name: ${{ format('libraries_{0}_{1}_{2}{3}_{4}_{5}', parameters.name, parameters.framework, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} @@ -75,6 +80,9 @@ jobs: - _finalFrameworkArg: -allConfigurations - _extraHelixArguments: /p:BuildAllConfigurations=true + - ${{ if eq(parameters.isSourceBuild, true) }}: + - _finalFrameworkArg: /p:DotnetBuildFromSource=true + - ${{ if eq(parameters.isOfficialAllConfigurations, true) }}: - librariesBuildArtifactName: 'libraries_bin_official_allconfigurations' diff --git a/eng/pipelines/libraries/build-job.yml b/eng/pipelines/libraries/build-job.yml index 2b4e3dd097ac1..2287c8f1dafb1 100644 --- a/eng/pipelines/libraries/build-job.yml +++ b/eng/pipelines/libraries/build-job.yml @@ -5,6 +5,7 @@ parameters: archType: '' crossrootfsDir: '' framework: '' + isSourceBuild: false isOfficialBuild: false isOfficialAllConfigurations: false runtimeVariant: '' @@ -37,6 +38,7 @@ jobs: framework: ${{ parameters.framework }} isOfficialBuild: ${{ parameters.isOfficialBuild }} isOfficialAllConfigurations: ${{ parameters.isOfficialAllConfigurations }} + isSourceBuild: ${{ parameters.isSourceBuild }} liveRuntimeBuildConfig: ${{ parameters.liveRuntimeBuildConfig }} runtimeFlavor: ${{ parameters.runtimeFlavor }} timeoutInMinutes: ${{ parameters.timeoutInMinutes }} @@ -96,7 +98,7 @@ jobs: df -h displayName: Disk Usage after Build - - ${{ if eq(parameters.runTests, false) }}: + - ${{ if and(eq(parameters.runTests, false), ne(parameters.isSourceBuild, true)) }}: - ${{ if ne(parameters.isOfficialBuild, true) }}: - task: CopyFiles@2 displayName: Prepare testhost folder to publish diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index c340890b49388..47df45a852015 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -548,6 +548,24 @@ jobs: eq(dependencies.checkout.outputs['SetPathVars_libraries.containsChange'], true), eq(variables['isFullMatrix'], true)) +# +# Libraries Sourcebuild Build +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/libraries/build-job.yml + buildConfig: Release + platforms: + - Linux_x64 + jobParameters: + runTests: false + liveRuntimeBuildConfig: release + isSourceBuild: true + condition: >- + or( + eq(dependencies.checkout.outputs['SetPathVars_libraries.containsChange'], true), + eq(variables['isFullMatrix'], true)) + # # Installer Build and Test # These are always built since they only take like 15 minutes From 806493637dca97cedba0b815692fa59aeea6a916 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Tue, 19 May 2020 23:00:47 +0100 Subject: [PATCH 284/420] Remove TheadPool initialization volatile (#36697) * Remove TheadPool initialization volatile * Better ThreadPoolGlobals setup for Mono * Feedback * Move back to lambda --- .../System/Threading/ThreadPool.CoreCLR.cs | 27 ++----- .../ConfiguredValueTaskAwaitable.cs | 4 +- .../CompilerServices/ValueTaskAwaiter.cs | 4 +- .../src/System/Threading/ThreadPool.cs | 71 +++++++------------ .../src/System/Threading/ThreadPool.Mono.cs | 8 +-- 5 files changed, 40 insertions(+), 74 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs index 9752c3cbde366..719576c06d033 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs @@ -192,6 +192,13 @@ public static partial class ThreadPool // Time in ms for which ThreadPoolWorkQueue.Dispatch keeps executing work items before returning to the OS private const uint DispatchQuantum = 30; + private static bool GetEnableWorkerTracking() + { + bool enableWorkerTracking = false; + InitializeVMTp(ref enableWorkerTracking); + return enableWorkerTracking; + } + internal static bool KeepDispatching(int startTickCount) { // Note: this function may incorrectly return false due to TickCount overflow @@ -302,25 +309,6 @@ bool compressStack public static unsafe bool UnsafeQueueNativeOverlapped(NativeOverlapped* overlapped) => PostQueuedCompletionStatus(overlapped); - // The thread pool maintains a per-appdomain managed work queue. - // New thread pool entries are added in the managed queue. - // The VM is responsible for the actual growing/shrinking of - // threads. - private static void EnsureInitialized() - { - if (!ThreadPoolGlobals.threadPoolInitialized) - { - EnsureVMInitializedCore(); // separate out to help with inlining - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static void EnsureVMInitializedCore() - { - InitializeVMTp(ref ThreadPoolGlobals.enableWorkerTracking); - ThreadPoolGlobals.threadPoolInitialized = true; - } - // Native methods: [MethodImpl(MethodImplOptions.InternalCall)] @@ -346,7 +334,6 @@ private static void EnsureVMInitializedCore() internal static void NotifyWorkItemProgress() { - EnsureInitialized(); NotifyWorkItemProgressNative(); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs index 78d70e7703c64..bf5edf4774c9e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs @@ -105,7 +105,7 @@ void IStateMachineBoxAwareAwaiter.AwaitUnsafeOnCompleted(IAsyncStateMachineBox b } else if (obj != null) { - Unsafe.As(obj).OnCompleted(ThreadPoolGlobals.s_invokeAsyncStateMachineBox, box, _value._token, + Unsafe.As(obj).OnCompleted(ThreadPool.s_invokeAsyncStateMachineBox, box, _value._token, _value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None); } else @@ -210,7 +210,7 @@ void IStateMachineBoxAwareAwaiter.AwaitUnsafeOnCompleted(IAsyncStateMachineBox b } else if (obj != null) { - Unsafe.As>(obj).OnCompleted(ThreadPoolGlobals.s_invokeAsyncStateMachineBox, box, _value._token, + Unsafe.As>(obj).OnCompleted(ThreadPool.s_invokeAsyncStateMachineBox, box, _value._token, _value._continueOnCapturedContext ? ValueTaskSourceOnCompletedFlags.UseSchedulingContext : ValueTaskSourceOnCompletedFlags.None); } else diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValueTaskAwaiter.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValueTaskAwaiter.cs index 07f9441518584..ca7a0a0ca742e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValueTaskAwaiter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValueTaskAwaiter.cs @@ -95,7 +95,7 @@ void IStateMachineBoxAwareAwaiter.AwaitUnsafeOnCompleted(IAsyncStateMachineBox b } else if (obj != null) { - Unsafe.As(obj).OnCompleted(ThreadPoolGlobals.s_invokeAsyncStateMachineBox, box, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext); + Unsafe.As(obj).OnCompleted(ThreadPool.s_invokeAsyncStateMachineBox, box, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext); } else { @@ -177,7 +177,7 @@ void IStateMachineBoxAwareAwaiter.AwaitUnsafeOnCompleted(IAsyncStateMachineBox b } else if (obj != null) { - Unsafe.As>(obj).OnCompleted(ThreadPoolGlobals.s_invokeAsyncStateMachineBox, box, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext); + Unsafe.As>(obj).OnCompleted(ThreadPool.s_invokeAsyncStateMachineBox, box, _value._token, ValueTaskSourceOnCompletedFlags.UseSchedulingContext); } else { diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs index fe1021272a282..de78cc1a7002f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs @@ -22,26 +22,6 @@ namespace System.Threading { - internal static class ThreadPoolGlobals - { - public static volatile bool threadPoolInitialized; - public static bool enableWorkerTracking; - - public static readonly ThreadPoolWorkQueue workQueue = new ThreadPoolWorkQueue(); - - /// Shim used to invoke of the supplied . - internal static readonly Action s_invokeAsyncStateMachineBox = state => - { - if (!(state is IAsyncStateMachineBox box)) - { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.state); - return; - } - - box.MoveNext(); - }; - } - [StructLayout(LayoutKind.Sequential)] // enforce layout so that padding reduces false sharing internal sealed class ThreadPoolWorkQueue { @@ -552,7 +532,7 @@ public long LocalCount /// internal static bool Dispatch() { - ThreadPoolWorkQueue outerWorkQueue = ThreadPoolGlobals.workQueue; + ThreadPoolWorkQueue outerWorkQueue = ThreadPool.s_workQueue; // // Save the start time @@ -627,7 +607,7 @@ internal static bool Dispatch() // // Execute the workitem outside of any finally blocks, so that it can be aborted if needed. // - if (ThreadPoolGlobals.enableWorkerTracking) + if (ThreadPool.s_enableWorkerTracking) { bool reportedStatus = false; try @@ -954,6 +934,21 @@ internal static void PerformWaitOrTimerCallback(_ThreadPoolWaitOrTimerCallback h public static partial class ThreadPool { + internal static readonly ThreadPoolWorkQueue s_workQueue = new ThreadPoolWorkQueue(); + internal static readonly bool s_enableWorkerTracking = GetEnableWorkerTracking(); + + /// Shim used to invoke of the supplied . + internal static readonly Action s_invokeAsyncStateMachineBox = state => + { + if (!(state is IAsyncStateMachineBox box)) + { + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.state); + return; + } + + box.MoveNext(); + }; + [CLSCompliant(false)] public static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle waitObject, @@ -1080,15 +1075,13 @@ public static bool QueueUserWorkItem(WaitCallback callBack, object? state) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callBack); } - EnsureInitialized(); - ExecutionContext? context = ExecutionContext.Capture(); object tpcallBack = (context == null || context.IsDefault) ? new QueueUserWorkItemCallbackDefaultContext(callBack!, state) : (object)new QueueUserWorkItemCallback(callBack!, state, context); - ThreadPoolGlobals.workQueue.Enqueue(tpcallBack, forceGlobal: true); + s_workQueue.Enqueue(tpcallBack, forceGlobal: true); return true; } @@ -1100,15 +1093,13 @@ public static bool QueueUserWorkItem(Action callBack, TState sta ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callBack); } - EnsureInitialized(); - ExecutionContext? context = ExecutionContext.Capture(); object tpcallBack = (context == null || context.IsDefault) ? new QueueUserWorkItemCallbackDefaultContext(callBack!, state) : (object)new QueueUserWorkItemCallback(callBack!, state, context); - ThreadPoolGlobals.workQueue.Enqueue(tpcallBack, forceGlobal: !preferLocal); + s_workQueue.Enqueue(tpcallBack, forceGlobal: !preferLocal); return true; } @@ -1126,7 +1117,7 @@ public static bool UnsafeQueueUserWorkItem(Action callBack, TSta // // This occurs when user code queues its provided continuation to the ThreadPool; // internally we call UnsafeQueueUserWorkItemInternal directly for Tasks. - if (ReferenceEquals(callBack, ThreadPoolGlobals.s_invokeAsyncStateMachineBox)) + if (ReferenceEquals(callBack, ThreadPool.s_invokeAsyncStateMachineBox)) { if (!(state is IAsyncStateMachineBox)) { @@ -1138,9 +1129,7 @@ public static bool UnsafeQueueUserWorkItem(Action callBack, TSta return true; } - EnsureInitialized(); - - ThreadPoolGlobals.workQueue.Enqueue( + s_workQueue.Enqueue( new QueueUserWorkItemCallbackDefaultContext(callBack!, state), forceGlobal: !preferLocal); return true; @@ -1153,11 +1142,9 @@ public static bool UnsafeQueueUserWorkItem(WaitCallback callBack, object? state) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.callBack); } - EnsureInitialized(); - object tpcallBack = new QueueUserWorkItemCallbackDefaultContext(callBack!, state); - ThreadPoolGlobals.workQueue.Enqueue(tpcallBack, forceGlobal: true); + s_workQueue.Enqueue(tpcallBack, forceGlobal: true); return true; } @@ -1183,25 +1170,21 @@ internal static void UnsafeQueueUserWorkItemInternal(object callBack, bool prefe { Debug.Assert((callBack is IThreadPoolWorkItem) ^ (callBack is Task)); - EnsureInitialized(); - - ThreadPoolGlobals.workQueue.Enqueue(callBack, forceGlobal: !preferLocal); + s_workQueue.Enqueue(callBack, forceGlobal: !preferLocal); } // This method tries to take the target callback out of the current thread's queue. internal static bool TryPopCustomWorkItem(object workItem) { Debug.Assert(null != workItem); - return - ThreadPoolGlobals.threadPoolInitialized && // if not initialized, so there's no way this workitem was ever queued. - ThreadPoolGlobals.workQueue.LocalFindAndPop(workItem); + return s_workQueue.LocalFindAndPop(workItem); } // Get all workitems. Called by TaskScheduler in its debugger hooks. internal static IEnumerable GetQueuedWorkItems() { // Enumerate global queue - foreach (object workItem in ThreadPoolGlobals.workQueue.workItems) + foreach (object workItem in s_workQueue.workItems) { yield return workItem; } @@ -1239,7 +1222,7 @@ internal static IEnumerable GetLocallyQueuedWorkItems() } } - internal static IEnumerable GetGloballyQueuedWorkItems() => ThreadPoolGlobals.workQueue.workItems; + internal static IEnumerable GetGloballyQueuedWorkItems() => s_workQueue.workItems; private static object[] ToObjectArray(IEnumerable workitems) { @@ -1285,7 +1268,7 @@ public static long PendingWorkItemCount { get { - ThreadPoolWorkQueue workQueue = ThreadPoolGlobals.workQueue; + ThreadPoolWorkQueue workQueue = s_workQueue; return workQueue.LocalCount + workQueue.GlobalCount + PendingUnmanagedWorkItemCount; } } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Threading/ThreadPool.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Threading/ThreadPool.Mono.cs index 023574d218002..ae757df4df433 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Threading/ThreadPool.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Threading/ThreadPool.Mono.cs @@ -8,11 +8,7 @@ namespace System.Threading { public static partial class ThreadPool { - private static void EnsureInitialized() - { - ThreadPoolGlobals.threadPoolInitialized = true; - ThreadPoolGlobals.enableWorkerTracking = false; - } + private static bool GetEnableWorkerTracking() => false; internal static void ReportThreadStatus(bool isWorking) { @@ -46,4 +42,4 @@ public static bool BindHandle(SafeHandle osHandle) private static long PendingUnmanagedWorkItemCount => 0; } -} \ No newline at end of file +} From 28e7864b3e6b2eae8bfcfc84cfe91d403ab4078f Mon Sep 17 00:00:00 2001 From: David Cantu Date: Tue, 19 May 2020 15:54:13 -0700 Subject: [PATCH 285/420] Remove duplicated tests from System.Text.Json.Tests (#36483) --- .../tests/JsonDateTimeTestData.cs | 3 - .../tests/JsonGuidTestData.cs | 55 ++++++++++--------- .../tests/Utf8JsonReaderTests.cs | 1 - 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/JsonDateTimeTestData.cs b/src/libraries/System.Text.Json/tests/JsonDateTimeTestData.cs index 7ff20c7e1c125..d172726159a2d 100644 --- a/src/libraries/System.Text.Json/tests/JsonDateTimeTestData.cs +++ b/src/libraries/System.Text.Json/tests/JsonDateTimeTestData.cs @@ -42,7 +42,6 @@ public static IEnumerable ValidISO8601Tests() yield return new object[] { "\"1997-07-16T19:20:30.6666660\"", "1997-07-16T19:20:30.666666" }; // Test fraction truncation. - yield return new object[] { "\"1997-07-16T19:20:30.0000000\"", "1997-07-16T19:20:30" }; yield return new object[] { "\"1997-07-16T19:20:30.00000001\"", "1997-07-16T19:20:30" }; yield return new object[] { "\"1997-07-16T19:20:30.000000001\"", "1997-07-16T19:20:30" }; yield return new object[] { "\"1997-07-16T19:20:30.77777770\"", "1997-07-16T19:20:30.7777777" }; @@ -153,7 +152,6 @@ public static IEnumerable InvalidISO8601Tests() // Invalid fractions. yield return new object[] { "\"1997-07-16T19.45\"" }; yield return new object[] { "\"1997-07-16T19:20.45\"" }; - yield return new object[] { "\"1997-07-16T19:20:30a\"" }; yield return new object[] { "\"1997-07-16T19:20:30,45\"" }; yield return new object[] { "\"1997-07-16T19:20:30.\"" }; yield return new object[] { "\"1997-07-16T19:20:30.a\"" }; @@ -168,7 +166,6 @@ public static IEnumerable InvalidISO8601Tests() yield return new object[] { "\"1997-07-16T19:20:30.4555555+01Z\"" }; yield return new object[] { "\"1997-07-16T19:20:30.4555555+01:\"" }; yield return new object[] { "\"1997-07-16T19:20:30.4555555 +01:00\"" }; - yield return new object[] { "\"1997-07-16T19:20:30.4555555+01:\"" }; yield return new object[] { "\"1997-07-16T19:20:30.4555555- 01:00\"" }; yield return new object[] { "\"1997-07-16T19:20:30.4555555+04 :30\"" }; yield return new object[] { "\"1997-07-16T19:20:30.4555555-04: 30\"" }; diff --git a/src/libraries/System.Text.Json/tests/JsonGuidTestData.cs b/src/libraries/System.Text.Json/tests/JsonGuidTestData.cs index 26fd675487085..bb74e59511b34 100644 --- a/src/libraries/System.Text.Json/tests/JsonGuidTestData.cs +++ b/src/libraries/System.Text.Json/tests/JsonGuidTestData.cs @@ -35,16 +35,40 @@ public static IEnumerable ValidHexGuidTests() public static IEnumerable InvalidGuidTests() { + // Invalid formats + Guid testGuid = new Guid(s_guidStr); + yield return new object[] { testGuid.ToString("B", CultureInfo.InvariantCulture) }; + yield return new object[] { testGuid.ToString("P", CultureInfo.InvariantCulture) }; + yield return new object[] { testGuid.ToString("N", CultureInfo.InvariantCulture) }; + + yield return new object[] { new string('$', 1) }; + yield return new object[] { new string(' ', 1) }; + yield return new object[] { new string('$', s_guidStr.Length) }; + yield return new object[] { new string(' ', s_guidStr.Length) }; + + for (int truncationPoint = 1; truncationPoint < s_guidStr.Length - 1; truncationPoint++) + { + string truncatedText = s_guidStr.Substring(0, truncationPoint); + + // Stop short + yield return new object[] { truncatedText }; + + // Append junk + yield return new object[] { truncatedText.PadRight(s_guidStr.Length, '$') }; + yield return new object[] { truncatedText.PadRight(s_guidStr.Length, ' ') }; + yield return new object[] { truncatedText.PadRight(truncatedText.Length + 1, '$') }; + yield return new object[] { truncatedText.PadRight(truncatedText.Length + 1, ' ') }; + // Prepend junk + yield return new object[] { truncatedText.PadLeft(s_guidStr.Length, '$') }; + yield return new object[] { truncatedText.PadLeft(s_guidStr.Length, ' ') }; + yield return new object[] { truncatedText.PadLeft(truncatedText.Length + 1, '$') }; + yield return new object[] { truncatedText.PadLeft(truncatedText.Length + 1, ' ') }; + } + foreach (object[] guid in ValidGuidTests()) { string guidStr = (string)guid[0]; - // Invalid formats - Guid testGuid = new Guid(guidStr); - yield return new object[] { testGuid.ToString("B", CultureInfo.InvariantCulture) }; - yield return new object[] { testGuid.ToString("P", CultureInfo.InvariantCulture) }; - yield return new object[] { testGuid.ToString("N", CultureInfo.InvariantCulture) }; - for (int i = 0; i < guidStr.Length; i++) { // Corrupt one character @@ -72,25 +96,6 @@ public static IEnumerable InvalidGuidTests() } } - for (int truncationPoint = 0; truncationPoint < guidStr.Length; truncationPoint++) - { - string truncatedText = guidStr.Substring(0, truncationPoint); - - // Stop short - yield return new object[] { truncatedText }; - - // Append junk - yield return new object[] { truncatedText.PadRight(guidStr.Length, '$') }; - yield return new object[] { truncatedText.PadRight(guidStr.Length, ' ') }; - yield return new object[] { truncatedText.PadRight(truncatedText.Length + 1, '$') }; - yield return new object[] { truncatedText.PadRight(truncatedText.Length + 1, ' ') }; - // Prepend junk - yield return new object[] { truncatedText.PadLeft(guidStr.Length, '$') }; - yield return new object[] { truncatedText.PadLeft(guidStr.Length, ' ') }; - yield return new object[] { truncatedText.PadLeft(truncatedText.Length + 1, '$') }; - yield return new object[] { truncatedText.PadLeft(truncatedText.Length + 1, ' ') }; - } - // Too long yield return new object[] { $"{guidStr} " }; yield return new object[] { $"{guidStr}$" }; diff --git a/src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.cs b/src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.cs index 392eeb1cc9dd1..3b80897e1ed94 100644 --- a/src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.cs +++ b/src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.cs @@ -4380,7 +4380,6 @@ public static IEnumerable InvalidJsonStrings new object[] {"+0", 0, 0}, new object[] {"+1", 0, 0}, new object[] {"0e", 0, 2}, - new object[] {"0.", 0, 2}, new object[] {"0.1e", 0, 4}, new object[] {"01", 0, 1}, new object[] {"1a", 0, 1}, From 50e15b2a76d153ee3511de4b72bf685595a55121 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Tue, 19 May 2020 16:18:41 -0700 Subject: [PATCH 286/420] Add build information to libraries helix jobs (#36713) * Add build information to libraries helix jobs * Remove BUILD_URI --- src/libraries/sendtohelix.proj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/sendtohelix.proj b/src/libraries/sendtohelix.proj index b62ca7e716148..aba5711af7884 100644 --- a/src/libraries/sendtohelix.proj +++ b/src/libraries/sendtohelix.proj @@ -76,6 +76,10 @@ <_RuntimeInputs Include="$(TestHostRootPath)**/*.dll" /> + + + + Date: Tue, 19 May 2020 17:56:27 -0700 Subject: [PATCH 287/420] Disable EventPipeProvider Context for runtime providers on EventPipe rundown --- src/coreclr/src/vm/eventpipe.cpp | 9 +++++++++ src/coreclr/src/vm/eventtrace.cpp | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/src/coreclr/src/vm/eventpipe.cpp b/src/coreclr/src/vm/eventpipe.cpp index a7b64acc216fb..26e20a528b651 100644 --- a/src/coreclr/src/vm/eventpipe.cpp +++ b/src/coreclr/src/vm/eventpipe.cpp @@ -434,6 +434,15 @@ void EventPipe::Disable(EventPipeSessionID id) if (s_numberOfSessions > 0) DisableInternal(id, pEventPipeProviderCallbackDataQueue); }); + +#ifdef DEBUG + if (s_numberOfSessions == 0) + { + _ASSERTE(!MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled); + _ASSERTE(!MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled); + _ASSERTE(!MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled); + } +#endif } static void LogProcessInformationEvent(EventPipeEventSource &eventSource) diff --git a/src/coreclr/src/vm/eventtrace.cpp b/src/coreclr/src/vm/eventtrace.cpp index d5099e498c2a6..6118a662a0b01 100644 --- a/src/coreclr/src/vm/eventtrace.cpp +++ b/src/coreclr/src/vm/eventtrace.cpp @@ -4267,6 +4267,7 @@ VOID EtwCallbackCommon( { ctxToUpdate->EventPipeProvider.Level = Level; ctxToUpdate->EventPipeProvider.EnabledKeywordsBitmask = MatchAnyKeyword; + ctxToUpdate->EventPipeProvider.IsEnabled = ControlCode; } if ( @@ -7612,6 +7613,11 @@ bool EventPipeHelper::IsEnabled(DOTNET_TRACE_CONTEXT Context, UCHAR Level, ULONG } CONTRACTL_END + if (!Context.EventPipeProvider.IsEnabled) + { + return false; + } + if (Level <= Context.EventPipeProvider.Level || Context.EventPipeProvider.Level == 0) { return (Keyword == (ULONGLONG)0) || (Keyword & Context.EventPipeProvider.EnabledKeywordsBitmask) != 0; From 1f0009526d73597deca1d13c133a7a3ecf60ea4f Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Tue, 19 May 2020 18:22:13 -0700 Subject: [PATCH 288/420] JIT: fix no return call accounting (#36719) The jit tracks the number of no return calls to determine if it should run throw helper merging and to decide if no return calls should tail called. The accounting is currently done when the calls are initially imported, so if code is duplicated (by say finally cloning the count may end up being an under-estimate. While not a correctness issue, it is better for the count to be accurate (or an over-estimate). So, update the count when cloning a no-return call. Closes #36584. --- src/coreclr/src/jit/gentree.cpp | 9 +++ .../JitBlue/Runtime_36584/Runtime_36584.cs | 56 +++++++++++++++++++ .../Runtime_36584/Runtime_36584.csproj | 13 +++++ 3 files changed, 78 insertions(+) create mode 100644 src/coreclr/tests/src/JIT/Regression/JitBlue/Runtime_36584/Runtime_36584.cs create mode 100644 src/coreclr/tests/src/JIT/Regression/JitBlue/Runtime_36584/Runtime_36584.csproj diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index f3208926e3bed..ece2e7c753fe3 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -7844,6 +7844,15 @@ GenTreeCall* Compiler::gtCloneExprCallHelper(GenTreeCall* tree, unsigned addFlag copy->CopyOtherRegFlags(tree); + // We keep track of the number of no return calls, so if we've cloned + // one of these, update the tracking. + // + if (tree->IsNoReturn()) + { + assert(copy->IsNoReturn()); + setMethodHasNoReturnCalls(); + } + return copy; } diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/Runtime_36584/Runtime_36584.cs b/src/coreclr/tests/src/JIT/Regression/JitBlue/Runtime_36584/Runtime_36584.cs new file mode 100644 index 0000000000000..bdc98c0cedf2e --- /dev/null +++ b/src/coreclr/tests/src/JIT/Regression/JitBlue/Runtime_36584/Runtime_36584.cs @@ -0,0 +1,56 @@ +// 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. + +using System; + +// Finally cloning creates new throw merge candidates that +// need to be properly counted. + +class Runtime_36584 +{ + static int x; + + static void ThrowHelper() + { + throw new Exception(); + } + + public static int Main() + { + x = 100; + + if (x != 100) + { + ThrowHelper(); + } + + if (x != 100) + { + ThrowHelper(); + } + + if (x != 100) + { + try + { + x++; + } + // This finally will be cloned + finally + { + if (x != 100) + { + ThrowHelper(); + } + + if (x != 100) + { + ThrowHelper(); + } + } + } + + return x; + } +} diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/Runtime_36584/Runtime_36584.csproj b/src/coreclr/tests/src/JIT/Regression/JitBlue/Runtime_36584/Runtime_36584.csproj new file mode 100644 index 0000000000000..5d49e8d49736f --- /dev/null +++ b/src/coreclr/tests/src/JIT/Regression/JitBlue/Runtime_36584/Runtime_36584.csproj @@ -0,0 +1,13 @@ + + + Exe + + + + True + True + + + + + From d4b356e506b1b19ad0d82c96a6837ef90079701c Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Tue, 19 May 2020 23:08:44 -0700 Subject: [PATCH 289/420] Remove Fedora29 from test matrix and add Fedora32 (#36716) --- eng/pipelines/libraries/helix-queues-setup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 3b3ac9d1106c9..7e450f8f4c0d0 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -58,8 +58,8 @@ jobs: - Ubuntu.1804.Amd64.Open - SLES.12.Amd64.Open - SLES.15.Amd64.Open - - (Fedora.29.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-29-helix-a12566d-20191210224553 - (Fedora.30.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-30-helix-4f8cef7-20200121150022 + - (Fedora.32.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-32-helix-20200512010618-efb9f14 - (Ubuntu.1910.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-19.10-helix-amd64-cfcfd50-20191030180623 - (Debian.10.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-amd64-bfcd90a-20200121150006 - ${{ if eq(parameters.jobParameters.isFullMatrix, false) }}: @@ -69,7 +69,7 @@ jobs: - Ubuntu.1604.Amd64.Open - Ubuntu.1804.Amd64.Open - SLES.15.Amd64.Open - - (Fedora.29.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-29-helix-a12566d-20191210224553 + - (Fedora.30.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-30-helix-4f8cef7-20200121150022 # OSX x64 - ${{ if eq(parameters.platform, 'OSX_x64') }}: From 43cad9b5d824af95742f4a1c0936a8dbd1008afc Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Wed, 20 May 2020 09:46:25 +0300 Subject: [PATCH 290/420] Code sharing between generic methods in member accessor (#36710) * Code sharing between generic methods in member accessor * Removed redudant value type check --- .../ReflectionEmitMemberAccessor.cs | 121 +++++++++--------- 1 file changed, 61 insertions(+), 60 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReflectionEmitMemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReflectionEmitMemberAccessor.cs index 137a74f593c65..a5d53eee033c1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReflectionEmitMemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReflectionEmitMemberAccessor.cs @@ -5,6 +5,7 @@ #if NETFRAMEWORK || NETCOREAPP using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Reflection.Emit; @@ -56,10 +57,14 @@ internal sealed class ReflectionEmitMemberAccessor : MemberAccessor return (JsonClassInfo.ConstructorDelegate)dynamicMethod.CreateDelegate(typeof(JsonClassInfo.ConstructorDelegate)); } - public override JsonClassInfo.ParameterizedConstructorDelegate? CreateParameterizedConstructor(ConstructorInfo constructor) + public override JsonClassInfo.ParameterizedConstructorDelegate? CreateParameterizedConstructor(ConstructorInfo constructor) => + CreateDelegate>(CreateParameterizedConstructor(constructor)); + + private static DynamicMethod? CreateParameterizedConstructor(ConstructorInfo constructor) { - Type type = typeof(T); + Type? type = constructor.DeclaringType; + Debug.Assert(type != null); Debug.Assert(!type.IsAbstract); Debug.Assert(type.GetConstructors(BindingFlags.Public | BindingFlags.Instance).Contains(constructor)); @@ -87,40 +92,35 @@ internal sealed class ReflectionEmitMemberAccessor : MemberAccessor generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4_S, i); generator.Emit(OpCodes.Ldelem_Ref); - - if (paramType.IsValueType) - { - generator.Emit(OpCodes.Unbox_Any, paramType); - } - else - { - generator.Emit(OpCodes.Castclass, paramType); - }; + generator.Emit(OpCodes.Unbox_Any, paramType); } generator.Emit(OpCodes.Newobj, constructor); generator.Emit(OpCodes.Ret); - return (JsonClassInfo.ParameterizedConstructorDelegate)dynamicMethod.CreateDelegate(typeof(JsonClassInfo.ParameterizedConstructorDelegate)); + return dynamicMethod; } public override JsonClassInfo.ParameterizedConstructorDelegate? - CreateParameterizedConstructor(ConstructorInfo constructor) + CreateParameterizedConstructor(ConstructorInfo constructor) => + CreateDelegate>( + CreateParameterizedConstructor(constructor, typeof(TArg0), typeof(TArg1), typeof(TArg2), typeof(TArg3))); + + private static DynamicMethod? CreateParameterizedConstructor(ConstructorInfo constructor, Type parameterType1, Type parameterType2, Type parameterType3, Type parameterType4) { - Type type = typeof(T); + Type? type = constructor.DeclaringType; + Debug.Assert(type != null); Debug.Assert(!type.IsAbstract); Debug.Assert(type.GetConstructors(BindingFlags.Public | BindingFlags.Instance).Contains(constructor)); ParameterInfo[] parameters = constructor.GetParameters(); int parameterCount = parameters.Length; - Debug.Assert(parameterCount <= JsonConstants.UnboxedParameterCountThreshold); - var dynamicMethod = new DynamicMethod( ConstructorInfo.ConstructorName, type, - new[] { typeof(TArg0), typeof(TArg1), typeof(TArg2), typeof(TArg3) }, + new[] { parameterType1, parameterType2, parameterType3, parameterType4 }, typeof(ReflectionEmitMemberAccessor).Module, skipVisibility: true); @@ -128,46 +128,37 @@ internal sealed class ReflectionEmitMemberAccessor : MemberAccessor for (int index = 0; index < parameterCount; index++) { - switch (index) - { - case 0: - generator.Emit(OpCodes.Ldarg_0); - break; - case 1: - generator.Emit(OpCodes.Ldarg_1); - break; - case 2: - generator.Emit(OpCodes.Ldarg_2); - break; - case 3: - generator.Emit(OpCodes.Ldarg_3); - break; - default: - Debug.Fail("We shouldn't be here if there are more than 4 parameters."); - throw new InvalidOperationException(); - } + Debug.Assert(index <= JsonConstants.UnboxedParameterCountThreshold); + + generator.Emit( + index switch + { + 0 => OpCodes.Ldarg_0, + 1 => OpCodes.Ldarg_1, + 2 => OpCodes.Ldarg_2, + 3 => OpCodes.Ldarg_3, + _ => throw new InvalidOperationException() + }); } generator.Emit(OpCodes.Newobj, constructor); generator.Emit(OpCodes.Ret); - return (JsonClassInfo.ParameterizedConstructorDelegate) - dynamicMethod.CreateDelegate( - typeof(JsonClassInfo.ParameterizedConstructorDelegate)); + return dynamicMethod; } - public override Action CreateAddMethodDelegate() - { - Type collectionType = typeof(TCollection); - Type elementType = typeof(object); + public override Action CreateAddMethodDelegate() => + CreateDelegate>(CreateAddMethodDelegate(typeof(TCollection))); + private static DynamicMethod CreateAddMethodDelegate(Type collectionType) + { // We verified this won't be null when we created the converter that calls this method. MethodInfo realMethod = (collectionType.GetMethod("Push") ?? collectionType.GetMethod("Enqueue"))!; var dynamicMethod = new DynamicMethod( realMethod.Name, typeof(void), - new[] { collectionType, elementType }, + new[] { collectionType, typeof(object) }, typeof(ReflectionEmitMemberAccessor).Module, skipVisibility: true); @@ -178,18 +169,21 @@ internal sealed class ReflectionEmitMemberAccessor : MemberAccessor generator.Emit(OpCodes.Callvirt, realMethod); generator.Emit(OpCodes.Ret); - return (Action)dynamicMethod.CreateDelegate(typeof(Action)); + return dynamicMethod; } - public override Func, TCollection> CreateImmutableEnumerableCreateRangeDelegate() + public override Func, TCollection> CreateImmutableEnumerableCreateRangeDelegate() => + CreateDelegate, TCollection>>( + CreateImmutableEnumerableCreateRangeDelegate(typeof(TCollection), typeof(TElement), typeof(IEnumerable))); + + private static DynamicMethod CreateImmutableEnumerableCreateRangeDelegate(Type collectionType, Type elementType, Type enumerableType) { - Type collectionType = typeof(TCollection); - MethodInfo realMethod = collectionType.GetImmutableEnumerableCreateRangeMethod(typeof(TElement)); + MethodInfo realMethod = collectionType.GetImmutableEnumerableCreateRangeMethod(elementType); var dynamicMethod = new DynamicMethod( realMethod.Name, collectionType, - new[] { typeof(IEnumerable) }, + new[] { enumerableType }, typeof(ReflectionEmitMemberAccessor).Module, skipVisibility: true); @@ -199,18 +193,21 @@ internal sealed class ReflectionEmitMemberAccessor : MemberAccessor generator.Emit(OpCodes.Call, realMethod); generator.Emit(OpCodes.Ret); - return (Func, TCollection>)dynamicMethod.CreateDelegate(typeof(Func, TCollection>)); + return dynamicMethod; } - public override Func>, TCollection> CreateImmutableDictionaryCreateRangeDelegate() + public override Func>, TCollection> CreateImmutableDictionaryCreateRangeDelegate() => + CreateDelegate>, TCollection>>( + CreateImmutableDictionaryCreateRangeDelegate(typeof(TCollection), typeof(TElement), typeof(IEnumerable>))); + + private static DynamicMethod CreateImmutableDictionaryCreateRangeDelegate(Type collectionType, Type elementType, Type enumerableType) { - Type collectionType = typeof(TCollection); - MethodInfo realMethod = collectionType.GetImmutableDictionaryCreateRangeMethod(typeof(TElement)); + MethodInfo realMethod = collectionType.GetImmutableDictionaryCreateRangeMethod(elementType); var dynamicMethod = new DynamicMethod( realMethod.Name, collectionType, - new[] { typeof(IEnumerable>) }, + new[] { enumerableType }, typeof(ReflectionEmitMemberAccessor).Module, skipVisibility: true); @@ -220,13 +217,13 @@ internal sealed class ReflectionEmitMemberAccessor : MemberAccessor generator.Emit(OpCodes.Call, realMethod); generator.Emit(OpCodes.Ret); - return (Func>, TCollection>)dynamicMethod.CreateDelegate(typeof(Func>, TCollection>)); + return dynamicMethod; } public override Func CreatePropertyGetter(PropertyInfo propertyInfo) => - (Func)CreatePropertyGetter(propertyInfo, propertyInfo.DeclaringType!, typeof(TProperty)); + CreateDelegate>(CreatePropertyGetter(propertyInfo, propertyInfo.DeclaringType!, typeof(TProperty))); - private static Delegate CreatePropertyGetter(PropertyInfo propertyInfo, Type classType, Type propertyType) + private static DynamicMethod CreatePropertyGetter(PropertyInfo propertyInfo, Type classType, Type propertyType) { MethodInfo? realMethod = propertyInfo.GetMethod; Type objectType = typeof(object); @@ -256,13 +253,13 @@ private static Delegate CreatePropertyGetter(PropertyInfo propertyInfo, Type cla generator.Emit(OpCodes.Ret); - return dynamicMethod.CreateDelegate(typeof(Func<,>).MakeGenericType(objectType, propertyType)); + return dynamicMethod; } public override Action CreatePropertySetter(PropertyInfo propertyInfo) => - (Action)CreatePropertySetter(propertyInfo, propertyInfo.DeclaringType!, typeof(TProperty)); + CreateDelegate>(CreatePropertySetter(propertyInfo, propertyInfo.DeclaringType!, typeof(TProperty))); - private static Delegate CreatePropertySetter(PropertyInfo propertyInfo, Type classType, Type propertyType) + private static DynamicMethod CreatePropertySetter(PropertyInfo propertyInfo, Type classType, Type propertyType) { MethodInfo? realMethod = propertyInfo.SetMethod; Type objectType = typeof(object); @@ -294,8 +291,12 @@ private static Delegate CreatePropertySetter(PropertyInfo propertyInfo, Type cla generator.Emit(OpCodes.Ret); - return dynamicMethod.CreateDelegate(typeof(Action<,>).MakeGenericType(objectType, propertyType)); + return dynamicMethod; } + + [return: NotNullIfNotNull("method")] + private static T? CreateDelegate(DynamicMethod? method) where T : Delegate => + (T?)method?.CreateDelegate(typeof(T)); } } #endif From 740fa669e1a1abbe266dfe9d6e203e61b8fb2e63 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Wed, 20 May 2020 00:24:53 -0700 Subject: [PATCH 291/420] Use latest compiler toolset from Arcade (#36741) --- eng/Versions.props | 2 -- 1 file changed, 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 23082297d6ab9..fe395c5ad1d8a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -18,8 +18,6 @@ true true false - - 3.7.0-2.20258.1 dotnet $(ContainerName) From a8b4ced325af5a33ddbf9f6e67f8d740bd9b8830 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Wed, 20 May 2020 13:47:22 +0300 Subject: [PATCH 292/420] [mono] Fix iOS sample and use `dotnet publish` (#36745) Use `dotnet publish` with linker just like for Android. --- src/mono/netcore/sample/Android/Makefile | 4 +- .../netcore/sample/Android/Program.csproj | 4 +- src/mono/netcore/sample/iOS/Makefile | 19 ++-- src/mono/netcore/sample/iOS/Program.cs | 1 + src/mono/netcore/sample/iOS/Program.csproj | 97 +++++++------------ .../AppleAppBuilder/AppleAppBuilder.cs | 2 +- 6 files changed, 51 insertions(+), 76 deletions(-) diff --git a/src/mono/netcore/sample/Android/Makefile b/src/mono/netcore/sample/Android/Makefile index 80211c3408d94..5ce28d98d9486 100644 --- a/src/mono/netcore/sample/Android/Makefile +++ b/src/mono/netcore/sample/Android/Makefile @@ -2,7 +2,7 @@ MONO_CONFIG=Release MONO_ARCH=arm64 DOTNET := ../../../../.././dotnet.sh -all: runtimepack apk +all: runtimepack run appbuilder: $(DOTNET) build -c Release ../../../../../tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.csproj @@ -10,7 +10,7 @@ appbuilder: runtimepack: ../../../../.././build.sh Mono+Libs -os Android -arch $(MONO_ARCH) -c $(MONO_CONFIG) -apk: clean appbuilder +run: clean appbuilder $(DOTNET) publish -c $(MONO_CONFIG) -r android-$(MONO_ARCH) \ /p:Platform=$(MONO_ARCH) /p:DeployAndRun=true diff --git a/src/mono/netcore/sample/Android/Program.csproj b/src/mono/netcore/sample/Android/Program.csproj index 406e6fa62c83e..cb8ff0a7489a6 100644 --- a/src/mono/netcore/sample/Android/Program.csproj +++ b/src/mono/netcore/sample/Android/Program.csproj @@ -4,8 +4,8 @@ bin Portable $(NetCoreAppCurrent) - $(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-Android-$(Configuration)-$(TargetArchitecture)\runtimes\android-$(TargetArchitecture) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', 'Debug', '$(NetCoreAppCurrent)')) + $(ArtifactsBinDir)lib-runtime-packs\$(NetCoreAppCurrent)-Android-$(Configuration)-$(TargetArchitecture)\runtimes\android-$(TargetArchitecture) + $(ArtifactsBinDir)AndroidAppBuilder\$(Configuration)\$(NetCoreAppCurrent) false true <_TrimmerDefaultAction>link diff --git a/src/mono/netcore/sample/iOS/Makefile b/src/mono/netcore/sample/iOS/Makefile index 240d55da76a1b..e59f9ec7dd140 100644 --- a/src/mono/netcore/sample/iOS/Makefile +++ b/src/mono/netcore/sample/iOS/Makefile @@ -3,19 +3,18 @@ MONO_ARCH=x64 DOTNET := ../../../../.././dotnet.sh USE_LLVM=True -# usage example: -# 'make all MONO_ARCH=x64 MONO_CONFIG=Release' to build the app for simulator -all: bundle +all: runtimepack app -program: - $(DOTNET) build -c $(MONO_CONFIG) Program.csproj +TOOLS_DIR=../../../../../tools-local/tasks/mobile.tasks +appbuilder: + $(DOTNET) build -c Release $(TOOLS_DIR)/AotCompilerTask/MonoAOTCompiler.csproj + $(DOTNET) build -c Release $(TOOLS_DIR)/AppleAppBuilder/AppleAppBuilder.csproj -bundle: clean program - $(DOTNET) msbuild /t:BuildAppBundle /p:Configuration=$(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH) \ - /p:UseLLVM=$(USE_LLVM) +runtimepack: + ../../../../.././build.sh Mono+Libs -os iOS -arch $(MONO_ARCH) -c $(MONO_CONFIG) -deploy-sim: - $(DOTNET) msbuild /t:IosDeployToSimulator /p:Configuration=$(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH) +run: clean appbuilder + $(DOTNET) publish -c $(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH) /p:UseLLVM=$(USE_LLVM) clean: rm -rf bin diff --git a/src/mono/netcore/sample/iOS/Program.cs b/src/mono/netcore/sample/iOS/Program.cs index 0de20347bd314..2b43cf7f52742 100644 --- a/src/mono/netcore/sample/iOS/Program.cs +++ b/src/mono/netcore/sample/iOS/Program.cs @@ -49,5 +49,6 @@ public static async Task Main(string[] args) } Console.WriteLine("Done!"); + await Task.Delay(-1); } } \ No newline at end of file diff --git a/src/mono/netcore/sample/iOS/Program.csproj b/src/mono/netcore/sample/iOS/Program.csproj index d30d644fd90f2..dfb084861bc91 100644 --- a/src/mono/netcore/sample/iOS/Program.csproj +++ b/src/mono/netcore/sample/iOS/Program.csproj @@ -5,58 +5,48 @@ Portable $(NetCoreAppCurrent) iOS - x64 - $(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-iOS-$(Configuration)-$(TargetArchitecture)\runtimes\ios-$(TargetArchitecture) - $(ArtifactsDir)bin\mono\iOS.$(TargetArchitecture).$(Configuration) - $(MSBuildThisFileDirectory)\bin\bundle - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder', 'Debug', '$(NetCoreAppCurrent)')) - $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'MonoAOTCompiler', 'Debug', '$(NetCoreAppCurrent)')) - true - true - false + $(ArtifactsBinDir)lib-runtime-packs\$(NetCoreAppCurrent)-iOS-$(Configuration)-$(TargetArchitecture)\runtimes\ios-$(TargetArchitecture) + false + ios-$(TargetArchitecture) + true + <_TrimmerDefaultAction>link - - - - - - + + + + + $(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-iOS-$(Configuration)-$(TargetArchitecture) + + + + + AssemblyFile="$(ArtifactsBinDir)AppleAppBuilder\$(Configuration)\$(NetCoreAppCurrent)\AppleAppBuilder.dll" /> + AssemblyFile="$(ArtifactsBinDir)MonoAOTCompiler\$(Configuration)\$(NetCoreAppCurrent)\MonoAOTCompiler.dll" /> - - - - - + + + $(MSBuildThisFileDirectory)$(PublishDir)\app + iPhone 11 + + + - - - - - - - - - - - + + @(MonoAOTCompilerDefaultAotArguments, ';') @(MonoAOTCompilerDefaultProcessArguments, ';') + - - - - - - - - - - + OutputDirectory="$(AppDir)" + Optimized="False" + AppDir="$(MSBuildThisFileDirectory)$(PublishDir)"> + - - - - iPhone 11 - - - - - - - + + + + + diff --git a/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs b/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs index 41bc3cb75eebe..a1d30a42ebf9a 100644 --- a/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs @@ -179,7 +179,7 @@ public override bool Execute() return true; } - static void GenerateLinkAllFile(IEnumerable asmFiles, string outputFile) + private static void GenerateLinkAllFile(IEnumerable asmFiles, string outputFile) { // Generates 'modules.m' in order to register all managed libraries // From 9d9008ee5ec979543c997616f33de5283b73bad5 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Wed, 20 May 2020 06:52:01 -0400 Subject: [PATCH 293/420] [interp] Small cleanups (#36706) Co-authored-by: BrzVlad --- src/mono/mono/mini/interp/interp.c | 27 ++++++++++++++++++--------- src/mono/mono/mini/interp/mintops.def | 1 + src/mono/mono/mini/interp/transform.c | 16 +++++++++++----- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 4563f1caab66c..6572376d07a2a 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -4969,6 +4969,24 @@ call:; ip += 3; MINT_IN_BREAK; } + MINT_IN_CASE(MINT_NEWOBJ_STRING) { + frame->ip = ip; + + cmethod = (InterpMethod*)frame->imethod->data_items [ip [1]]; + + const int param_count = ip [2]; + if (param_count) { + sp -= param_count; + memmove (sp + 2, sp, param_count * sizeof (stackval)); + } + + retval = sp; + ++sp; + sp->data.p = NULL; // first parameter + is_void = TRUE; + ip += 3; + goto call; + } MINT_IN_CASE(MINT_NEWOBJ_FAST) { MonoVTable *vtable = (MonoVTable*) frame->imethod->data_items [ip [3]]; INIT_VTABLE (vtable); @@ -5091,15 +5109,6 @@ call:; g_assert (!m_class_is_valuetype (newobj_class)); - // This branch could be avoided. Move it to transform, and use a new opcode NEWOBJ_STRING. - if (newobj_class == mono_defaults.string_class) { - retval = sp; - ++sp; - sp->data.p = NULL; // first parameter - is_void = TRUE; - goto call; - } - MonoDomain* const domain = frame->imethod->domain; MonoVTable *vtable = mono_class_vtable_checked (domain, newobj_class, error); if (!is_ok (error) || !mono_runtime_class_init_full (vtable, error)) { diff --git a/src/mono/mono/mini/interp/mintops.def b/src/mono/mono/mini/interp/mintops.def index d3a7a73b17718..d3dd6cc5a7c87 100644 --- a/src/mono/mono/mini/interp/mintops.def +++ b/src/mono/mono/mini/interp/mintops.def @@ -380,6 +380,7 @@ OPDEF(MINT_ENDFILTER, "endfilter", 1, Pop0, Push0, MintOpNoArgs) OPDEF(MINT_NEWOBJ, "newobj", 2, VarPop, Push1, MintOpMethodToken) OPDEF(MINT_NEWOBJ_ARRAY, "newobj_array", 3, VarPop, Push1, MintOpMethodToken) +OPDEF(MINT_NEWOBJ_STRING, "newobj_string", 3, VarPop, Push1, MintOpMethodToken) OPDEF(MINT_NEWOBJ_FAST, "newobj_fast", 4, VarPop, Push1, MintOpMethodToken) OPDEF(MINT_NEWOBJ_VT_FAST, "newobj_vt_fast", 3, VarPop, Push1, MintOpMethodToken) OPDEF(MINT_NEWOBJ_VTST_FAST, "newobj_vtst_fast", 4, VarPop, Push1, MintOpMethodToken) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 4554273a0357c..5d78ab524f1a9 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -2489,11 +2489,12 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target #endif if (op != -1) { - td->last_ins->data[1] = op; - if (td->last_ins->opcode == MINT_CALLI_NAT_FAST) - td->last_ins->data[2] = save_last_error; - } else if (op == -1 && td->last_ins->opcode == MINT_CALLI_NAT) { - td->last_ins->data[1] = save_last_error; + g_assert (td->last_ins->opcode == MINT_CALLI_NAT_FAST); + td->last_ins->data [1] = op; + td->last_ins->data [2] = save_last_error; + } else if (native) { + g_assert (td->last_ins->opcode == MINT_CALLI_NAT); + td->last_ins->data [1] = save_last_error; } } else { InterpMethod *imethod = mono_interp_get_imethod (domain, target_method, error); @@ -4610,6 +4611,10 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, interp_add_ins (td, MINT_NEWOBJ_ARRAY); td->last_ins->data [0] = get_data_item_index (td, m->klass); td->last_ins->data [1] = csignature->param_count; + } else if (klass == mono_defaults.string_class) { + interp_add_ins (td, MINT_NEWOBJ_STRING); + td->last_ins->data [0] = get_data_item_index (td, mono_interp_get_imethod (domain, m, error)); + td->last_ins->data [1] = csignature->param_count; } else if (m_class_get_image (klass) == mono_defaults.corlib && !strcmp (m_class_get_name (m->klass), "ByReference`1") && !strcmp (m->name, ".ctor")) { @@ -6489,6 +6494,7 @@ get_inst_stack_usage (TransformData *td, InterpInst *ins, int *pop, int *push) break; } case MINT_NEWOBJ_ARRAY: + case MINT_NEWOBJ_STRING: *pop = ins->data [1]; *push = 1; break; From 3620e8d850bdf3988af3ae89c9a5078230b895b3 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Wed, 20 May 2020 11:20:06 -0400 Subject: [PATCH 294/420] [interp] Fix interp entry for methods with lots of arguments in llvmonly+interp mode. (#36678) Fixes https://github.com/mono/mono/issues/19801. Co-authored-by: vargaz --- src/mono/mono/mini/aot-compiler.c | 15 ++++++++++++--- src/mono/mono/mini/interp/interp.c | 13 ++++++++----- src/mono/mono/mini/interp/interp.h | 2 ++ src/mono/mono/mini/mini-generic-sharing.c | 3 ++- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 762a5a743fc29..adb9cab48538c 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -68,6 +68,7 @@ #include "mini-gc.h" #include "mini-llvm.h" #include "mini-runtime.h" +#include "interp/interp.h" static MonoMethod* try_get_method_nofail (MonoClass *klass, const char *method_name, int param_count, int flags) @@ -8608,7 +8609,7 @@ add_gsharedvt_wrappers (MonoAotCompile *acfg, MonoMethodSignature *sig, gboolean if (gsharedvt_out && g_hash_table_lookup (acfg->gsharedvt_out_signatures, sig)) add_out = FALSE; - if (!add_in && !add_out) + if (!add_in && !add_out && !interp_in) return; if (mini_is_gsharedvt_variable_signature (sig)) @@ -8637,7 +8638,6 @@ add_gsharedvt_wrappers (MonoAotCompile *acfg, MonoMethodSignature *sig, gboolean if (interp_in) { wrapper = mini_get_interp_in_wrapper (sig); add_extra_method (acfg, wrapper); - //printf ("X: %s\n", mono_method_full_name (wrapper, 1)); } #endif } @@ -8965,7 +8965,16 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method) for (l = cfg->interp_in_signatures; l; l = l->next) { MonoMethodSignature *sig = mono_metadata_signature_dup ((MonoMethodSignature*)l->data); - add_gsharedvt_wrappers (acfg, sig, TRUE, FALSE, FALSE); + /* + * Interpreter methods in llvmonly+interp mode are called using gsharedvt_in wrappers, + * since we already generate those in llvmonly mode. But methods with a large + * number of arguments need special processing (see interp_create_method_pointer_llvmonly), + * which only interp_in wrappers do. + */ + if (sig->param_count > MAX_INTERP_ENTRY_ARGS) + add_gsharedvt_wrappers (acfg, sig, FALSE, FALSE, TRUE); + else + add_gsharedvt_wrappers (acfg, sig, TRUE, FALSE, FALSE); } } else if (mono_aot_mode_is_full (&acfg->aot_opts) && mono_aot_mode_is_interp (&acfg->aot_opts)) { /* The interpreter uses these wrappers to call aot-ed code */ diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 6572376d07a2a..35de785f66f7e 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -2531,8 +2531,6 @@ copy_varargs_vtstack (MonoMethodSignature *csig, stackval *sp, guchar *vt_sp_sta * this/static * ret/void * 16 arguments -> 64 functions. */ -#define MAX_INTERP_ENTRY_ARGS 8 - #define INTERP_ENTRY_BASE(_method, _this_arg, _res) \ InterpEntryData data; \ (data).rmethod = (_method); \ @@ -2819,8 +2817,14 @@ interp_create_method_pointer_llvmonly (MonoMethod *method, gboolean unbox, MonoE * to use a ftndesc. The caller uses a normal signature, while the * entry functions use a gsharedvt_in signature, so wrap the entry function in * a gsharedvt_in_sig wrapper. + * We use a gsharedvt_in_sig wrapper instead of an interp_in wrapper, because they + * are mostly the same, and they are already generated. The exception is the + * wrappers for methods with more than 8 arguments, those are different. */ - wrapper = mini_get_gsharedvt_in_sig_wrapper (sig); + if (sig->param_count > MAX_INTERP_ENTRY_ARGS) + wrapper = mini_get_interp_in_wrapper (sig); + else + wrapper = mini_get_gsharedvt_in_sig_wrapper (sig); entry_wrapper = mono_jit_compile_method_jit_only (wrapper, error); mono_error_assertf_ok (error, "couldn't compile wrapper \"%s\" for \"%s\"", @@ -2828,8 +2832,7 @@ interp_create_method_pointer_llvmonly (MonoMethod *method, gboolean unbox, MonoE mono_method_get_name_full (method, TRUE, TRUE, MONO_TYPE_NAME_FORMAT_IL)); if (sig->param_count > MAX_INTERP_ENTRY_ARGS) { - g_assert_not_reached (); - //entry_func = (gpointer)interp_entry_general; + entry_func = (gpointer)interp_entry_general; } else if (sig->hasthis) { if (sig->ret->type == MONO_TYPE_VOID) entry_func = entry_funcs_instance [sig->param_count]; diff --git a/src/mono/mono/mini/interp/interp.h b/src/mono/mono/mini/interp/interp.h index 40c9e96829e23..198d423f7f4f5 100644 --- a/src/mono/mono/mini/interp/interp.h +++ b/src/mono/mono/mini/interp/interp.h @@ -14,6 +14,8 @@ #define INTERP_ICALL_TRAMP_FARGS 4 #endif +#define MAX_INTERP_ENTRY_ARGS 8 + struct _InterpMethodArguments { size_t ilen; gpointer *iargs; diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index 23a702868a81e..7ef020e8c5548 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -26,6 +26,7 @@ #include "aot-runtime.h" #include "mini-runtime.h" #include "llvmonly-runtime.h" +#include "interp/interp.h" #define ALLOW_PARTIAL_SHARING TRUE //#define ALLOW_PARTIAL_SHARING FALSE @@ -1711,7 +1712,7 @@ mini_get_interp_in_wrapper (MonoMethodSignature *sig) return res; } - if (sig->param_count > 8) + if (sig->param_count > MAX_INTERP_ENTRY_ARGS) /* Call the generic interpreter entry point, the specialized ones only handle a limited number of arguments */ generic = TRUE; From af2e5c982947362e1de328ddd752840c7a8cf7b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Wed, 20 May 2020 17:57:57 +0200 Subject: [PATCH 295/420] Use a Brewfile for installing brew packages (#36747) This means we won't be upgrading existing packages on the system that we don't need for the build. Marks install-native-dependencies.sh as executable (+x) so we don't need to start it with `sh` in the build .yml Fixes https://github.com/dotnet/runtime/issues/36727 --- .../requirements/macos-requirements.md | 6 ++-- eng/Brewfile | 8 +++++ eng/install-native-dependencies.sh | 35 +++---------------- eng/pipelines/common/global-build-job.yml | 2 +- .../templates/runtimes/build-test-job.yml | 2 +- eng/pipelines/coreclr/templates/build-job.yml | 2 +- eng/pipelines/installer/jobs/base-job.yml | 2 +- eng/pipelines/libraries/build-job.yml | 2 +- eng/pipelines/mono/templates/build-job.yml | 2 +- 9 files changed, 21 insertions(+), 40 deletions(-) create mode 100644 eng/Brewfile mode change 100644 => 100755 eng/install-native-dependencies.sh diff --git a/docs/workflow/requirements/macos-requirements.md b/docs/workflow/requirements/macos-requirements.md index 82a6610321bb5..4604b87f60f85 100644 --- a/docs/workflow/requirements/macos-requirements.md +++ b/docs/workflow/requirements/macos-requirements.md @@ -16,7 +16,7 @@ Install Apple Xcode developer tools from the Mac App Store ([link](https://apps. Toolchain Setup --------------- -Building dotnet/runtime depends on several tools to be installed. You can download them individually or use [Homebrew](http://brew.sh) for easier toolchain setup. +Building dotnet/runtime depends on several tools to be installed. You can download them individually or use [Homebrew](https://brew.sh) for easier toolchain setup. Install the following packages: @@ -29,8 +29,8 @@ Install the following packages: - pkg-config - python3 -The lines to install all the packages above using Homebrew. +You can install all the packages above using Homebrew by running this command in the repository root: ``` -brew install cmake autoconf automake icu4c libtool openssl@1.1 pkg-config python3 +brew bundle --no-lock --file eng/Brewfile ``` diff --git a/eng/Brewfile b/eng/Brewfile new file mode 100644 index 0000000000000..40252a15f3048 --- /dev/null +++ b/eng/Brewfile @@ -0,0 +1,8 @@ +brew "autoconf" +brew "automake" +brew "cmake" +brew "icu4c" +brew "libtool" +brew "openssl@1.1" +brew "pkg-config" +brew "python3" diff --git a/eng/install-native-dependencies.sh b/eng/install-native-dependencies.sh old mode 100644 new mode 100755 index be154811ea7f1..00be5a6287289 --- a/eng/install-native-dependencies.sh +++ b/eng/install-native-dependencies.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash if [ "$1" = "Linux" ]; then sudo apt update @@ -9,36 +9,9 @@ if [ "$1" = "Linux" ]; then if [ "$?" != "0" ]; then exit 1; fi -elif [ "$1" = "OSX" ]; then - brew update - brew upgrade - if [ "$?" != "0" ]; then - exit 1; - fi - brew install autoconf automake icu4c libtool openssl@1.1 pkg-config python3 - if [ "$?" != "0" ]; then - exit 1; - fi - if [ "$?" != "0" ]; then - exit 1; - fi -elif [ "$1" = "tvOS" ]; then - brew update - brew upgrade - if [ "$?" != "0" ]; then - exit 1; - fi - brew install autoconf automake libtool openssl@1.1 pkg-config python3 - if [ "$?" != "0" ]; then - exit 1; - fi -elif [ "$1" = "iOS" ]; then - brew update - brew upgrade - if [ "$?" != "0" ]; then - exit 1; - fi - brew install autoconf automake libtool openssl@1.1 pkg-config python3 +elif [ "$1" = "OSX" ] || [ "$1" = "tvOS" ] || [ "$1" = "iOS" ]; then + engdir=$(dirname "${BASH_SOURCE[0]}") + brew bundle --no-lock --file "${engdir}/Brewfile" if [ "$?" != "0" ]; then exit 1; fi diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index e0f71a3f128a9..29071209e79dc 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -28,7 +28,7 @@ jobs: - template: /eng/pipelines/common/clone-checkout-bundle-step.yml - ${{ if in(parameters.osGroup, 'OSX', 'iOS', 'tvOS') }}: - - script: sh $(Build.SourcesDirectory)/eng/install-native-dependencies.sh ${{ parameters.osGroup }} + - script: $(Build.SourcesDirectory)/eng/install-native-dependencies.sh ${{ parameters.osGroup }} displayName: Install Build Dependencies - script: | diff --git a/eng/pipelines/common/templates/runtimes/build-test-job.yml b/eng/pipelines/common/templates/runtimes/build-test-job.yml index a4f94efcc56b4..6c46cfadeb0c4 100644 --- a/eng/pipelines/common/templates/runtimes/build-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/build-test-job.yml @@ -85,7 +85,7 @@ jobs: # Install test build dependencies - ${{ if eq(parameters.osGroup, 'OSX') }}: - - script: sh $(Build.SourcesDirectory)/eng/install-native-dependencies.sh $(osGroup) + - script: $(Build.SourcesDirectory)/eng/install-native-dependencies.sh $(osGroup) displayName: Install native dependencies - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: # Necessary to install correct cmake version diff --git a/eng/pipelines/coreclr/templates/build-job.yml b/eng/pipelines/coreclr/templates/build-job.yml index 870cdc6c0822a..c23db63f95666 100644 --- a/eng/pipelines/coreclr/templates/build-job.yml +++ b/eng/pipelines/coreclr/templates/build-job.yml @@ -106,7 +106,7 @@ jobs: # and FreeBSD builds use a build agent with dependencies # preinstalled, so we only need this step for OSX and Windows. - ${{ if eq(parameters.osGroup, 'OSX') }}: - - script: sh $(Build.SourcesDirectory)/eng/install-native-dependencies.sh $(osGroup) + - script: $(Build.SourcesDirectory)/eng/install-native-dependencies.sh $(osGroup) displayName: Install native dependencies - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: # Necessary to install python diff --git a/eng/pipelines/installer/jobs/base-job.yml b/eng/pipelines/installer/jobs/base-job.yml index 2c309c03892a7..8e9c3f1824bb2 100644 --- a/eng/pipelines/installer/jobs/base-job.yml +++ b/eng/pipelines/installer/jobs/base-job.yml @@ -457,7 +457,7 @@ jobs: cleanUnpackFolder: false - ${{ if in(parameters.osGroup, 'OSX', 'iOS', 'tvOS') }}: - - script: sh $(Build.SourcesDirectory)/eng/install-native-dependencies.sh ${{ parameters.osGroup }} + - script: $(Build.SourcesDirectory)/eng/install-native-dependencies.sh ${{ parameters.osGroup }} displayName: Install Build Dependencies - script: | diff --git a/eng/pipelines/libraries/build-job.yml b/eng/pipelines/libraries/build-job.yml index 2287c8f1dafb1..94df7e9469e34 100644 --- a/eng/pipelines/libraries/build-job.yml +++ b/eng/pipelines/libraries/build-job.yml @@ -78,7 +78,7 @@ jobs: - template: /eng/pipelines/common/restore-internal-tools.yml - ${{ if in(parameters.osGroup, 'OSX', 'iOS', 'tvOS') }}: - - script: sh $(Build.SourcesDirectory)/eng/install-native-dependencies.sh ${{ parameters.osGroup }} + - script: $(Build.SourcesDirectory)/eng/install-native-dependencies.sh ${{ parameters.osGroup }} displayName: Install Build Dependencies - script: | diff --git a/eng/pipelines/mono/templates/build-job.yml b/eng/pipelines/mono/templates/build-job.yml index 8593d86481033..901bab9a0f660 100644 --- a/eng/pipelines/mono/templates/build-job.yml +++ b/eng/pipelines/mono/templates/build-job.yml @@ -89,7 +89,7 @@ jobs: # and FreeBSD builds use a build agent with dependencies # preinstalled, so we only need this step for OSX and Windows. - ${{ if in(parameters.osGroup, 'OSX', 'iOS', 'tvOS') }}: - - script: sh $(Build.SourcesDirectory)/eng/install-native-dependencies.sh $(osGroup) + - script: $(Build.SourcesDirectory)/eng/install-native-dependencies.sh $(osGroup) displayName: Install native dependencies - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: # Necessary to install python From e9c272c0afd193f3f6ef2cb1f33b3778bd4adcf7 Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Wed, 20 May 2020 09:09:15 -0700 Subject: [PATCH 296/420] Adding OSX support for System.DirectoryServices.Protocols (#36669) * Adding OSX support for System.DirectoryServices.Protocols * Addressing PR Feedback * Fixing issue in netfx builds where local member is assigned but never used --- .../src/Interop/OSX/Interop.Libraries.cs | 1 + .../System.DirectoryServices.Protocols.csproj | 17 ++++++++---- .../tests/DirectoryServicesTestHelpers.cs | 27 +++++++++---------- ...m.DirectoryServices.Protocols.Tests.csproj | 2 +- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs b/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs index 6c2a0ab78c8d7..9ba6608df1212 100644 --- a/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs +++ b/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs @@ -14,6 +14,7 @@ internal static partial class Libraries internal const string LibSystemCommonCrypto = "/usr/lib/system/libcommonCrypto"; internal const string LibSystemKernel = "/usr/lib/system/libsystem_kernel"; internal const string Odbc32 = "libodbc.2.dylib"; + internal const string OpenLdap = "libldap"; internal const string SystemConfigurationLibrary = "/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration"; internal const string AppleCryptoNative = "System.Security.Cryptography.Native.Apple"; internal const string MsQuic = "msquic"; diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj index 2ffb1d93dfbc6..03d310243f3b3 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj +++ b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj @@ -3,7 +3,7 @@ true $(NoWarn);0649;CA1810 true - $(NetCoreAppCurrent)-Linux;netcoreapp2.0-Linux;$(NetCoreAppCurrent)-Windows_NT;netstandard2.0;netcoreapp2.0-Windows_NT;_$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;netcoreapp2.0-Windows_NT;$(NetCoreAppCurrent)-OSX;netcoreapp2.0-OSX;$(NetCoreAppCurrent)-Linux;netcoreapp2.0-Linux;netstandard2.0;_$(NetFrameworkCurrent) true @@ -57,16 +57,13 @@ Common\Interop\Windows\Wldap32\Interop.Ber.cs - + - - Common\Interop\Linux\Interop.Libraries.cs - Common\Interop\Linux\OpenLdap\Interop.Ldap.cs @@ -74,6 +71,16 @@ Common\Interop\Linux\OpenLdap\Interop.Ber.cs + + + Common\Interop\Linux\Interop.Libraries.cs + + + + + Common\Interop\OSX\Interop.Libraries.cs + + diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesTestHelpers.cs b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesTestHelpers.cs index 80ac7ec9c6084..98d45457c7ae7 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesTestHelpers.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesTestHelpers.cs @@ -16,34 +16,31 @@ public static class DirectoryServicesTestHelpers // Cache the check once we have performed it once private static bool? _isLibLdapInstalled = null; + /// + /// Returns true if able to PInvoke into Linux or OSX, false otherwise + /// public static bool IsLibLdapInstalled { get { +#if NETCOREAPP if (!_isLibLdapInstalled.HasValue) { - try + if (PlatformDetection.IsOSX) { - // Attempt PInvoking into libldap - IntPtr handle = ber_alloc(1); - ber_free(handle, 1); - _isLibLdapInstalled = true; + _isLibLdapInstalled = NativeLibrary.TryLoad("libldap.dylib", out _); } - catch (Exception) + else { - _isLibLdapInstalled = false; + _isLibLdapInstalled = NativeLibrary.TryLoad("libldap-2.4.so.2", out _); } } return _isLibLdapInstalled.Value; +#else + _isLibLdapInstalled = true; // In .NET Framework ldap is always installed. + return _isLibLdapInstalled.Value; +#endif } } - - internal const string OpenLdap = "libldap-2.4.so.2"; - - [DllImport(OpenLdap, EntryPoint = "ber_alloc_t", CharSet = CharSet.Ansi)] - internal static extern IntPtr ber_alloc(int option); - - [DllImport(OpenLdap, EntryPoint = "ber_free", CharSet = CharSet.Ansi)] - public static extern IntPtr ber_free([In] IntPtr berelement, int option); } } diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/System.DirectoryServices.Protocols.Tests.csproj b/src/libraries/System.DirectoryServices.Protocols/tests/System.DirectoryServices.Protocols.Tests.csproj index 164327720e330..4c621fb35408b 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/System.DirectoryServices.Protocols.Tests.csproj +++ b/src/libraries/System.DirectoryServices.Protocols/tests/System.DirectoryServices.Protocols.Tests.csproj @@ -1,6 +1,6 @@ - $(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent) + $(NetCoreAppCurrent);$(NetFrameworkCurrent) From 3fda6ef73cf359b4bb3780a339a831e261b1c732 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 20 May 2020 09:15:28 -0700 Subject: [PATCH 297/420] Optimize call indirect for R2R, Arm and Arm64 scenarios (#35675) * Use a different approach to optimize the indirect calls for R2R During lowering, don't create a controlExpr for indirect call. Instead use temp register for such calls and during codegen, load the indirect from x11 into that temp register before calling the address in that temp register. --- src/coreclr/src/jit/codegenarmarch.cpp | 21 +++++++++++++++++++++ src/coreclr/src/jit/lower.cpp | 18 +++++++++++++----- src/coreclr/src/jit/lsraarmarch.cpp | 6 ++++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index a5e2bd4152657..21b4ba72ee294 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -2523,6 +2523,27 @@ void CodeGen::genCallInstruction(GenTreeCall* call) INDEBUG_LDISASM_COMMA(sigInfo) nullptr, // addr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize), ilOffset, target->GetRegNum()); } +#if defined(FEATURE_READYTORUN_COMPILER) && defined(TARGET_ARMARCH) + else if (call->IsR2RRelativeIndir()) + { + // Generate a direct call to a non-virtual user defined or helper method + assert(callType == CT_HELPER || callType == CT_USER_FUNC); + assert(call->gtEntryPoint.accessType == IAT_PVALUE); + assert(call->gtControlExpr == nullptr); + + regNumber tmpReg = call->GetSingleTempReg(); + GetEmitter()->emitIns_R_R(ins_Load(TYP_I_IMPL), emitActualTypeSize(TYP_I_IMPL), tmpReg, REG_R2R_INDIRECT_PARAM); + + // We have now generated code for gtControlExpr evaluating it into `tmpReg`. + // We just need to emit "call tmpReg" in this case. + // + assert(genIsValidIntReg(tmpReg)); + + genEmitCall(emitter::EC_INDIR_R, methHnd, + INDEBUG_LDISASM_COMMA(sigInfo) nullptr, // addr + retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize), ilOffset, tmpReg); + } +#endif // FEATURE_READYTORUN_COMPILER && TARGET_ARMARCH else { // Generate a direct call to a non-virtual user defined or helper method diff --git a/src/coreclr/src/jit/lower.cpp b/src/coreclr/src/jit/lower.cpp index b2b9a30322a4f..173f4702e480b 100644 --- a/src/coreclr/src/jit/lower.cpp +++ b/src/coreclr/src/jit/lower.cpp @@ -3287,11 +3287,19 @@ GenTree* Lowering::LowerDirectCall(GenTreeCall* call) case IAT_PVALUE: { - // Non-virtual direct calls to addresses accessed by - // a single indirection. - GenTree* cellAddr = AddrGen(addr); - GenTree* indir = Ind(cellAddr); - result = indir; + bool isR2RRelativeIndir = false; +#if defined(FEATURE_READYTORUN_COMPILER) && defined(TARGET_ARMARCH) + isR2RRelativeIndir = call->IsR2RRelativeIndir(); +#endif // FEATURE_READYTORUN_COMPILER && TARGET_ARMARCH + + if (!isR2RRelativeIndir) + { + // Non-virtual direct calls to addresses accessed by + // a single indirection. + GenTree* cellAddr = AddrGen(addr); + GenTree* indir = Ind(cellAddr); + result = indir; + } break; } diff --git a/src/coreclr/src/jit/lsraarmarch.cpp b/src/coreclr/src/jit/lsraarmarch.cpp index 8452ac68759d2..64d18bf6d80bd 100644 --- a/src/coreclr/src/jit/lsraarmarch.cpp +++ b/src/coreclr/src/jit/lsraarmarch.cpp @@ -182,6 +182,12 @@ int LinearScan::BuildCall(GenTreeCall* call) ctrlExprCandidates = RBM_FASTTAILCALL_TARGET; } } +#if defined(FEATURE_READYTORUN_COMPILER) && defined(TARGET_ARMARCH) + else if (call->IsR2RRelativeIndir()) + { + buildInternalIntRegisterDefForNode(call); + } +#endif // FEATURE_READYTORUN_COMPILER && TARGET_ARMARCH #ifdef TARGET_ARM else { From 8e36fcc00643a0e1238ac6904946b6100ff29f96 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Wed, 20 May 2020 20:55:37 +0300 Subject: [PATCH 298/420] Add FullAOT mode for Simulator to AppleAppBuilder (#36759) --- src/mono/netcore/sample/iOS/Makefile | 5 +++-- src/mono/netcore/sample/iOS/Program.csproj | 8 +++++--- .../mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs | 11 ++++++++--- .../AppleAppBuilder/Templates/CMakeLists.txt.template | 2 ++ .../AppleAppBuilder/Templates/main-console.m | 2 +- .../mobile.tasks/AppleAppBuilder/Templates/runtime.m | 6 +++--- .../tasks/mobile.tasks/AppleAppBuilder/Xcode.cs | 3 +++ 7 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/mono/netcore/sample/iOS/Makefile b/src/mono/netcore/sample/iOS/Makefile index e59f9ec7dd140..36dec2bc18dab 100644 --- a/src/mono/netcore/sample/iOS/Makefile +++ b/src/mono/netcore/sample/iOS/Makefile @@ -3,7 +3,7 @@ MONO_ARCH=x64 DOTNET := ../../../../.././dotnet.sh USE_LLVM=True -all: runtimepack app +all: runtimepack run TOOLS_DIR=../../../../../tools-local/tasks/mobile.tasks appbuilder: @@ -14,7 +14,8 @@ runtimepack: ../../../../.././build.sh Mono+Libs -os iOS -arch $(MONO_ARCH) -c $(MONO_CONFIG) run: clean appbuilder - $(DOTNET) publish -c $(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH) /p:UseLLVM=$(USE_LLVM) + $(DOTNET) publish -c $(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH) \ + /p:UseLLVM=$(USE_LLVM) /p:UseAotForSimulator=true clean: rm -rf bin diff --git a/src/mono/netcore/sample/iOS/Program.csproj b/src/mono/netcore/sample/iOS/Program.csproj index dfb084861bc91..f08d1806b4f4c 100644 --- a/src/mono/netcore/sample/iOS/Program.csproj +++ b/src/mono/netcore/sample/iOS/Program.csproj @@ -10,6 +10,7 @@ ios-$(TargetArchitecture) true <_TrimmerDefaultAction>link + True @@ -46,7 +47,7 @@ @@ -78,7 +80,7 @@ - + diff --git a/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs b/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs index a1d30a42ebf9a..4722c7f0a5f07 100644 --- a/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs @@ -97,6 +97,11 @@ public class AppleAppBuilderTask : Task [Output] public string AppBundlePath { get; set; } = ""!; + /// + /// Prefer FullAOT mode for Simulator over JIT + /// + public bool UseAotForSimulator { get; set; } + /// /// Path to xcode project /// @@ -145,7 +150,7 @@ public override bool Execute() } } - if (isDevice && !assemblerFiles.Any()) + if ((isDevice || UseAotForSimulator) && !assemblerFiles.Any()) { throw new InvalidOperationException("Need list of AOT files for device builds."); } @@ -158,7 +163,7 @@ public override bool Execute() if (GenerateXcodeProject) { XcodeProjectPath = Xcode.GenerateXCode(ProjectName, MainLibraryFileName, assemblerFiles, - AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, NativeMainSource); + AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, UseAotForSimulator, NativeMainSource); if (BuildAppBundle) { @@ -202,7 +207,7 @@ private static void GenerateLinkAllFile(IEnumerable asmFiles, string out .AppendLine("#include ") .AppendLine("#include ") .AppendLine() - .AppendLine("#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR") + .AppendLine("#if TARGET_OS_IPHONE && (!TARGET_IPHONE_SIMULATOR || USE_AOT_FOR_SIMULATOR)") .AppendLine(); var lsUsage = new StringBuilder(); diff --git a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/CMakeLists.txt.template b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/CMakeLists.txt.template index 11c5631a6d9fe..ecd3d6c1e614d 100644 --- a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/CMakeLists.txt.template +++ b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/CMakeLists.txt.template @@ -18,6 +18,8 @@ add_executable( %AotSources% +%Defines% + include_directories("%MonoInclude%") set_target_properties(%ProjectName% PROPERTIES diff --git a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/main-console.m b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/main-console.m index 65dedbe328e3c..847d5787aae85 100644 --- a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/main-console.m +++ b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/main-console.m @@ -48,7 +48,7 @@ - (void)viewDidLoad { summaryLabel.font = [UIFont boldSystemFontOfSize: 12]; summaryLabel.numberOfLines = 2; summaryLabel.textAlignment = NSTextAlignmentLeft; -#ifdef TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR +#ifdef TARGET_OS_IPHONE && (!TARGET_IPHONE_SIMULATOR || USE_AOT_FOR_SIMULATOR) summaryLabel.text = @"Loading..."; #else summaryLabel.text = @"Jitting..."; diff --git a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/runtime.m b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/runtime.m index b575aa2ca8594..45b277365c29b 100644 --- a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/runtime.m +++ b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/runtime.m @@ -197,7 +197,7 @@ //%DllMap% } -#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR +#if TARGET_OS_IPHONE && (!TARGET_IPHONE_SIMULATOR || USE_AOT_FOR_SIMULATOR) void mono_jit_set_aot_mode (MonoAotMode mode); void mono_ios_register_modules (void); #endif @@ -229,7 +229,7 @@ // TODO: set TRUSTED_PLATFORM_ASSEMBLIES, APP_PATHS and NATIVE_DLL_SEARCH_DIRECTORIES monovm_initialize(0, NULL, NULL); -#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR +#if TARGET_OS_IPHONE && (!TARGET_IPHONE_SIMULATOR || USE_AOT_FOR_SIMULATOR) register_dllmap (); // register modules mono_ios_register_modules (); @@ -250,7 +250,7 @@ } mono_jit_init_version ("dotnet.ios", "mobile"); -#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR +#if TARGET_OS_IPHONE && (!TARGET_IPHONE_SIMULATOR || USE_AOT_FOR_SIMULATOR) // device runtimes are configured to use lazy gc thread creation MONO_ENTER_GC_UNSAFE; mono_gc_init_finalizer_thread (); diff --git a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs index c0db9d1d2837e..821f2671500e5 100644 --- a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs +++ b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs @@ -21,6 +21,7 @@ internal class Xcode string monoInclude, bool preferDylibs, bool useConsoleUiTemplate, + bool useAotForSimulator, string? nativeMainSource = null) { // bundle everything as resources excluding native files @@ -80,6 +81,8 @@ internal class Xcode cmakeLists = cmakeLists.Replace("%NativeLibrariesToLink%", toLink); cmakeLists = cmakeLists.Replace("%AotSources%", aotSources); + cmakeLists = cmakeLists.Replace("%Defines%", + useAotForSimulator ? "add_definitions(-DUSE_AOT_FOR_SIMULATOR=1)" : ""); string plist = Utils.GetEmbeddedResource("Info.plist.template") .Replace("%BundleIdentifier%", projectName); From b4fc2f26178a251b833ba810f5ce8156ae2dc508 Mon Sep 17 00:00:00 2001 From: David Mason Date: Wed, 20 May 2020 11:17:06 -0700 Subject: [PATCH 299/420] Add managed array type support for EventPipe (#36242) Add support for emitting an event with an arbitrary number of arguments over EventPipe. --- .../Diagnostics/Eventing/EventPipe.CoreCLR.cs | 2 +- src/coreclr/src/vm/eventpipeblock.cpp | 2 - src/coreclr/src/vm/eventpipeevent.cpp | 3 +- src/coreclr/src/vm/eventpipeevent.h | 3 +- src/coreclr/src/vm/eventpipefile.cpp | 15 +- src/coreclr/src/vm/eventpipeprovider.cpp | 4 +- src/coreclr/src/vm/eventpipeprovider.h | 3 +- .../Tracing/EventPipeEventProvider.cs | 3 +- .../Tracing/EventPipeMetadataGenerator.cs | 461 ++++++++++++++++-- .../Diagnostics/Tracing/EventProvider.cs | 6 +- .../System/Diagnostics/Tracing/EventSource.cs | 7 +- .../Diagnostics/Tracing/IEventProvider.cs | 3 +- .../TraceLogging/EnumerableTypeInfo.cs | 2 + .../Tracing/TraceLogging/NameInfo.cs | 7 +- 14 files changed, 445 insertions(+), 76 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.CoreCLR.cs index bd1ad774bea18..7d3ab6c6af68d 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipe.CoreCLR.cs @@ -33,7 +33,7 @@ internal static partial class EventPipeInternal internal static extern IntPtr CreateProvider(string providerName, Interop.Advapi32.EtwEnableCallback callbackFunc); [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] - internal static extern unsafe IntPtr DefineEvent(IntPtr provHandle, uint eventID, long keywords, uint eventVersion, uint level, void* pMetadata, uint metadataLength); + internal static extern unsafe IntPtr DefineEvent(IntPtr provHandle, uint eventID, long keywords, uint eventVersion, uint level, void *pMetadata, uint metadataLength); [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] internal static extern IntPtr GetProvider(string providerName); diff --git a/src/coreclr/src/vm/eventpipeblock.cpp b/src/coreclr/src/vm/eventpipeblock.cpp index d72715956df7e..dd8807d3364c2 100644 --- a/src/coreclr/src/vm/eventpipeblock.cpp +++ b/src/coreclr/src/vm/eventpipeblock.cpp @@ -462,6 +462,4 @@ bool EventPipeStackBlock::WriteStack(DWORD stackId, StackContents* pStack) return true; } - - #endif // FEATURE_PERFTRACING diff --git a/src/coreclr/src/vm/eventpipeevent.cpp b/src/coreclr/src/vm/eventpipeevent.cpp index e352afb456c3e..a56ed9429847c 100644 --- a/src/coreclr/src/vm/eventpipeevent.cpp +++ b/src/coreclr/src/vm/eventpipeevent.cpp @@ -23,7 +23,8 @@ EventPipeEvent::EventPipeEvent( m_level(level), m_needStack(needStack), m_enabledMask(0), - m_pMetadata(nullptr) + m_pMetadata(nullptr), + m_metadataLength(0) { CONTRACTL { diff --git a/src/coreclr/src/vm/eventpipeevent.h b/src/coreclr/src/vm/eventpipeevent.h index f2dfe4ec232ef..06da70f90f6c3 100644 --- a/src/coreclr/src/vm/eventpipeevent.h +++ b/src/coreclr/src/vm/eventpipeevent.h @@ -49,7 +49,8 @@ class EventPipeEvent // Only EventPipeProvider can create events. // The provider is responsible for allocating and freeing events. - EventPipeEvent(EventPipeProvider &provider, INT64 keywords, unsigned int eventID, unsigned int eventVersion, EventPipeEventLevel level, bool needStack, BYTE *pMetadata = NULL, unsigned int metadataLength = 0); + EventPipeEvent(EventPipeProvider &provider, INT64 keywords, unsigned int eventID, unsigned int eventVersion, EventPipeEventLevel level, bool needStack, + BYTE *pMetadata = NULL, unsigned int metadataLength = 0); public: ~EventPipeEvent(); diff --git a/src/coreclr/src/vm/eventpipefile.cpp b/src/coreclr/src/vm/eventpipefile.cpp index 6baeaeefa9cf5..5a69f502e724b 100644 --- a/src/coreclr/src/vm/eventpipefile.cpp +++ b/src/coreclr/src/vm/eventpipefile.cpp @@ -201,10 +201,11 @@ void EventPipeFile::WriteEvent(EventPipeEventInstance &instance, ULONGLONG captu THROWS; GC_NOTRIGGER; MODE_ANY; - PRECONDITION(m_pSerializer != nullptr); } CONTRACTL_END; + if (HasErrors()) return; + #ifdef DEBUG _ASSERTE(instance.GetTimeStamp()->QuadPart >= m_lastSortedTimestamp.QuadPart); if (isSortedEvent) @@ -221,14 +222,15 @@ void EventPipeFile::WriteEvent(EventPipeEventInstance &instance, ULONGLONG captu // Check to see if we've seen this event type before. // If not, then write the event metadata to the event stream first. - unsigned int metadataId = GetMetadataId(*instance.GetEvent()); + EventPipeEvent* pEvent = instance.GetEvent(); + unsigned int metadataId = GetMetadataId(*pEvent); if(metadataId == 0) { metadataId = GenerateMetadataId(); EventPipeEventInstance* pMetadataInstance = EventPipe::BuildEventMetadataEvent(instance, metadataId); - WriteEventToBlock(*pMetadataInstance, 0); // metadataId=0 breaks recursion and represents the metadata event. + WriteEventToBlock(*pMetadataInstance, 0); // metadataId=0 breaks recursion and represents the metadata event. SaveMetadataId(*instance.GetEvent(), metadataId); @@ -247,7 +249,6 @@ void EventPipeFile::WriteSequencePoint(EventPipeSequencePoint* pSequencePoint) GC_NOTRIGGER; MODE_ANY; PRECONDITION(pSequencePoint != nullptr); - PRECONDITION(m_pSerializer != nullptr); } CONTRACTL_END; @@ -259,6 +260,9 @@ void EventPipeFile::WriteSequencePoint(EventPipeSequencePoint* pSequencePoint) Flush(FlushAllBlocks); EventPipeSequencePointBlock sequencePointBlock(pSequencePoint); + + if (HasErrors()) return; + m_pSerializer->WriteObject(&sequencePointBlock); // stack cache resets on sequence points @@ -278,13 +282,14 @@ void EventPipeFile::Flush(FlushFlags flags) NOTHROW; GC_NOTRIGGER; MODE_ANY; - PRECONDITION(m_pSerializer != nullptr); PRECONDITION(m_pMetadataBlock != nullptr); PRECONDITION(m_pStackBlock != nullptr); PRECONDITION(m_pBlock != nullptr); } CONTRACTL_END; + if (HasErrors()) return; + // we write current blocks to the disk, whether they are full or not if ((m_pMetadataBlock->GetBytesWritten() != 0) && ((flags & FlushMetadataBlock) != 0)) { diff --git a/src/coreclr/src/vm/eventpipeprovider.cpp b/src/coreclr/src/vm/eventpipeprovider.cpp index f2d7760b5b32e..1995b0689b8f7 100644 --- a/src/coreclr/src/vm/eventpipeprovider.cpp +++ b/src/coreclr/src/vm/eventpipeprovider.cpp @@ -152,7 +152,8 @@ EventPipeProviderCallbackData EventPipeProvider::UnsetConfiguration( return PrepareCallbackData(m_keywords, m_providerLevel, pFilterData); } -EventPipeEvent *EventPipeProvider::AddEvent(unsigned int eventID, INT64 keywords, unsigned int eventVersion, EventPipeEventLevel level, bool needStack, BYTE *pMetadata, unsigned int metadataLength) +EventPipeEvent *EventPipeProvider::AddEvent(unsigned int eventID, INT64 keywords, unsigned int eventVersion, EventPipeEventLevel level, bool needStack, + BYTE *pMetadata, unsigned int metadataLength) { CONTRACTL { @@ -172,7 +173,6 @@ EventPipeEvent *EventPipeProvider::AddEvent(unsigned int eventID, INT64 keywords needStack, pMetadata, metadataLength); - // Add it to the list of events. AddEvent(*pEvent); return pEvent; diff --git a/src/coreclr/src/vm/eventpipeprovider.h b/src/coreclr/src/vm/eventpipeprovider.h index d842f18044bb3..2fe93e969686a 100644 --- a/src/coreclr/src/vm/eventpipeprovider.h +++ b/src/coreclr/src/vm/eventpipeprovider.h @@ -76,7 +76,8 @@ class EventPipeProvider INT64 ComputeEventEnabledMask(INT64 keywords, EventPipeEventLevel eventLevel) const; // Create a new event. - EventPipeEvent* AddEvent(unsigned int eventID, INT64 keywords, unsigned int eventVersion, EventPipeEventLevel level, bool needStack, BYTE *pMetadata = NULL, unsigned int metadataLength = 0); + EventPipeEvent* AddEvent(unsigned int eventID, INT64 keywords, unsigned int eventVersion, EventPipeEventLevel level, bool needStack, + BYTE *pMetadata = NULL, unsigned int metadataLength = 0); private: diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventProvider.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventProvider.cs index 34a7b861e3057..8d0afa17111fc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventProvider.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventProvider.cs @@ -80,7 +80,8 @@ int IEventProvider.EventActivityIdControl(Interop.Advapi32.ActivityControl Contr } // Define an EventPipeEvent handle. - unsafe IntPtr IEventProvider.DefineEventHandle(uint eventID, string eventName, long keywords, uint eventVersion, uint level, byte* pMetadata, uint metadataLength) + unsafe IntPtr IEventProvider.DefineEventHandle(uint eventID, string eventName, long keywords, uint eventVersion, uint level, + byte *pMetadata, uint metadataLength) { IntPtr eventHandlePtr = EventPipeInternal.DefineEvent(m_provHandle, eventID, keywords, eventVersion, level, pMetadata, metadataLength); return eventHandlePtr; diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeMetadataGenerator.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeMetadataGenerator.cs index fd81d059621b2..50f1f41bbbf9b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeMetadataGenerator.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeMetadataGenerator.cs @@ -9,6 +9,12 @@ namespace System.Diagnostics.Tracing #if FEATURE_PERFTRACING internal sealed class EventPipeMetadataGenerator { + private enum MetadataTag + { + Opcode = 1, + ParameterPayload = 2 + } + public static EventPipeMetadataGenerator Instance = new EventPipeMetadataGenerator(); private EventPipeMetadataGenerator() { } @@ -19,7 +25,8 @@ internal sealed class EventPipeMetadataGenerator EventParameterInfo[] eventParams = new EventParameterInfo[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { - eventParams[i].SetInfo(parameters[i].Name!, parameters[i].ParameterType); + EventParameterInfo.GetTypeInfoFromType(parameters[i].ParameterType, out TraceLoggingTypeInfo? paramTypeInfo); + eventParams[i].SetInfo(parameters[i].Name!, parameters[i].ParameterType, paramTypeInfo); } return GenerateMetadata( @@ -28,6 +35,7 @@ internal sealed class EventPipeMetadataGenerator eventMetadata.Descriptor.Keywords, eventMetadata.Descriptor.Level, eventMetadata.Descriptor.Version, + (EventOpcode)eventMetadata.Descriptor.Opcode, eventParams); } @@ -37,6 +45,7 @@ internal sealed class EventPipeMetadataGenerator EventKeywords keywords, EventLevel level, uint version, + EventOpcode opcode, TraceLoggingEventTypes eventTypes) { TraceLoggingTypeInfo[] typeInfos = eventTypes.typeInfos; @@ -52,7 +61,7 @@ internal sealed class EventPipeMetadataGenerator eventParams[i].SetInfo(paramName, typeInfos[i].DataType, typeInfos[i]); } - return GenerateMetadata(eventId, eventName, (long)keywords, (uint)level, version, eventParams); + return GenerateMetadata(eventId, eventName, (long)keywords, (uint)level, version, opcode, eventParams); } internal unsafe byte[]? GenerateMetadata( @@ -61,9 +70,11 @@ internal sealed class EventPipeMetadataGenerator long keywords, uint level, uint version, + EventOpcode opcode, EventParameterInfo[] parameters) { byte[]? metadata = null; + bool hasV2ParameterTypes = false; try { // eventID : 4 bytes @@ -72,8 +83,9 @@ internal sealed class EventPipeMetadataGenerator // eventVersion : 4 bytes // level : 4 bytes // parameterCount : 4 bytes - uint metadataLength = 24 + ((uint)eventName.Length + 1) * 2; - uint defaultMetadataLength = metadataLength; + uint v1MetadataLength = 24 + ((uint)eventName.Length + 1) * 2; + uint v2MetadataLength = 0; + uint defaultV1MetadataLength = v1MetadataLength; // Check for an empty payload. // Write calls with no arguments by convention have a parameter of @@ -86,42 +98,115 @@ internal sealed class EventPipeMetadataGenerator // Increase the metadataLength for parameters. foreach (EventParameterInfo parameter in parameters) { - int pMetadataLength = parameter.GetMetadataLength(); - // The call above may return -1 which means we failed to get the metadata length. - // We then return a default metadata blob (with parameterCount of 0) to prevent it from generating malformed metadata. - if (pMetadataLength < 0) + uint pMetadataLength; + if (!parameter.GetMetadataLength(out pMetadataLength)) { - parameters = Array.Empty(); - metadataLength = defaultMetadataLength; + // The call above may return false which means it is an unsupported type for V1. + // If that is the case we use the v2 blob for metadata instead + hasV2ParameterTypes = true; break; } - metadataLength += (uint)pMetadataLength; + + v1MetadataLength += (uint)pMetadataLength; + } + + + if (hasV2ParameterTypes) + { + v1MetadataLength = defaultV1MetadataLength; + + // V2 length is the parameter count (4 bytes) plus the size of the params + v2MetadataLength = 4; + foreach (EventParameterInfo parameter in parameters) + { + uint pMetadataLength; + if (!parameter.GetMetadataLengthV2(out pMetadataLength)) + { + // We ran in to an unsupported type, return empty event metadata + parameters = Array.Empty(); + v1MetadataLength = defaultV1MetadataLength; + v2MetadataLength = 0; + hasV2ParameterTypes = false; + break; + } + + v2MetadataLength += (uint)pMetadataLength; + } } - metadata = new byte[metadataLength]; + // Optional opcode length needs 1 byte for the opcode + 5 bytes for the tag (4 bytes size, 1 byte kind) + uint opcodeMetadataLength = opcode == EventOpcode.Info ? 0u : 6u; + // Optional V2 metadata needs the size of the params + 5 bytes for the tag (4 bytes size, 1 byte kind) + uint v2MetadataPayloadLength = v2MetadataLength == 0 ? 0 : v2MetadataLength + 5; + uint totalV2MetadataLength = v2MetadataPayloadLength + opcodeMetadataLength; + uint totalMetadataLength = v1MetadataLength + totalV2MetadataLength; + metadata = new byte[totalMetadataLength]; - // Write metadata: eventID, eventName, keywords, eventVersion, level, parameterCount, param1 type, param1 name... + // Write metadata: metadataHeaderLength, eventID, eventName, keywords, eventVersion, level, + // parameterCount, param1..., optional extended metadata fixed (byte* pMetadata = metadata) { uint offset = 0; - WriteToBuffer(pMetadata, metadataLength, ref offset, (uint)eventId); + + WriteToBuffer(pMetadata, totalMetadataLength, ref offset, (uint)eventId); fixed (char* pEventName = eventName) { - WriteToBuffer(pMetadata, metadataLength, ref offset, (byte*)pEventName, ((uint)eventName.Length + 1) * 2); + WriteToBuffer(pMetadata, totalMetadataLength, ref offset, (byte*)pEventName, ((uint)eventName.Length + 1) * 2); } - WriteToBuffer(pMetadata, metadataLength, ref offset, keywords); - WriteToBuffer(pMetadata, metadataLength, ref offset, version); - WriteToBuffer(pMetadata, metadataLength, ref offset, level); - WriteToBuffer(pMetadata, metadataLength, ref offset, (uint)parameters.Length); - foreach (EventParameterInfo parameter in parameters) + WriteToBuffer(pMetadata, totalMetadataLength, ref offset, keywords); + WriteToBuffer(pMetadata, totalMetadataLength, ref offset, version); + WriteToBuffer(pMetadata, totalMetadataLength, ref offset, level); + + if (hasV2ParameterTypes) + { + // If we have unsupported types, the V1 metadata must be empty. Write 0 count of params. + WriteToBuffer(pMetadata, totalMetadataLength, ref offset, 0); + } + else + { + // Without unsupported V1 types we can write all the params now. + WriteToBuffer(pMetadata, totalMetadataLength, ref offset, (uint)parameters.Length); + foreach (var parameter in parameters) + { + if (!parameter.GenerateMetadata(pMetadata, ref offset, totalMetadataLength)) + { + // If we fail to generate metadata for any parameter, we should return the "default" metadata without any parameters + return GenerateMetadata(eventId, eventName, keywords, level, version, opcode, Array.Empty()); + } + } + } + + Debug.Assert(offset == v1MetadataLength); + + if (opcode != EventOpcode.Info) { - if (!parameter.GenerateMetadata(pMetadata, ref offset, metadataLength)) + // Size of opcode + WriteToBuffer(pMetadata, totalMetadataLength, ref offset, 1); + WriteToBuffer(pMetadata, totalMetadataLength, ref offset, (byte)MetadataTag.Opcode); + WriteToBuffer(pMetadata, totalMetadataLength, ref offset, (byte)opcode); + } + + if (hasV2ParameterTypes) + { + // Write the V2 supported metadata now + // Starting with the size of the V2 payload + WriteToBuffer(pMetadata, totalMetadataLength, ref offset, v2MetadataLength); + // Now the tag to identify it as a V2 parameter payload + WriteToBuffer(pMetadata, totalMetadataLength, ref offset, (byte)MetadataTag.ParameterPayload); + // Then the count of parameters + WriteToBuffer(pMetadata, totalMetadataLength, ref offset, (uint)parameters.Length); + // Finally the parameters themselves + foreach (var parameter in parameters) { - // If we fail to generate metadata for any parameter, we should return the "default" metadata without any parameters - return GenerateMetadata(eventId, eventName, keywords, level, version, Array.Empty()); + if (!parameter.GenerateMetadataV2(pMetadata, ref offset, totalMetadataLength)) + { + // If we fail to generate metadata for any parameter, we should return the "default" metadata without any parameters + return GenerateMetadata(eventId, eventName, keywords, level, version, opcode, Array.Empty()); + } } } - Debug.Assert(metadataLength == offset); + + Debug.Assert(totalMetadataLength == offset); } } catch @@ -147,28 +232,11 @@ internal static unsafe void WriteToBuffer(byte* buffer, uint bufferLength, ref u offset += srcLength; } - // Copy uint value to buffer. - internal static unsafe void WriteToBuffer(byte* buffer, uint bufferLength, ref uint offset, uint value) - { - Debug.Assert(bufferLength >= (offset + 4)); - *(uint*)(buffer + offset) = value; - offset += 4; - } - - // Copy long value to buffer. - internal static unsafe void WriteToBuffer(byte* buffer, uint bufferLength, ref uint offset, long value) + internal static unsafe void WriteToBuffer(byte* buffer, uint bufferLength, ref uint offset, T value) where T : unmanaged { - Debug.Assert(bufferLength >= (offset + 8)); - *(long*)(buffer + offset) = value; - offset += 8; - } - - // Copy char value to buffer. - internal static unsafe void WriteToBuffer(byte* buffer, uint bufferLength, ref uint offset, char value) - { - Debug.Assert(bufferLength >= (offset + 2)); - *(char*)(buffer + offset) = value; - offset += 2; + Debug.Assert(bufferLength >= (offset + sizeof(T))); + *(T*)(buffer + offset) = value; + offset += (uint)sizeof(T); } } @@ -307,16 +375,207 @@ private static unsafe bool GenerateMetadataForProperty(PropertyAnalysis property return true; } - internal int GetMetadataLength() + internal unsafe bool GenerateMetadataV2(byte* pMetadataBlob, ref uint offset, uint blobSize) + { + if (TypeInfo == null) + return false; + return GenerateMetadataForNamedTypeV2(ParameterName, TypeInfo, pMetadataBlob, ref offset, blobSize); + } + + private static unsafe bool GenerateMetadataForNamedTypeV2(string name, TraceLoggingTypeInfo typeInfo, byte* pMetadataBlob, ref uint offset, uint blobSize) { - int ret = 0; + Debug.Assert(pMetadataBlob != null); + + if (!GetMetadataLengthForNamedTypeV2(name, typeInfo, out uint length)) + { + return false; + } + + EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, length); + + // Write the property name. + fixed (char *pPropertyName = name) + { + EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (byte *)pPropertyName, ((uint)name.Length + 1) * 2); + } + + return GenerateMetadataForTypeV2(typeInfo, pMetadataBlob, ref offset, blobSize); + } + + private static unsafe bool GenerateMetadataForTypeV2(TraceLoggingTypeInfo? typeInfo, byte* pMetadataBlob, ref uint offset, uint blobSize) + { + Debug.Assert(typeInfo != null); + Debug.Assert(pMetadataBlob != null); + + // Check if this type is a nested struct. + if (typeInfo is InvokeTypeInfo invokeTypeInfo) + { + // Each nested struct is serialized as: + // TypeCode.Object : 4 bytes + // Number of properties : 4 bytes + // Property description 0...N + EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)TypeCode.Object); + + // Get the set of properties to be serialized. + PropertyAnalysis[]? properties = invokeTypeInfo.properties; + if (properties != null) + { + // Write the count of serializable properties. + EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)properties.Length); + + foreach (PropertyAnalysis prop in properties) + { + if (!GenerateMetadataForNamedTypeV2(prop.name, prop.typeInfo, pMetadataBlob, ref offset, blobSize)) + { + return false; + } + } + } + else + { + // This struct has zero serializable properties so we just write the property count. + EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)0); + } + } + else if (typeInfo is EnumerableTypeInfo enumerableTypeInfo) + { + // Each enumerable is serialized as: + // TypeCode.Array : 4 bytes + // ElementType : N bytes + EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, EventPipeTypeCodeArray); + GenerateMetadataForTypeV2(enumerableTypeInfo.ElementInfo, pMetadataBlob, ref offset, blobSize); + } + else if (typeInfo is ScalarArrayTypeInfo arrayTypeInfo) + { + // Each enumerable is serialized as: + // TypeCode.Array : 4 bytes + // ElementType : N bytes + if (!arrayTypeInfo.DataType.HasElementType) + { + return false; + } + + TraceLoggingTypeInfo? elementTypeInfo; + if (!GetTypeInfoFromType(arrayTypeInfo.DataType.GetElementType(), out elementTypeInfo)) + { + return false; + } + + EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, EventPipeTypeCodeArray); + GenerateMetadataForTypeV2(elementTypeInfo, pMetadataBlob, ref offset, blobSize); + } + else + { + // Each primitive type is serialized as: + // TypeCode : 4 bytes + TypeCode typeCode = GetTypeCodeExtended(typeInfo.DataType); + + // EventPipe does not support this type. Throw, which will cause no metadata to be registered for this event. + if (typeCode == TypeCode.Object) + { + return false; + } + + // Write the type code. + EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)typeCode); + } + return true; + } + + internal static bool GetTypeInfoFromType(Type? type, out TraceLoggingTypeInfo? typeInfo) + { + if (type == typeof(bool)) + { + typeInfo = ScalarTypeInfo.Boolean(); + return true; + } + else if (type == typeof(byte)) + { + typeInfo = ScalarTypeInfo.Byte(); + return true; + } + else if (type == typeof(sbyte)) + { + typeInfo = ScalarTypeInfo.SByte(); + return true; + } + else if (type == typeof(char)) + { + typeInfo = ScalarTypeInfo.Char(); + return true; + } + else if (type == typeof(short)) + { + typeInfo = ScalarTypeInfo.Int16(); + return true; + } + else if (type == typeof(ushort)) + { + typeInfo = ScalarTypeInfo.UInt16(); + return true; + } + else if (type == typeof(int)) + { + typeInfo = ScalarTypeInfo.Int32(); + return true; + } + else if (type == typeof(uint)) + { + typeInfo = ScalarTypeInfo.UInt32(); + return true; + } + else if (type == typeof(long)) + { + typeInfo = ScalarTypeInfo.Int64(); + return true; + } + else if (type == typeof(ulong)) + { + typeInfo = ScalarTypeInfo.UInt64(); + return true; + } + else if (type == typeof(IntPtr)) + { + typeInfo = ScalarTypeInfo.IntPtr(); + return true; + } + else if (type == typeof(UIntPtr)) + { + typeInfo = ScalarTypeInfo.UIntPtr(); + return true; + } + else if (type == typeof(float)) + { + typeInfo = ScalarTypeInfo.Single(); + return true; + } + else if (type == typeof(double)) + { + typeInfo = ScalarTypeInfo.Double(); + return true; + } + else if (type == typeof(Guid)) + { + typeInfo = ScalarTypeInfo.Guid(); + return true; + } + else + { + typeInfo = null; + return false; + } + } + + internal bool GetMetadataLength(out uint size) + { + size = 0; TypeCode typeCode = GetTypeCodeExtended(ParameterType); if (typeCode == TypeCode.Object) { if (!(TypeInfo is InvokeTypeInfo typeInfo)) { - return -1; + return false; } // Each nested struct is serialized as: @@ -324,7 +583,7 @@ internal int GetMetadataLength() // Number of properties : 4 bytes // Property description 0...N // Nested struct property name : NULL-terminated string. - ret += sizeof(uint) // TypeCode + size += sizeof(uint) // TypeCode + sizeof(uint); // Property count // Get the set of properties to be serialized. @@ -333,21 +592,21 @@ internal int GetMetadataLength() { foreach (PropertyAnalysis prop in properties) { - ret += (int)GetMetadataLengthForProperty(prop); + size += GetMetadataLengthForProperty(prop); } } // For simplicity when writing a reader, we write a NULL char // after the metadata for a top-level struct (for its name) so that // readers don't have do special case the outer-most struct. - ret += sizeof(char); + size += sizeof(char); } else { - ret += (int)(sizeof(uint) + ((ParameterName.Length + 1) * 2)); + size += (uint)(sizeof(uint) + ((ParameterName.Length + 1) * 2)); } - return ret; + return true; } private static uint GetMetadataLengthForProperty(PropertyAnalysis property) @@ -388,6 +647,9 @@ private static uint GetMetadataLengthForProperty(PropertyAnalysis property) return ret; } + // Array is not part of TypeCode, we decided to use 19 to represent it. (18 is the last type code value, string) + private const int EventPipeTypeCodeArray = 19; + private static TypeCode GetTypeCodeExtended(Type parameterType) { // Guid is not part of TypeCode, we decided to use 17 to represent it, as it's the "free slot" @@ -406,6 +668,99 @@ private static TypeCode GetTypeCodeExtended(Type parameterType) return Type.GetTypeCode(parameterType); } + + internal bool GetMetadataLengthV2(out uint size) + { + return GetMetadataLengthForNamedTypeV2(ParameterName, TypeInfo, out size); + } + + private static bool GetMetadataLengthForTypeV2(TraceLoggingTypeInfo? typeInfo, out uint size) + { + size = 0; + if (typeInfo == null) + { + return false; + } + + if (typeInfo is InvokeTypeInfo invokeTypeInfo) + { + // Struct is serialized as: + // TypeCode.Object : 4 bytes + // Number of properties : 4 bytes + // Property description 0...N + size += sizeof(uint) // TypeCode + + sizeof(uint); // Property count + + // Get the set of properties to be serialized. + PropertyAnalysis[]? properties = invokeTypeInfo.properties; + if (properties != null) + { + foreach (PropertyAnalysis prop in properties) + { + if (!GetMetadataLengthForNamedTypeV2(prop.name, prop.typeInfo, out uint typeSize)) + { + return false; + } + + size += typeSize; + } + } + } + else if (typeInfo is EnumerableTypeInfo enumerableTypeInfo) + { + // IEnumerable is serialized as: + // TypeCode : 4 bytes + // ElementType : N bytes + size += sizeof(uint); + if (!GetMetadataLengthForTypeV2(enumerableTypeInfo.ElementInfo, out uint typeSize)) + { + return false; + } + + size += typeSize; + } + else if (typeInfo is ScalarArrayTypeInfo arrayTypeInfo) + { + TraceLoggingTypeInfo? elementTypeInfo; + if (!arrayTypeInfo.DataType.HasElementType + || !GetTypeInfoFromType(arrayTypeInfo.DataType.GetElementType(), out elementTypeInfo)) + { + return false; + } + + size += sizeof(uint); + if (!GetMetadataLengthForTypeV2(elementTypeInfo, out uint typeSize)) + { + return false; + } + + size += typeSize; + } + else + { + size += (uint)sizeof(uint); + } + + return true; + } + + private static bool GetMetadataLengthForNamedTypeV2(string name, TraceLoggingTypeInfo? typeInfo, out uint size) + { + // Named type is serialized + // SizeOfTypeDescription : 4 bytes + // Name : NULL-terminated UTF16 string + // Type : N bytes + size = (uint)(sizeof(uint) + + ((name.Length + 1) * 2)); + + if (!GetMetadataLengthForTypeV2(typeInfo, out uint typeSize)) + { + return false; + } + + size += typeSize; + return true; + } } #endif // FEATURE_PERFTRACING diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs index fd0bd6eab4a32..dbc70abfb741d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs @@ -1325,7 +1325,8 @@ int IEventProvider.EventActivityIdControl(Interop.Advapi32.ActivityControl Contr } // Define an EventPipeEvent handle. - unsafe IntPtr IEventProvider.DefineEventHandle(uint eventID, string eventName, long keywords, uint eventVersion, uint level, byte* pMetadata, uint metadataLength) + unsafe IntPtr IEventProvider.DefineEventHandle(uint eventID, string eventName, long keywords, uint eventVersion, + uint level, byte* pMetadata, uint metadataLength) { throw new System.NotSupportedException(); } @@ -1366,7 +1367,8 @@ int IEventProvider.EventActivityIdControl(Interop.Advapi32.ActivityControl Contr } // Define an EventPipeEvent handle. - unsafe IntPtr IEventProvider.DefineEventHandle(uint eventID, string eventName, long keywords, uint eventVersion, uint level, byte* pMetadata, uint metadataLength) + unsafe IntPtr IEventProvider.DefineEventHandle(uint eventID, string eventName, long keywords, uint eventVersion, + uint level, byte* pMetadata, uint metadataLength) { return IntPtr.Zero; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index fd42fb69b6183..90e260acd6254 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -691,7 +691,7 @@ private unsafe void DefineEventPipeEvents() uint eventVersion = m_eventData[i].Descriptor.Version; uint level = m_eventData[i].Descriptor.Level; - fixed (byte* pMetadata = metadata) + fixed (byte *pMetadata = metadata) { IntPtr eventHandle = m_eventPipeProvider.m_eventProvider.DefineEventHandle( eventID, @@ -2221,12 +2221,13 @@ private unsafe void WriteEventString(string msgString) string eventName = "EventSourceMessage"; EventParameterInfo paramInfo = default(EventParameterInfo); paramInfo.SetInfo("message", typeof(string)); - byte[]? metadata = EventPipeMetadataGenerator.Instance.GenerateMetadata(0, eventName, keywords, (uint)level, 0, new EventParameterInfo[] { paramInfo }); + byte[]? metadata = EventPipeMetadataGenerator.Instance.GenerateMetadata(0, eventName, keywords, (uint)level, 0, EventOpcode.Info, new EventParameterInfo[] { paramInfo }); uint metadataLength = (metadata != null) ? (uint)metadata.Length : 0; fixed (byte* pMetadata = metadata) { - m_writeEventStringEventHandle = m_eventPipeProvider.m_eventProvider.DefineEventHandle(0, eventName, keywords, 0, (uint)level, pMetadata, metadataLength); + m_writeEventStringEventHandle = m_eventPipeProvider.m_eventProvider.DefineEventHandle(0, eventName, keywords, 0, (uint)level, + pMetadata, metadataLength); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/IEventProvider.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/IEventProvider.cs index 2ceb92f99c034..fc50ec76af5b5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/IEventProvider.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/IEventProvider.cs @@ -39,6 +39,7 @@ internal interface IEventProvider int EventActivityIdControl(Interop.Advapi32.ActivityControl ControlCode, ref Guid ActivityId); // Define an EventPipeEvent handle. - unsafe IntPtr DefineEventHandle(uint eventID, string eventName, long keywords, uint eventVersion, uint level, byte* pMetadata, uint metadataLength); + unsafe IntPtr DefineEventHandle(uint eventID, string eventName, long keywords, uint eventVersion, + uint level, byte *pMetadata, uint metadataLength); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/EnumerableTypeInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/EnumerableTypeInfo.cs index 92a1a823f94ee..56d0e061d5a2d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/EnumerableTypeInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/EnumerableTypeInfo.cs @@ -25,6 +25,8 @@ public EnumerableTypeInfo(Type type, TraceLoggingTypeInfo elementInfo) this.elementInfo = elementInfo; } + internal TraceLoggingTypeInfo ElementInfo { get { return elementInfo; } } + public override void WriteMetadata( TraceLoggingMetadataCollector collector, string? name, diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs index 17bf2eb2aeda6..4ca0b83988f26 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs @@ -88,18 +88,19 @@ public IntPtr GetOrCreateEventHandle(EventProvider provider, TraceLoggingEventHa { if ((eventHandle = eventHandleTable[descriptor.EventId]) == IntPtr.Zero) { - byte[]? metadataBlob = EventPipeMetadataGenerator.Instance.GenerateEventMetadata( + byte[]? metadata = EventPipeMetadataGenerator.Instance.GenerateEventMetadata( descriptor.EventId, name, (EventKeywords)descriptor.Keywords, (EventLevel)descriptor.Level, descriptor.Version, + (EventOpcode)descriptor.Opcode, eventTypes); - uint metadataLength = (metadataBlob != null) ? (uint)metadataBlob.Length : 0; + uint metadataLength = (metadata != null) ? (uint)metadata.Length : 0; unsafe { - fixed (byte* pMetadataBlob = metadataBlob) + fixed (byte* pMetadataBlob = metadata) { // Define the event. eventHandle = provider.m_eventProvider.DefineEventHandle( From 66e6fda900582ff278fc9da43d6e7a7079bfa499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Wed, 20 May 2020 20:46:24 +0200 Subject: [PATCH 300/420] Remove overwriting RuntimeIdentifier in runtime.depproj for wasm/ios/android (#36757) It shouldn't be needed anymore since we have real assets for these targets now. --- src/libraries/restore/runtime/runtime.depproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libraries/restore/runtime/runtime.depproj b/src/libraries/restore/runtime/runtime.depproj index c89e37e8c77b2..72e20f0ab8660 100644 --- a/src/libraries/restore/runtime/runtime.depproj +++ b/src/libraries/restore/runtime/runtime.depproj @@ -1,8 +1,6 @@  $(PackageRID) - - $(ToolRuntimeRID) $(NoWarn);NU1603;NU1605 true false From 54db4a39f86f07ca2a7d91c4620268d87ff324b2 Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Wed, 20 May 2020 20:47:28 +0200 Subject: [PATCH 301/420] Cache Uri.IdnHost and Uri.PathAndQuery (#36460) * Cache Uri.IdnHost and Uri.PathAndQuery * Continue caching DnsSafeHost * Move PathAndQuery cache from MoreInfo to UriInfo * Move DnsSafeHost and IdnHost logic to IdnHost getter * Add more Host tests --- .../System.Private.Uri/src/System/Uri.cs | 122 ++++++++++-------- .../FunctionalTests/IdnDnsSafeHostTest.cs | 48 +++++++ .../tests/FunctionalTests/UriTests.cs | 21 +++ 3 files changed, 139 insertions(+), 52 deletions(-) diff --git a/src/libraries/System.Private.Uri/src/System/Uri.cs b/src/libraries/System.Private.Uri/src/System/Uri.cs index 2ed3c4ec70146..495ec603d589e 100644 --- a/src/libraries/System.Private.Uri/src/System/Uri.cs +++ b/src/libraries/System.Private.Uri/src/System/Uri.cs @@ -141,11 +141,16 @@ internal void DebugAssertInCtor() private class UriInfo { - public string? Host; - public string? ScopeId; //only IP v6 may need this - public string? String; public Offset Offset; - public string? DnsSafeHost; // stores dns safe host when idn is on and we have unicode or idn host + public string? String; + public string? Host; + public string? IdnHost; + public string? PathAndQuery; + + /// + /// Only IP v6 may need this + /// + public string? ScopeId; private MoreInfo? _moreInfo; public MoreInfo MoreInfo @@ -321,8 +326,9 @@ private void EnsureParseRemaining() private void EnsureHostString(bool allowDnsOptimization) { - EnsureUriInfo(); - if ((object?)_info.Host == null) + UriInfo info = EnsureUriInfo(); + + if (info.Host is null) { if (allowDnsOptimization && InFact(Flags.CanonicalDnsHost)) { @@ -838,16 +844,23 @@ public string PathAndQuery throw new InvalidOperationException(SR.net_uri_NotAbsolute); } - string result = GetParts(UriComponents.PathAndQuery, UriFormat.UriEscaped); - // - // Compatibility: - // Remove the first slash from a Dos Path if it's present - // - if (IsDosPath && result[0] == '/') + UriInfo info = EnsureUriInfo(); + + if (info.PathAndQuery is null) { - result = result.Substring(1); + string result = GetParts(UriComponents.PathAndQuery, UriFormat.UriEscaped); + + // Compatibility: + // Remove the first slash from a Dos Path if it's present + if (IsDosPath && result[0] == '/') + { + result = result.Substring(1); + } + + info.PathAndQuery = result; } - return result; + + return info.PathAndQuery; } } @@ -1129,44 +1142,15 @@ public string DnsSafeHost EnsureHostString(false); - if (_info.DnsSafeHost != null) - { - // Cached - return _info.DnsSafeHost; - } - else if (_info.Host!.Length == 0) - { - // Empty host, no possible processing - return string.Empty; - } - - // Special case, will include ScopeID and strip [] around IPv6 - // This will also unescape the host string - string ret = _info.Host; - - if (HostType == Flags.IPv6HostType) + Flags hostType = HostType; + if (hostType == Flags.IPv6HostType || (hostType == Flags.BasicHostType && InFact(Flags.HostNotCanonical | Flags.E_HostNotCanonical))) { - ret = _info.ScopeId != null ? - string.Concat(ret.AsSpan(1, ret.Length - 2), _info.ScopeId) : - ret.Substring(1, ret.Length - 2); + return IdnHost; } - // Validate that this basic host qualifies as Dns safe, - // It has looser parsing rules that might allow otherwise. - // It might be a registry-based host from RFC 2396 Section 3.2.1 - else if (HostType == Flags.BasicHostType - && InFact(Flags.HostNotCanonical | Flags.E_HostNotCanonical)) + else { - // Unescape everything - char[] dest = new char[ret.Length]; - int count = 0; - UriHelper.UnescapeString(ret, 0, ret.Length, dest, ref count, c_DummyChar, c_DummyChar, - c_DummyChar, UnescapeMode.Unescape | UnescapeMode.UnescapeAll, _syntax, false); - ret = new string(dest, 0, count); + return _info.Host!; } - - _info.DnsSafeHost = ret; - - return ret; } } @@ -1175,14 +1159,48 @@ public string IdnHost { get { - string host = this.DnsSafeHost; + if (IsNotAbsoluteUri) + { + throw new InvalidOperationException(SR.net_uri_NotAbsolute); + } - if (HostType == Flags.DnsHostType) + if (_info?.IdnHost is null) { - host = DomainNameHelper.IdnEquivalent(host); + EnsureHostString(false); + + string host = _info!.Host!; + + Flags hostType = HostType; + if (hostType == Flags.DnsHostType) + { + host = DomainNameHelper.IdnEquivalent(host); + } + else if (hostType == Flags.IPv6HostType) + { + host = _info.ScopeId != null ? + string.Concat(host.AsSpan(1, host.Length - 2), _info.ScopeId) : + host.Substring(1, host.Length - 2); + } + // Validate that this basic host qualifies as Dns safe, + // It has looser parsing rules that might allow otherwise. + // It might be a registry-based host from RFC 2396 Section 3.2.1 + else if (hostType == Flags.BasicHostType && InFact(Flags.HostNotCanonical | Flags.E_HostNotCanonical)) + { + // Unescape everything + ValueStringBuilder dest = new ValueStringBuilder(stackalloc char[256]); + + UriHelper.UnescapeString(host, 0, host.Length, ref dest, + c_DummyChar, c_DummyChar, c_DummyChar, + UnescapeMode.Unescape | UnescapeMode.UnescapeAll, + _syntax, isQuery: false); + + host = dest.ToString(); + } + + _info.IdnHost = host; } - return host; + return _info.IdnHost; } } diff --git a/src/libraries/System.Private.Uri/tests/FunctionalTests/IdnDnsSafeHostTest.cs b/src/libraries/System.Private.Uri/tests/FunctionalTests/IdnDnsSafeHostTest.cs index 7685cdd655002..539702f65c582 100644 --- a/src/libraries/System.Private.Uri/tests/FunctionalTests/IdnDnsSafeHostTest.cs +++ b/src/libraries/System.Private.Uri/tests/FunctionalTests/IdnDnsSafeHostTest.cs @@ -77,5 +77,53 @@ public void IdnDnsSafeHost_MultiLabelAllExceptIntranet_Punycode() Assert.Equal("xn--pck.com", test.IdnHost); Assert.Equal("https://\u30AF.com/", test.AbsoluteUri); } + + [Theory] + [InlineData("foo", "foo", "foo", "foo")] + [InlineData("BAR", "bar", "bar", "bar")] + [InlineData("\u00FC", "\u00FC", "\u00FC", "xn--tda")] + [InlineData("\u00FC.\u00FC", "\u00FC.\u00FC", "\u00FC.\u00FC", "xn--tda.xn--tda")] + [InlineData("\u00FC.foo.\u00FC", "\u00FC.foo.\u00FC", "\u00FC.foo.\u00FC", "xn--tda.foo.xn--tda")] + [InlineData("xn--tda", "xn--tda", "xn--tda", "xn--tda")] + [InlineData("xn--tda.xn--tda", "xn--tda.xn--tda", "xn--tda.xn--tda", "xn--tda.xn--tda")] + [InlineData("127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1")] + [InlineData("127.0.o.1", "127.0.o.1", "127.0.o.1", "127.0.o.1")] + [InlineData("127.0.0.1.1", "127.0.0.1.1", "127.0.0.1.1", "127.0.0.1.1")] + [InlineData("[::]", "[::]", "::", "::")] + [InlineData("[123::]", "[123::]", "123::", "123::")] + [InlineData("[123:123::]", "[123:123::]", "123:123::", "123:123::")] + [InlineData("[123:123::%]", "[123:123::]", "123:123::%", "123:123::%")] + [InlineData("[123:123::%foo]", "[123:123::]", "123:123::%foo", "123:123::%foo")] + [InlineData("[123:123::%foo%20bar]", "[123:123::]", "123:123::%foo%20bar", "123:123::%foo%20bar")] + public void Host_DnsSafeHost_IdnHost_ProcessedCorrectly(string hostString, string host, string dnsSafeHost, string idnHost) + { + Asserts($"wss://{hostString}", host, dnsSafeHost, idnHost); + Asserts($"wss://{hostString}:1", host, dnsSafeHost, idnHost); + Asserts($"http://{hostString}", host, dnsSafeHost, idnHost); + Asserts($"http://{hostString}:1", host, dnsSafeHost, idnHost); + Asserts($"https://{hostString}", host, dnsSafeHost, idnHost); + Asserts($"https://{hostString}:1", host, dnsSafeHost, idnHost); + + Asserts($"\\\\{hostString}", host, dnsSafeHost, idnHost); + Asserts($"file:////{hostString}", host, dnsSafeHost, idnHost); + + static void Asserts(string uriString, string host, string dnsSafeHost, string idnHost) + { + var uri = new Uri(uriString); + + Assert.Equal(host, uri.Host); + Assert.Equal(dnsSafeHost, uri.DnsSafeHost); + Assert.Equal(idnHost, uri.IdnHost); + + if (host == dnsSafeHost) + { + Assert.Same(uri.Host, uri.DnsSafeHost); + } + else + { + Assert.Same(uri.DnsSafeHost, uri.IdnHost); + } + } + } } } diff --git a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs index 6317c87b2942b..140b9ef6aaa93 100644 --- a/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs +++ b/src/libraries/System.Private.Uri/tests/FunctionalTests/UriTests.cs @@ -710,6 +710,27 @@ public static void Uri_EmptyPort_UsesDefaultPort() Assert.Equal(80, u.Port); } + [Fact] + public static void Uri_CachesIdnHost() + { + var uri = new Uri("https://\u00FCnicode/foo"); + Assert.Same(uri.IdnHost, uri.IdnHost); + } + + [Fact] + public static void Uri_CachesPathAndQuery() + { + var uri = new Uri("https://foo/bar?one=two"); + Assert.Same(uri.PathAndQuery, uri.PathAndQuery); + } + + [Fact] + public static void Uri_CachesDnsSafeHost() + { + var uri = new Uri("https://[::]/bar"); + Assert.Same(uri.DnsSafeHost, uri.DnsSafeHost); + } + [Fact] public static void Uri_DoesNotLockOnString() { From cf654f08fb0078a96a4e414a0d2eab5e6c069387 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Wed, 20 May 2020 17:35:59 -0400 Subject: [PATCH 302/420] [interp] Add separate opcode for pop vt (#36760) Before this change, pop-ing a vt from the stack was done in 2 opcodes, a MINT_POP (decrementing the stack) and the weird MINT_VTRESULT (decrementing the vtstack). However, optimizations could have removed both the initial loading of the value type on the stack as well as the MINT_POP, leaving MINT_VTRESULT underflowing the vtstack. Fix this and cleanup the code by pop-ing a value type from the stack in a single instruction. Co-authored-by: BrzVlad --- src/mono/mono/mini/interp/interp.c | 7 +++++++ src/mono/mono/mini/interp/mintops.def | 1 + src/mono/mono/mini/interp/transform.c | 11 ++++++----- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 35de785f66f7e..6fb7279b7a0ff 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -3567,6 +3567,13 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs ip++; MINT_IN_BREAK; } + MINT_IN_CASE(MINT_POP_VT) { + int i32 = READ32 (ip + 1); + vt_sp -= ALIGN_TO (i32, MINT_VT_ALIGNMENT); + sp--; + ip += 3; + MINT_IN_BREAK; + } MINT_IN_CASE(MINT_POP1) { sp [-2] = sp [-1]; sp--; diff --git a/src/mono/mono/mini/interp/mintops.def b/src/mono/mono/mini/interp/mintops.def index d3dd6cc5a7c87..f3cbbb5f91167 100644 --- a/src/mono/mono/mini/interp/mintops.def +++ b/src/mono/mono/mini/interp/mintops.def @@ -16,6 +16,7 @@ OPDEF(MINT_LDNULL, "ldnull", 1, Pop0, Push1, MintOpNoArgs) OPDEF(MINT_DUP, "dup", 1, Pop1, Push2, MintOpNoArgs) OPDEF(MINT_DUP_VT, "dup.vt", 3, Pop1, Push2, MintOpInt) OPDEF(MINT_POP, "pop", 1, Pop1, Push0, MintOpNoArgs) +OPDEF(MINT_POP_VT, "pop.vt", 3, Pop1, Push0, MintOpNoArgs) OPDEF(MINT_POP1, "pop1", 1, Pop2, Push1, MintOpNoArgs) OPDEF(MINT_RET, "ret", 1, Pop1, Push0, MintOpNoArgs) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 5d78ab524f1a9..70d866ed11108 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -3740,14 +3740,15 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, } case CEE_POP: CHECK_STACK(td, 1); - SIMPLE_OP(td, MINT_POP); if (td->sp [-1].type == STACK_TYPE_VT) { int size = mono_class_value_size (td->sp [-1].klass, NULL); size = ALIGN_TO (size, MINT_VT_ALIGNMENT); - interp_add_ins (td, MINT_VTRESULT); - td->last_ins->data [0] = 0; - WRITE32_INS (td->last_ins, 1, &size); + interp_add_ins (td, MINT_POP_VT); + WRITE32_INS (td->last_ins, 0, &size); td->vt_sp -= size; + td->ip++; + } else { + SIMPLE_OP(td, MINT_POP); } --td->sp; break; @@ -7347,7 +7348,7 @@ interp_cprop (TransformData *td) sp [-i].ins = NULL; memset (sp, 0, sizeof (StackContentInfo)); sp++; - } else if (ins->opcode == MINT_POP) { + } else if (ins->opcode == MINT_POP || ins->opcode == MINT_POP_VT) { sp--; if (sp->ins) { // The top of the stack is not used by any instructions. Kill both the From fa99dbad0d7687fe86b5f80ad610e92f0bf6c9a9 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 21 May 2020 00:51:11 +0200 Subject: [PATCH 303/420] [master] Update dependencies from mono/linker dotnet/llvm-project dotnet/xharness (#36764) * Update dependencies from https://github.com/dotnet/llvm-project build 20200518.2 runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools , runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools , runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk , runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools , runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk , runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk From Version 9.0.1-alpha.1.20262.1 -> To Version 9.0.1-alpha.1.20268.2 * Update dependencies from https://github.com/mono/linker build 20200519.1 Microsoft.NET.ILLink.Tasks From Version 5.0.0-preview.3.20268.5 -> To Version 5.0.0-preview.3.20269.1 * Update dependencies from https://github.com/dotnet/xharness build 20200520.1 Microsoft.DotNet.XHarness.Tests.Runners From Version 1.0.0-prerelease.20265.8 -> To Version 1.0.0-prerelease.20270.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 32 ++++++++++++++++---------------- eng/Versions.props | 16 ++++++++-------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a0025342df1b3..16d072aca3d99 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -118,29 +118,29 @@ https://github.com/dotnet/runtime-assets 71b9284907ebc69e5f80b491a51084c75e0ef7d3 - + https://github.com/dotnet/llvm-project - 783010917d17a9c8e9955d2be149deb40c8362f9 + d179d1b519fb0b3e4a4b3f15ee55920e310c582f - + https://github.com/dotnet/llvm-project - 783010917d17a9c8e9955d2be149deb40c8362f9 + d179d1b519fb0b3e4a4b3f15ee55920e310c582f - + https://github.com/dotnet/llvm-project - 783010917d17a9c8e9955d2be149deb40c8362f9 + d179d1b519fb0b3e4a4b3f15ee55920e310c582f - + https://github.com/dotnet/llvm-project - 783010917d17a9c8e9955d2be149deb40c8362f9 + d179d1b519fb0b3e4a4b3f15ee55920e310c582f - + https://github.com/dotnet/llvm-project - 783010917d17a9c8e9955d2be149deb40c8362f9 + d179d1b519fb0b3e4a4b3f15ee55920e310c582f - + https://github.com/dotnet/llvm-project - 783010917d17a9c8e9955d2be149deb40c8362f9 + d179d1b519fb0b3e4a4b3f15ee55920e310c582f https://github.com/dotnet/runtime @@ -170,13 +170,13 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - 45730defebfff077bff4991d4884e0ff32f78913 + 3409a1a819e380c0ffeedfaaccc74f064b67b2ff - + https://github.com/dotnet/xharness - 7f79598da0ffe62781affb5bab1fc477e479d767 + 875d086091bb053dbbefd8d55718245e6820ddc8 diff --git a/eng/Versions.props b/eng/Versions.props index fe395c5ad1d8a..52dc93a876b92 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -107,7 +107,7 @@ 4.8.0 16.7.0-preview-20200518-01 - 1.0.0-prerelease.20265.8 + 1.0.0-prerelease.20270.1 2.4.1 1.2.1 2.0.5 @@ -116,14 +116,14 @@ 3.1.0-preview-20200129.1 - 5.0.0-preview.3.20268.5 + 5.0.0-preview.3.20269.1 - 9.0.1-alpha.1.20262.1 - 9.0.1-alpha.1.20262.1 - 9.0.1-alpha.1.20262.1 - 9.0.1-alpha.1.20262.1 - 9.0.1-alpha.1.20262.1 - 9.0.1-alpha.1.20262.1 + 9.0.1-alpha.1.20268.2 + 9.0.1-alpha.1.20268.2 + 9.0.1-alpha.1.20268.2 + 9.0.1-alpha.1.20268.2 + 9.0.1-alpha.1.20268.2 + 9.0.1-alpha.1.20268.2 From 41882cbf086270042f65445dc54cfec9a4b54c50 Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Wed, 20 May 2020 15:52:13 -0700 Subject: [PATCH 304/420] Support !JitDoOldStructRetyping on other platforms. (#35943) * Add more test cases. * Initialize `ReturnTypeDesc` when we keep struct types. * Add a few const modifiers. * Additional checks in `LowerRet` * Support `return double(cnst int)`. * Optimize `LowerRetStruct`: no need for bitcast when read from memory. * Prepare `LowerNode` for store local and local field to multireg. * Compile the new methods with FEATURE_MULTIREG_RET. * Improve `LowerRetStructLclVar`. Don't use bitcast if the source is in memory or has the same type. * Extract `LowerStoreLocCommon`. * Support 3, 5. 6, 7 bytes structs in `LowerCallStruct`. Move call handling to the users. * Disable `JitDoOldStructRetyping` for x86 and x64. Windows x64 was supported in a previous PR, this adds x86 (Windows and Linux) and x64 Unix. * Fix suggestions. * Disable by default for the merge. --- src/coreclr/src/jit/importer.cpp | 32 +- src/coreclr/src/jit/jitconfigvalues.h | 6 +- src/coreclr/src/jit/lower.cpp | 422 +++++++++++++----- src/coreclr/src/jit/lower.h | 13 +- src/coreclr/src/jit/lowerarmarch.cpp | 4 +- src/coreclr/src/jit/lowerxarch.cpp | 4 +- .../JIT/Directed/StructABI/structreturn.cs | 402 +++++++++++++++++ 7 files changed, 751 insertions(+), 132 deletions(-) diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 010cd3395cb14..9a6f1afef4879 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -9059,10 +9059,21 @@ GenTree* Compiler::impFixupCallStructReturn(GenTreeCall* call, CORINFO_CLASS_HAN } else { + +#if FEATURE_MULTIREG_RET + const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); + const unsigned retRegCount = retTypeDesc->GetReturnRegCount(); + assert(retRegCount != 0); + if (!compDoOldStructRetyping() && retRegCount == 1) + { + return call; + } +#else // !FEATURE_MULTIREG_RET if (!compDoOldStructRetyping()) { return call; } +#endif // !FEATURE_MULTIREG_RET assert(returnType != TYP_UNKNOWN); // See if the struct size is smaller than the return @@ -9095,9 +9106,6 @@ GenTree* Compiler::impFixupCallStructReturn(GenTreeCall* call, CORINFO_CLASS_HAN } #if FEATURE_MULTIREG_RET - const unsigned retRegCount = call->GetReturnTypeDesc()->GetReturnRegCount(); - assert(retRegCount != 0); - if (retRegCount >= 2) { if ((!call->CanTailCall()) && (!call->IsInlineCandidate())) @@ -9130,12 +9138,6 @@ GenTree* Compiler::impFixupStructReturnType(GenTree* op, CORINFO_CLASS_HANDLE re assert(varTypeIsStruct(info.compRetType)); assert(info.compRetBuffArg == BAD_VAR_NUM); - if (!compDoOldStructRetyping() && (!op->IsCall() || !op->AsCall()->TreatAsHasRetBufArg(this))) - { - // Don't retype `struct` as a primitive type in `ret` instruction. - return op; - } - JITDUMP("\nimpFixupStructReturnType: retyping\n"); DISPTREE(op); @@ -9250,6 +9252,12 @@ GenTree* Compiler::impFixupStructReturnType(GenTree* op, CORINFO_CLASS_HANDLE re #endif // FEATURE_MULTIREG_RET && FEATURE_HFA + if (!compDoOldStructRetyping() && (!op->IsCall() || !op->AsCall()->TreatAsHasRetBufArg(this))) + { + // Don't retype `struct` as a primitive type in `ret` instruction. + return op; + } + REDO_RETURN_NODE: // adjust the type away from struct to integral // and no normalizing @@ -15214,6 +15222,9 @@ void Compiler::impImportBlockCode(BasicBlock* block) if (!compDoOldStructRetyping()) { op1->AsCall()->gtRetClsHnd = classHandle; +#if FEATURE_MULTIREG_RET + op1->AsCall()->InitializeStructReturnType(this, classHandle); +#endif } tiRetVal = typeInfo(TI_STRUCT, classHandle); @@ -15258,6 +15269,9 @@ void Compiler::impImportBlockCode(BasicBlock* block) op1->AsCall()->gtReturnType = GetRuntimeHandleUnderlyingType(); if (!compDoOldStructRetyping()) { +#if FEATURE_MULTIREG_RET + op1->AsCall()->InitializeStructReturnType(this, tokenType); +#endif op1->AsCall()->gtRetClsHnd = tokenType; } diff --git a/src/coreclr/src/jit/jitconfigvalues.h b/src/coreclr/src/jit/jitconfigvalues.h index cb86931dfaa7a..d531362543ebe 100644 --- a/src/coreclr/src/jit/jitconfigvalues.h +++ b/src/coreclr/src/jit/jitconfigvalues.h @@ -437,13 +437,13 @@ CONFIG_INTEGER(JitSaveFpLrWithCalleeSavedRegisters, W("JitSaveFpLrWithCalleeSave #endif // defined(TARGET_ARM64) #endif // DEBUG -#if !FEATURE_MULTIREG_RET +#if defined(TARGET_ARMARCH) CONFIG_INTEGER(JitDoOldStructRetyping, W("JitDoOldStructRetyping"), 1) // Allow Jit to retype structs as primitive types // when possible. -#else // FEATURE_MULTIREG_RET +#else CONFIG_INTEGER(JitDoOldStructRetyping, W("JitDoOldStructRetyping"), 1) // Allow Jit to retype structs as primitive types // when possible. -#endif // FEATURE_MULTIREG_RET +#endif #undef CONFIG_INTEGER #undef CONFIG_STRING diff --git a/src/coreclr/src/jit/lower.cpp b/src/coreclr/src/jit/lower.cpp index 173f4702e480b..2c093a67d048b 100644 --- a/src/coreclr/src/jit/lower.cpp +++ b/src/coreclr/src/jit/lower.cpp @@ -37,7 +37,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // Notes: // If 'childNode' it has any existing sources, they will now be sources for the parent. // -void Lowering::MakeSrcContained(GenTree* parentNode, GenTree* childNode) +void Lowering::MakeSrcContained(GenTree* parentNode, GenTree* childNode) const { assert(!parentNode->OperIsLeaf()); assert(childNode->canBeContained()); @@ -255,6 +255,13 @@ GenTree* Lowering::LowerNode(GenTree* node) case GT_STORE_BLK: case GT_STORE_OBJ: + if (node->AsBlk()->Data()->IsCall()) + { + assert(!comp->compDoOldStructRetyping()); + LowerStoreCallStruct(node->AsBlk()); + break; + } + __fallthrough; case GT_STORE_DYN_BLK: LowerBlockStore(node->AsBlk()); break; @@ -297,64 +304,8 @@ GenTree* Lowering::LowerNode(GenTree* node) __fallthrough; case GT_STORE_LCL_FLD: - { - GenTreeLclVarCommon* const store = node->AsLclVarCommon(); - GenTree* src = store->gtGetOp1(); - if ((varTypeUsesFloatReg(store) != varTypeUsesFloatReg(src)) && !store->IsPhiDefn() && - (src->TypeGet() != TYP_STRUCT)) - { - if (m_lsra->isRegCandidate(comp->lvaGetDesc(store->GetLclNum()))) - { - GenTreeUnOp* bitcast = new (comp, GT_BITCAST) GenTreeOp(GT_BITCAST, store->TypeGet(), src, nullptr); - store->gtOp1 = bitcast; - src = store->gtGetOp1(); - BlockRange().InsertBefore(store, bitcast); - ContainCheckBitCast(bitcast); - } - else - { - // This is an actual store, we'll just retype it. - store->gtType = src->TypeGet(); - } - } - - if ((node->TypeGet() == TYP_STRUCT) && (src->OperGet() != GT_PHI)) - { - LclVarDsc* varDsc = comp->lvaGetDesc(store); -#if FEATURE_MULTIREG_RET - if (src->OperGet() == GT_CALL) - { - assert(src->AsCall()->HasMultiRegRetVal()); - } - else -#endif // FEATURE_MULTIREG_RET - if (!src->OperIs(GT_LCL_VAR, GT_CALL) || varDsc->GetLayout()->GetRegisterType() == TYP_UNDEF) - { - GenTreeLclVar* addr = comp->gtNewLclVarAddrNode(store->GetLclNum(), TYP_BYREF); - - addr->gtFlags |= GTF_VAR_DEF; - assert(!addr->IsPartialLclFld(comp)); - addr->gtFlags |= GTF_DONT_CSE; - - // Create the assignment node. - store->ChangeOper(GT_STORE_OBJ); - - store->gtFlags = GTF_ASG | GTF_IND_NONFAULTING | GTF_IND_TGT_NOT_HEAP; -#ifndef JIT32_GCENCODER - store->AsObj()->gtBlkOpGcUnsafe = false; -#endif - store->AsObj()->gtBlkOpKind = GenTreeObj::BlkOpKindInvalid; - store->AsObj()->SetLayout(varDsc->GetLayout()); - store->AsObj()->SetAddr(addr); - store->AsObj()->SetData(src); - BlockRange().InsertBefore(store, addr); - LowerBlockStore(store->AsObj()); - break; - } - } - LowerStoreLoc(node->AsLclVarCommon()); + LowerStoreLocCommon(node->AsLclVarCommon()); break; - } #if defined(TARGET_ARM64) case GT_CMPXCHG: @@ -1689,13 +1640,10 @@ void Lowering::LowerCall(GenTree* node) LowerFastTailCall(call); } -#if !FEATURE_MULTIREG_RET if (varTypeIsStruct(call)) { - assert(!comp->compDoOldStructRetyping()); LowerCallStruct(call); } -#endif // !FEATURE_MULTIREG_RET ContainCheckCallOperands(call); JITDUMP("lowering call (after):\n"); @@ -2993,7 +2941,6 @@ void Lowering::LowerRet(GenTreeUnOp* ret) BlockRange().InsertBefore(ret, bitcast); ContainCheckBitCast(bitcast); } -#if !FEATURE_MULTIREG_RET else { #ifdef DEBUG @@ -3002,19 +2949,38 @@ void Lowering::LowerRet(GenTreeUnOp* ret) GenTree* retVal = ret->gtGetOp1(); if (varTypeIsStruct(ret->TypeGet()) != varTypeIsStruct(retVal->TypeGet())) { - // This could happen if we have retyped op1 as a primitive type during struct promotion, - // check `retypedFieldsMap` for details. - assert(genActualType(comp->info.compRetNativeType) == genActualType(retVal->TypeGet())); + if (varTypeIsStruct(ret->TypeGet())) + { + assert(!comp->compDoOldStructRetyping()); + bool actualTypesMatch = false; + if (genActualType(comp->info.compRetNativeType) == genActualType(retVal->TypeGet())) + { + // This could happen if we have retyped op1 as a primitive type during struct promotion, + // check `retypedFieldsMap` for details. + actualTypesMatch = true; + } + bool constStructInit = retVal->IsConstInitVal(); + assert(actualTypesMatch || constStructInit); + } + else + { +#ifdef FEATURE_SIMD + assert(comp->compDoOldStructRetyping()); + assert(ret->TypeIs(TYP_DOUBLE)); + assert(retVal->TypeIs(TYP_SIMD8)); +#else // !FEATURE_SIMD + unreached(); +#endif // !FEATURE_SIMD + } } } -#endif - if (varTypeIsStruct(ret)) +#endif // DEBUG + if (varTypeIsStruct(ret) && !comp->compMethodReturnsMultiRegRetType()) { assert(!comp->compDoOldStructRetyping()); LowerRetStruct(ret); } } -#endif // !FEATURE_MULTIREG_RET // Method doing PInvokes has exactly one return block unless it has tail calls. if (comp->compMethodRequiresPInvokeFrame() && (comp->compCurBB == comp->genReturnBB)) @@ -3024,7 +2990,111 @@ void Lowering::LowerRet(GenTreeUnOp* ret) ContainCheckRet(ret); } -#if !FEATURE_MULTIREG_RET +//---------------------------------------------------------------------------------------------- +// LowerStoreLocCommon: platform idependent part of local var or field store lowering. +// +// Arguments: +// lclStore - The store lcl node to lower. +// +void Lowering::LowerStoreLocCommon(GenTreeLclVarCommon* lclStore) +{ + assert(lclStore->OperIs(GT_STORE_LCL_FLD, GT_STORE_LCL_VAR)); + GenTree* src = lclStore->gtGetOp1(); + LclVarDsc* varDsc = comp->lvaGetDesc(lclStore); + if ((varTypeUsesFloatReg(lclStore) != varTypeUsesFloatReg(src)) && !lclStore->IsPhiDefn() && + (src->TypeGet() != TYP_STRUCT)) + { + if (m_lsra->isRegCandidate(varDsc)) + { + GenTreeUnOp* bitcast = new (comp, GT_BITCAST) GenTreeOp(GT_BITCAST, lclStore->TypeGet(), src, nullptr); + lclStore->gtOp1 = bitcast; + src = lclStore->gtGetOp1(); + BlockRange().InsertBefore(lclStore, bitcast); + ContainCheckBitCast(bitcast); + } + else + { + // This is an actual store, we'll just retype it. + lclStore->gtType = src->TypeGet(); + } + } + + if ((lclStore->TypeGet() == TYP_STRUCT) && (src->OperGet() != GT_PHI)) + { + if (src->OperGet() == GT_CALL) + { + GenTreeCall* call = src->AsCall(); + const ClassLayout* layout = varDsc->GetLayout(); + const var_types regType = layout->GetRegisterType(); + +#ifdef DEBUG + const unsigned slotCount = layout->GetSlotCount(); +#if defined(TARGET_XARCH) && !defined(UNIX_AMD64_ABI) + // Windows x64 doesn't have multireg returns, + // x86 uses it only for long return type, not for structs. + assert(!comp->compDoOldStructRetyping()); + assert(slotCount == 1); + assert(regType != TYP_UNDEF); +#else // !TARGET_XARCH || UNIX_AMD64_ABI + if (!varDsc->lvIsHfa()) + { + if (slotCount > 1) + { + assert(call->HasMultiRegRetVal()); + } + else + { + assert(!comp->compDoOldStructRetyping()); + unsigned size = layout->GetSize(); + assert((size <= 8) || (size == 16)); + bool isPowerOf2 = (((size - 1) & size) == 0); + bool isTypeDefined = (regType != TYP_UNDEF); + assert(isPowerOf2 == isTypeDefined); + } + } +#endif // !TARGET_XARCH || UNIX_AMD64_ABI +#endif // DEBUG + +#if !defined(WINDOWS_AMD64_ABI) + if (!call->HasMultiRegRetVal() && (regType == TYP_UNDEF)) + { + // If we have a single return register, + // but we can't retype it as a primitive type, we must spill it. + GenTreeLclVar* spilledCall = SpillStructCallResult(call); + lclStore->gtOp1 = spilledCall; + src = lclStore->gtOp1; + LowerStoreLocCommon(lclStore); + return; + } +#endif // !WINDOWS_AMD64_ABI + } + else if (!src->OperIs(GT_LCL_VAR) || varDsc->GetLayout()->GetRegisterType() == TYP_UNDEF) + { + GenTreeLclVar* addr = comp->gtNewLclVarAddrNode(lclStore->GetLclNum(), TYP_BYREF); + + addr->gtFlags |= GTF_VAR_DEF; + assert(!addr->IsPartialLclFld(comp)); + addr->gtFlags |= GTF_DONT_CSE; + + // Create the assignment node. + lclStore->ChangeOper(GT_STORE_OBJ); + GenTreeBlk* objStore = lclStore->AsObj(); + objStore->gtFlags = GTF_ASG | GTF_IND_NONFAULTING | GTF_IND_TGT_NOT_HEAP; +#ifndef JIT32_GCENCODER + objStore->gtBlkOpGcUnsafe = false; +#endif + objStore->gtBlkOpKind = GenTreeObj::BlkOpKindInvalid; + objStore->SetLayout(varDsc->GetLayout()); + objStore->SetAddr(addr); + objStore->SetData(src); + BlockRange().InsertBefore(objStore, addr); + LowerBlockStore(objStore); + return; + } + } + LowerStoreLoc(lclStore); +} + //---------------------------------------------------------------------------------------------- // LowerRetStructLclVar: Lowers a struct return node. // @@ -3033,6 +3103,7 @@ void Lowering::LowerRet(GenTreeUnOp* ret) // void Lowering::LowerRetStruct(GenTreeUnOp* ret) { + assert(!comp->compMethodReturnsMultiRegRetType()); assert(!comp->compDoOldStructRetyping()); assert(ret->OperIs(GT_RETURN)); assert(varTypeIsStruct(ret)); @@ -3050,6 +3121,13 @@ void Lowering::LowerRetStruct(GenTreeUnOp* ret) case GT_CNS_INT: assert(retVal->TypeIs(TYP_INT)); + assert(retVal->AsIntCon()->IconValue() == 0); + if (varTypeUsesFloatReg(nativeReturnType)) + { + retVal->ChangeOperConst(GT_CNS_DBL); + retVal->ChangeType(TYP_FLOAT); + retVal->AsDblCon()->gtDconVal = 0; + } break; case GT_OBJ: @@ -3063,20 +3141,38 @@ void Lowering::LowerRetStruct(GenTreeUnOp* ret) LowerRetStructLclVar(ret); break; +#if defined(FEATURE_SIMD) || defined(FEATURE_HW_INTRINSICS) #ifdef FEATURE_SIMD case GT_SIMD: #endif // FEATURE_SIMD #ifdef FEATURE_HW_INTRINSICS case GT_HWINTRINSIC: #endif // FEATURE_HW_INTRINSICS + { + assert(!retVal->TypeIs(TYP_STRUCT)); + if (varTypeUsesFloatReg(ret) != varTypeUsesFloatReg(retVal)) + { + GenTreeUnOp* bitcast = new (comp, GT_BITCAST) GenTreeOp(GT_BITCAST, ret->TypeGet(), retVal, nullptr); + ret->gtOp1 = bitcast; + BlockRange().InsertBefore(ret, bitcast); + ContainCheckBitCast(bitcast); + } + } + break; +#endif // FEATURE_SIMD || FEATURE_HW_INTRINSICS + case GT_LCL_FLD: { - GenTreeUnOp* bitcast = new (comp, GT_BITCAST) GenTreeOp(GT_BITCAST, ret->TypeGet(), retVal, nullptr); - ret->gtOp1 = bitcast; - BlockRange().InsertBefore(ret, bitcast); - ContainCheckBitCast(bitcast); - break; +#ifdef DEBUG + GenTreeLclFld* lclFld = retVal->AsLclFld(); + unsigned lclNum = lclFld->GetLclNum(); + LclVarDsc* varDsc = comp->lvaGetDesc(lclNum); + assert(varDsc->lvDoNotEnregister); +#endif + retVal->ChangeType(nativeReturnType); } + break; + default: unreached(); } @@ -3086,15 +3182,21 @@ void Lowering::LowerRetStruct(GenTreeUnOp* ret) // LowerRetStructLclVar: Lowers a return node with a struct lclVar as a source. // // Arguments: -// node - The return node to lower. +// node - The return node to lower. +// +// Notes: +// - if LclVar is allocated in memory then read it as return type; +// - if LclVar can be enregistered read it as register type and add a bitcast if necessary; // void Lowering::LowerRetStructLclVar(GenTreeUnOp* ret) { + assert(!comp->compMethodReturnsMultiRegRetType()); assert(!comp->compDoOldStructRetyping()); assert(ret->OperIs(GT_RETURN)); - GenTreeLclVar* lclVar = ret->gtGetOp1()->AsLclVar(); - unsigned lclNum = lclVar->GetLclNum(); - LclVarDsc* varDsc = comp->lvaGetDesc(lclNum); + GenTreeLclVarCommon* lclVar = ret->gtGetOp1()->AsLclVar(); + assert(lclVar->OperIs(GT_LCL_VAR)); + unsigned lclNum = lclVar->GetLclNum(); + LclVarDsc* varDsc = comp->lvaGetDesc(lclNum); #ifdef DEBUG if (comp->gtGetStructHandleIfPresent(lclVar) == NO_CLASS_HANDLE) @@ -3105,10 +3207,9 @@ void Lowering::LowerRetStructLclVar(GenTreeUnOp* ret) #endif if (varDsc->lvPromoted && (comp->lvaGetPromotionType(lclNum) == Compiler::PROMOTION_TYPE_INDEPENDENT)) { - bool canEnregister = false; if (varDsc->lvFieldCnt == 1) { - // We have to replace it with its field. + // We can replace the struct with its only field and keep the field on a register. assert(varDsc->lvRefCnt() == 0); unsigned fieldLclNum = varDsc->lvFieldLclStart; LclVarDsc* fieldDsc = comp->lvaGetDesc(fieldLclNum); @@ -3118,10 +3219,11 @@ void Lowering::LowerRetStructLclVar(GenTreeUnOp* ret) JITDUMP("Replacing an independently promoted local var with its only field for the return %u, %u\n", lclNum, fieldLclNum); lclVar->ChangeType(fieldDsc->lvType); - canEnregister = true; + lclNum = fieldLclNum; + varDsc = comp->lvaGetDesc(lclNum); } } - if (!canEnregister) + else { // TODO-1stClassStructs: We can no longer promote or enregister this struct, // since it is referenced as a whole. @@ -3129,16 +3231,25 @@ void Lowering::LowerRetStructLclVar(GenTreeUnOp* ret) } } - var_types regType = varDsc->GetRegisterType(lclVar); - assert((regType != TYP_STRUCT) && (regType != TYP_UNKNOWN)); - // Note: regType could be a small type, in this case return will generate an extension move. - lclVar->ChangeType(regType); - if (varTypeUsesFloatReg(ret) != varTypeUsesFloatReg(lclVar)) + if (varDsc->lvDoNotEnregister) { - GenTreeUnOp* bitcast = new (comp, GT_BITCAST) GenTreeOp(GT_BITCAST, ret->TypeGet(), lclVar, nullptr); - ret->gtOp1 = bitcast; - BlockRange().InsertBefore(ret, bitcast); - ContainCheckBitCast(bitcast); + lclVar->ChangeOper(GT_LCL_FLD); + lclVar->AsLclFld()->SetLclOffs(0); + lclVar->ChangeType(ret->TypeGet()); + } + else + { + var_types lclVarType = varDsc->GetRegisterType(lclVar); + assert(lclVarType != TYP_UNDEF); + lclVar->ChangeType(lclVarType); + + if (varTypeUsesFloatReg(ret) != varTypeUsesFloatReg(lclVarType)) + { + GenTreeUnOp* bitcast = new (comp, GT_BITCAST) GenTreeOp(GT_BITCAST, ret->TypeGet(), lclVar, nullptr); + ret->gtOp1 = bitcast; + BlockRange().InsertBefore(ret, bitcast); + ContainCheckBitCast(bitcast); + } } } @@ -3148,16 +3259,32 @@ void Lowering::LowerRetStructLclVar(GenTreeUnOp* ret) // Arguments: // call - The call node to lower. // -// Note: it transforms the call's user. +// Notes: +// - this handles only single-register returns; +// - it transforms the call's user for `GT_STOREIND`. // void Lowering::LowerCallStruct(GenTreeCall* call) { + assert(varTypeIsStruct(call)); + if (call->HasMultiRegRetVal()) + { + return; + } + +#ifdef TARGET_ARMARCH + // !compDoOldStructRetyping is not supported on arm yet, + // because of HFA. + assert(comp->compDoOldStructRetyping()); + return; +#else // !TARGET_ARMARCH + assert(!comp->compDoOldStructRetyping()); CORINFO_CLASS_HANDLE retClsHnd = call->gtRetClsHnd; Compiler::structPassingKind howToReturnStruct; var_types returnType = comp->getReturnTypeForStruct(retClsHnd, &howToReturnStruct); assert(!varTypeIsStruct(returnType) && returnType != TYP_UNKNOWN); - call->gtType = genActualType(returnType); // the callee normalizes small return types. + var_types origType = call->TypeGet(); + call->gtType = genActualType(returnType); LIR::Use callUse; if (BlockRange().TryGetUse(call, &callUse)) @@ -3167,35 +3294,108 @@ void Lowering::LowerCallStruct(GenTreeCall* call) { case GT_RETURN: case GT_STORE_LCL_VAR: - // Leave as is, the user will handle it. - break; - case GT_STORE_BLK: case GT_STORE_OBJ: - { - GenTreeBlk* storeBlk = user->AsBlk(); -#ifdef DEBUG - unsigned storeSize = storeBlk->GetLayout()->GetSize(); - assert(storeSize == genTypeSize(returnType)); -#endif // DEBUG - // For `STORE_BLK<2>(dst, call struct<2>)` we will have call retyped as `int`, - // but `STORE` has to use the unwidened type. - user->ChangeType(returnType); - user->SetOper(GT_STOREIND); - } - break; + // Leave as is, the user will handle it. + assert(user->TypeIs(origType)); + break; case GT_STOREIND: - assert(user->TypeIs(TYP_SIMD8, TYP_REF)); - user->ChangeType(returnType); +#ifdef FEATURE_SIMD + if (user->TypeIs(TYP_SIMD8)) + { + user->ChangeType(returnType); + break; + } +#endif // FEATURE_SIMD + // importer has a separate mechanism to retype calls to helpers, + // keep it for now. + assert(user->TypeIs(TYP_REF)); + assert(call->IsHelperCall()); + assert(returnType == user->TypeGet()); break; default: unreached(); } } +#endif // !TARGET_ARMARCH +} + +//---------------------------------------------------------------------------------------------- +// LowerStoreCallStruct: Lowers a store block where source is a struct typed call. +// +// Arguments: +// store - The store node to lower. +// +// Notes: +// - it spills the call's result if it can be retyped as a primitive type. +// +void Lowering::LowerStoreCallStruct(GenTreeBlk* store) +{ + assert(!comp->compDoOldStructRetyping()); + assert(varTypeIsStruct(store)); + assert(store->Data()->IsCall()); + GenTreeCall* call = store->Data()->AsCall(); + + const ClassLayout* layout = store->GetLayout(); + assert(layout->GetSlotCount() == 1); + const var_types regType = layout->GetRegisterType(); + + unsigned storeSize = store->GetLayout()->GetSize(); + if (regType != TYP_UNDEF) + { + store->ChangeType(regType); + store->SetOper(GT_STOREIND); + LowerStoreIndir(store->AsIndir()); + } + else + { +#if defined(WINDOWS_AMD64_ABI) + // All ABI except Windows x64 supports passing 3 byte structs in registers. + // Other 64 bites ABI-s support passing 5, 6, 7 byte structs. + unreached(); +#else // !WINDOWS_AMD64_ABI + if (store->OperIs(GT_STORE_OBJ)) + { + store->SetOper(GT_STORE_BLK); + } + store->gtBlkOpKind = GenTreeObj::BlkOpKindUnroll; + + GenTreeLclVar* spilledCall = SpillStructCallResult(call); + store->SetData(spilledCall); + LowerBlockStore(store); +#endif // WINDOWS_AMD64_ABI + } +} + +#if !defined(WINDOWS_AMD64_ABI) +//---------------------------------------------------------------------------------------------- +// SpillStructCallResult: Spill call result to memory. +// +// Arguments: +// call - call with 3, 5, 6 or 7 return size that has to be spilled to memory. +// +// Return Value: +// load of the spilled variable. +// +GenTreeLclVar* Lowering::SpillStructCallResult(GenTreeCall* call) const +{ + // TODO-1stClassStructs: we can support this in codegen for `GT_STORE_BLK` without new temps. + const unsigned spillNum = comp->lvaGrabTemp(true DEBUGARG("Return value temp for an odd struct return size")); + CORINFO_CLASS_HANDLE retClsHnd = call->gtRetClsHnd; + comp->lvaSetStruct(spillNum, retClsHnd, false); + GenTreeLclFld* spill = new (comp, GT_STORE_LCL_FLD) GenTreeLclFld(GT_STORE_LCL_FLD, call->gtType, spillNum, 0); + spill->gtOp1 = call; + spill->gtFlags |= GTF_VAR_DEF; + + BlockRange().InsertAfter(call, spill); + ContainCheckStoreLoc(spill); + GenTreeLclVar* loadCallResult = comp->gtNewLclvNode(spillNum, TYP_STRUCT)->AsLclVar(); + BlockRange().InsertAfter(spill, loadCallResult); + return loadCallResult; } -#endif // !FEATURE_MULTIREG_RET +#endif // !WINDOWS_AMD64_ABI GenTree* Lowering::LowerDirectCall(GenTreeCall* call) { diff --git a/src/coreclr/src/jit/lower.h b/src/coreclr/src/jit/lower.h index ae19cd29c3c3b..b7efee0f7831c 100644 --- a/src/coreclr/src/jit/lower.h +++ b/src/coreclr/src/jit/lower.h @@ -92,7 +92,7 @@ class Lowering final : public Phase void ContainCheckStoreIndir(GenTreeIndir* indirNode); void ContainCheckMul(GenTreeOp* node); void ContainCheckShiftRotate(GenTreeOp* node); - void ContainCheckStoreLoc(GenTreeLclVarCommon* storeLoc); + void ContainCheckStoreLoc(GenTreeLclVarCommon* storeLoc) const; void ContainCheckCast(GenTreeCast* node); void ContainCheckCompare(GenTreeOp* node); void ContainCheckBinary(GenTreeOp* node); @@ -132,11 +132,14 @@ class Lowering final : public Phase GenTreeCC* LowerNodeCC(GenTree* node, GenCondition condition); void LowerJmpMethod(GenTree* jmp); void LowerRet(GenTreeUnOp* ret); -#if !FEATURE_MULTIREG_RET + void LowerStoreLocCommon(GenTreeLclVarCommon* lclVar); void LowerRetStruct(GenTreeUnOp* ret); void LowerRetStructLclVar(GenTreeUnOp* ret); void LowerCallStruct(GenTreeCall* call); -#endif + void LowerStoreCallStruct(GenTreeBlk* store); +#if !defined(WINDOWS_AMD64_ABI) + GenTreeLclVar* SpillStructCallResult(GenTreeCall* call) const; +#endif // WINDOWS_AMD64_ABI GenTree* LowerDelegateInvoke(GenTreeCall* call); GenTree* LowerIndirectNonvirtCall(GenTreeCall* call); GenTree* LowerDirectCall(GenTreeCall* call); @@ -459,7 +462,7 @@ class Lowering final : public Phase // return true if 'childNode' is an immediate that can be contained // by the 'parentNode' (i.e. folded into an instruction) // for example small enough and non-relocatable - bool IsContainableImmed(GenTree* parentNode, GenTree* childNode); + bool IsContainableImmed(GenTree* parentNode, GenTree* childNode) const; // Return true if 'node' is a containable memory op. bool IsContainableMemoryOp(GenTree* node) @@ -478,7 +481,7 @@ class Lowering final : public Phase bool AreSourcesPossiblyModifiedLocals(GenTree* addr, GenTree* base, GenTree* index); // Makes 'childNode' contained in the 'parentNode' - void MakeSrcContained(GenTree* parentNode, GenTree* childNode); + void MakeSrcContained(GenTree* parentNode, GenTree* childNode) const; // Checks and makes 'childNode' contained in the 'parentNode' bool CheckImmedAndMakeContained(GenTree* parentNode, GenTree* childNode); diff --git a/src/coreclr/src/jit/lowerarmarch.cpp b/src/coreclr/src/jit/lowerarmarch.cpp index 899531b896d21..ae3d03ea125c8 100644 --- a/src/coreclr/src/jit/lowerarmarch.cpp +++ b/src/coreclr/src/jit/lowerarmarch.cpp @@ -52,7 +52,7 @@ bool Lowering::IsCallTargetInRange(void* addr) // TODO-CQ: we can contain a floating point 0.0 constant in a compare instruction // (vcmp on arm, fcmp on arm64). // -bool Lowering::IsContainableImmed(GenTree* parentNode, GenTree* childNode) +bool Lowering::IsContainableImmed(GenTree* parentNode, GenTree* childNode) const { if (!varTypeIsFloating(parentNode->TypeGet())) { @@ -973,7 +973,7 @@ void Lowering::ContainCheckShiftRotate(GenTreeOp* node) // Arguments: // node - pointer to the node // -void Lowering::ContainCheckStoreLoc(GenTreeLclVarCommon* storeLoc) +void Lowering::ContainCheckStoreLoc(GenTreeLclVarCommon* storeLoc) const { assert(storeLoc->OperIsLocalStore()); GenTree* op1 = storeLoc->gtGetOp1(); diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index f2a66d1166f76..4e05fa6a4e6d5 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -2530,7 +2530,7 @@ bool Lowering::IsCallTargetInRange(void* addr) } // return true if the immediate can be folded into an instruction, for example small enough and non-relocatable -bool Lowering::IsContainableImmed(GenTree* parentNode, GenTree* childNode) +bool Lowering::IsContainableImmed(GenTree* parentNode, GenTree* childNode) const { if (!childNode->IsIntCnsFitsInI32()) { @@ -3066,7 +3066,7 @@ void Lowering::ContainCheckShiftRotate(GenTreeOp* node) // Arguments: // node - pointer to the node // -void Lowering::ContainCheckStoreLoc(GenTreeLclVarCommon* storeLoc) +void Lowering::ContainCheckStoreLoc(GenTreeLclVarCommon* storeLoc) const { assert(storeLoc->OperIsLocalStore()); GenTree* op1 = storeLoc->gtGetOp1(); diff --git a/src/coreclr/tests/src/JIT/Directed/StructABI/structreturn.cs b/src/coreclr/tests/src/JIT/Directed/StructABI/structreturn.cs index e63b9b27f843f..226818941c806 100644 --- a/src/coreclr/tests/src/JIT/Directed/StructABI/structreturn.cs +++ b/src/coreclr/tests/src/JIT/Directed/StructABI/structreturn.cs @@ -927,6 +927,406 @@ public static void Test() } #endregion +class TestHFA +{ + [MethodImpl(MethodImplOptions.NoInlining)] + static float ReturnFloat() + { + return 1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static double ReturnDouble() + { + return 1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Vector2 ReturnVector2() + { + return new Vector2(1); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Vector3 ReturnVector3() + { + return new Vector3(1); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Vector4 ReturnVector4() + { + return new Vector4(1); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Vector4 ReturnVector4UsingCall() + { + return ReturnVector4(); + } + + struct FloatWrapper + { + public float f; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static FloatWrapper ReturnFloatWrapper() + { + return new FloatWrapper(); + } + + struct DoubleWrapper + { + public double f; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static DoubleWrapper ReturnDoubleWrapper() + { + return new DoubleWrapper(); + } + + struct Floats2Wrapper + { + public float f1; + public float f2; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Floats2Wrapper ReturnFloats2Wrapper() + { + return new Floats2Wrapper(); + } + + struct Doubles2Wrapper + { + public double f1; + public double f2; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Doubles2Wrapper ReturnDoubles2Wrapper() + { + return new Doubles2Wrapper(); + } + struct Floats3Wrapper + { + public float f1; + public float f2; + public float f3; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Floats3Wrapper ReturnFloats3Wrapper() + { + return new Floats3Wrapper(); + } + + struct Doubles3Wrapper + { + public double f1; + public double f2; + public double f3; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Doubles3Wrapper ReturnDoubles3Wrapper() + { + return new Doubles3Wrapper(); + } + + struct Floats4Wrapper + { + public float f1; + public float f2; + public float f3; + public float f4; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Floats4Wrapper ReturnFloats4Wrapper() + { + return new Floats4Wrapper(); + } + + struct Doubles4Wrapper + { + public double f1; + public double f2; + public double f3; + public double f4; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Doubles4Wrapper ReturnDoubles4Wrapper() + { + return new Doubles4Wrapper(); + } + + struct Vector2Wrapper + { + Vector2 f1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Vector2Wrapper ReturnVector2Wrapper() + { + return new Vector2Wrapper(); + } + + struct Vector3Wrapper + { + Vector3 f1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Vector3Wrapper ReturnVector3Wrapper() + { + return new Vector3Wrapper(); + } + + struct Vector4Wrapper + { + Vector4 f1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Vector4Wrapper ReturnVector4Wrapper() + { + return new Vector4Wrapper(); + } + + struct Vector2x2Wrapper + { + Vector2 f1; + Vector2 f2; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Vector2x2Wrapper ReturnVector2x2Wrapper() + { + return new Vector2x2Wrapper(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void Test() + { + ReturnFloat(); + ReturnDouble(); + ReturnVector2(); + ReturnVector3(); + ReturnVector4(); + ReturnVector4UsingCall(); + ReturnFloatWrapper(); + ReturnDoubleWrapper(); + ReturnFloats2Wrapper(); + ReturnDoubles2Wrapper(); + ReturnFloats3Wrapper(); + ReturnDoubles3Wrapper(); + ReturnFloats4Wrapper(); + ReturnDoubles4Wrapper(); + ReturnVector2Wrapper(); + ReturnVector3Wrapper(); + ReturnVector4Wrapper(); + ReturnVector2x2Wrapper(); + } +} + +class TestNon2PowerStructs +{ + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct Byte3Struct + { + public byte f1; + public byte f2; + public byte f3; + + [MethodImpl(MethodImplOptions.NoInlining)] + public Byte3Struct(int v) + { + f1 = 1; + f2 = 2; + f3 = 3; + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct Byte5Struct + { + public byte f1; + public byte f2; + public byte f3; + public byte f4; + public byte f5; + + [MethodImpl(MethodImplOptions.NoInlining)] + public Byte5Struct(int v) + { + f1 = 4; + f2 = 5; + f3 = 6; + f4 = 7; + f5 = 8; + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct Byte6Struct + { + public byte f1; + public byte f2; + public byte f3; + public byte f4; + public byte f5; + public byte f6; + + [MethodImpl(MethodImplOptions.NoInlining)] + public Byte6Struct(int v) + { + f1 = 9; + f2 = 10; + f3 = 11; + f4 = 12; + f5 = 13; + f6 = 14; + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct Byte7Struct + { + public byte f1; + public byte f2; + public byte f3; + public byte f4; + public byte f5; + public byte f6; + public byte f7; + + [MethodImpl(MethodImplOptions.NoInlining)] + public Byte7Struct(int v) + { + f1 = 15; + f2 = 16; + f3 = 17; + f4 = 18; + f5 = 19; + f6 = 20; + f7 = 21; + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct CompositeOfOddStructs + { + public Byte3Struct a; + public Byte5Struct b; + public Byte6Struct c; + public Byte7Struct d; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Byte3Struct Return3() + { + return new Byte3Struct(0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Byte5Struct Return5() + { + return new Byte5Struct(0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Byte6Struct Return6() + { + return new Byte6Struct(0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Byte7Struct Return7() + { + return new Byte7Struct(0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static CompositeOfOddStructs CreateComposite() + { + CompositeOfOddStructs c = new CompositeOfOddStructs(); + c.a = Return3(); + c.b = Return5(); + c.c = Return6(); + c.d = Return7(); + return c; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TestComposite() + { + var c = CreateComposite(); + Debug.Assert(c.a.f1 == 1); + Debug.Assert(c.a.f2 == 2); + Debug.Assert(c.a.f3 == 3); + Debug.Assert(c.b.f1 == 4); + Debug.Assert(c.b.f2 == 5); + Debug.Assert(c.b.f3 == 6); + Debug.Assert(c.b.f4 == 7); + Debug.Assert(c.b.f5 == 8); + Debug.Assert(c.c.f1 == 9); + Debug.Assert(c.c.f2 == 10); + Debug.Assert(c.c.f3 == 11); + Debug.Assert(c.c.f4 == 12); + Debug.Assert(c.c.f5 == 13); + Debug.Assert(c.c.f6 == 14); + Debug.Assert(c.d.f1 == 15); + Debug.Assert(c.d.f2 == 16); + Debug.Assert(c.d.f3 == 17); + Debug.Assert(c.d.f4 == 18); + Debug.Assert(c.d.f5 == 19); + Debug.Assert(c.d.f6 == 20); + Debug.Assert(c.d.f7 == 21); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static byte TestLocals(int v) + { + var a = Return3(); + var a1 = a; + a1.f1 = 0; + var b = Return5(); + var c = Return6(); + var d = Return7(); + if (v == 0) + { + return a.f1; + } + else if (v == 1) + { + return b.f1; + } + else if (v == 3) + { + return c.f1; + } + else if (v == 4) + { + return d.f1; + } + else + { + return a1.f1; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void Test() + { + TestComposite(); + TestLocals(0); + } +} + class TestStructs { public static int Main() @@ -934,6 +1334,8 @@ public static int Main() TestStructReturns.Test(); TestUnsafeCasts.Test(); TestMergeReturnBlocks.Test(); + TestHFA.Test(); + TestNon2PowerStructs.Test(); return 100; } } From e3c8c47c1555a05a0f12177ed95758a03375c644 Mon Sep 17 00:00:00 2001 From: Alexis Christoforides Date: Wed, 20 May 2020 18:59:29 -0400 Subject: [PATCH 305/420] [mono] Implement AsAny marshalling for simple arrays (#35686) * [mono] Implement AsAny marshalling for simple arrays Simple here means of rank 1, and with a blittable value type as element type. * Also implement char arrays * Do not allow in-params to be marshalled this way, as the callee would have write-ability that is not allowed by in-params --- src/mono/mono/metadata/marshal.c | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index e7264dfa888e5..6223aca76475e 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -6268,6 +6268,36 @@ mono_marshal_asany_impl (MonoObjectHandle o, MonoMarshalNative string_encoding, return res; } + case MONO_TYPE_SZARRAY: { + //TODO: Implement structs and in-params for all value types + MonoClass *klass = t->data.klass; + MonoClass *eklass = m_class_get_element_class (klass); + MonoArray *arr = (MonoArray *) MONO_HANDLE_RAW (o); + + // we only support char[] for in-params; we return a pointer to the managed heap here, and that's not 'in'-safe + if ((param_attrs & PARAM_ATTRIBUTE_IN) && eklass != mono_get_char_class ()) + break; + + if (m_class_get_rank (klass) > 1) + break; + + if (arr->bounds) + if (arr->bounds->lower_bound != 0) + break; + + if (mono_class_is_auto_layout (eklass)) + break; + + if (m_class_is_valuetype (eklass) && (mono_class_is_explicit_layout (eklass) || m_class_is_blittable (eklass) || m_class_is_enumtype (eklass))) + return arr->vector; + + if (eklass == mono_get_char_class ()) { + char *res = mono_utf16_to_utf8 ((mono_unichar2 *) arr->vector, arr->max_length, error); + return_val_if_nok (error, NULL); + return res; + } + break; + } default: break; } @@ -6328,6 +6358,20 @@ mono_marshal_free_asany_impl (MonoObjectHandle o, gpointer ptr, MonoMarshalNativ mono_marshal_free (ptr); break; } + case MONO_TYPE_SZARRAY: { + MonoClass *klass = t->data.klass; + MonoClass *eklass = m_class_get_element_class (klass); + MonoArray *arr = (MonoArray *) MONO_HANDLE_RAW (o); + + if (eklass != mono_get_char_class ()) + break; + + mono_unichar2 *utf16_array = g_utf8_to_utf16 ((const char *)ptr, arr->max_length, NULL, NULL, NULL); + g_free (ptr); + memcpy (arr->vector, utf16_array, arr->max_length * sizeof (mono_unichar2)); + g_free (utf16_array); + break; + } default: break; } From 9ceeb18f20c07aca607e67bec5217e83c4176219 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Wed, 20 May 2020 16:00:51 -0700 Subject: [PATCH 306/420] JIT: widen type of constant or special static fields (#36769) Since we're pushing the value of these fields we need to widen the value to a stack type. Addresses issues seen in #36592. --- src/coreclr/src/jit/importer.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 9a6f1afef4879..06522b7193006 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -14410,6 +14410,12 @@ void Compiler::impImportBlockCode(BasicBlock* block) assert(pFldAddr == nullptr); op1 = impImportStaticReadOnlyField(fldAddr, lclTyp); + + // Widen small types since we're propagating the value + // instead of producing an indir. + // + op1->gtType = genActualType(lclTyp); + goto FIELD_DONE; } } @@ -14427,7 +14433,9 @@ void Compiler::impImportBlockCode(BasicBlock* block) case CORINFO_FIELD_INTRINSIC_ZERO: { assert(aflags & CORINFO_ACCESS_GET); - op1 = gtNewIconNode(0, lclTyp); + // Widen to stack type + lclTyp = genActualType(lclTyp); + op1 = gtNewIconNode(0, lclTyp); goto FIELD_DONE; } break; @@ -14446,6 +14454,8 @@ void Compiler::impImportBlockCode(BasicBlock* block) case CORINFO_FIELD_INTRINSIC_ISLITTLEENDIAN: { assert(aflags & CORINFO_ACCESS_GET); + // Widen to stack type + lclTyp = genActualType(lclTyp); #if BIGENDIAN op1 = gtNewIconNode(0, lclTyp); #else From 34fd21edebf010cfc9a9d685e4ad22d06f916fc1 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 20 May 2020 16:32:50 -0700 Subject: [PATCH 307/420] Optimize ToVector128, ToVector128Unsafe and Vector128.GetLower() (#36732) * Optimize ToVector128 , ToVector128Unsafe and Vector128.GetLower() --- src/coreclr/src/jit/hwintrinsic.cpp | 2 +- src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp | 12 ++++++++++++ src/coreclr/src/jit/hwintrinsiclistarm64.h | 3 +++ .../src/System/Runtime/Intrinsics/Vector128.cs | 1 + .../src/System/Runtime/Intrinsics/Vector64.cs | 2 ++ 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/jit/hwintrinsic.cpp b/src/coreclr/src/jit/hwintrinsic.cpp index d0b2c1b53f338..15c623ceca151 100644 --- a/src/coreclr/src/jit/hwintrinsic.cpp +++ b/src/coreclr/src/jit/hwintrinsic.cpp @@ -610,7 +610,7 @@ static bool isSupportedBaseType(NamedIntrinsic intrinsic, var_types baseType) (intrinsic >= NI_Vector256_get_AllBitsSet && intrinsic <= NI_Vector256_ToScalar)); #else assert((intrinsic >= NI_Vector64_AsByte && intrinsic <= NI_Vector64_AsUInt32) || - (intrinsic >= NI_Vector64_get_AllBitsSet && intrinsic <= NI_Vector64_ToScalar) || + (intrinsic >= NI_Vector64_get_AllBitsSet && intrinsic <= NI_Vector64_ToVector128Unsafe) || (intrinsic >= NI_Vector128_As && intrinsic <= NI_Vector128_AsUInt64) || (intrinsic >= NI_Vector128_get_AllBitsSet && intrinsic <= NI_Vector128_ToScalar)); #endif diff --git a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp index e2093a5b5f951..7b16a566410b0 100644 --- a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp @@ -617,6 +617,18 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) } break; + case NI_Vector64_ToVector128: + GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg); + break; + + case NI_Vector64_ToVector128Unsafe: + case NI_Vector128_GetLower: + if (op1Reg != targetReg) + { + GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg); + } + break; + case NI_Vector64_GetElement: case NI_Vector128_GetElement: case NI_Vector64_ToScalar: diff --git a/src/coreclr/src/jit/hwintrinsiclistarm64.h b/src/coreclr/src/jit/hwintrinsiclistarm64.h index 80a5f487e2ff4..5407ba7670ef9 100644 --- a/src/coreclr/src/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/src/jit/hwintrinsiclistarm64.h @@ -30,6 +30,8 @@ HARDWARE_INTRINSIC(Vector64, get_Count, HARDWARE_INTRINSIC(Vector64, get_Zero, 8, 0, {INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector64, GetElement, 8, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_NoJmpTableIMM|HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector64, ToScalar, 8, 1, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, ToVector128, 8, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector64, ToVector128Unsafe, 8, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags @@ -53,6 +55,7 @@ HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, 1 HARDWARE_INTRINSIC(Vector128, get_Count, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, get_Zero, 16, 0, {INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector128, GetElement, 16, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_NoJmpTableIMM|HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector128, GetLower, 16, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector128, ToScalar, 16, 1, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs index 5caec4828975a..f2b4fe0ae6d9d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs @@ -1554,6 +1554,7 @@ public static Vector128 WithElement(this Vector128 vector, int index, T /// The vector to get the lower 64-bits from. /// The value of the lower 64-bits as a new . /// The type of () is not supported. + [Intrinsic] public static Vector64 GetLower(this Vector128 vector) where T : struct { 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 873056c31dca9..d370a622ae001 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 @@ -942,6 +942,7 @@ public static T ToScalar(this Vector64 vector) /// The vector to extend. /// A new with the lower 64-bits set to the value of and the upper 64-bits initialized to zero. /// The type of () is not supported. + [Intrinsic] public static Vector128 ToVector128(this Vector64 vector) where T : struct { @@ -957,6 +958,7 @@ public static Vector128 ToVector128(this Vector64 vector) /// The vector to extend. /// A new with the lower 64-bits set to the value of and the upper 64-bits left uninitialized. /// The type of () is not supported. + [Intrinsic] public static unsafe Vector128 ToVector128Unsafe(this Vector64 vector) where T : struct { From d1bdc1372897a775da53b7016534bf0a962314dd Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Wed, 20 May 2020 17:17:52 -0700 Subject: [PATCH 308/420] Fix evaluate paths bug when multiple include paths are specified (#36780) --- eng/pipelines/evaluate-changed-paths.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/evaluate-changed-paths.sh b/eng/pipelines/evaluate-changed-paths.sh index 0df618957245b..bfc5c857b64fe 100755 --- a/eng/pipelines/evaluate-changed-paths.sh +++ b/eng/pipelines/evaluate-changed-paths.sh @@ -162,7 +162,7 @@ probePaths() { if [[ "$include_path_string" == "" ]]; then include_path_string=":$_path" else - include_path_string="$exclude_path_string :$_path" + include_path_string="$include_path_string :$_path" fi done From 5b7d6319ec8ff44c7eda6f8358e29cfdd53d81b5 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Wed, 20 May 2020 17:52:07 -0700 Subject: [PATCH 309/420] Fix signing due to subset projects rename (#36791) --- eng/SubsetValidation.targets | 2 +- src/installer/signing/SignBinaries.proj | 2 +- src/installer/signing/SignBurnBundleFiles.proj | 2 +- src/installer/signing/SignBurnEngineFiles.proj | 2 +- src/installer/signing/SignMsiFiles.proj | 2 +- src/installer/signing/SignR2RBinaries.proj | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/SubsetValidation.targets b/eng/SubsetValidation.targets index 53ea39ccd4959..3b0acd5c5e156 100644 --- a/eng/SubsetValidation.targets +++ b/eng/SubsetValidation.targets @@ -6,7 +6,7 @@ on a whole subset, and the dependency on the subset is disregarded automatically when Subset doesn't contain it. - %(InstallerProject.SignPhase): Indicates this project must be built before a certain signing + %(ProjectToBuild.SignPhase): Indicates this project must be built before a certain signing phase. Projects can depend on 'signing/stages/Sign.proj' to wait until all projects that are part of a stage are complete. This allows the build to perform complex container signing that isn't (can't be?) supported by Arcade's single pass, such as MSIs and bundles: diff --git a/src/installer/signing/SignBinaries.proj b/src/installer/signing/SignBinaries.proj index d1f8fb542904e..8b1f6811f442f 100644 --- a/src/installer/signing/SignBinaries.proj +++ b/src/installer/signing/SignBinaries.proj @@ -1,7 +1,7 @@ - + diff --git a/src/installer/signing/SignBurnBundleFiles.proj b/src/installer/signing/SignBurnBundleFiles.proj index 52cac286090a1..55c7a8c5810de 100644 --- a/src/installer/signing/SignBurnBundleFiles.proj +++ b/src/installer/signing/SignBurnBundleFiles.proj @@ -4,7 +4,7 @@ diff --git a/src/installer/signing/SignBurnEngineFiles.proj b/src/installer/signing/SignBurnEngineFiles.proj index dc610b685cfb3..382eb202318fb 100644 --- a/src/installer/signing/SignBurnEngineFiles.proj +++ b/src/installer/signing/SignBurnEngineFiles.proj @@ -1,7 +1,7 @@ - + diff --git a/src/installer/signing/SignMsiFiles.proj b/src/installer/signing/SignMsiFiles.proj index 55804e6c46c4e..55dd18dca6732 100644 --- a/src/installer/signing/SignMsiFiles.proj +++ b/src/installer/signing/SignMsiFiles.proj @@ -1,7 +1,7 @@ - + - PdbOnly - true - - - - - diff --git a/src/coreclr/tests/src/GC/API/GC/RemoveMemoryPressureTest.cs b/src/coreclr/tests/src/GC/API/GC/RemoveMemoryPressureTest.cs deleted file mode 100644 index e288efb6f8c07..0000000000000 --- a/src/coreclr/tests/src/GC/API/GC/RemoveMemoryPressureTest.cs +++ /dev/null @@ -1,132 +0,0 @@ -// 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. - -/* RemoveMemoryPressureTest - * - * Tests GC.RemoveMemoryPressure by passing it values that are too small (<=0) and - * values that are too large (>Int32.MaxValue on 32-bit). - */ - - -using System; -using System.Diagnostics; -using System.Security; -using System.Runtime.InteropServices; - -public class RemoveMemoryPressureTest -{ - public int TestCount = 0; - - private long[] _negValues = { 0, -1, Int32.MinValue - (long)1, Int64.MinValue / (long)2, Int64.MinValue }; - private long[] _largeValues = { Int32.MaxValue + (long)1, Int64.MaxValue }; - - - private RemoveMemoryPressureTest() - { - } - - - public bool TooSmallTest() - { - TestCount++; - bool retVal = true; - - foreach (long i in _negValues) - { - try - { - GC.RemoveMemoryPressure(i); - Console.WriteLine("Failure at TooSmallTest: {0}", i); - retVal = false; - break; - } - catch (ArgumentOutOfRangeException) - { - } - catch (Exception e) - { - Console.WriteLine(e.Message); - Console.WriteLine("Failure at TooSmallTest: {0}", i); - retVal = false; - break; - } - } - - if (retVal) - Console.WriteLine("TooSmallTest Passed"); - return retVal; - } - - - public bool TooLargeTest() - { - TestCount++; - - bool retVal = true; - - foreach (long i in _largeValues) - { - try - { - GC.RemoveMemoryPressure(i); - // this should throw exception on 32-bit - if (IntPtr.Size == Marshal.SizeOf(new Int32())) - { - Console.WriteLine("Failure at LargeValueTest: {0}", i); - retVal = false; - break; - } - } - catch (ArgumentOutOfRangeException) - { - // this should not throw exception on 64-bit - if (IntPtr.Size == Marshal.SizeOf(new Int64())) - { - Console.WriteLine("Failure at LargeValueTest: {0}", i); - retVal = false; - break; - } - } - catch (Exception e) - { - Console.WriteLine(e.Message); - retVal = false; - break; - } - } - - if (retVal) - Console.WriteLine("TooLargeTest Passed"); - return retVal; - } - - - public bool RunTest() - { - int passCount = 0; - - if (TooSmallTest()) - passCount++; - - if (TooLargeTest()) - passCount++; - - return (passCount == TestCount); - } - - - public static int Main() - { - RemoveMemoryPressureTest test = new RemoveMemoryPressureTest(); - - if (test.RunTest()) - { - Console.WriteLine("Test Passed"); - return 100; - } - - Console.WriteLine("Test Failed"); - return 1; - } -} diff --git a/src/coreclr/tests/src/GC/API/GC/RemoveMemoryPressureTest.csproj b/src/coreclr/tests/src/GC/API/GC/RemoveMemoryPressureTest.csproj deleted file mode 100644 index bb01dcdf950c7..0000000000000 --- a/src/coreclr/tests/src/GC/API/GC/RemoveMemoryPressureTest.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - Exe - - - - PdbOnly - - - - - From 733003c51c5f682f108b367802ec262292601516 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid Date: Thu, 21 May 2020 07:10:26 +0300 Subject: [PATCH 313/420] Fix two issues with hosting on SunOS (#36527) Fix two issues with hosting on SunOS: * Compile corehost without use-cxa-atexit with gcc * Disable RapidJson's 48-bit optimization on SunOS * Compile without [`use-cxa-atexit`](https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html) in case of gcc * libc tries to invoke `pthread_cond_destroy()` in `dlclose()`ed fxr library in the consumer code. PR disables this feature. * Backtrace available at http://sprunge.us/bx4dlk. This happens _after_ the main() exits. * Disable RapidJson's 48-bit pointer optimization on SunOS. * This optimization relies on zeros in higher 16-bits, whereas SunOS has 1s. More details at https://github.com/Tencent/rapidjson/issues/1596. * The impact here was that `runtimeOptions` key available in `hwapp.runtimeconfig.json` was not located by RapidJson's `FindMember()` API and we were getting `false` from: https://github.com/dotnet/runtime/blob/78b303df8fbb242985d049a277d0d199cafd51b5/src/installer/corehost/cli/runtime_config.cpp#L416-L422 Contributes to: #34944. --- src/installer/corehost/CMakeLists.txt | 4 ++++ src/installer/corehost/cli/json_parser.h | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/installer/corehost/CMakeLists.txt b/src/installer/corehost/CMakeLists.txt index 43a59a1a6955d..4fa7f45b42ab0 100644 --- a/src/installer/corehost/CMakeLists.txt +++ b/src/installer/corehost/CMakeLists.txt @@ -9,6 +9,10 @@ if(MSVC) # Host components don't try to handle asynchronous exceptions add_compile_options(/EHsc) +elseif (CMAKE_CXX_COMPILER_ID MATCHES GNU) + # Prevents libc from calling pthread_cond_destroy on static objects in + # dlopen()'ed library which we dlclose() in pal::unload_library. + add_compile_options(-fno-use-cxa-atexit) endif() add_subdirectory(cli) diff --git a/src/installer/corehost/cli/json_parser.h b/src/installer/corehost/cli/json_parser.h index 16ed21bd03307..344d03647774f 100644 --- a/src/installer/corehost/cli/json_parser.h +++ b/src/installer/corehost/cli/json_parser.h @@ -5,6 +5,14 @@ #ifndef __JSON_PARSER_H__ #define __JSON_PARSER_H__ +#ifdef __sun +// This optimization relies on zeros in higher 16-bits, whereas SunOS has 1s. More details at +// https://github.com/Tencent/rapidjson/issues/1596. +// The impact here was that runtimeOptions key available in hwapp.runtimeconfig.json was not +// located by RapidJson's FindMember() API from runtime_config_t::ensure_parsed(). +#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0 +#endif + #include "pal.h" #include "rapidjson/document.h" #include "rapidjson/fwd.h" From 02db9d254d05dd0253408d088fa18d0dc1d464a9 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Wed, 20 May 2020 21:34:49 -0700 Subject: [PATCH 314/420] Add R2R testing on Windows arm/arm64 (#36793) --- eng/pipelines/coreclr/r2r.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/eng/pipelines/coreclr/r2r.yml b/eng/pipelines/coreclr/r2r.yml index 04ef6d73c06bf..781e934c6d6e3 100644 --- a/eng/pipelines/coreclr/r2r.yml +++ b/eng/pipelines/coreclr/r2r.yml @@ -24,6 +24,8 @@ jobs: - Linux_arm - Linux_arm64 - Linux_x64 + - Windows_NT_arm + - Windows_NT_arm64 - Windows_NT_x64 - Windows_NT_x86 jobParameters: @@ -37,6 +39,8 @@ jobs: - Linux_arm - Linux_arm64 - Linux_x64 + - Windows_NT_arm + - Windows_NT_arm64 - Windows_NT_x64 - Windows_NT_x86 helixQueueGroup: ci From 00c0328e078351f9514a0958e23361983543e3e2 Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Wed, 20 May 2020 23:42:00 -0700 Subject: [PATCH 315/420] Add JIT EventCounters (#36489) * Add JIT counters * Some renames * fix build * change return type of GetMethodsJittedCount to int * remove ifdef * Fix * CR feedback * More CR feedback * More CR Feedback * more code review feedback * Fix build error and add displayunit to IL bytes jitted counter --- .../RuntimeHelpers.CoreCLR.cs | 6 ++++ src/coreclr/src/vm/ecalllist.h | 2 ++ src/coreclr/src/vm/jitinterface.cpp | 29 +++++++++++++++---- src/coreclr/src/vm/jitinterface.h | 3 ++ .../Diagnostics/Tracing/RuntimeEventSource.cs | 5 +++- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index 49e8a4e08c8c0..55d7ee78afc3a 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -288,6 +288,12 @@ public static IntPtr AllocateTypeAssociatedMemory(Type type, int size) [MethodImpl(MethodImplOptions.InternalCall)] private static unsafe extern TailCallTls* GetTailCallInfo(IntPtr retAddrSlot, IntPtr* retAddr); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern long GetILBytesJitted(); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern int GetMethodsJittedCount(); } // Helper class to assist with unsafe pinning of arbitrary objects. // It's used by VM code. diff --git a/src/coreclr/src/vm/ecalllist.h b/src/coreclr/src/vm/ecalllist.h index 155ae2c516e7c..243a735c2b2e4 100644 --- a/src/coreclr/src/vm/ecalllist.h +++ b/src/coreclr/src/vm/ecalllist.h @@ -909,6 +909,8 @@ FCFuncStart(gRuntimeHelpers) FCFuncElement("AllocTailCallArgBuffer", TailCallHelp::AllocTailCallArgBuffer) FCFuncElement("FreeTailCallArgBuffer", TailCallHelp::FreeTailCallArgBuffer) FCFuncElement("GetTailCallInfo", TailCallHelp::GetTailCallInfo) + FCFuncElement("GetILBytesJitted", GetJittedBytes) + FCFuncElement("GetMethodsJittedCount", GetJittedMethodsCount) FCFuncEnd() FCFuncStart(gContextSynchronizationFuncs) diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index 312afabe00e6b..98150ad8e2c47 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -99,6 +99,27 @@ GARY_IMPL(VMHELPDEF, hlpDynamicFuncTable, DYNAMIC_CORINFO_HELP_COUNT); #else // DACCESS_COMPILE +uint64_t g_cbILJitted = 0; +uint32_t g_cMethodsJitted = 0; + +#ifndef CROSSGEN_COMPILE +FCIMPL0(INT64, GetJittedBytes) +{ + FCALL_CONTRACT; + + return g_cbILJitted; +} +FCIMPLEND + +FCIMPL0(INT32, GetJittedMethodsCount) +{ + FCALL_CONTRACT; + + return g_cMethodsJitted; +} +FCIMPLEND +#endif + /*********************************************************************/ inline CORINFO_MODULE_HANDLE GetScopeHandle(MethodDesc* method) @@ -12585,10 +12606,6 @@ void ThrowExceptionForJit(HRESULT res) } // ******************************************************************** -#ifdef _DEBUG -LONG g_JitCount = 0; -#endif - //#define PERF_TRACK_METHOD_JITTIMES #ifdef TARGET_AMD64 BOOL g_fAllowRel32 = TRUE; @@ -12965,7 +12982,6 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config, } #ifdef _DEBUG - FastInterlockIncrement(&g_JitCount); static BOOL fHeartbeat = -1; if (fHeartbeat == -1) @@ -12975,6 +12991,9 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config, printf("."); #endif // _DEBUG + FastInterlockExchangeAddLong((LONG64*)&g_cbILJitted, methodInfo.ILCodeSize); + FastInterlockIncrement((LONG*)&g_cMethodsJitted); + COOPERATIVE_TRANSITION_END(); return ret; } diff --git a/src/coreclr/src/vm/jitinterface.h b/src/coreclr/src/vm/jitinterface.h index faf4300a5c66c..0e52a1eccc572 100644 --- a/src/coreclr/src/vm/jitinterface.h +++ b/src/coreclr/src/vm/jitinterface.h @@ -1684,5 +1684,8 @@ CORJIT_FLAGS GetDebuggerCompileFlags(Module* pModule, CORJIT_FLAGS flags); bool __stdcall TrackAllocationsEnabled(); +FCDECL0(INT64, GetJittedBytes); +FCDECL0(INT32, GetJittedMethodsCount); + #endif // JITINTERFACE_H diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs index 4086fa0491ccd..663074856b21b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs @@ -37,6 +37,8 @@ internal sealed class RuntimeEventSource : EventSource private PollingCounter? _lohSizeCounter; private PollingCounter? _pohSizeCounter; private PollingCounter? _assemblyCounter; + private PollingCounter? _ilBytesJittedCounter; + private PollingCounter? _methodsJittedCounter; #endif public static void Initialize() @@ -69,7 +71,6 @@ protected override void OnEventCommand(EventCommandEventArgs command) _completedItemsCounter ??= new IncrementingPollingCounter("threadpool-completed-items-count", this, () => ThreadPool.CompletedWorkItemCount) { DisplayName = "ThreadPool Completed Work Item Count", DisplayRateTimeScale = new TimeSpan(0, 0, 1) }; _allocRateCounter ??= new IncrementingPollingCounter("alloc-rate", this, () => GC.GetTotalAllocatedBytes()) { DisplayName = "Allocation Rate", DisplayUnits = "B", DisplayRateTimeScale = new TimeSpan(0, 0, 1) }; _timerCounter ??= new PollingCounter("active-timer-count", this, () => Timer.ActiveCount) { DisplayName = "Number of Active Timers" }; - #if !MONO _exceptionCounter ??= new IncrementingPollingCounter("exception-count", this, () => Exception.GetExceptionCount()) { DisplayName = "Exception Count", DisplayRateTimeScale = new TimeSpan(0, 0, 1) }; _gcTimeCounter ??= new PollingCounter("time-in-gc", this, () => GC.GetLastGCPercentTimeInGC()) { DisplayName = "% Time in GC since last GC", DisplayUnits = "%" }; @@ -79,6 +80,8 @@ protected override void OnEventCommand(EventCommandEventArgs command) _lohSizeCounter ??= new PollingCounter("loh-size", this, () => GC.GetGenerationSize(3)) { DisplayName = "LOH Size", DisplayUnits = "B" }; _pohSizeCounter ??= new PollingCounter("poh-size", this, () => GC.GetGenerationSize(4)) { DisplayName = "POH (Pinned Object Heap) Size", DisplayUnits = "B" }; _assemblyCounter ??= new PollingCounter("assembly-count", this, () => System.Reflection.Assembly.GetAssemblyCount()) { DisplayName = "Number of Assemblies Loaded" }; + _ilBytesJittedCounter ??= new PollingCounter("il-bytes-jitted", this, () => System.Runtime.CompilerServices.RuntimeHelpers.GetILBytesJitted()) { DisplayName = "IL Bytes Jitted", DisplayUnits = "B" }; + _methodsJittedCounter ??= new PollingCounter("methods-jitted-count", this, () => System.Runtime.CompilerServices.RuntimeHelpers.GetMethodsJittedCount()) { DisplayName = "Number of Methods Jitted" }; #endif } From c1052b40b9d94e49d5221f57b65a2feed6a64f71 Mon Sep 17 00:00:00 2001 From: Adeel Mujahid Date: Thu, 21 May 2020 11:41:31 +0300 Subject: [PATCH 316/420] Fix missing symbol issues in SunOS build (#36455) * Fix missing symbol issues in SunOS build * Fix SIGSEGV due to invalid free() --- src/coreclr/src/dlls/dbgshim/CMakeLists.txt | 15 +++++++-------- src/coreclr/src/dlls/mscordac/CMakeLists.txt | 15 +++++++-------- src/coreclr/src/dlls/mscordbi/CMakeLists.txt | 15 +++++++-------- .../src/dlls/mscoree/coreclr/CMakeLists.txt | 19 +++++++++++-------- .../hosts/unixcoreruncommon/coreruncommon.cpp | 19 +++++-------------- src/coreclr/src/jit/CMakeLists.txt | 11 ++++++----- src/installer/corehost/cli/common.cmake | 2 +- .../CMakeLists.txt | 2 ++ .../Native/Unix/System.Native/CMakeLists.txt | 6 +++--- 9 files changed, 49 insertions(+), 55 deletions(-) diff --git a/src/coreclr/src/dlls/dbgshim/CMakeLists.txt b/src/coreclr/src/dlls/dbgshim/CMakeLists.txt index 8f3ef4a3330c1..ef2d0e360782b 100644 --- a/src/coreclr/src/dlls/dbgshim/CMakeLists.txt +++ b/src/coreclr/src/dlls/dbgshim/CMakeLists.txt @@ -26,25 +26,24 @@ else(CLR_CMAKE_TARGET_WIN32) generate_exports_file(${DEF_SOURCES} ${EXPORTS_FILE}) endif(CLR_CMAKE_TARGET_WIN32) -if(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) +if(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD OR CLR_CMAKE_HOST_SUNOS) # This option is necessary to ensure that the overloaded delete operator defined inside # of the utilcode will be used instead of the standard library delete operator. set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Xlinker -Bsymbolic") # Add linker exports file option - set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE}) -endif(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) + if(CLR_CMAKE_HOST_SUNOS) + set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) + else(CLR_CMAKE_HOST_SUNOS) + set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE}) + endif(CLR_CMAKE_HOST_SUNOS) +endif(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD OR CLR_CMAKE_HOST_SUNOS) if(CLR_CMAKE_HOST_OSX) # Add linker exports file option set(EXPORTS_LINKER_OPTION -Wl,-exported_symbols_list,${EXPORTS_FILE}) endif(CLR_CMAKE_HOST_OSX) -if(CLR_CMAKE_HOST_SUNOS) - # Add linker exports file option - set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) -endif(CLR_CMAKE_HOST_SUNOS) - add_library_clr(dbgshim SHARED ${DBGSHIM_SOURCES}) if(CLR_CMAKE_HOST_UNIX) diff --git a/src/coreclr/src/dlls/mscordac/CMakeLists.txt b/src/coreclr/src/dlls/mscordac/CMakeLists.txt index d005acc8c5a74..ddf66b4a0d45b 100644 --- a/src/coreclr/src/dlls/mscordac/CMakeLists.txt +++ b/src/coreclr/src/dlls/mscordac/CMakeLists.txt @@ -73,7 +73,7 @@ else(CLR_CMAKE_HOST_WIN32) endif(CLR_CMAKE_HOST_LINUX) endif(CLR_CMAKE_HOST_WIN32) -if(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) +if(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD OR CLR_CMAKE_HOST_SUNOS) # This option is necessary to ensure that the overloaded delete operator defined inside # of the utilcode will be used instead of the standard library delete operator. set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Xlinker -Bsymbolic") @@ -88,19 +88,18 @@ if(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) set(END_WHOLE_ARCHIVE -Wl,--no-whole-archive) # Add linker exports file option - set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE}) -endif(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) + if(CLR_CMAKE_HOST_SUNOS) + set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) + else(CLR_CMAKE_HOST_SUNOS) + set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE}) + endif(CLR_CMAKE_HOST_SUNOS) +endif(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD OR CLR_CMAKE_HOST_SUNOS) if(CLR_CMAKE_HOST_OSX) # Add linker exports file option set(EXPORTS_LINKER_OPTION -Wl,-exported_symbols_list,${EXPORTS_FILE}) endif(CLR_CMAKE_HOST_OSX) -if(CLR_CMAKE_HOST_SUNOS) - # Add linker exports file option - set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) -endif(CLR_CMAKE_HOST_SUNOS) - # Create object library to enable creation of proper dependency of mscordaccore.exp on mscordac.obj and # mscordaccore on both the mscordaccore.exp and mscordac.obj. _add_library(mscordacobj OBJECT mscordac.cpp) diff --git a/src/coreclr/src/dlls/mscordbi/CMakeLists.txt b/src/coreclr/src/dlls/mscordbi/CMakeLists.txt index 6a54e77733246..ffd48ee489aba 100644 --- a/src/coreclr/src/dlls/mscordbi/CMakeLists.txt +++ b/src/coreclr/src/dlls/mscordbi/CMakeLists.txt @@ -41,25 +41,24 @@ else(CLR_CMAKE_HOST_WIN32) generate_exports_file(${DEF_SOURCES} ${EXPORTS_FILE}) endif(CLR_CMAKE_HOST_WIN32) -if(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) +if(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD OR CLR_CMAKE_HOST_SUNOS) # This option is necessary to ensure that the overloaded new/delete operators defined inside # of the utilcode will be used instead of the standard library delete operator. set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Xlinker -Bsymbolic") # Add linker exports file option - set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE}) -endif(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD) + if(CLR_CMAKE_HOST_SUNOS) + set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) + else(CLR_CMAKE_HOST_SUNOS) + set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE}) + endif(CLR_CMAKE_HOST_SUNOS) +endif(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD OR CLR_CMAKE_HOST_SUNOS) if(CLR_CMAKE_HOST_OSX) # Add linker exports file option set(EXPORTS_LINKER_OPTION -Wl,-exported_symbols_list,${EXPORTS_FILE}) endif(CLR_CMAKE_HOST_OSX) -if(CLR_CMAKE_HOST_SUNOS) - # Add linker exports file option - set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) -endif(CLR_CMAKE_HOST_SUNOS) - add_library_clr(mscordbi SHARED ${MSCORDBI_SOURCES}) target_precompile_header(TARGET mscordbi HEADER stdafx.h) diff --git a/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt index 4260ea92d1916..918fbf27a6848 100644 --- a/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt @@ -32,7 +32,7 @@ else(CLR_CMAKE_HOST_WIN32) set(EXPORTS_FILE ${CMAKE_CURRENT_BINARY_DIR}/coreclr.exports) generate_exports_file(${DEF_SOURCES} ${EXPORTS_FILE}) - if(CLR_CMAKE_TARGET_LINUX OR CLR_CMAKE_TARGET_FREEBSD OR CLR_CMAKE_TARGET_NETBSD) + if(CLR_CMAKE_TARGET_LINUX OR CLR_CMAKE_TARGET_FREEBSD OR CLR_CMAKE_TARGET_NETBSD OR CLR_CMAKE_TARGET_SUNOS) # This option is necessary to ensure that the overloaded delete operator defined inside # of the utilcode will be used instead of the standard library delete operator. add_link_options("LINKER:-Bsymbolic") @@ -46,8 +46,12 @@ else(CLR_CMAKE_HOST_WIN32) set(START_WHOLE_ARCHIVE -Wl,--whole-archive) set(END_WHOLE_ARCHIVE -Wl,--no-whole-archive) - set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE}) - endif(CLR_CMAKE_TARGET_LINUX OR CLR_CMAKE_TARGET_FREEBSD OR CLR_CMAKE_TARGET_NETBSD) + if(CLR_CMAKE_TARGET_SUNOS) + set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) + elseif(CLR_CMAKE_TARGET_SUNOS) + set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE}) + endif(CLR_CMAKE_TARGET_SUNOS) + endif(CLR_CMAKE_TARGET_LINUX OR CLR_CMAKE_TARGET_FREEBSD OR CLR_CMAKE_TARGET_NETBSD OR CLR_CMAKE_TARGET_SUNOS) if(CLR_CMAKE_TARGET_OSX) # These options are used to force every object to be included even if it's unused. @@ -61,11 +65,6 @@ else(CLR_CMAKE_HOST_WIN32) set(EXPORTS_LINKER_OPTION "${EXPORTS_LINKER_OPTION} -Wl,--no-warn-shared-textrel") endif(CLR_CMAKE_TARGET_ANDROID AND CLR_CMAKE_HOST_ARCH_ARM) - if(CLR_CMAKE_TARGET_SUNOS) - # Add linker exports file option - set(EXPORTS_LINKER_OPTION -Wl,-M,${EXPORTS_FILE}) - endif(CLR_CMAKE_TARGET_SUNOS) - endif (CLR_CMAKE_HOST_WIN32) add_definitions(-DFX_VER_INTERNALNAME_STR=CoreCLR.dll) @@ -151,6 +150,10 @@ if(CLR_CMAKE_TARGET_LINUX) tracepointprovider ${END_WHOLE_ARCHIVE} ) +elseif(CLR_CMAKE_TARGET_SUNOS) + list(APPEND CORECLR_LIBRARIES + socket + ) endif(CLR_CMAKE_TARGET_LINUX) if(FEATURE_PERFTRACING) diff --git a/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp b/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp index b927f3802e683..1b6e1fa820410 100644 --- a/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp +++ b/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp @@ -131,18 +131,11 @@ bool GetEntrypointExecutableAbsolutePath(std::string& entrypointExecutable) } else { - char *joined; - if (asprintf(&joined, "%s/%s", cwd, path) < 0) - { - result = false; - } - else - { - entrypointExecutable.assign(joined); - result = true; - free(joined); - } - + entrypointExecutable + .assign(cwd) + .append("/") + .append(path); + result = true; free(cwd); } } @@ -151,8 +144,6 @@ bool GetEntrypointExecutableAbsolutePath(std::string& entrypointExecutable) entrypointExecutable.assign(path); result = true; } - - free((void*)path); #else #if HAVE_GETAUXVAL && defined(AT_EXECFN) diff --git a/src/coreclr/src/jit/CMakeLists.txt b/src/coreclr/src/jit/CMakeLists.txt index 0fd69af598209..a3f0b1aeb2e0d 100644 --- a/src/coreclr/src/jit/CMakeLists.txt +++ b/src/coreclr/src/jit/CMakeLists.txt @@ -318,16 +318,17 @@ else() set(JIT_EXPORTS_FILE ${CMAKE_CURRENT_BINARY_DIR}/clrjit.exports) generate_exports_file(${CLRJIT_EXPORTS} ${JIT_EXPORTS_FILE}) - if(CLR_CMAKE_TARGET_LINUX OR CLR_CMAKE_TARGET_FREEBSD OR CLR_CMAKE_TARGET_NETBSD) + if(CLR_CMAKE_TARGET_LINUX OR CLR_CMAKE_TARGET_FREEBSD OR CLR_CMAKE_TARGET_NETBSD OR CLR_CMAKE_TARGET_SUNOS) # This is required to force using our own PAL, not one that we are loaded with. set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Xlinker -Bsymbolic") - set(JIT_EXPORTS_LINKER_OPTION -Wl,--version-script=${JIT_EXPORTS_FILE}) + if(CLR_CMAKE_TARGET_SUNOS) + set(JIT_EXPORTS_LINKER_OPTION -Wl,-M,${JIT_EXPORTS_FILE}) + else(CLR_CMAKE_TARGET_SUNOS) + set(JIT_EXPORTS_LINKER_OPTION -Wl,--version-script=${JIT_EXPORTS_FILE}) + endif(CLR_CMAKE_TARGET_SUNOS) elseif(CLR_CMAKE_TARGET_OSX) set(JIT_EXPORTS_LINKER_OPTION -Wl,-exported_symbols_list,${JIT_EXPORTS_FILE}) - elseif(CLR_CMAKE_TARGET_SUNOS) - # Add linker exports file option - set(JIT_EXPORTS_LINKER_OPTION -Wl,-M,${JIT_EXPORTS_FILE}) endif() set(SHARED_LIB_SOURCES ${SOURCES}) diff --git a/src/installer/corehost/cli/common.cmake b/src/installer/corehost/cli/common.cmake index 5f9289659684c..1ad7ee619abd8 100644 --- a/src/installer/corehost/cli/common.cmake +++ b/src/installer/corehost/cli/common.cmake @@ -38,7 +38,7 @@ endif() # This is required to map a symbol reference to a matching definition local to the module (.so) # containing the reference instead of using definitions from other modules. -if(CLR_CMAKE_TARGET_LINUX) +if(CLR_CMAKE_TARGET_LINUX OR CLR_CMAKE_TARGET_SUNOS) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Xlinker -Bsymbolic") endif() diff --git a/src/libraries/Native/Unix/System.IO.Compression.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.IO.Compression.Native/CMakeLists.txt index d1bfa9f4b8490..602d6a3989715 100644 --- a/src/libraries/Native/Unix/System.IO.Compression.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.IO.Compression.Native/CMakeLists.txt @@ -5,6 +5,8 @@ if (CLR_CMAKE_TARGET_BROWSER) elseif (CLR_CMAKE_TARGET_ANDROID) # need special case here since we want to link against libz.so but find_package() would resolve libz.a set(ZLIB_LIBRARIES z) +elseif (CLR_CMAKE_TARGET_SUNOS) + set(ZLIB_LIBRARIES z m) else () find_package(ZLIB REQUIRED) endif () diff --git a/src/libraries/Native/Unix/System.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Native/CMakeLists.txt index 884e1b065814e..e72161d0ee77e 100644 --- a/src/libraries/Native/Unix/System.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.Native/CMakeLists.txt @@ -52,14 +52,14 @@ if (GEN_SHARED_LIB) ) if (CLR_CMAKE_TARGET_LINUX AND NOT CLR_CMAKE_TARGET_ANDROID) target_link_libraries(System.Native rt) - endif () - - if (CLR_CMAKE_TARGET_FREEBSD) + elseif (CLR_CMAKE_TARGET_FREEBSD) target_link_libraries(System.Native pthread) if (HAVE_INOTIFY) find_library(INOTIFY_LIBRARY inotify HINTS /usr/local/lib) target_link_libraries(System.Native ${INOTIFY_LIBRARY}) endif () + elseif (CLR_CMAKE_TARGET_SUNOS) + target_link_libraries(System.Native socket) endif () install_with_stripped_symbols (System.Native PROGRAMS .) endif () From 45e20479eedff3aa3f19fed9b807cf3a189e8a95 Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Thu, 21 May 2020 06:29:14 -0300 Subject: [PATCH 317/420] Fixing tests on android. (#36788) The linker was removing the icu shim functions even exporting them. The unique solution that we found until now is to force the linking using the -u flag. This is a temporary fix until we don't implement QCalls. Fixes https://github.com/dotnet/runtime/issues/36685 --- src/mono/mono/metadata/native-library.c | 2 +- .../Templates/CMakeLists-android.txt | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c index 2b04f0d6d83c1..be893b11a766e 100644 --- a/src/mono/mono/metadata/native-library.c +++ b/src/mono/mono/metadata/native-library.c @@ -1272,7 +1272,7 @@ lookup_pinvoke_call_impl (MonoMethod *method, MonoLookupPInvokeStatus *status_ou new_scope = g_strdup ("libcoreclr.dylib"); #else #if defined(TARGET_ANDROID) - new_scope = g_strdup ("libmonosgen-2.0.so"); + new_scope = g_strdup ("libruntime-android.so"); #else new_scope = g_strdup ("libcoreclr.so"); #endif diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/CMakeLists-android.txt b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/CMakeLists-android.txt index 619d576de7e19..18727daa90605 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/CMakeLists-android.txt +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/CMakeLists-android.txt @@ -13,4 +13,14 @@ target_link_libraries( runtime-android %NativeLibrariesToLink% libz.so - log) + log + "-u GlobalizationNative_LoadICU" + "-u GlobalizationNative_GetLatestJapaneseEra" + "-u GlobalizationNative_ChangeCase" + "-u GlobalizationNative_CloseSortHandle" + "-u GlobalizationNative_GetLocales" + "-u GlobalizationNative_GetLocaleInfoInt" + "-u GlobalizationNative_GetLocaleTimeFormat" + "-u GlobalizationNative_ToUnicode" + "-u GlobalizationNative_NormalizeString" + "-u GlobalizationNative_GetTimeZoneDisplayName") From 514ea59fcd898e4eca18282f351ff080737016df Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Thu, 21 May 2020 17:11:57 +0300 Subject: [PATCH 318/420] Add autoconf, automake and libtool as dependencies (#36475) * Add autoconf, automake and libtool as dependencies * Update instructions --- .../building/coreclr/linux-instructions.md | 42 +------------------ .../requirements/linux-requirements.md | 8 +++- 2 files changed, 7 insertions(+), 43 deletions(-) diff --git a/docs/workflow/building/coreclr/linux-instructions.md b/docs/workflow/building/coreclr/linux-instructions.md index 7f2e046a781fd..6328037313992 100644 --- a/docs/workflow/building/coreclr/linux-instructions.md +++ b/docs/workflow/building/coreclr/linux-instructions.md @@ -71,47 +71,7 @@ Minimum RAM required to build is 1GB. The build is known to fail on 512 MB VMs ( Toolchain Setup --------------- -Add Kitware's APT feed to your configuration for a newer version of CMake. See their instructions at . - -Install the following packages for the toolchain: - -- cmake (at least 3.15.5) -- llvm-3.9 -- clang-9 -- libunwind8 -- libunwind8-dev -- gettext -- libicu-dev -- liblttng-ust-dev -- libcurl4-openssl-dev -- libssl-dev -- libkrb5-dev -- libnuma-dev (optional, enables numa support) - -Note: ARM clang has a known issue with CompareExchange -([#15074](https://github.com/dotnet/coreclr/issues/15074)), so for ARM you must -use clang-4.0 or higher. Moreover, when building with clang-5.0, the -following errors occur: - -``` -src/coreclr/src/debug/inc/arm/primitives.h:66:1: error: __declspec attribute 'selectany' is - not supported [-Werror,-Wignored-attributes] -``` - -This is fixed in clang-5.0.2, which can be installed from the apt -repository listed below. - -For other version of Debian/Ubuntu, please visit http://apt.llvm.org/. - -Then install the packages you need: - - ~$ sudo apt-get install cmake llvm-3.9 clang-9 libunwind8 libunwind8-dev gettext libicu-dev liblttng-ust-dev libcurl4-openssl-dev libssl-dev libnuma-dev libkrb5-dev - -You now have all the required components. - -If you are using Fedora, then you will need to install the following packages: - - ~$ sudo dnf install llvm cmake clang lldb-devel libunwind-devel lttng-ust-devel libicu-devel numactl-devel +Follow instructions and install dependencies listed [here](https://github.com/dotnet/runtime/blob/master/docs/workflow/requirements/linux-requirements.md#toolchain-setup). Git Setup --------- diff --git a/docs/workflow/requirements/linux-requirements.md b/docs/workflow/requirements/linux-requirements.md index 5cb61d12c20ed..6f13897bc6455 100644 --- a/docs/workflow/requirements/linux-requirements.md +++ b/docs/workflow/requirements/linux-requirements.md @@ -88,8 +88,12 @@ Install the following packages for the toolchain: - libnuma-dev (optional, enables numa support) - zlib1g-dev -A single line to install all packages above: +The following dependencies are needed if Mono Runtime is enabled (default behavior): - ~$ sudo apt-get install cmake llvm-9 clang-9 autoconf automake libtool build-essential python curl git lldb-6.0 liblldb-6.0-dev libunwind8 libunwind8-dev gettext libicu-dev liblttng-ust-dev libssl-dev libnuma-dev libkrb5-dev zlib1g-dev +- autoconf +- automake +- libtool + + ~$ sudo apt-get install cmake llvm-9 clang-9 autoconf automake libtool build-essential python curl git lldb-6.0 liblldb-6.0-dev libunwind8 libunwind8-dev gettext libicu-dev liblttng-ust-dev libssl-dev libnuma-dev libkrb5-dev zlib1g-dev autoconf automake libtool You now have all the required components. From 0458185f68b6fcc9213e8c47f18b7d58c4dbb558 Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Thu, 21 May 2020 11:14:46 -0700 Subject: [PATCH 319/420] Handle multi-reg copies/reloads (#36802) Fix #36619 --- src/coreclr/src/jit/codegenarmarch.cpp | 4 ++-- src/coreclr/src/jit/codegenxarch.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index 21b4ba72ee294..cb1a495c058c3 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -1402,7 +1402,7 @@ void CodeGen::genMultiRegStoreToLocal(GenTree* treeNode) // Insert pieces in reverse order for (int i = regCount - 1; i >= 0; --i) { - var_types type = op1->GetRegTypeByIndex(i); + var_types type = op1->gtSkipReloadOrCopy()->GetRegTypeByIndex(i); regNumber reg = op1->GetRegByIndex(i); if (op1->IsCopyOrReload()) { @@ -1444,7 +1444,7 @@ void CodeGen::genMultiRegStoreToLocal(GenTree* treeNode) { for (unsigned i = 0; i < regCount; ++i) { - var_types type = op1->GetRegTypeByIndex(i); + var_types type = op1->gtSkipReloadOrCopy()->GetRegTypeByIndex(i); regNumber reg = op1->GetRegByIndex(i); if (op1->IsCopyOrReload()) { diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index e6bb678d93a26..f365138a91227 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -1968,7 +1968,7 @@ void CodeGen::genMultiRegStoreToLocal(GenTree* treeNode) int offset = 0; for (unsigned i = 0; i < regCount; ++i) { - var_types type = op1->GetRegTypeByIndex(i); + var_types type = op1->gtSkipReloadOrCopy()->GetRegTypeByIndex(i); regNumber reg = op1->GetRegByIndex(i); if (op1->IsCopyOrReload()) { From 48a42c655d11b7fc8c6c018ad1d22987f93ad52f Mon Sep 17 00:00:00 2001 From: monojenkins Date: Thu, 21 May 2020 14:24:31 -0400 Subject: [PATCH 320/420] Adding check to bypass decoding pdbs that have no sequence points. (#36771) Unity has a pdb with zero sequence points somehow. If a user added a reference to the library and then attempted to set a managed breakpoint mono would hit an assert and crash when it would attempt to decode this pdb. Call stack would look like: ``` > mono-2.0-boehm.dll!mono_ppdb_get_seq_points(_MonoDebugMethodInfo * minfo, char * * source_file, _GPtrArray * * source_file_list, int * * source_files, MonoSymSeqPoint * * seq_points, int * n_seq_points) Line 508 C mono-2.0-boehm.dll!mono_debug_get_seq_points(_MonoDebugMethodInfo * minfo, char * * source_file, _GPtrArray * * source_file_list, int * * source_files, MonoSymSeqPoint * * seq_points, int * n_seq_points) Line 1093 C mono-2.0-boehm.dll!get_source_files_for_type(_MonoClass * klass) Line 6920 C mono-2.0-boehm.dll!get_types_for_source_file(void * key, void * value, void * user_data) Line 7003 C mono-2.0-boehm.dll!monoeg_g_hash_table_foreach(_GHashTable * hash, void(*)(void *, void *, void *) func, void * user_data) Line 364 C mono-2.0-boehm.dll!mono_de_foreach_domain(void(*)(void *, void *, void *) func, void * user_data) Line 95 C mono-2.0-boehm.dll!vm_commands(int command, int id, unsigned char * p, unsigned char * end, Buffer * buf) Line 7341 C mono-2.0-boehm.dll!debugger_thread(void * arg) Line 10323 C mono-2.0-boehm.dll!start_wrapper_internal(StartInfo * start_info, unsigned __int64 * stack_ptr) Line 1241 C mono-2.0-boehm.dll!start_wrapper(void * data) Line 1315 C kernel32.dll!00007ffc12017bd4() Unknown ntdll.dll!00007ffc121ece51() Unknown ``` Adding a check to ignore pdbs like this prevents the crash and debugging can continue normally. Related unity issue: https://issuetracker.unity3d.com/issues/macos-editor-crashes-on-mono-log-write-logfile-when-attaching-a-debugger-and-then-setting-a-breakpoint Co-authored-by: UnityAlex --- src/mono/mono/metadata/debug-mono-ppdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/debug-mono-ppdb.c b/src/mono/mono/metadata/debug-mono-ppdb.c index 28c78c237b0e0..a5634f6c1e4cd 100644 --- a/src/mono/mono/metadata/debug-mono-ppdb.c +++ b/src/mono/mono/metadata/debug-mono-ppdb.c @@ -497,7 +497,7 @@ mono_ppdb_get_seq_points (MonoDebugMethodInfo *minfo, char **source_file, GPtrAr if (source_files) sindexes = g_ptr_array_new (); - if (!method->token) + if (!method->token || tables [MONO_TABLE_METHODBODY].rows == 0) return; method_idx = mono_metadata_token_index (method->token); From 8ea47977401873ae53fde73d43fea00cc6966ef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Thu, 21 May 2020 20:25:01 +0200 Subject: [PATCH 321/420] Allow building Browser/wasm config on Windows (#36816) Seems to work fine for the `Mono.CoreLib` subset, which is all we care about in the IL Linker-land. --- eng/build.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/build.ps1 b/eng/build.ps1 index c5c0031b8d21e..d03d2262e063f 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -5,12 +5,12 @@ Param( [ValidateSet("Debug","Release","Checked")][string[]][Alias('c')]$configuration = @("Debug"), [string][Alias('f')]$framework, [string]$vs, - [ValidateSet("Windows_NT","Linux","OSX")][string]$os, + [ValidateSet("Windows_NT","Linux","OSX","Browser")][string]$os, [switch]$allconfigurations, [switch]$coverage, [string]$testscope, [switch]$testnobuild, - [ValidateSet("x86","x64","arm","arm64")][string[]][Alias('a')]$arch = @([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant()), + [ValidateSet("x86","x64","arm","arm64","wasm")][string[]][Alias('a')]$arch = @([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant()), [Parameter(Position=0)][string][Alias('s')]$subset, [ValidateSet("Debug","Release","Checked")][string][Alias('rc')]$runtimeConfiguration, [ValidateSet("Debug","Release")][string][Alias('lc')]$librariesConfiguration, @@ -21,8 +21,8 @@ function Get-Help() { Write-Host "Common settings:" Write-Host " -subset Build a subset, print available subsets with -subset help (short: -s)" Write-Host " -vs Open the solution with VS for Test Explorer support. Path or solution name (ie -vs Microsoft.CSharp)" - Write-Host " -os Build operating system: Windows_NT, Linux or OSX" - Write-Host " -arch Build platform: x86, x64, arm or arm64 (short: -a). Pass a comma-separated list to build for multiple architectures." + Write-Host " -os Build operating system: Windows_NT, Linux, OSX, or Browser" + Write-Host " -arch Build platform: x86, x64, arm, arm64, or wasm (short: -a). Pass a comma-separated list to build for multiple architectures." Write-Host " -configuration Build configuration: Debug, Release or [CoreCLR]Checked (short: -c). Pass a comma-separated list to build for multiple configurations" Write-Host " -runtimeConfiguration Runtime build configuration: Debug, Release or [CoreCLR]Checked (short: -rc)" Write-Host " -librariesConfiguration Libraries build configuration: Debug or Release (short: -lc)" From a2663dabe5325befb2ccd6fd02480c54f766bf6b Mon Sep 17 00:00:00 2001 From: Fan Yang <52458914+fanyang-mono@users.noreply.github.com> Date: Thu, 21 May 2020 14:39:47 -0400 Subject: [PATCH 322/420] Enable passing coreclr tests (#36702) --- src/coreclr/tests/issues.targets | 42 -------------------------------- 1 file changed, 42 deletions(-) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index a29dda03c8ec6..c1ce557f91bc3 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -1266,36 +1266,9 @@ needs triage - - needs triage - - - needs triage - - - needs triage - - - needs triage - - - needs triage - - - needs triage - - - needs triage - https://github.com/dotnet/runtime/issues/34068 - - needs triage - - - needs triage - https://github.com/dotnet/runtime/issues/34068 @@ -1305,9 +1278,6 @@ https://github.com/dotnet/runtime/issues/34068 - - needs triage - https://github.com/dotnet/runtime/issues/34068 @@ -1380,12 +1350,6 @@ needs triage - - needs triage - - - needs triage - https://github.com/dotnet/runtime/issues/34068 @@ -1407,12 +1371,6 @@ needs triage - - needs triage - - - needs triage - needs triage From aa7668dec5dab838623f2d74bdeda8913a45eb79 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 21 May 2020 12:51:50 -0700 Subject: [PATCH 323/420] Updating the HWIntrinsics to support dropping unnecessary casts (#36512) * Updating the HWIntrinsics to support dropping unnecessary casts * Applying formatting patch * Only drop the cast operation if the source is greater than or equal to the expected size --- src/coreclr/src/jit/lower.h | 4 + src/coreclr/src/jit/lowerarmarch.cpp | 115 +++++++++++++++++++++++---- src/coreclr/src/jit/lowerxarch.cpp | 55 +++++++++++++ 3 files changed, 157 insertions(+), 17 deletions(-) diff --git a/src/coreclr/src/jit/lower.h b/src/coreclr/src/jit/lower.h index b7efee0f7831c..f45e9973fa18d 100644 --- a/src/coreclr/src/jit/lower.h +++ b/src/coreclr/src/jit/lower.h @@ -321,6 +321,10 @@ class Lowering final : public Phase void LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node); void LowerFusedMultiplyAdd(GenTreeHWIntrinsic* node); +#ifdef TARGET_ARM64 + bool IsValidConstForMovImm(GenTreeHWIntrinsic* node); +#endif // TARGET_ARM64 + union VectorConstant { int8_t i8[32]; uint8_t u8[32]; diff --git a/src/coreclr/src/jit/lowerarmarch.cpp b/src/coreclr/src/jit/lowerarmarch.cpp index ae3d03ea125c8..a6050c9baa48b 100644 --- a/src/coreclr/src/jit/lowerarmarch.cpp +++ b/src/coreclr/src/jit/lowerarmarch.cpp @@ -560,6 +560,71 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) ContainCheckHWIntrinsic(node); } +//---------------------------------------------------------------------------------------------- +// Lowering::IsValidConstForMovImm: Determines if the given node can be replaced by a mov/fmov immediate instruction +// +// Arguments: +// node - The hardware intrinsic node. +// +// Returns: +// true if the node can be replaced by a mov/fmov immediate instruction; otherwise, false +// +// IMPORTANT: +// This check may end up modifying node->gtOp1 if it is a cast node that can be removed +bool Lowering::IsValidConstForMovImm(GenTreeHWIntrinsic* node) +{ + assert((node->gtHWIntrinsicId == NI_Vector64_Create) || (node->gtHWIntrinsicId == NI_Vector128_Create) || + (node->gtHWIntrinsicId == NI_Vector64_CreateScalarUnsafe) || + (node->gtHWIntrinsicId == NI_Vector128_CreateScalarUnsafe) || + (node->gtHWIntrinsicId == NI_AdvSimd_DuplicateToVector64) || + (node->gtHWIntrinsicId == NI_AdvSimd_DuplicateToVector128) || + (node->gtHWIntrinsicId == NI_AdvSimd_Arm64_DuplicateToVector64) || + (node->gtHWIntrinsicId == NI_AdvSimd_Arm64_DuplicateToVector128)); + assert(HWIntrinsicInfo::lookupNumArgs(node) == 1); + + GenTree* op1 = node->gtOp1; + GenTree* castOp = nullptr; + + if (varTypeIsIntegral(node->gtSIMDBaseType) && op1->OperIs(GT_CAST)) + { + // We will sometimes get a cast around a constant value (such as for + // certain long constants) which would block the below containment. + // So we will temporarily check what the cast is from instead so we + // can catch those cases as well. + + castOp = op1->AsCast()->CastOp(); + op1 = castOp; + } + + if (op1->IsCnsIntOrI()) + { + const ssize_t dataValue = op1->AsIntCon()->gtIconVal; + + if (comp->GetEmitter()->emitIns_valid_imm_for_movi(dataValue, emitActualTypeSize(node->gtSIMDBaseType))) + { + if (castOp != nullptr) + { + // We found a containable immediate under + // a cast, so remove the cast from the LIR. + + BlockRange().Remove(node->gtOp1); + node->gtOp1 = op1; + } + return true; + } + } + else if (op1->IsCnsFltOrDbl()) + { + assert(varTypeIsFloating(node->gtSIMDBaseType)); + assert(castOp == nullptr); + + const double dataValue = op1->AsDblCon()->gtDconVal; + return comp->GetEmitter()->emitIns_valid_imm_for_fmov(dataValue); + } + + return false; +} + //---------------------------------------------------------------------------------------------- // Lowering::LowerHWIntrinsicCreate: Lowers a Vector64 or Vector128 Create call // @@ -642,6 +707,33 @@ void Lowering::LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node) } assert((argCnt == 1) || (argCnt == (simdSize / genTypeSize(baseType)))); + if ((argCnt == cnsArgCnt) && (argCnt == 1)) + { + GenTree* castOp = nullptr; + + if (varTypeIsIntegral(baseType) && op1->OperIs(GT_CAST)) + { + // We will sometimes get a cast around a constant value (such as for + // certain long constants) which would block the below containment. + // So we will temporarily check what the cast is from instead so we + // can catch those cases as well. + + castOp = op1->AsCast()->CastOp(); + op1 = castOp; + } + + if (IsValidConstForMovImm(node)) + { + // Set the cnsArgCnt to zero so we get lowered to a DuplicateToVector + // intrinsic, which will itself mark the node as contained. + cnsArgCnt = 0; + + // Reacquire op1 as the above check may have removed a cast node and + // changed op1. + op1 = node->gtOp1; + } + } + if (argCnt == cnsArgCnt) { if (op1->OperIsList()) @@ -1201,27 +1293,16 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AdvSimd_DuplicateToVector128: case NI_AdvSimd_Arm64_DuplicateToVector64: case NI_AdvSimd_Arm64_DuplicateToVector128: - if (intrin.op1->IsCnsIntOrI()) - { - const ssize_t dataValue = intrin.op1->AsIntCon()->gtIconVal; - - if (comp->GetEmitter()->emitIns_valid_imm_for_movi(dataValue, emitActualTypeSize(intrin.baseType))) - { - MakeSrcContained(node, intrin.op1); - } - } - else if (intrin.op1->IsCnsFltOrDbl()) + { + if (IsValidConstForMovImm(node)) { - assert(varTypeIsFloating(intrin.baseType)); - - const double dataValue = intrin.op1->AsDblCon()->gtDconVal; + // Use node->gtOp1 as the above check may + // have removed a cast node and changed op1 - if (comp->GetEmitter()->emitIns_valid_imm_for_fmov(dataValue)) - { - MakeSrcContained(node, intrin.op1); - } + MakeSrcContained(node, node->gtOp1); } break; + } default: unreached(); diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index 4e05fa6a4e6d5..3cb0c50afba5f 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -947,6 +947,61 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) return; } + case NI_SSE2_Insert: + case NI_SSE41_Insert: + case NI_SSE41_X64_Insert: + { + assert(HWIntrinsicInfo::lookupNumArgs(node) == 3); + + GenTreeArgList* argList = node->gtOp1->AsArgList(); + GenTree* op2 = argList->Rest()->Current(); + + if (!op2->OperIs(GT_CAST)) + { + break; + } + + // Insert takes either a 32-bit register or a memory operand. + // In either case, only gtSIMDBaseType bits are read and so + // widening or narrowing the operand may be unnecessary and it + // can just be used directly. + + GenTree* castOp = op2->AsCast()->CastOp(); + + if (genTypeSize(castOp->gtType) >= genTypeSize(node->gtSIMDBaseType)) + { + BlockRange().Remove(op2); + argList->Rest()->gtOp1 = castOp; + } + break; + } + + case NI_SSE42_Crc32: + { + assert(HWIntrinsicInfo::lookupNumArgs(node) == 2); + + GenTree* op2 = node->gtOp2; + + if (!op2->OperIs(GT_CAST)) + { + break; + } + + // Crc32 takes either a bit register or a memory operand. + // In either case, only gtType bits are read and so widening + // or narrowing the operand may be unnecessary and it can + // just be used directly. + + GenTree* castOp = op2->AsCast()->CastOp(); + + if (genTypeSize(castOp->gtType) >= genTypeSize(node->gtType)) + { + BlockRange().Remove(op2); + node->gtOp2 = castOp; + } + break; + } + case NI_SSE2_CompareGreaterThan: { if (node->gtSIMDBaseType != TYP_DOUBLE) From a2ec75f3feaabec604fb03ad5252c92d3e152aa9 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Thu, 21 May 2020 21:14:52 +0100 Subject: [PATCH 324/420] Minor documentation improvements (#36834) --- docs/workflow/debugging/libraries/debugging-vscode.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/workflow/debugging/libraries/debugging-vscode.md b/docs/workflow/debugging/libraries/debugging-vscode.md index a27aa1dcbed57..4b82a4265811b 100644 --- a/docs/workflow/debugging/libraries/debugging-vscode.md +++ b/docs/workflow/debugging/libraries/debugging-vscode.md @@ -5,7 +5,7 @@ - Open the folder containing the source you want to debug in VS Code - i.e., if you are debugging a test failure in System.Net.Sockets, open `runtime/src/libraries/System.Net.Sockets` - Open the debug window: `ctrl-shift-D` or click on the button on the left - Click the gear button at the top to create a launch configuration, select `.NET Core` from the selection dropdown -- In the `.NET Core Launch (console)` configuration do the following +- In the ".NET Core Launch (console)" `launch.json` configuration file make the following changes: - delete the `preLaunchTask` property - set `program` to the full path to `dotnet` in the artifacts/bin/testhost directory. - something like `artifacts/bin/testhost/netcoreapp-{OS}-{Configuration}-{Architecture}`, plus the full path to your dotnet/runtime directory. @@ -13,5 +13,5 @@ - using the System.Net.Sockets example, it should be something like `artifacts/bin/System.Net.Sockets.Tests/netcoreapp-{OS}-{Configuration}-{Architecture}`, plus the full path to your dotnet/runtime directory. - set `args` to the command line arguments to pass to the test - something like: `[ "exec", "--runtimeconfig", "{TestProjectName}.runtimeconfig.json", "xunit.console.dll", "{TestProjectName}.dll", "-notrait", ... ]`, where TestProjectName would be `System.Net.Sockets.Tests` - - to run a specific test, you can append something like: `[ "method", "System.Net.Sockets.Tests.{ClassName}.{TestMethodName}", ...]` + - to run a specific test, you can append something like: `[ "-method", "System.Net.Sockets.Tests.{ClassName}.{TestMethodName}", ...]` - Set a breakpoint and launch the debugger, inspecting variables and call stacks will now work From bdc09433b6d451e66943de959afdab92117c502e Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 21 May 2020 15:05:21 -0700 Subject: [PATCH 325/420] [Arm64] ASIMD Shift instructions (#36552) * sqrshl * sqrshrn * sqrshrn2 * sqrshrun * sqrshrun2 * sqshl * sqshlu * sqshrn * sqshrn2 * sqshrun * sqshrun2 * srshl * sshl * uqrshl * uqrshrn * uqrshrn2 * uqshl * uqshrn * uqshrn2 * urshl * ushl --- src/coreclr/src/jit/codegenarm64.cpp | 591 +++++++++--- src/coreclr/src/jit/emitarm64.cpp | 516 +++++++---- src/coreclr/src/jit/emitarm64.h | 12 +- src/coreclr/src/jit/emitfmtsarm64.h | 1 + src/coreclr/src/jit/instr.cpp | 14 +- src/coreclr/src/jit/instr.h | 14 +- src/coreclr/src/jit/instrsarm64.h | 1285 +++++++++++++------------- 7 files changed, 1463 insertions(+), 970 deletions(-) diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index f6b6ee3a3ff7b..2392eb88a22d1 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -4312,17 +4312,10 @@ void CodeGen::genSIMDIntrinsicWiden(GenTreeSIMD* simdNode) instruction ins = getOpForSIMDIntrinsic(simdNode->gtSIMDIntrinsicID, baseType); - if (varTypeIsFloating(baseType)) - { - GetEmitter()->emitIns_R_R(ins, EA_8BYTE, targetReg, op1Reg); - } - else - { - emitAttr attr = (simdNode->gtSIMDIntrinsicID == SIMDIntrinsicWidenHi) ? EA_16BYTE : EA_8BYTE; - insOpts opt = genGetSimdInsOpt(attr, baseType); + emitAttr attr = (simdNode->gtSIMDIntrinsicID == SIMDIntrinsicWidenHi) ? EA_16BYTE : EA_8BYTE; + insOpts opt = genGetSimdInsOpt(attr, baseType); - GetEmitter()->emitIns_R_R(ins, attr, targetReg, op1Reg, opt); - } + GetEmitter()->emitIns_R_R(ins, attr, targetReg, op1Reg, opt); genProduceReg(simdNode); } @@ -4362,43 +4355,39 @@ void CodeGen::genSIMDIntrinsicNarrow(GenTreeSIMD* simdNode) instruction ins = getOpForSIMDIntrinsic(simdNode->gtSIMDIntrinsicID, baseType); assert((ins == INS_fcvtn) || (ins == INS_xtn)); - if (ins == INS_fcvtn) + instruction ins2 = (ins == INS_fcvtn) ? INS_fcvtn2 : INS_xtn2; + + insOpts opt = INS_OPTS_NONE; + insOpts opt2 = INS_OPTS_NONE; + + // This is not the same as genGetSimdInsOpt() + // Basetype is the soure operand type + // However encoding is based on the destination operand type which is 1/2 the basetype. + switch (baseType) { - GetEmitter()->emitIns_R_R(INS_fcvtn, EA_8BYTE, targetReg, op1Reg); - GetEmitter()->emitIns_R_R(INS_fcvtn2, EA_8BYTE, targetReg, op2Reg); + case TYP_ULONG: + case TYP_LONG: + case TYP_DOUBLE: + opt = INS_OPTS_2S; + opt2 = INS_OPTS_4S; + break; + case TYP_UINT: + case TYP_INT: + opt = INS_OPTS_4H; + opt2 = INS_OPTS_8H; + break; + case TYP_USHORT: + case TYP_SHORT: + opt = INS_OPTS_8B; + opt2 = INS_OPTS_16B; + break; + default: + assert(!"Unsupported narrowing element type"); + unreached(); } - else - { - insOpts opt = INS_OPTS_NONE; - insOpts opt2 = INS_OPTS_NONE; - // This is not the same as genGetSimdInsOpt() - // Basetype is the soure operand type - // However encoding is based on the destination operand type which is 1/2 the basetype. - switch (baseType) - { - case TYP_ULONG: - case TYP_LONG: - opt = INS_OPTS_2S; - opt2 = INS_OPTS_4S; - break; - case TYP_UINT: - case TYP_INT: - opt = INS_OPTS_4H; - opt2 = INS_OPTS_8H; - break; - case TYP_USHORT: - case TYP_SHORT: - opt = INS_OPTS_8B; - opt2 = INS_OPTS_16B; - break; - default: - assert(!"Unsupported narrowing element type"); - unreached(); - } - GetEmitter()->emitIns_R_R(INS_xtn, EA_8BYTE, targetReg, op1Reg, opt); - GetEmitter()->emitIns_R_R(INS_xtn2, EA_16BYTE, targetReg, op2Reg, opt2); - } + GetEmitter()->emitIns_R_R(ins, EA_8BYTE, targetReg, op1Reg, opt); + GetEmitter()->emitIns_R_R(ins2, EA_16BYTE, targetReg, op2Reg, opt2); genProduceReg(simdNode); } @@ -5463,35 +5452,35 @@ void CodeGen::genArm64EmitterUnitTests() // tbl Vd, {Vt}, Vm theEmitter->emitIns_R_R_R(INS_tbl, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_8B); - theEmitter->emitIns_R_R_R(INS_tbl, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_tbl, EA_16BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); // tbx Vd, {Vt}, Vm theEmitter->emitIns_R_R_R(INS_tbx, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_8B); - theEmitter->emitIns_R_R_R(INS_tbx, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_tbx, EA_16BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); // tbl Vd, {Vt, Vt2}, Vm theEmitter->emitIns_R_R_R(INS_tbl_2regs, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_8B); - theEmitter->emitIns_R_R_R(INS_tbl_2regs, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_tbl_2regs, EA_16BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); // tbx Vd, {Vt, Vt2}, Vm theEmitter->emitIns_R_R_R(INS_tbx_2regs, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_8B); - theEmitter->emitIns_R_R_R(INS_tbx_2regs, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_tbx_2regs, EA_16BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); // tbl Vd, {Vt, Vt2, Vt3}, Vm theEmitter->emitIns_R_R_R(INS_tbl_3regs, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_8B); - theEmitter->emitIns_R_R_R(INS_tbl_3regs, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_tbl_3regs, EA_16BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); // tbx Vd, {Vt, Vt2, Vt3}, Vm theEmitter->emitIns_R_R_R(INS_tbx_3regs, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_8B); - theEmitter->emitIns_R_R_R(INS_tbx_3regs, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_tbx_3regs, EA_16BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); // tbl Vd, {Vt, Vt2, Vt3, Vt4}, Vm theEmitter->emitIns_R_R_R(INS_tbl_4regs, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_8B); - theEmitter->emitIns_R_R_R(INS_tbl_4regs, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_tbl_4regs, EA_16BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); // tbx Vd, {Vt, Vt2, Vt3, Vt4}, Vm theEmitter->emitIns_R_R_R(INS_tbx_4regs, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_8B); - theEmitter->emitIns_R_R_R(INS_tbx_4regs, EA_8BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_tbx_4regs, EA_16BYTE, REG_V0, REG_V1, REG_V6, INS_OPTS_16B); #endif // ALL_ARM64_EMITTER_UNIT_TESTS @@ -7938,17 +7927,18 @@ void CodeGen::genArm64EmitterUnitTests() theEmitter->emitIns_R_R(INS_ursqrte, EA_8BYTE, REG_V0, REG_V1, INS_OPTS_2S); theEmitter->emitIns_R_R(INS_ursqrte, EA_16BYTE, REG_V2, REG_V3, INS_OPTS_4S); - // INS_fcvtl - theEmitter->emitIns_R_R(INS_fcvtl, EA_4BYTE, REG_V0, REG_V1); + // fcvtl{2} vector + theEmitter->emitIns_R_R(INS_fcvtl, EA_8BYTE, REG_V0, REG_V1, INS_OPTS_4H); + theEmitter->emitIns_R_R(INS_fcvtl2, EA_16BYTE, REG_V2, REG_V3, INS_OPTS_8H); + theEmitter->emitIns_R_R(INS_fcvtl, EA_8BYTE, REG_V4, REG_V5, INS_OPTS_2S); + theEmitter->emitIns_R_R(INS_fcvtl2, EA_16BYTE, REG_V5, REG_V6, INS_OPTS_4S); - // INS_fcvtl2 - theEmitter->emitIns_R_R(INS_fcvtl2, EA_4BYTE, REG_V0, REG_V1); + // fcvtn{2} vector + theEmitter->emitIns_R_R(INS_fcvtn, EA_8BYTE, REG_V0, REG_V1, INS_OPTS_4H); + theEmitter->emitIns_R_R(INS_fcvtn2, EA_16BYTE, REG_V2, REG_V3, INS_OPTS_8H); + theEmitter->emitIns_R_R(INS_fcvtn, EA_8BYTE, REG_V4, REG_V5, INS_OPTS_2S); + theEmitter->emitIns_R_R(INS_fcvtn2, EA_16BYTE, REG_V5, REG_V6, INS_OPTS_4S); - // INS_fcvtn - theEmitter->emitIns_R_R(INS_fcvtn, EA_8BYTE, REG_V0, REG_V1); - - // INS_fcvtn2 - theEmitter->emitIns_R_R(INS_fcvtn2, EA_8BYTE, REG_V0, REG_V1); #endif #ifdef ALL_ARM64_EMITTER_UNIT_TESTS @@ -8188,196 +8178,200 @@ void CodeGen::genArm64EmitterUnitTests() // R_R_I vector operations, one dest, one source reg, one immed // + // Some of the tests cases below might appear redundant since they emit same combinations of instruction x size x + // vector arrangements. However, these are added to verify that the split constant encoding works with both - small + // and large constants. + genDefineTempLabel(genCreateTempLabel()); - // 'sshr' scalar + // sshr scalar theEmitter->emitIns_R_R_I(INS_sshr, EA_8BYTE, REG_V0, REG_V1, 1); theEmitter->emitIns_R_R_I(INS_sshr, EA_8BYTE, REG_V2, REG_V3, 14); theEmitter->emitIns_R_R_I(INS_sshr, EA_8BYTE, REG_V4, REG_V5, 27); theEmitter->emitIns_R_R_I(INS_sshr, EA_8BYTE, REG_V6, REG_V7, 40); - theEmitter->emitIns_R_R_I(INS_sshr, EA_8BYTE, REG_V8, REG_V9, 63); + theEmitter->emitIns_R_R_I(INS_sshr, EA_8BYTE, REG_V8, REG_V9, 64); - // 'sshr' vector + // sshr vector theEmitter->emitIns_R_R_I(INS_sshr, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); - theEmitter->emitIns_R_R_I(INS_sshr, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_sshr, EA_16BYTE, REG_V2, REG_V3, 8, INS_OPTS_16B); theEmitter->emitIns_R_R_I(INS_sshr, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); - theEmitter->emitIns_R_R_I(INS_sshr, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_sshr, EA_16BYTE, REG_V6, REG_V7, 16, INS_OPTS_8H); theEmitter->emitIns_R_R_I(INS_sshr, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); - theEmitter->emitIns_R_R_I(INS_sshr, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_sshr, EA_16BYTE, REG_V10, REG_V11, 32, INS_OPTS_4S); theEmitter->emitIns_R_R_I(INS_sshr, EA_16BYTE, REG_V12, REG_V13, 33, INS_OPTS_2D); - theEmitter->emitIns_R_R_I(INS_sshr, EA_16BYTE, REG_V14, REG_V15, 63, INS_OPTS_2D); + theEmitter->emitIns_R_R_I(INS_sshr, EA_16BYTE, REG_V14, REG_V15, 64, INS_OPTS_2D); - // 'ssra' scalar + // ssra scalar theEmitter->emitIns_R_R_I(INS_ssra, EA_8BYTE, REG_V0, REG_V1, 1); theEmitter->emitIns_R_R_I(INS_ssra, EA_8BYTE, REG_V2, REG_V3, 14); theEmitter->emitIns_R_R_I(INS_ssra, EA_8BYTE, REG_V4, REG_V5, 27); theEmitter->emitIns_R_R_I(INS_ssra, EA_8BYTE, REG_V6, REG_V7, 40); - theEmitter->emitIns_R_R_I(INS_ssra, EA_8BYTE, REG_V8, REG_V9, 63); + theEmitter->emitIns_R_R_I(INS_ssra, EA_8BYTE, REG_V8, REG_V9, 64); - // 'ssra' vector + // ssra vector theEmitter->emitIns_R_R_I(INS_ssra, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); - theEmitter->emitIns_R_R_I(INS_ssra, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_ssra, EA_16BYTE, REG_V2, REG_V3, 8, INS_OPTS_16B); theEmitter->emitIns_R_R_I(INS_ssra, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); - theEmitter->emitIns_R_R_I(INS_ssra, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_ssra, EA_16BYTE, REG_V6, REG_V7, 16, INS_OPTS_8H); theEmitter->emitIns_R_R_I(INS_ssra, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); - theEmitter->emitIns_R_R_I(INS_ssra, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_ssra, EA_16BYTE, REG_V10, REG_V11, 32, INS_OPTS_4S); theEmitter->emitIns_R_R_I(INS_ssra, EA_16BYTE, REG_V12, REG_V13, 33, INS_OPTS_2D); - theEmitter->emitIns_R_R_I(INS_ssra, EA_16BYTE, REG_V14, REG_V15, 63, INS_OPTS_2D); + theEmitter->emitIns_R_R_I(INS_ssra, EA_16BYTE, REG_V14, REG_V15, 64, INS_OPTS_2D); - // 'srshr' scalar + // srshr scalar theEmitter->emitIns_R_R_I(INS_srshr, EA_8BYTE, REG_V0, REG_V1, 1); theEmitter->emitIns_R_R_I(INS_srshr, EA_8BYTE, REG_V2, REG_V3, 14); theEmitter->emitIns_R_R_I(INS_srshr, EA_8BYTE, REG_V4, REG_V5, 27); theEmitter->emitIns_R_R_I(INS_srshr, EA_8BYTE, REG_V6, REG_V7, 40); - theEmitter->emitIns_R_R_I(INS_srshr, EA_8BYTE, REG_V8, REG_V9, 63); + theEmitter->emitIns_R_R_I(INS_srshr, EA_8BYTE, REG_V8, REG_V9, 64); - // 'srshr' vector + // srshr vector theEmitter->emitIns_R_R_I(INS_srshr, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); - theEmitter->emitIns_R_R_I(INS_srshr, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_srshr, EA_16BYTE, REG_V2, REG_V3, 8, INS_OPTS_16B); theEmitter->emitIns_R_R_I(INS_srshr, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); - theEmitter->emitIns_R_R_I(INS_srshr, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_srshr, EA_16BYTE, REG_V6, REG_V7, 16, INS_OPTS_8H); theEmitter->emitIns_R_R_I(INS_srshr, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); - theEmitter->emitIns_R_R_I(INS_srshr, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_srshr, EA_16BYTE, REG_V10, REG_V11, 32, INS_OPTS_4S); theEmitter->emitIns_R_R_I(INS_srshr, EA_16BYTE, REG_V12, REG_V13, 33, INS_OPTS_2D); - theEmitter->emitIns_R_R_I(INS_srshr, EA_16BYTE, REG_V14, REG_V15, 63, INS_OPTS_2D); + theEmitter->emitIns_R_R_I(INS_srshr, EA_16BYTE, REG_V14, REG_V15, 64, INS_OPTS_2D); - // 'srsra' scalar + // srsra scalar theEmitter->emitIns_R_R_I(INS_srsra, EA_8BYTE, REG_V0, REG_V1, 1); theEmitter->emitIns_R_R_I(INS_srsra, EA_8BYTE, REG_V2, REG_V3, 14); theEmitter->emitIns_R_R_I(INS_srsra, EA_8BYTE, REG_V4, REG_V5, 27); theEmitter->emitIns_R_R_I(INS_srsra, EA_8BYTE, REG_V6, REG_V7, 40); - theEmitter->emitIns_R_R_I(INS_srsra, EA_8BYTE, REG_V8, REG_V9, 63); + theEmitter->emitIns_R_R_I(INS_srsra, EA_8BYTE, REG_V8, REG_V9, 64); - // 'srsra' vector + // srsra vector theEmitter->emitIns_R_R_I(INS_srsra, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); - theEmitter->emitIns_R_R_I(INS_srsra, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_srsra, EA_16BYTE, REG_V2, REG_V3, 8, INS_OPTS_16B); theEmitter->emitIns_R_R_I(INS_srsra, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); - theEmitter->emitIns_R_R_I(INS_srsra, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_srsra, EA_16BYTE, REG_V6, REG_V7, 16, INS_OPTS_8H); theEmitter->emitIns_R_R_I(INS_srsra, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); - theEmitter->emitIns_R_R_I(INS_srsra, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_srsra, EA_16BYTE, REG_V10, REG_V11, 32, INS_OPTS_4S); theEmitter->emitIns_R_R_I(INS_srsra, EA_16BYTE, REG_V12, REG_V13, 33, INS_OPTS_2D); - theEmitter->emitIns_R_R_I(INS_srsra, EA_16BYTE, REG_V14, REG_V15, 63, INS_OPTS_2D); + theEmitter->emitIns_R_R_I(INS_srsra, EA_16BYTE, REG_V14, REG_V15, 64, INS_OPTS_2D); - // 'shl' scalar - theEmitter->emitIns_R_R_I(INS_shl, EA_8BYTE, REG_V0, REG_V1, 1); + // shl scalar + theEmitter->emitIns_R_R_I(INS_shl, EA_8BYTE, REG_V0, REG_V1, 0); theEmitter->emitIns_R_R_I(INS_shl, EA_8BYTE, REG_V2, REG_V3, 14); theEmitter->emitIns_R_R_I(INS_shl, EA_8BYTE, REG_V4, REG_V5, 27); theEmitter->emitIns_R_R_I(INS_shl, EA_8BYTE, REG_V6, REG_V7, 40); theEmitter->emitIns_R_R_I(INS_shl, EA_8BYTE, REG_V8, REG_V9, 63); - // 'shl' vector - theEmitter->emitIns_R_R_I(INS_shl, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); + // shl vector + theEmitter->emitIns_R_R_I(INS_shl, EA_8BYTE, REG_V0, REG_V1, 0, INS_OPTS_8B); theEmitter->emitIns_R_R_I(INS_shl, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); - theEmitter->emitIns_R_R_I(INS_shl, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_shl, EA_8BYTE, REG_V4, REG_V5, 8, INS_OPTS_4H); theEmitter->emitIns_R_R_I(INS_shl, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); - theEmitter->emitIns_R_R_I(INS_shl, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_shl, EA_8BYTE, REG_V8, REG_V9, 16, INS_OPTS_2S); theEmitter->emitIns_R_R_I(INS_shl, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); - theEmitter->emitIns_R_R_I(INS_shl, EA_16BYTE, REG_V12, REG_V13, 33, INS_OPTS_2D); + theEmitter->emitIns_R_R_I(INS_shl, EA_16BYTE, REG_V12, REG_V13, 32, INS_OPTS_2D); theEmitter->emitIns_R_R_I(INS_shl, EA_16BYTE, REG_V14, REG_V15, 63, INS_OPTS_2D); - // 'ushr' scalar + // ushr scalar theEmitter->emitIns_R_R_I(INS_ushr, EA_8BYTE, REG_V0, REG_V1, 1); theEmitter->emitIns_R_R_I(INS_ushr, EA_8BYTE, REG_V2, REG_V3, 14); theEmitter->emitIns_R_R_I(INS_ushr, EA_8BYTE, REG_V4, REG_V5, 27); theEmitter->emitIns_R_R_I(INS_ushr, EA_8BYTE, REG_V6, REG_V7, 40); - theEmitter->emitIns_R_R_I(INS_ushr, EA_8BYTE, REG_V8, REG_V9, 63); + theEmitter->emitIns_R_R_I(INS_ushr, EA_8BYTE, REG_V8, REG_V9, 64); - // 'ushr' vector + // ushr vector theEmitter->emitIns_R_R_I(INS_ushr, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); - theEmitter->emitIns_R_R_I(INS_ushr, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_ushr, EA_16BYTE, REG_V2, REG_V3, 8, INS_OPTS_16B); theEmitter->emitIns_R_R_I(INS_ushr, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); - theEmitter->emitIns_R_R_I(INS_ushr, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_ushr, EA_16BYTE, REG_V6, REG_V7, 16, INS_OPTS_8H); theEmitter->emitIns_R_R_I(INS_ushr, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); - theEmitter->emitIns_R_R_I(INS_ushr, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_ushr, EA_16BYTE, REG_V10, REG_V11, 32, INS_OPTS_4S); theEmitter->emitIns_R_R_I(INS_ushr, EA_16BYTE, REG_V12, REG_V13, 33, INS_OPTS_2D); - theEmitter->emitIns_R_R_I(INS_ushr, EA_16BYTE, REG_V14, REG_V15, 63, INS_OPTS_2D); + theEmitter->emitIns_R_R_I(INS_ushr, EA_16BYTE, REG_V14, REG_V15, 64, INS_OPTS_2D); - // 'usra' scalar + // usra scalar theEmitter->emitIns_R_R_I(INS_usra, EA_8BYTE, REG_V0, REG_V1, 1); theEmitter->emitIns_R_R_I(INS_usra, EA_8BYTE, REG_V2, REG_V3, 14); theEmitter->emitIns_R_R_I(INS_usra, EA_8BYTE, REG_V4, REG_V5, 27); theEmitter->emitIns_R_R_I(INS_usra, EA_8BYTE, REG_V6, REG_V7, 40); - theEmitter->emitIns_R_R_I(INS_usra, EA_8BYTE, REG_V8, REG_V9, 63); + theEmitter->emitIns_R_R_I(INS_usra, EA_8BYTE, REG_V8, REG_V9, 64); - // 'usra' vector + // usra vector theEmitter->emitIns_R_R_I(INS_usra, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); - theEmitter->emitIns_R_R_I(INS_usra, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_usra, EA_16BYTE, REG_V2, REG_V3, 8, INS_OPTS_16B); theEmitter->emitIns_R_R_I(INS_usra, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); - theEmitter->emitIns_R_R_I(INS_usra, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_usra, EA_16BYTE, REG_V6, REG_V7, 16, INS_OPTS_8H); theEmitter->emitIns_R_R_I(INS_usra, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); - theEmitter->emitIns_R_R_I(INS_usra, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_usra, EA_16BYTE, REG_V10, REG_V11, 32, INS_OPTS_4S); theEmitter->emitIns_R_R_I(INS_usra, EA_16BYTE, REG_V12, REG_V13, 33, INS_OPTS_2D); - theEmitter->emitIns_R_R_I(INS_usra, EA_16BYTE, REG_V14, REG_V15, 63, INS_OPTS_2D); + theEmitter->emitIns_R_R_I(INS_usra, EA_16BYTE, REG_V14, REG_V15, 64, INS_OPTS_2D); - // 'urshr' scalar + // urshr scalar theEmitter->emitIns_R_R_I(INS_urshr, EA_8BYTE, REG_V0, REG_V1, 1); theEmitter->emitIns_R_R_I(INS_urshr, EA_8BYTE, REG_V2, REG_V3, 14); theEmitter->emitIns_R_R_I(INS_urshr, EA_8BYTE, REG_V4, REG_V5, 27); theEmitter->emitIns_R_R_I(INS_urshr, EA_8BYTE, REG_V6, REG_V7, 40); - theEmitter->emitIns_R_R_I(INS_urshr, EA_8BYTE, REG_V8, REG_V9, 63); + theEmitter->emitIns_R_R_I(INS_urshr, EA_8BYTE, REG_V8, REG_V9, 64); - // 'urshr' vector + // urshr vector theEmitter->emitIns_R_R_I(INS_urshr, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); - theEmitter->emitIns_R_R_I(INS_urshr, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_urshr, EA_16BYTE, REG_V2, REG_V3, 8, INS_OPTS_16B); theEmitter->emitIns_R_R_I(INS_urshr, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); - theEmitter->emitIns_R_R_I(INS_urshr, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_urshr, EA_16BYTE, REG_V6, REG_V7, 16, INS_OPTS_8H); theEmitter->emitIns_R_R_I(INS_urshr, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); - theEmitter->emitIns_R_R_I(INS_urshr, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_urshr, EA_16BYTE, REG_V10, REG_V11, 32, INS_OPTS_4S); theEmitter->emitIns_R_R_I(INS_urshr, EA_16BYTE, REG_V12, REG_V13, 33, INS_OPTS_2D); - theEmitter->emitIns_R_R_I(INS_urshr, EA_16BYTE, REG_V14, REG_V15, 63, INS_OPTS_2D); + theEmitter->emitIns_R_R_I(INS_urshr, EA_16BYTE, REG_V14, REG_V15, 64, INS_OPTS_2D); - // 'ursra' scalar + // ursra scalar theEmitter->emitIns_R_R_I(INS_ursra, EA_8BYTE, REG_V0, REG_V1, 1); theEmitter->emitIns_R_R_I(INS_ursra, EA_8BYTE, REG_V2, REG_V3, 14); theEmitter->emitIns_R_R_I(INS_ursra, EA_8BYTE, REG_V4, REG_V5, 27); theEmitter->emitIns_R_R_I(INS_ursra, EA_8BYTE, REG_V6, REG_V7, 40); - theEmitter->emitIns_R_R_I(INS_ursra, EA_8BYTE, REG_V8, REG_V9, 63); + theEmitter->emitIns_R_R_I(INS_ursra, EA_8BYTE, REG_V8, REG_V9, 64); - // 'srsra' vector + // ursra vector theEmitter->emitIns_R_R_I(INS_ursra, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); - theEmitter->emitIns_R_R_I(INS_ursra, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_ursra, EA_16BYTE, REG_V2, REG_V3, 8, INS_OPTS_16B); theEmitter->emitIns_R_R_I(INS_ursra, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); - theEmitter->emitIns_R_R_I(INS_ursra, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_ursra, EA_16BYTE, REG_V6, REG_V7, 16, INS_OPTS_8H); theEmitter->emitIns_R_R_I(INS_ursra, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); - theEmitter->emitIns_R_R_I(INS_ursra, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_ursra, EA_16BYTE, REG_V10, REG_V11, 32, INS_OPTS_4S); theEmitter->emitIns_R_R_I(INS_ursra, EA_16BYTE, REG_V12, REG_V13, 33, INS_OPTS_2D); - theEmitter->emitIns_R_R_I(INS_ursra, EA_16BYTE, REG_V14, REG_V15, 63, INS_OPTS_2D); + theEmitter->emitIns_R_R_I(INS_ursra, EA_16BYTE, REG_V14, REG_V15, 64, INS_OPTS_2D); - // 'sri' scalar + // sri scalar theEmitter->emitIns_R_R_I(INS_sri, EA_8BYTE, REG_V0, REG_V1, 1); theEmitter->emitIns_R_R_I(INS_sri, EA_8BYTE, REG_V2, REG_V3, 14); theEmitter->emitIns_R_R_I(INS_sri, EA_8BYTE, REG_V4, REG_V5, 27); theEmitter->emitIns_R_R_I(INS_sri, EA_8BYTE, REG_V6, REG_V7, 40); - theEmitter->emitIns_R_R_I(INS_sri, EA_8BYTE, REG_V8, REG_V9, 63); + theEmitter->emitIns_R_R_I(INS_sri, EA_8BYTE, REG_V8, REG_V9, 64); - // 'sri' vector + // sri vector theEmitter->emitIns_R_R_I(INS_sri, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); - theEmitter->emitIns_R_R_I(INS_sri, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_sri, EA_16BYTE, REG_V2, REG_V3, 8, INS_OPTS_16B); theEmitter->emitIns_R_R_I(INS_sri, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); - theEmitter->emitIns_R_R_I(INS_sri, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_sri, EA_16BYTE, REG_V6, REG_V7, 16, INS_OPTS_8H); theEmitter->emitIns_R_R_I(INS_sri, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); - theEmitter->emitIns_R_R_I(INS_sri, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_sri, EA_16BYTE, REG_V10, REG_V11, 32, INS_OPTS_4S); theEmitter->emitIns_R_R_I(INS_sri, EA_16BYTE, REG_V12, REG_V13, 33, INS_OPTS_2D); - theEmitter->emitIns_R_R_I(INS_sri, EA_16BYTE, REG_V14, REG_V15, 63, INS_OPTS_2D); + theEmitter->emitIns_R_R_I(INS_sri, EA_16BYTE, REG_V14, REG_V15, 64, INS_OPTS_2D); - // 'sli' scalar - theEmitter->emitIns_R_R_I(INS_sli, EA_8BYTE, REG_V0, REG_V1, 1); + // sli scalar + theEmitter->emitIns_R_R_I(INS_sli, EA_8BYTE, REG_V0, REG_V1, 0); theEmitter->emitIns_R_R_I(INS_sli, EA_8BYTE, REG_V2, REG_V3, 14); theEmitter->emitIns_R_R_I(INS_sli, EA_8BYTE, REG_V4, REG_V5, 27); theEmitter->emitIns_R_R_I(INS_sli, EA_8BYTE, REG_V6, REG_V7, 40); theEmitter->emitIns_R_R_I(INS_sli, EA_8BYTE, REG_V8, REG_V9, 63); - // 'sli' vector - theEmitter->emitIns_R_R_I(INS_sli, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); + // sli vector + theEmitter->emitIns_R_R_I(INS_sli, EA_8BYTE, REG_V0, REG_V1, 0, INS_OPTS_8B); theEmitter->emitIns_R_R_I(INS_sli, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); - theEmitter->emitIns_R_R_I(INS_sli, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_sli, EA_8BYTE, REG_V4, REG_V5, 8, INS_OPTS_4H); theEmitter->emitIns_R_R_I(INS_sli, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); - theEmitter->emitIns_R_R_I(INS_sli, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_sli, EA_8BYTE, REG_V8, REG_V9, 16, INS_OPTS_2S); theEmitter->emitIns_R_R_I(INS_sli, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); - theEmitter->emitIns_R_R_I(INS_sli, EA_16BYTE, REG_V12, REG_V13, 33, INS_OPTS_2D); + theEmitter->emitIns_R_R_I(INS_sli, EA_16BYTE, REG_V12, REG_V13, 32, INS_OPTS_2D); theEmitter->emitIns_R_R_I(INS_sli, EA_16BYTE, REG_V14, REG_V15, 63, INS_OPTS_2D); - // 'sshll' vector + // sshll{2} vector theEmitter->emitIns_R_R_I(INS_sshll, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); theEmitter->emitIns_R_R_I(INS_sshll2, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); theEmitter->emitIns_R_R_I(INS_sshll, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); @@ -8385,7 +8379,7 @@ void CodeGen::genArm64EmitterUnitTests() theEmitter->emitIns_R_R_I(INS_sshll, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); theEmitter->emitIns_R_R_I(INS_sshll2, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); - // 'ushll' vector + // ushll{2} vector theEmitter->emitIns_R_R_I(INS_ushll, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); theEmitter->emitIns_R_R_I(INS_ushll2, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); theEmitter->emitIns_R_R_I(INS_ushll, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); @@ -8393,23 +8387,23 @@ void CodeGen::genArm64EmitterUnitTests() theEmitter->emitIns_R_R_I(INS_ushll, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); theEmitter->emitIns_R_R_I(INS_ushll2, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); - // 'shrn' vector + // shrn{2} vector theEmitter->emitIns_R_R_I(INS_shrn, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); - theEmitter->emitIns_R_R_I(INS_shrn2, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_shrn2, EA_16BYTE, REG_V2, REG_V3, 8, INS_OPTS_16B); theEmitter->emitIns_R_R_I(INS_shrn, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); - theEmitter->emitIns_R_R_I(INS_shrn2, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_shrn2, EA_16BYTE, REG_V6, REG_V7, 16, INS_OPTS_8H); theEmitter->emitIns_R_R_I(INS_shrn, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); - theEmitter->emitIns_R_R_I(INS_shrn2, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_shrn2, EA_16BYTE, REG_V10, REG_V11, 32, INS_OPTS_4S); - // 'rshrn' vector + // rshrn{2} vector theEmitter->emitIns_R_R_I(INS_rshrn, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); - theEmitter->emitIns_R_R_I(INS_rshrn2, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_rshrn2, EA_16BYTE, REG_V2, REG_V3, 8, INS_OPTS_16B); theEmitter->emitIns_R_R_I(INS_rshrn, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); - theEmitter->emitIns_R_R_I(INS_rshrn2, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_rshrn2, EA_16BYTE, REG_V6, REG_V7, 16, INS_OPTS_8H); theEmitter->emitIns_R_R_I(INS_rshrn, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); - theEmitter->emitIns_R_R_I(INS_rshrn2, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_rshrn2, EA_16BYTE, REG_V10, REG_V11, 32, INS_OPTS_4S); - // 'sxtl' vector + // sxtl{2} vector theEmitter->emitIns_R_R(INS_sxtl, EA_8BYTE, REG_V0, REG_V1, INS_OPTS_8B); theEmitter->emitIns_R_R(INS_sxtl2, EA_16BYTE, REG_V2, REG_V3, INS_OPTS_16B); theEmitter->emitIns_R_R(INS_sxtl, EA_8BYTE, REG_V4, REG_V5, INS_OPTS_4H); @@ -8417,7 +8411,7 @@ void CodeGen::genArm64EmitterUnitTests() theEmitter->emitIns_R_R(INS_sxtl, EA_8BYTE, REG_V8, REG_V9, INS_OPTS_2S); theEmitter->emitIns_R_R(INS_sxtl2, EA_16BYTE, REG_V10, REG_V11, INS_OPTS_4S); - // 'uxtl' vector + // uxtl{2} vector theEmitter->emitIns_R_R(INS_uxtl, EA_8BYTE, REG_V0, REG_V1, INS_OPTS_8B); theEmitter->emitIns_R_R(INS_uxtl2, EA_16BYTE, REG_V2, REG_V3, INS_OPTS_16B); theEmitter->emitIns_R_R(INS_uxtl, EA_8BYTE, REG_V4, REG_V5, INS_OPTS_4H); @@ -8425,6 +8419,195 @@ void CodeGen::genArm64EmitterUnitTests() theEmitter->emitIns_R_R(INS_uxtl, EA_8BYTE, REG_V8, REG_V9, INS_OPTS_2S); theEmitter->emitIns_R_R(INS_uxtl2, EA_16BYTE, REG_V10, REG_V11, INS_OPTS_4S); + // sqrshrn scalar + theEmitter->emitIns_R_R_I(INS_sqrshrn, EA_1BYTE, REG_V0, REG_V1, 1, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqrshrn, EA_1BYTE, REG_V2, REG_V3, 8, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqrshrn, EA_2BYTE, REG_V4, REG_V5, 9, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqrshrn, EA_2BYTE, REG_V6, REG_V7, 16, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqrshrn, EA_4BYTE, REG_V8, REG_V9, 17, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqrshrn, EA_4BYTE, REG_V10, REG_V11, 32, INS_OPTS_NONE); + + // sqrshrn{2} vector + theEmitter->emitIns_R_R_I(INS_sqrshrn, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_sqrshrn, EA_8BYTE, REG_V2, REG_V3, 8, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_sqrshrn2, EA_16BYTE, REG_V4, REG_V5, 1, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_sqrshrn2, EA_16BYTE, REG_V6, REG_V7, 8, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_sqrshrn, EA_8BYTE, REG_V8, REG_V9, 9, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_sqrshrn, EA_8BYTE, REG_V10, REG_V11, 16, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_sqrshrn2, EA_16BYTE, REG_V12, REG_V13, 9, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_sqrshrn2, EA_16BYTE, REG_V14, REG_V15, 16, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_sqrshrn, EA_8BYTE, REG_V16, REG_V17, 17, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_sqrshrn, EA_8BYTE, REG_V18, REG_V18, 32, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_sqrshrn2, EA_16BYTE, REG_V20, REG_V21, 17, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_sqrshrn2, EA_16BYTE, REG_V22, REG_V23, 32, INS_OPTS_4S); + + // sqrshrun scalar + theEmitter->emitIns_R_R_I(INS_sqrshrun, EA_1BYTE, REG_V0, REG_V1, 1, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqrshrun, EA_1BYTE, REG_V0, REG_V1, 8, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqrshrun, EA_2BYTE, REG_V2, REG_V3, 9, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqrshrun, EA_2BYTE, REG_V2, REG_V3, 16, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqrshrun, EA_4BYTE, REG_V4, REG_V5, 17, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqrshrun, EA_4BYTE, REG_V4, REG_V5, 32, INS_OPTS_NONE); + + // sqrshrun{2} vector + theEmitter->emitIns_R_R_I(INS_sqrshrun, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_sqrshrun, EA_8BYTE, REG_V2, REG_V3, 8, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_sqrshrun2, EA_16BYTE, REG_V4, REG_V5, 1, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_sqrshrun2, EA_16BYTE, REG_V6, REG_V7, 8, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_sqrshrun, EA_8BYTE, REG_V8, REG_V9, 9, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_sqrshrun, EA_8BYTE, REG_V10, REG_V11, 16, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_sqrshrun2, EA_16BYTE, REG_V12, REG_V13, 9, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_sqrshrun2, EA_16BYTE, REG_V14, REG_V15, 16, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_sqrshrun, EA_8BYTE, REG_V16, REG_V17, 17, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_sqrshrun, EA_8BYTE, REG_V18, REG_V18, 32, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_sqrshrun2, EA_16BYTE, REG_V20, REG_V21, 17, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_sqrshrun2, EA_16BYTE, REG_V22, REG_V23, 32, INS_OPTS_4S); + + // sqshl scalar + theEmitter->emitIns_R_R_I(INS_sqshl, EA_1BYTE, REG_V0, REG_V1, 0, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshl, EA_1BYTE, REG_V2, REG_V3, 7, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshl, EA_2BYTE, REG_V4, REG_V5, 8, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshl, EA_2BYTE, REG_V6, REG_V7, 15, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshl, EA_4BYTE, REG_V8, REG_V9, 16, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshl, EA_4BYTE, REG_V10, REG_V11, 31, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshl, EA_8BYTE, REG_V12, REG_V13, 32, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshl, EA_8BYTE, REG_V14, REG_V15, 63, INS_OPTS_NONE); + + // sqshl vector + theEmitter->emitIns_R_R_I(INS_sqshl, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_sqshl, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_sqshl, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_sqshl, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_sqshl, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_sqshl, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_sqshl, EA_16BYTE, REG_V12, REG_V13, 63, INS_OPTS_2D); + + // sqshlu scalar + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_1BYTE, REG_V0, REG_V1, 0, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_1BYTE, REG_V2, REG_V3, 7, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_2BYTE, REG_V4, REG_V5, 8, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_2BYTE, REG_V6, REG_V7, 15, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_4BYTE, REG_V8, REG_V9, 16, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_4BYTE, REG_V10, REG_V11, 31, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_8BYTE, REG_V12, REG_V13, 32, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_8BYTE, REG_V14, REG_V15, 63, INS_OPTS_NONE); + + // sqshlu vector + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_sqshlu, EA_16BYTE, REG_V12, REG_V13, 63, INS_OPTS_2D); + + // sqshrn scalar + theEmitter->emitIns_R_R_I(INS_sqshrn, EA_1BYTE, REG_V0, REG_V1, 1, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshrn, EA_1BYTE, REG_V2, REG_V3, 8, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshrn, EA_2BYTE, REG_V4, REG_V5, 9, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshrn, EA_2BYTE, REG_V6, REG_V7, 16, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshrn, EA_4BYTE, REG_V8, REG_V9, 17, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshrn, EA_4BYTE, REG_V10, REG_V11, 32, INS_OPTS_NONE); + + // sqshrn{2} vector + theEmitter->emitIns_R_R_I(INS_sqshrn, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_sqshrn, EA_8BYTE, REG_V2, REG_V3, 8, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_sqshrn2, EA_16BYTE, REG_V4, REG_V5, 1, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_sqshrn2, EA_16BYTE, REG_V6, REG_V7, 8, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_sqshrn, EA_8BYTE, REG_V8, REG_V9, 9, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_sqshrn, EA_8BYTE, REG_V10, REG_V11, 16, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_sqshrn2, EA_16BYTE, REG_V12, REG_V13, 9, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_sqshrn2, EA_16BYTE, REG_V14, REG_V15, 16, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_sqshrn, EA_8BYTE, REG_V16, REG_V17, 17, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_sqshrn, EA_8BYTE, REG_V18, REG_V18, 32, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_sqshrn2, EA_16BYTE, REG_V20, REG_V21, 17, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_sqshrn2, EA_16BYTE, REG_V22, REG_V23, 32, INS_OPTS_4S); + + // sqshrun scalar + theEmitter->emitIns_R_R_I(INS_sqshrun, EA_1BYTE, REG_V0, REG_V1, 1, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshrun, EA_1BYTE, REG_V2, REG_V3, 8, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshrun, EA_2BYTE, REG_V4, REG_V5, 9, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshrun, EA_2BYTE, REG_V6, REG_V7, 16, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshrun, EA_4BYTE, REG_V8, REG_V9, 17, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_sqshrun, EA_4BYTE, REG_V10, REG_V11, 32, INS_OPTS_NONE); + + // sqshrun{2} vector + theEmitter->emitIns_R_R_I(INS_sqshrun, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_sqshrun, EA_8BYTE, REG_V2, REG_V3, 8, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_sqshrun2, EA_16BYTE, REG_V4, REG_V5, 1, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_sqshrun2, EA_16BYTE, REG_V6, REG_V7, 8, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_sqshrun, EA_8BYTE, REG_V8, REG_V9, 9, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_sqshrun, EA_8BYTE, REG_V10, REG_V11, 16, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_sqshrun2, EA_16BYTE, REG_V12, REG_V13, 9, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_sqshrun2, EA_16BYTE, REG_V14, REG_V15, 16, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_sqshrun, EA_8BYTE, REG_V16, REG_V17, 17, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_sqshrun, EA_8BYTE, REG_V18, REG_V18, 32, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_sqshrun2, EA_16BYTE, REG_V20, REG_V21, 17, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_sqshrun2, EA_16BYTE, REG_V22, REG_V23, 32, INS_OPTS_4S); + + // uqrshrn scalar + theEmitter->emitIns_R_R_I(INS_uqrshrn, EA_1BYTE, REG_V0, REG_V1, 1, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqrshrn, EA_1BYTE, REG_V2, REG_V3, 8, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqrshrn, EA_2BYTE, REG_V4, REG_V5, 9, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqrshrn, EA_2BYTE, REG_V6, REG_V7, 16, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqrshrn, EA_4BYTE, REG_V8, REG_V9, 17, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqrshrn, EA_4BYTE, REG_V10, REG_V11, 32, INS_OPTS_NONE); + + // uqrshrn{2} vector + theEmitter->emitIns_R_R_I(INS_uqrshrn, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_uqrshrn, EA_8BYTE, REG_V2, REG_V3, 8, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_uqrshrn2, EA_16BYTE, REG_V4, REG_V5, 1, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_uqrshrn2, EA_16BYTE, REG_V6, REG_V7, 8, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_uqrshrn, EA_8BYTE, REG_V8, REG_V9, 9, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_uqrshrn, EA_8BYTE, REG_V10, REG_V11, 16, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_uqrshrn2, EA_16BYTE, REG_V12, REG_V13, 9, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_uqrshrn2, EA_16BYTE, REG_V14, REG_V15, 16, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_uqrshrn, EA_8BYTE, REG_V16, REG_V17, 17, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_uqrshrn, EA_8BYTE, REG_V18, REG_V18, 32, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_uqrshrn2, EA_16BYTE, REG_V20, REG_V21, 17, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_uqrshrn2, EA_16BYTE, REG_V22, REG_V23, 32, INS_OPTS_4S); + + // uqshl scalar + theEmitter->emitIns_R_R_I(INS_uqshl, EA_1BYTE, REG_V0, REG_V1, 0, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqshl, EA_1BYTE, REG_V2, REG_V3, 7, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqshl, EA_2BYTE, REG_V4, REG_V5, 8, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqshl, EA_2BYTE, REG_V6, REG_V7, 15, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqshl, EA_4BYTE, REG_V8, REG_V9, 16, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqshl, EA_4BYTE, REG_V10, REG_V11, 31, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqshl, EA_8BYTE, REG_V12, REG_V13, 32, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqshl, EA_8BYTE, REG_V14, REG_V15, 63, INS_OPTS_NONE); + + // uqshl vector + theEmitter->emitIns_R_R_I(INS_uqshl, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_uqshl, EA_16BYTE, REG_V2, REG_V3, 7, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_uqshl, EA_8BYTE, REG_V4, REG_V5, 9, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_uqshl, EA_16BYTE, REG_V6, REG_V7, 15, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_uqshl, EA_8BYTE, REG_V8, REG_V9, 17, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_uqshl, EA_16BYTE, REG_V10, REG_V11, 31, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_uqshl, EA_16BYTE, REG_V12, REG_V13, 63, INS_OPTS_2D); + + // uqshrn scalar + theEmitter->emitIns_R_R_I(INS_uqshrn, EA_1BYTE, REG_V0, REG_V1, 1, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqshrn, EA_1BYTE, REG_V2, REG_V3, 8, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqshrn, EA_2BYTE, REG_V4, REG_V5, 9, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqshrn, EA_2BYTE, REG_V6, REG_V7, 16, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqshrn, EA_4BYTE, REG_V8, REG_V9, 17, INS_OPTS_NONE); + theEmitter->emitIns_R_R_I(INS_uqshrn, EA_4BYTE, REG_V10, REG_V11, 32, INS_OPTS_NONE); + + // uqshrn{2} vector + theEmitter->emitIns_R_R_I(INS_uqshrn, EA_8BYTE, REG_V0, REG_V1, 1, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_uqshrn, EA_8BYTE, REG_V2, REG_V3, 8, INS_OPTS_8B); + theEmitter->emitIns_R_R_I(INS_uqshrn2, EA_16BYTE, REG_V4, REG_V5, 1, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_uqshrn2, EA_16BYTE, REG_V6, REG_V7, 8, INS_OPTS_16B); + theEmitter->emitIns_R_R_I(INS_uqshrn, EA_8BYTE, REG_V8, REG_V9, 9, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_uqshrn, EA_8BYTE, REG_V10, REG_V11, 16, INS_OPTS_4H); + theEmitter->emitIns_R_R_I(INS_uqshrn2, EA_16BYTE, REG_V12, REG_V13, 9, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_uqshrn2, EA_16BYTE, REG_V14, REG_V15, 16, INS_OPTS_8H); + theEmitter->emitIns_R_R_I(INS_uqshrn, EA_8BYTE, REG_V16, REG_V17, 17, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_uqshrn, EA_8BYTE, REG_V18, REG_V18, 32, INS_OPTS_2S); + theEmitter->emitIns_R_R_I(INS_uqshrn2, EA_16BYTE, REG_V20, REG_V21, 17, INS_OPTS_4S); + theEmitter->emitIns_R_R_I(INS_uqshrn2, EA_16BYTE, REG_V22, REG_V23, 32, INS_OPTS_4S); + #endif // ALL_ARM64_EMITTER_UNIT_TESTS #ifdef ALL_ARM64_EMITTER_UNIT_TESTS @@ -8738,6 +8921,54 @@ void CodeGen::genArm64EmitterUnitTests() #endif // ALL_ARM64_EMITTER_UNIT_TESTS #ifdef ALL_ARM64_EMITTER_UNIT_TESTS + // srshl scalar + theEmitter->emitIns_R_R_R(INS_srshl, EA_8BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_NONE); + + // srshl vector + theEmitter->emitIns_R_R_R(INS_srshl, EA_8BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_8B); + theEmitter->emitIns_R_R_R(INS_srshl, EA_16BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_srshl, EA_8BYTE, REG_V6, REG_V7, REG_V8, INS_OPTS_4H); + theEmitter->emitIns_R_R_R(INS_srshl, EA_16BYTE, REG_V9, REG_V10, REG_V11, INS_OPTS_8H); + theEmitter->emitIns_R_R_R(INS_srshl, EA_8BYTE, REG_V12, REG_V13, REG_V14, INS_OPTS_2S); + theEmitter->emitIns_R_R_R(INS_srshl, EA_16BYTE, REG_V15, REG_V16, REG_V17, INS_OPTS_4S); + theEmitter->emitIns_R_R_R(INS_srshl, EA_16BYTE, REG_V18, REG_V19, REG_V20, INS_OPTS_2D); + + // sshl scalar + theEmitter->emitIns_R_R_R(INS_sshl, EA_8BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_NONE); + + // sshl vector + theEmitter->emitIns_R_R_R(INS_sshl, EA_8BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_8B); + theEmitter->emitIns_R_R_R(INS_sshl, EA_16BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_sshl, EA_8BYTE, REG_V6, REG_V7, REG_V8, INS_OPTS_4H); + theEmitter->emitIns_R_R_R(INS_sshl, EA_16BYTE, REG_V9, REG_V10, REG_V11, INS_OPTS_8H); + theEmitter->emitIns_R_R_R(INS_sshl, EA_8BYTE, REG_V12, REG_V13, REG_V14, INS_OPTS_2S); + theEmitter->emitIns_R_R_R(INS_sshl, EA_16BYTE, REG_V15, REG_V16, REG_V17, INS_OPTS_4S); + theEmitter->emitIns_R_R_R(INS_sshl, EA_16BYTE, REG_V18, REG_V19, REG_V20, INS_OPTS_2D); + + // urshl scalar + theEmitter->emitIns_R_R_R(INS_urshl, EA_8BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_NONE); + + // urshl vector + theEmitter->emitIns_R_R_R(INS_urshl, EA_8BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_8B); + theEmitter->emitIns_R_R_R(INS_urshl, EA_16BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_urshl, EA_8BYTE, REG_V6, REG_V7, REG_V8, INS_OPTS_4H); + theEmitter->emitIns_R_R_R(INS_urshl, EA_16BYTE, REG_V9, REG_V10, REG_V11, INS_OPTS_8H); + theEmitter->emitIns_R_R_R(INS_urshl, EA_8BYTE, REG_V12, REG_V13, REG_V14, INS_OPTS_2S); + theEmitter->emitIns_R_R_R(INS_urshl, EA_16BYTE, REG_V15, REG_V16, REG_V17, INS_OPTS_4S); + theEmitter->emitIns_R_R_R(INS_urshl, EA_16BYTE, REG_V18, REG_V19, REG_V20, INS_OPTS_2D); + + // ushl scalar + theEmitter->emitIns_R_R_R(INS_ushl, EA_8BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_NONE); + + // ushl vector + theEmitter->emitIns_R_R_R(INS_ushl, EA_8BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_8B); + theEmitter->emitIns_R_R_R(INS_ushl, EA_16BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_ushl, EA_8BYTE, REG_V6, REG_V7, REG_V8, INS_OPTS_4H); + theEmitter->emitIns_R_R_R(INS_ushl, EA_16BYTE, REG_V9, REG_V10, REG_V11, INS_OPTS_8H); + theEmitter->emitIns_R_R_R(INS_ushl, EA_8BYTE, REG_V12, REG_V13, REG_V14, INS_OPTS_2S); + theEmitter->emitIns_R_R_R(INS_ushl, EA_16BYTE, REG_V15, REG_V16, REG_V17, INS_OPTS_4S); + theEmitter->emitIns_R_R_R(INS_ushl, EA_16BYTE, REG_V18, REG_V19, REG_V20, INS_OPTS_2D); + // addhn vector theEmitter->emitIns_R_R_R(INS_addhn, EA_8BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_8B); theEmitter->emitIns_R_R_R(INS_addhn, EA_8BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_4H); @@ -8838,6 +9069,36 @@ void CodeGen::genArm64EmitterUnitTests() theEmitter->emitIns_R_R_R(INS_sqadd, EA_16BYTE, REG_V12, REG_V13, REG_V14, INS_OPTS_8H); theEmitter->emitIns_R_R_R(INS_sqadd, EA_16BYTE, REG_V15, REG_V16, REG_V17, INS_OPTS_4S); + // sqrshl scalar + theEmitter->emitIns_R_R_R(INS_sqrshl, EA_1BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_NONE); + theEmitter->emitIns_R_R_R(INS_sqrshl, EA_2BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_NONE); + theEmitter->emitIns_R_R_R(INS_sqrshl, EA_4BYTE, REG_V6, REG_V7, REG_V8, INS_OPTS_NONE); + theEmitter->emitIns_R_R_R(INS_sqrshl, EA_8BYTE, REG_V9, REG_V10, REG_V11, INS_OPTS_NONE); + + // sqrshl vector + theEmitter->emitIns_R_R_R(INS_sqrshl, EA_8BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_8B); + theEmitter->emitIns_R_R_R(INS_sqrshl, EA_8BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_4H); + theEmitter->emitIns_R_R_R(INS_sqrshl, EA_8BYTE, REG_V6, REG_V7, REG_V8, INS_OPTS_2S); + theEmitter->emitIns_R_R_R(INS_sqrshl, EA_16BYTE, REG_V9, REG_V10, REG_V11, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_sqrshl, EA_16BYTE, REG_V12, REG_V13, REG_V14, INS_OPTS_8H); + theEmitter->emitIns_R_R_R(INS_sqrshl, EA_16BYTE, REG_V15, REG_V16, REG_V17, INS_OPTS_4S); + theEmitter->emitIns_R_R_R(INS_sqrshl, EA_16BYTE, REG_V18, REG_V19, REG_V20, INS_OPTS_2D); + + // sqshl scalar + theEmitter->emitIns_R_R_R(INS_sqshl, EA_1BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_NONE); + theEmitter->emitIns_R_R_R(INS_sqshl, EA_2BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_NONE); + theEmitter->emitIns_R_R_R(INS_sqshl, EA_4BYTE, REG_V6, REG_V7, REG_V8, INS_OPTS_NONE); + theEmitter->emitIns_R_R_R(INS_sqshl, EA_8BYTE, REG_V9, REG_V10, REG_V11, INS_OPTS_NONE); + + // sqshl vector + theEmitter->emitIns_R_R_R(INS_sqshl, EA_8BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_8B); + theEmitter->emitIns_R_R_R(INS_sqshl, EA_8BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_4H); + theEmitter->emitIns_R_R_R(INS_sqshl, EA_8BYTE, REG_V6, REG_V7, REG_V8, INS_OPTS_2S); + theEmitter->emitIns_R_R_R(INS_sqshl, EA_16BYTE, REG_V9, REG_V10, REG_V11, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_sqshl, EA_16BYTE, REG_V12, REG_V13, REG_V14, INS_OPTS_8H); + theEmitter->emitIns_R_R_R(INS_sqshl, EA_16BYTE, REG_V15, REG_V16, REG_V17, INS_OPTS_4S); + theEmitter->emitIns_R_R_R(INS_sqshl, EA_16BYTE, REG_V18, REG_V19, REG_V20, INS_OPTS_2D); + // sqsub scalar theEmitter->emitIns_R_R_R(INS_sqsub, EA_1BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_NONE); theEmitter->emitIns_R_R_R(INS_sqsub, EA_2BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_NONE); @@ -8960,6 +9221,36 @@ void CodeGen::genArm64EmitterUnitTests() theEmitter->emitIns_R_R_R(INS_uqadd, EA_16BYTE, REG_V12, REG_V13, REG_V14, INS_OPTS_8H); theEmitter->emitIns_R_R_R(INS_uqadd, EA_16BYTE, REG_V15, REG_V16, REG_V17, INS_OPTS_4S); + // uqrshl scalar + theEmitter->emitIns_R_R_R(INS_uqrshl, EA_1BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_NONE); + theEmitter->emitIns_R_R_R(INS_uqrshl, EA_2BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_NONE); + theEmitter->emitIns_R_R_R(INS_uqrshl, EA_4BYTE, REG_V6, REG_V7, REG_V8, INS_OPTS_NONE); + theEmitter->emitIns_R_R_R(INS_uqrshl, EA_8BYTE, REG_V9, REG_V10, REG_V11, INS_OPTS_NONE); + + // uqrshl vector + theEmitter->emitIns_R_R_R(INS_uqrshl, EA_8BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_8B); + theEmitter->emitIns_R_R_R(INS_uqrshl, EA_8BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_4H); + theEmitter->emitIns_R_R_R(INS_uqrshl, EA_8BYTE, REG_V6, REG_V7, REG_V8, INS_OPTS_2S); + theEmitter->emitIns_R_R_R(INS_uqrshl, EA_16BYTE, REG_V9, REG_V10, REG_V11, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_uqrshl, EA_16BYTE, REG_V12, REG_V13, REG_V14, INS_OPTS_8H); + theEmitter->emitIns_R_R_R(INS_uqrshl, EA_16BYTE, REG_V15, REG_V16, REG_V17, INS_OPTS_4S); + theEmitter->emitIns_R_R_R(INS_uqrshl, EA_16BYTE, REG_V18, REG_V19, REG_V20, INS_OPTS_2D); + + // uqshl scalar + theEmitter->emitIns_R_R_R(INS_uqshl, EA_1BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_NONE); + theEmitter->emitIns_R_R_R(INS_uqshl, EA_2BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_NONE); + theEmitter->emitIns_R_R_R(INS_uqshl, EA_4BYTE, REG_V6, REG_V7, REG_V8, INS_OPTS_NONE); + theEmitter->emitIns_R_R_R(INS_uqshl, EA_8BYTE, REG_V9, REG_V10, REG_V11, INS_OPTS_NONE); + + // uqshl vector + theEmitter->emitIns_R_R_R(INS_uqshl, EA_8BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_8B); + theEmitter->emitIns_R_R_R(INS_uqshl, EA_8BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_4H); + theEmitter->emitIns_R_R_R(INS_uqshl, EA_8BYTE, REG_V6, REG_V7, REG_V8, INS_OPTS_2S); + theEmitter->emitIns_R_R_R(INS_uqshl, EA_16BYTE, REG_V9, REG_V10, REG_V11, INS_OPTS_16B); + theEmitter->emitIns_R_R_R(INS_uqshl, EA_16BYTE, REG_V12, REG_V13, REG_V14, INS_OPTS_8H); + theEmitter->emitIns_R_R_R(INS_uqshl, EA_16BYTE, REG_V15, REG_V16, REG_V17, INS_OPTS_4S); + theEmitter->emitIns_R_R_R(INS_uqshl, EA_16BYTE, REG_V18, REG_V19, REG_V20, INS_OPTS_2D); + // uqsub scalar theEmitter->emitIns_R_R_R(INS_uqsub, EA_1BYTE, REG_V0, REG_V1, REG_V2, INS_OPTS_NONE); theEmitter->emitIns_R_R_R(INS_uqsub, EA_2BYTE, REG_V3, REG_V4, REG_V5, INS_OPTS_NONE); diff --git a/src/coreclr/src/jit/emitarm64.cpp b/src/coreclr/src/jit/emitarm64.cpp index 5780ffbe70be7..7df6edf7ea6c4 100644 --- a/src/coreclr/src/jit/emitarm64.cpp +++ b/src/coreclr/src/jit/emitarm64.cpp @@ -604,20 +604,23 @@ void emitter::emitInsSanityCheck(instrDesc* id) break; case IF_DV_2N: // DV_2N .........iiiiiii ......nnnnnddddd Vd Vn imm (shift - scalar) - assert(id->idOpSize() == EA_8BYTE); + ins = id->idIns(); + datasize = id->idOpSize(); assert(insOptsNone(id->idInsOpt())); assert(isVectorRegister(id->idReg1())); assert(isVectorRegister(id->idReg2())); - assert(isValidImmShift(emitGetInsSC(id), EA_8BYTE)); + assert(isValidVectorShiftAmount(emitGetInsSC(id), datasize, emitInsIsVectorRightShift(ins))); break; case IF_DV_2O: // DV_2O .Q.......iiiiiii ......nnnnnddddd Vd Vn imm (shift - vector) - assert(isValidVectorDatasize(id->idOpSize())); - assert(isValidArrangement(id->idOpSize(), id->idInsOpt())); + ins = id->idIns(); + datasize = id->idOpSize(); + elemsize = optGetElemsize(id->idInsOpt()); + assert(isValidVectorDatasize(datasize)); + assert(isValidArrangement(datasize, id->idInsOpt())); assert(isVectorRegister(id->idReg1())); assert(isVectorRegister(id->idReg2())); - elemsize = optGetElemsize(id->idInsOpt()); - assert(isValidImmShift(emitGetInsSC(id), elemsize)); + assert(isValidVectorShiftAmount(emitGetInsSC(id), elemsize, emitInsIsVectorRightShift(ins))); break; case IF_DV_2B: // DV_2B .Q.........iiiii ......nnnnnddddd Rd Vn[] (umov/smov - to general) @@ -1376,13 +1379,13 @@ emitter::insFormat emitter::emitInsFormat(instruction ins) // clang-format off const static insFormat insFormats[] = { - #define INST1(id, nm, fp, ldst, fmt, e1 ) fmt, - #define INST2(id, nm, fp, ldst, fmt, e1, e2 ) fmt, - #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3 ) fmt, - #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4 ) fmt, - #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5 ) fmt, - #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6 ) fmt, - #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) fmt, + #define INST1(id, nm, info, fmt, e1 ) fmt, + #define INST2(id, nm, info, fmt, e1, e2 ) fmt, + #define INST3(id, nm, info, fmt, e1, e2, e3 ) fmt, + #define INST4(id, nm, info, fmt, e1, e2, e3, e4 ) fmt, + #define INST5(id, nm, info, fmt, e1, e2, e3, e4, e5 ) fmt, + #define INST6(id, nm, info, fmt, e1, e2, e3, e4, e5, e6 ) fmt, + #define INST9(id, nm, info, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) fmt, #include "instrs.h" }; // clang-format on @@ -1393,76 +1396,81 @@ emitter::insFormat emitter::emitInsFormat(instruction ins) return insFormats[ins]; } -// INST_FP is 1 -#define LD 2 -#define ST 4 -#define CMP 8 +#define LD 1 +#define ST 2 +#define CMP 4 +#define RSH 8 // clang-format off /*static*/ const BYTE CodeGenInterface::instInfo[] = { - #define INST1(id, nm, fp, ldst, fmt, e1 ) ldst | INST_FP*fp, - #define INST2(id, nm, fp, ldst, fmt, e1, e2 ) ldst | INST_FP*fp, - #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3 ) ldst | INST_FP*fp, - #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4 ) ldst | INST_FP*fp, - #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5 ) ldst | INST_FP*fp, - #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6 ) ldst | INST_FP*fp, - #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) ldst | INST_FP*fp, + #define INST1(id, nm, info, fmt, e1 ) info, + #define INST2(id, nm, info, fmt, e1, e2 ) info, + #define INST3(id, nm, info, fmt, e1, e2, e3 ) info, + #define INST4(id, nm, info, fmt, e1, e2, e3, e4 ) info, + #define INST5(id, nm, info, fmt, e1, e2, e3, e4, e5 ) info, + #define INST6(id, nm, info, fmt, e1, e2, e3, e4, e5, e6 ) info, + #define INST9(id, nm, info, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) info, #include "instrs.h" }; // clang-format on -/***************************************************************************** - * - * Returns true if the instruction is some kind of compare or test instruction - */ - +//------------------------------------------------------------------------ +// emitInsIsCompare: Returns true if the instruction is some kind of compare or test instruction. +// bool emitter::emitInsIsCompare(instruction ins) { // We have pseudo ins like lea which are not included in emitInsLdStTab. if (ins < ArrLen(CodeGenInterface::instInfo)) - return (CodeGenInterface::instInfo[ins] & CMP) ? true : false; + return (CodeGenInterface::instInfo[ins] & CMP) != 0; else return false; } -/***************************************************************************** - * - * Returns true if the instruction is some kind of load instruction - */ - +//------------------------------------------------------------------------ +// emitInsIsLoad: Returns true if the instruction is some kind of load instruction. +// bool emitter::emitInsIsLoad(instruction ins) { // We have pseudo ins like lea which are not included in emitInsLdStTab. if (ins < ArrLen(CodeGenInterface::instInfo)) - return (CodeGenInterface::instInfo[ins] & LD) ? true : false; + return (CodeGenInterface::instInfo[ins] & LD) != 0; else return false; } -/***************************************************************************** - * - * Returns true if the instruction is some kind of store instruction - */ +//------------------------------------------------------------------------ +// emitInsIsStore: Returns true if the instruction is some kind of store instruction. +// bool emitter::emitInsIsStore(instruction ins) { // We have pseudo ins like lea which are not included in emitInsLdStTab. if (ins < ArrLen(CodeGenInterface::instInfo)) - return (CodeGenInterface::instInfo[ins] & ST) ? true : false; + return (CodeGenInterface::instInfo[ins] & ST) != 0; else return false; } -/***************************************************************************** - * - * Returns true if the instruction is some kind of load/store instruction - */ - +//------------------------------------------------------------------------ +// emitInsIsLoadOrStore: Returns true if the instruction is some kind of load or store instruction. +// bool emitter::emitInsIsLoadOrStore(instruction ins) { // We have pseudo ins like lea which are not included in emitInsLdStTab. if (ins < ArrLen(CodeGenInterface::instInfo)) - return (CodeGenInterface::instInfo[ins] & (LD | ST)) ? true : false; + return (CodeGenInterface::instInfo[ins] & (LD | ST)) != 0; + else + return false; +} + +//------------------------------------------------------------------------ +// emitInsIsVectorRightShift: Returns true if the instruction is ASIMD right shift. +// +bool emitter::emitInsIsVectorRightShift(instruction ins) +{ + // We have pseudo ins like lea which are not included in emitInsLdStTab. + if (ins < ArrLen(CodeGenInterface::instInfo)) + return (CodeGenInterface::instInfo[ins] & RSH) != 0; else return false; } @@ -1470,6 +1478,7 @@ bool emitter::emitInsIsLoadOrStore(instruction ins) #undef LD #undef ST #undef CMP +#undef RHS /***************************************************************************** * @@ -1481,101 +1490,101 @@ emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt) // clang-format off const static code_t insCodes1[] = { - #define INST1(id, nm, fp, ldst, fmt, e1 ) e1, - #define INST2(id, nm, fp, ldst, fmt, e1, e2 ) e1, - #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3 ) e1, - #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4 ) e1, - #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5 ) e1, - #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6 ) e1, - #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e1, + #define INST1(id, nm, info, fmt, e1 ) e1, + #define INST2(id, nm, info, fmt, e1, e2 ) e1, + #define INST3(id, nm, info, fmt, e1, e2, e3 ) e1, + #define INST4(id, nm, info, fmt, e1, e2, e3, e4 ) e1, + #define INST5(id, nm, info, fmt, e1, e2, e3, e4, e5 ) e1, + #define INST6(id, nm, info, fmt, e1, e2, e3, e4, e5, e6 ) e1, + #define INST9(id, nm, info, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e1, #include "instrs.h" }; const static code_t insCodes2[] = { - #define INST1(id, nm, fp, ldst, fmt, e1 ) - #define INST2(id, nm, fp, ldst, fmt, e1, e2 ) e2, - #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3 ) e2, - #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4 ) e2, - #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5 ) e2, - #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6 ) e2, - #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e2, + #define INST1(id, nm, info, fmt, e1 ) + #define INST2(id, nm, info, fmt, e1, e2 ) e2, + #define INST3(id, nm, info, fmt, e1, e2, e3 ) e2, + #define INST4(id, nm, info, fmt, e1, e2, e3, e4 ) e2, + #define INST5(id, nm, info, fmt, e1, e2, e3, e4, e5 ) e2, + #define INST6(id, nm, info, fmt, e1, e2, e3, e4, e5, e6 ) e2, + #define INST9(id, nm, info, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e2, #include "instrs.h" }; const static code_t insCodes3[] = { - #define INST1(id, nm, fp, ldst, fmt, e1 ) - #define INST2(id, nm, fp, ldst, fmt, e1, e2 ) - #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3 ) e3, - #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4 ) e3, - #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5 ) e3, - #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6 ) e3, - #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e3, + #define INST1(id, nm, info, fmt, e1 ) + #define INST2(id, nm, info, fmt, e1, e2 ) + #define INST3(id, nm, info, fmt, e1, e2, e3 ) e3, + #define INST4(id, nm, info, fmt, e1, e2, e3, e4 ) e3, + #define INST5(id, nm, info, fmt, e1, e2, e3, e4, e5 ) e3, + #define INST6(id, nm, info, fmt, e1, e2, e3, e4, e5, e6 ) e3, + #define INST9(id, nm, info, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e3, #include "instrs.h" }; const static code_t insCodes4[] = { - #define INST1(id, nm, fp, ldst, fmt, e1 ) - #define INST2(id, nm, fp, ldst, fmt, e1, e2 ) - #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3 ) - #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4 ) e4, - #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5 ) e4, - #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6 ) e4, - #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e4, + #define INST1(id, nm, info, fmt, e1 ) + #define INST2(id, nm, info, fmt, e1, e2 ) + #define INST3(id, nm, info, fmt, e1, e2, e3 ) + #define INST4(id, nm, info, fmt, e1, e2, e3, e4 ) e4, + #define INST5(id, nm, info, fmt, e1, e2, e3, e4, e5 ) e4, + #define INST6(id, nm, info, fmt, e1, e2, e3, e4, e5, e6 ) e4, + #define INST9(id, nm, info, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e4, #include "instrs.h" }; const static code_t insCodes5[] = { - #define INST1(id, nm, fp, ldst, fmt, e1 ) - #define INST2(id, nm, fp, ldst, fmt, e1, e2 ) - #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3 ) - #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4 ) - #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5 ) e5, - #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6 ) e5, - #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e5, + #define INST1(id, nm, info, fmt, e1 ) + #define INST2(id, nm, info, fmt, e1, e2 ) + #define INST3(id, nm, info, fmt, e1, e2, e3 ) + #define INST4(id, nm, info, fmt, e1, e2, e3, e4 ) + #define INST5(id, nm, info, fmt, e1, e2, e3, e4, e5 ) e5, + #define INST6(id, nm, info, fmt, e1, e2, e3, e4, e5, e6 ) e5, + #define INST9(id, nm, info, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e5, #include "instrs.h" }; const static code_t insCodes6[] = { - #define INST1(id, nm, fp, ldst, fmt, e1 ) - #define INST2(id, nm, fp, ldst, fmt, e1, e2 ) - #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3 ) - #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4 ) - #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5 ) - #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6 ) e6, - #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e6, + #define INST1(id, nm, info, fmt, e1 ) + #define INST2(id, nm, info, fmt, e1, e2 ) + #define INST3(id, nm, info, fmt, e1, e2, e3 ) + #define INST4(id, nm, info, fmt, e1, e2, e3, e4 ) + #define INST5(id, nm, info, fmt, e1, e2, e3, e4, e5 ) + #define INST6(id, nm, info, fmt, e1, e2, e3, e4, e5, e6 ) e6, + #define INST9(id, nm, info, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e6, #include "instrs.h" }; const static code_t insCodes7[] = { - #define INST1(id, nm, fp, ldst, fmt, e1 ) - #define INST2(id, nm, fp, ldst, fmt, e1, e2 ) - #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3 ) - #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4 ) - #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5 ) - #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6 ) - #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e7, + #define INST1(id, nm, info, fmt, e1 ) + #define INST2(id, nm, info, fmt, e1, e2 ) + #define INST3(id, nm, info, fmt, e1, e2, e3 ) + #define INST4(id, nm, info, fmt, e1, e2, e3, e4 ) + #define INST5(id, nm, info, fmt, e1, e2, e3, e4, e5 ) + #define INST6(id, nm, info, fmt, e1, e2, e3, e4, e5, e6 ) + #define INST9(id, nm, info, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e7, #include "instrs.h" }; const static code_t insCodes8[] = { - #define INST1(id, nm, fp, ldst, fmt, e1 ) - #define INST2(id, nm, fp, ldst, fmt, e1, e2 ) - #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3 ) - #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4 ) - #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5 ) - #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6 ) - #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e8, + #define INST1(id, nm, info, fmt, e1 ) + #define INST2(id, nm, info, fmt, e1, e2 ) + #define INST3(id, nm, info, fmt, e1, e2, e3 ) + #define INST4(id, nm, info, fmt, e1, e2, e3, e4 ) + #define INST5(id, nm, info, fmt, e1, e2, e3, e4, e5 ) + #define INST6(id, nm, info, fmt, e1, e2, e3, e4, e5, e6 ) + #define INST9(id, nm, info, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e8, #include "instrs.h" }; const static code_t insCodes9[] = { - #define INST1(id, nm, fp, ldst, fmt, e1 ) - #define INST2(id, nm, fp, ldst, fmt, e1, e2 ) - #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3 ) - #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4 ) - #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5 ) - #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6 ) - #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e9, + #define INST1(id, nm, info, fmt, e1 ) + #define INST2(id, nm, info, fmt, e1, e2 ) + #define INST3(id, nm, info, fmt, e1, e2, e3 ) + #define INST4(id, nm, info, fmt, e1, e2, e3, e4 ) + #define INST5(id, nm, info, fmt, e1, e2, e3, e4, e5 ) + #define INST6(id, nm, info, fmt, e1, e2, e3, e4, e5, e6 ) + #define INST9(id, nm, info, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e9, #include "instrs.h" }; // clang-format on @@ -1596,6 +1605,7 @@ emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt) const static insFormat formatEncode4G[4] = {IF_DR_2E, IF_DR_2F, IF_DV_2M, IF_DV_2L}; const static insFormat formatEncode4H[4] = {IF_DV_3E, IF_DV_3A, IF_DV_2L, IF_DV_2M}; const static insFormat formatEncode4I[4] = {IF_DV_3D, IF_DV_3B, IF_DV_2G, IF_DV_2A}; + const static insFormat formatEncode4J[4] = {IF_DV_2N, IF_DV_2O, IF_DV_3E, IF_DV_3A}; const static insFormat formatEncode3A[3] = {IF_DR_3A, IF_DR_3B, IF_DI_2C}; const static insFormat formatEncode3B[3] = {IF_DR_2A, IF_DR_2B, IF_DI_1C}; const static insFormat formatEncode3C[3] = {IF_DR_3A, IF_DR_3B, IF_DV_3C}; @@ -1798,6 +1808,17 @@ emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt) } break; + case IF_EN4J: + for (index = 0; index < 4; index++) + { + if (fmt == formatEncode4J[index]) + { + encoding_found = true; + break; + } + } + break; + case IF_EN3A: for (index = 0; index < 3; index++) { @@ -4393,15 +4414,21 @@ void emitter::emitIns_R_R( break; case INS_fcvtl: - case INS_fcvtl2: case INS_fcvtn: + assert(isVectorRegister(reg1)); + assert(isVectorRegister(reg2)); + assert(size == EA_8BYTE); + assert((opt == INS_OPTS_4H) || (opt == INS_OPTS_2S)); + fmt = IF_DV_2A; + break; + + case INS_fcvtl2: case INS_fcvtn2: assert(isVectorRegister(reg1)); assert(isVectorRegister(reg2)); - assert(isValidVectorDatasize(size)); - assert(insOptsNone(opt)); - assert(size == EA_8BYTE); // Narrowing from Double or Widening to Double (Half not supported) - fmt = IF_DV_2G; + assert(size == EA_16BYTE); + assert((opt == INS_OPTS_8H) || (opt == INS_OPTS_4S)); + fmt = IF_DV_2A; break; case INS_scvtf: @@ -4797,6 +4824,7 @@ void emitter::emitIns_R_R_I( bool canEncode; bitMaskImm bmi; unsigned registerListSize; + bool isRightShift; case INS_mov: // Check for the 'mov' aliases for the vector registers @@ -4850,19 +4878,21 @@ void emitter::emitIns_R_R_I( fmt = IF_DI_2B; break; - case INS_sshr: - case INS_ssra: + case INS_shl: + case INS_sli: + case INS_sri: case INS_srshr: case INS_srsra: - case INS_shl: - case INS_ushr: - case INS_usra: + case INS_sshr: + case INS_ssra: case INS_urshr: case INS_ursra: - case INS_sri: - case INS_sli: + case INS_ushr: + case INS_usra: assert(isVectorRegister(reg1)); assert(isVectorRegister(reg2)); + isRightShift = emitInsIsVectorRightShift(ins); + if (insOptsAnyArrangement(opt)) { // Vector operation @@ -4870,7 +4900,7 @@ void emitter::emitIns_R_R_I( assert(isValidArrangement(size, opt)); elemsize = optGetElemsize(opt); assert(isValidVectorElemsize(elemsize)); - assert(isValidImmShift(imm, elemsize)); + assert(isValidVectorShiftAmount(imm, elemsize, isRightShift)); assert(opt != INS_OPTS_1D); // Reserved encoding fmt = IF_DV_2O; break; @@ -4880,7 +4910,63 @@ void emitter::emitIns_R_R_I( // Scalar operation assert(insOptsNone(opt)); assert(size == EA_8BYTE); // only supported size - assert(isValidImmShift(imm, size)); + assert(isValidVectorShiftAmount(imm, size, isRightShift)); + fmt = IF_DV_2N; + } + break; + + case INS_sqshl: + case INS_uqshl: + case INS_sqshlu: + assert(isVectorRegister(reg1)); + assert(isVectorRegister(reg2)); + isRightShift = emitInsIsVectorRightShift(ins); + + if (insOptsAnyArrangement(opt)) + { + // Vector operation + assert(isValidArrangement(size, opt)); + assert(opt != INS_OPTS_1D); // The encoding immh = 1xxx, Q = 0 is reserved + elemsize = optGetElemsize(opt); + assert(isValidVectorShiftAmount(imm, elemsize, isRightShift)); + fmt = IF_DV_2O; + } + else + { + // Scalar operation + assert(insOptsNone(opt)); + assert(isValidVectorElemsize(size)); + assert(isValidVectorShiftAmount(imm, size, isRightShift)); + fmt = IF_DV_2N; + } + break; + + case INS_sqrshrn: + case INS_sqrshrun: + case INS_sqshrn: + case INS_sqshrun: + case INS_uqrshrn: + case INS_uqshrn: + assert(isVectorRegister(reg1)); + assert(isVectorRegister(reg2)); + isRightShift = emitInsIsVectorRightShift(ins); + + if (insOptsAnyArrangement(opt)) + { + // Vector operation + assert(isValidArrangement(size, opt)); + assert((opt != INS_OPTS_1D) && (opt != INS_OPTS_2D)); // The encoding immh = 1xxx, Q = x is reserved + elemsize = optGetElemsize(opt); + assert(isValidVectorShiftAmount(imm, elemsize, isRightShift)); + fmt = IF_DV_2O; + } + else + { + // Scalar operation + assert(insOptsNone(opt)); + assert(isValidVectorElemsize(size)); + assert(size != EA_8BYTE); // The encoding immh = 1xxx is reserved + assert(isValidVectorShiftAmount(imm, size, isRightShift)); fmt = IF_DV_2N; } break; @@ -4890,19 +4976,20 @@ void emitter::emitIns_R_R_I( assert(imm == 0); __fallthrough; - case INS_shrn: case INS_rshrn: + case INS_shrn: case INS_sshll: case INS_ushll: assert(isVectorRegister(reg1)); assert(isVectorRegister(reg2)); + isRightShift = emitInsIsVectorRightShift(ins); // Vector operation assert(size == EA_8BYTE); assert(isValidArrangement(size, opt)); elemsize = optGetElemsize(opt); assert(elemsize != EA_8BYTE); // Reserved encodings assert(isValidVectorElemsize(elemsize)); - assert(isValidImmShift(imm, elemsize)); + assert(isValidVectorShiftAmount(imm, elemsize, isRightShift)); fmt = IF_DV_2O; break; @@ -4911,19 +4998,27 @@ void emitter::emitIns_R_R_I( assert(imm == 0); __fallthrough; - case INS_shrn2: case INS_rshrn2: + case INS_shrn2: + case INS_sqrshrn2: + case INS_sqrshrun2: + case INS_sqshrn2: + case INS_sqshrun2: case INS_sshll2: + case INS_uqrshrn2: + case INS_uqshrn2: case INS_ushll2: assert(isVectorRegister(reg1)); assert(isVectorRegister(reg2)); + isRightShift = emitInsIsVectorRightShift(ins); + // Vector operation assert(size == EA_16BYTE); assert(isValidArrangement(size, opt)); elemsize = optGetElemsize(opt); - assert(elemsize != EA_8BYTE); // Reserved encodings + assert(elemsize != EA_8BYTE); // The encoding immh = 1xxx, Q = x is reserved assert(isValidVectorElemsize(elemsize)); - assert(isValidImmShift(imm, elemsize)); + assert(isValidVectorShiftAmount(imm, elemsize, isRightShift)); fmt = IF_DV_2O; break; @@ -5571,6 +5666,10 @@ void emitter::emitIns_R_R_R( case INS_cmhi: case INS_cmhs: case INS_cmtst: + case INS_srshl: + case INS_sshl: + case INS_urshl: + case INS_ushl: assert(isVectorRegister(reg1)); assert(isVectorRegister(reg2)); assert(isVectorRegister(reg3)); @@ -5592,8 +5691,12 @@ void emitter::emitIns_R_R_R( break; case INS_sqadd: + case INS_sqrshl: + case INS_sqshl: case INS_sqsub: case INS_uqadd: + case INS_uqrshl: + case INS_uqshl: case INS_uqsub: assert(isVectorRegister(reg1)); assert(isVectorRegister(reg2)); @@ -8754,18 +8857,33 @@ void emitter::emitIns_Call(EmitCallType callType, return bits; } -/***************************************************************************** - * - * Returns the encoding to shift by 'shift' for an Arm64 vector or scalar instruction - */ - -/*static*/ emitter::code_t emitter::insEncodeVectorShift(emitAttr size, ssize_t shift) +// insEncodeVectorShift: Returns the encoding for the SIMD shift (immediate) instructions. +// +// Arguments: +// size - for the scalar variants specifies 'datasize', for the vector variants specifies 'element size'. +// shift - if the shift is positive, the operation is a left shift. Otherwise, it is a right shift. +// +// Returns: +// "immh:immb" field of the instruction that contains encoded shift amount. +// +/*static*/ emitter::code_t emitter::insEncodeVectorShift(emitAttr size, ssize_t shiftAmount) { - assert(shift < getBitWidth(size)); - - code_t imm = (code_t)(getBitWidth(size) + shift); + if (shiftAmount < 0) + { + shiftAmount = -shiftAmount; + // The right shift amount must be in the range 1 to the destination element width in bits. + assert((shiftAmount > 0) && (shiftAmount <= getBitWidth(size))); - return imm << 16; + code_t imm = (code_t)(2 * getBitWidth(size) - shiftAmount); + return imm << 16; + } + else + { + // The left shift amount must in the range 0 to the element width in bits minus 1. + assert(shiftAmount < getBitWidth(size)); + code_t imm = (code_t)(getBitWidth(size) + shiftAmount); + return imm << 16; + } } /***************************************************************************** @@ -10595,9 +10713,25 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) elemsize = optGetElemsize(id->idInsOpt()); code = emitInsCode(ins, fmt); code |= insEncodeVectorsize(id->idOpSize()); // Q - code |= insEncodeFloatElemsize(elemsize); // X - code |= insEncodeReg_Vd(id->idReg1()); // ddddd - code |= insEncodeReg_Vn(id->idReg2()); // nnnnn + if ((ins == INS_fcvtl) || (ins == INS_fcvtl2) || (ins == INS_fcvtn) || (ins == INS_fcvtn2)) + { + // fcvtl{2} and fcvtn{2} encode the element size as + // esize = 16 << UInt(sz) + if (elemsize == EA_4BYTE) + { + code |= 0x00400000; // X + } + else + { + assert(elemsize == EA_2BYTE); + } + } + else + { + code |= insEncodeFloatElemsize(elemsize); // X + } + code |= insEncodeReg_Vd(id->idReg1()); // ddddd + code |= insEncodeReg_Vn(id->idReg2()); // nnnnn dst += emitOutput_Instr(dst, code); break; @@ -10738,11 +10872,12 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) break; case IF_DV_2N: // DV_2N .........iiiiiii ......nnnnnddddd Vd Vn imm (shift - scalar) - imm = emitGetInsSC(id); - code = emitInsCode(ins, fmt); - code |= insEncodeVectorShift(EA_8BYTE, imm); // iiiiiii - code |= insEncodeReg_Vd(id->idReg1()); // ddddd - code |= insEncodeReg_Vn(id->idReg2()); // nnnnn + imm = emitGetInsSC(id); + elemsize = id->idOpSize(); + code = emitInsCode(ins, fmt); + code |= insEncodeVectorShift(elemsize, emitInsIsVectorRightShift(ins) ? -imm : imm); // iiiiiii + code |= insEncodeReg_Vd(id->idReg1()); // ddddd + code |= insEncodeReg_Vn(id->idReg2()); // nnnnn dst += emitOutput_Instr(dst, code); break; @@ -10750,10 +10885,10 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) imm = emitGetInsSC(id); elemsize = optGetElemsize(id->idInsOpt()); code = emitInsCode(ins, fmt); - code |= insEncodeVectorsize(id->idOpSize()); // Q - code |= insEncodeVectorShift(elemsize, imm); // iiiiiii - code |= insEncodeReg_Vd(id->idReg1()); // ddddd - code |= insEncodeReg_Vn(id->idReg2()); // nnnnn + code |= insEncodeVectorsize(id->idOpSize()); // Q + code |= insEncodeVectorShift(elemsize, emitInsIsVectorRightShift(ins) ? -imm : imm); // iiiiiii + code |= insEncodeReg_Vd(id->idReg1()); // ddddd + code |= insEncodeReg_Vn(id->idReg2()); // nnnnn dst += emitOutput_Instr(dst, code); break; @@ -12345,6 +12480,23 @@ void emitter::emitDispIns( break; case IF_DV_2A: // DV_2A .Q.......X...... ......nnnnnddddd Vd Vn (fabs, fcvt - vector) + if ((ins == INS_fcvtl) || (ins == INS_fcvtl2)) + { + emitDispVectorReg(id->idReg1(), optWidenElemsize(id->idInsOpt()), true); + emitDispVectorReg(id->idReg2(), id->idInsOpt(), false); + } + else if ((ins == INS_fcvtn) || (ins == INS_fcvtn2)) + { + emitDispVectorReg(id->idReg1(), id->idInsOpt(), true); + emitDispVectorReg(id->idReg2(), optWidenElemsize(id->idInsOpt()), false); + } + else + { + emitDispVectorReg(id->idReg1(), id->idInsOpt(), true); + emitDispVectorReg(id->idReg2(), id->idInsOpt(), false); + } + break; + case IF_DV_2P: // DV_2P ................ ......nnnnnddddd Vd Vn (aes*, sha1su1) emitDispVectorReg(id->idReg1(), id->idInsOpt(), true); emitDispVectorReg(id->idReg2(), id->idInsOpt(), false); @@ -12492,7 +12644,14 @@ void emitter::emitDispIns( } else { - elemsize = optGetElemsize(id->idInsOpt()); + if ((ins == INS_saddlv) || (ins == INS_uaddlv)) + { + elemsize = optGetElemsize(optWidenDstArrangement(id->idInsOpt())); + } + else + { + elemsize = optGetElemsize(id->idInsOpt()); + } emitDispReg(id->idReg1(), elemsize, true); emitDispVectorReg(id->idReg2(), id->idInsOpt(), false); } @@ -13931,6 +14090,14 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins result.insLatency = PERFSCORE_LATENCY_2C; break; + case INS_fcvtl: + case INS_fcvtl2: + case INS_fcvtn: + case INS_fcvtn2: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; + result.insLatency = PERFSCORE_LATENCY_4C; + break; + default: // all other instructions perfScoreUnhandledInstruction(id, &result); @@ -13983,14 +14150,6 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins result.insLatency = PERFSCORE_LATENCY_2C; break; - case INS_fcvtl: - case INS_fcvtl2: - case INS_fcvtn: - case INS_fcvtn2: - result.insThroughput = PERFSCORE_THROUGHPUT_1C; - result.insLatency = PERFSCORE_LATENCY_4C; - break; - case INS_frecpe: case INS_frecpx: case INS_frsqrte: @@ -14297,6 +14456,8 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_shadd: case INS_shsub: case INS_srhadd: + case INS_srshl: + case INS_sshl: case INS_smax: case INS_smaxp: case INS_smin: @@ -14308,6 +14469,8 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_uhadd: case INS_uhsub: case INS_urhadd: + case INS_urshl: + case INS_ushl: case INS_uzp1: case INS_uzp2: case INS_zip1: @@ -14346,6 +14509,10 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_mul: case INS_mla: case INS_mls: + case INS_sqshl: + case INS_sqrshl: + case INS_uqrshl: + case INS_uqshl: result.insThroughput = PERFSCORE_THROUGHPUT_2X; result.insLatency = PERFSCORE_LATENCY_4C; break; @@ -14475,9 +14642,13 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_rshrn: case INS_rshrn2: - case INS_ssra: case INS_srshr: + case INS_sqshrn: + case INS_sqshrn2: + case INS_ssra: case INS_urshr: + case INS_uqshrn: + case INS_uqshrn2: case INS_usra: if (id->idOpSize() == EA_16BYTE) { @@ -14497,6 +14668,29 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins result.insLatency = PERFSCORE_LATENCY_4C; break; + case INS_sqrshrn: + case INS_sqrshrn2: + case INS_sqrshrun: + case INS_sqrshrun2: + case INS_sqshrun: + case INS_sqshrun2: + case INS_sqshl: + case INS_sqshlu: + case INS_uqrshrn: + case INS_uqrshrn2: + case INS_uqshl: + if (id->idOpSize() == EA_16BYTE) + { + result.insThroughput = PERFSCORE_THROUGHPUT_1C; + result.insLatency = PERFSCORE_LATENCY_4C; + } + else + { + result.insThroughput = PERFSCORE_THROUGHPUT_2X; + result.insLatency = PERFSCORE_LATENCY_4C; + } + break; + default: // all other instructions perfScoreUnhandledInstruction(id, &result); diff --git a/src/coreclr/src/jit/emitarm64.h b/src/coreclr/src/jit/emitarm64.h index 96bbb37aec732..9c365c005d1fd 100644 --- a/src/coreclr/src/jit/emitarm64.h +++ b/src/coreclr/src/jit/emitarm64.h @@ -87,6 +87,7 @@ bool emitInsIsCompare(instruction ins); bool emitInsIsLoad(instruction ins); bool emitInsIsStore(instruction ins); bool emitInsIsLoadOrStore(instruction ins); +bool emitInsIsVectorRightShift(instruction ins); emitAttr emitInsTargetRegSize(instrDesc* id); emitAttr emitInsLoadStoreSize(instrDesc* id); @@ -300,8 +301,8 @@ static code_t insEncodeVectorIndex2(emitAttr elemsize, ssize_t index2); // Returns the encoding to select 'index' for an Arm64 'mul' elem instruction static code_t insEncodeVectorIndexLMH(emitAttr elemsize, ssize_t index); -// Returns the encoding to shift by 'shift' bits for an Arm64 vector or scalar instruction -static code_t insEncodeVectorShift(emitAttr size, ssize_t shift); +// Returns the encoding for ASIMD Shift instruction. +static code_t insEncodeVectorShift(emitAttr size, ssize_t shiftAmount); // Returns the encoding to select the 1/2/4/8 byte elemsize for an Arm64 vector instruction static code_t insEncodeElemsize(emitAttr size); @@ -517,6 +518,13 @@ inline static unsigned isValidImmShift(ssize_t imm, emitAttr size) return (imm >= 0) && (imm < getBitWidth(size)); } +// Returns true if the 'shiftAmount' represents a valid shift for the given 'size'. +inline static unsigned isValidVectorShiftAmount(ssize_t shiftAmount, emitAttr size, bool rightShift) +{ + return (rightShift && (shiftAmount >= 1) && (shiftAmount <= getBitWidth(size))) || + ((shiftAmount >= 0) && (shiftAmount < getBitWidth(size))); +} + inline static bool isValidGeneralDatasize(emitAttr size) { return (size == EA_8BYTE) || (size == EA_4BYTE); diff --git a/src/coreclr/src/jit/emitfmtsarm64.h b/src/coreclr/src/jit/emitfmtsarm64.h index 16244c1a34285..c39f85d99ae69 100644 --- a/src/coreclr/src/jit/emitfmtsarm64.h +++ b/src/coreclr/src/jit/emitfmtsarm64.h @@ -61,6 +61,7 @@ IF_DEF(EN4F, IS_NONE, NONE) // Instruction has 4 possible encoding types, type F IF_DEF(EN4G, IS_NONE, NONE) // Instruction has 4 possible encoding types, type G IF_DEF(EN4H, IS_NONE, NONE) // Instruction has 4 possible encoding types, type H IF_DEF(EN4I, IS_NONE, NONE) // Instruction has 4 possible encoding types, type I +IF_DEF(EN4J, IS_NONE, NONE) // Instruction has 3 possible encoding types, type J IF_DEF(EN3A, IS_NONE, NONE) // Instruction has 3 possible encoding types, type A IF_DEF(EN3B, IS_NONE, NONE) // Instruction has 3 possible encoding types, type B IF_DEF(EN3C, IS_NONE, NONE) // Instruction has 3 possible encoding types, type C diff --git a/src/coreclr/src/jit/instr.cpp b/src/coreclr/src/jit/instr.cpp index 969efe5a4573d..ec776cbea9a91 100644 --- a/src/coreclr/src/jit/instr.cpp +++ b/src/coreclr/src/jit/instr.cpp @@ -57,13 +57,13 @@ const char* CodeGen::genInsName(instruction ins) #include "instrs.h" #elif defined(TARGET_ARM64) - #define INST1(id, nm, fp, ldst, fmt, e1 ) nm, - #define INST2(id, nm, fp, ldst, fmt, e1, e2 ) nm, - #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3 ) nm, - #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4 ) nm, - #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5 ) nm, - #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6 ) nm, - #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9 ) nm, + #define INST1(id, nm, ldst, fmt, e1 ) nm, + #define INST2(id, nm, ldst, fmt, e1, e2 ) nm, + #define INST3(id, nm, ldst, fmt, e1, e2, e3 ) nm, + #define INST4(id, nm, ldst, fmt, e1, e2, e3, e4 ) nm, + #define INST5(id, nm, ldst, fmt, e1, e2, e3, e4, e5 ) nm, + #define INST6(id, nm, ldst, fmt, e1, e2, e3, e4, e5, e6 ) nm, + #define INST9(id, nm, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9 ) nm, #include "instrs.h" #else diff --git a/src/coreclr/src/jit/instr.h b/src/coreclr/src/jit/instr.h index 26ba6eec4ac01..3c0404c6079e9 100644 --- a/src/coreclr/src/jit/instr.h +++ b/src/coreclr/src/jit/instr.h @@ -37,13 +37,13 @@ enum instruction : unsigned INS_lea, // Not a real instruction. It is used for load the address of stack locals #elif defined(TARGET_ARM64) - #define INST1(id, nm, fp, ldst, fmt, e1 ) INS_##id, - #define INST2(id, nm, fp, ldst, fmt, e1, e2 ) INS_##id, - #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3 ) INS_##id, - #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4 ) INS_##id, - #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5 ) INS_##id, - #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6 ) INS_##id, - #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) INS_##id, + #define INST1(id, nm, ldst, fmt, e1 ) INS_##id, + #define INST2(id, nm, ldst, fmt, e1, e2 ) INS_##id, + #define INST3(id, nm, ldst, fmt, e1, e2, e3 ) INS_##id, + #define INST4(id, nm, ldst, fmt, e1, e2, e3, e4 ) INS_##id, + #define INST5(id, nm, ldst, fmt, e1, e2, e3, e4, e5 ) INS_##id, + #define INST6(id, nm, ldst, fmt, e1, e2, e3, e4, e5, e6 ) INS_##id, + #define INST9(id, nm, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) INS_##id, #include "instrs.h" INS_lea, // Not a real instruction. It is used for load the address of stack locals diff --git a/src/coreclr/src/jit/instrsarm64.h b/src/coreclr/src/jit/instrsarm64.h index 4569606835996..41d33443c68d3 100644 --- a/src/coreclr/src/jit/instrsarm64.h +++ b/src/coreclr/src/jit/instrsarm64.h @@ -7,14 +7,17 @@ * * id -- the enum name for the instruction * nm -- textual name (for assembly dipslay) - * fp -- floating point instruction - * ld/st/cmp -- load/store/compare instruction + * info -- miscellaneous instruction info (load/store/compare/ASIMD right shift) * fmt -- encoding format used by this instruction * e1 -- encoding 1 * e2 -- encoding 2 * e3 -- encoding 3 * e4 -- encoding 4 * e5 -- encoding 5 + * e6 -- encoding 6 + * e7 -- encoding 7 + * e8 -- encoding 8 + * e9 -- encoding 9 * ******************************************************************************/ @@ -45,7 +48,7 @@ #endif /*****************************************************************************/ -/* The following is ARM64-specific */ +/* The following is ARM64-specific */ /*****************************************************************************/ // If you're adding a new instruction: @@ -54,10 +57,10 @@ // emitInsMayWriteMultipleRegs in emitArm64.cpp. // clang-format off -INST9(invalid, "INVALID", 0, 0, IF_NONE, BAD_CODE, BAD_CODE, BAD_CODE, BAD_CODE, BAD_CODE, BAD_CODE, BAD_CODE, BAD_CODE, BAD_CODE) +INST9(invalid, "INVALID", 0, IF_NONE, BAD_CODE, BAD_CODE, BAD_CODE, BAD_CODE, BAD_CODE, BAD_CODE, BAD_CODE, BAD_CODE, BAD_CODE) -// enum name FP LD/ST DR_2E DR_2G DI_1B DI_1D DV_3C DV_2B DV_2C DV_2E DV_2F -INST9(mov, "mov", 0, 0, IF_EN9, 0x2A0003E0, 0x11000000, 0x52800000, 0x320003E0, 0x0EA01C00, 0x0E003C00, 0x4E001C00, 0x5E000400, 0x6E000400) +// enum name info DR_2E DR_2G DI_1B DI_1D DV_3C DV_2B DV_2C DV_2E DV_2F +INST9(mov, "mov", 0, IF_EN9, 0x2A0003E0, 0x11000000, 0x52800000, 0x320003E0, 0x0EA01C00, 0x0E003C00, 0x4E001C00, 0x5E000400, 0x6E000400) // mov Rd,Rm DR_2E X0101010000mmmmm 00000011111ddddd 2A00 03E0 // mov Rd,Rn DR_2G X001000100000000 000000nnnnnddddd 1100 0000 mov to/from SP only // mov Rd,imm(i16,hw) DI_1B X10100101hwiiiii iiiiiiiiiiiddddd 5280 0000 imm(i16,hw) @@ -68,8 +71,8 @@ INST9(mov, "mov", 0, 0, IF_EN9, 0x2A0003E0, 0x11000000, 0x52800000, // mov Vd,Vn[] DV_2E 01011110000iiiii 000001nnnnnddddd 5E00 0400 Vd,Vn[] (scalar by elem) // mov Vd[],Vn[] DV_2F 01101110000iiiii 0jjjj1nnnnnddddd 6E00 0400 Vd[],Vn[] (from/to elem) -// enum name FP LD/ST DR_3A DR_3B DR_3C DI_2A DV_3A DV_3E -INST6(add, "add", 0, 0, IF_EN6A, 0x0B000000, 0x0B000000, 0x0B200000, 0x11000000, 0x0E208400, 0x5EE08400) +// enum name info DR_3A DR_3B DR_3C DI_2A DV_3A DV_3E +INST6(add, "add", 0, IF_EN6A, 0x0B000000, 0x0B000000, 0x0B200000, 0x11000000, 0x0E208400, 0x5EE08400) // add Rd,Rn,Rm DR_3A X0001011000mmmmm 000000nnnnnddddd 0B00 0000 Rd,Rn,Rm // add Rd,Rn,(Rm,shk,imm) DR_3B X0001011sh0mmmmm ssssssnnnnnddddd 0B00 0000 Rm {LSL,LSR,ASR} imm(0-63) // add Rd,Rn,(Rm,ext,shl) DR_3C X0001011001mmmmm ooosssnnnnnddddd 0B20 0000 ext(Rm) LSL imm(0-4) @@ -77,7 +80,7 @@ INST6(add, "add", 0, 0, IF_EN6A, 0x0B000000, 0x0B000000, 0x0B200000, // add Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 100001nnnnnddddd 0E20 8400 Vd,Vn,Vm (vector) // add Vd,Vn,Vm DV_3E 01011110111mmmmm 100001nnnnnddddd 5EE0 8400 Vd,Vn,Vm (scalar) -INST6(sub, "sub", 0, 0, IF_EN6A, 0x4B000000, 0x4B000000, 0x4B200000, 0x51000000, 0x2E208400, 0x7EE08400) +INST6(sub, "sub", 0, IF_EN6A, 0x4B000000, 0x4B000000, 0x4B200000, 0x51000000, 0x2E208400, 0x7EE08400) // sub Rd,Rn,Rm DR_3A X1001011000mmmmm 000000nnnnnddddd 4B00 0000 Rd,Rn,Rm // sub Rd,Rn,(Rm,shk,imm) DR_3B X1001011sh0mmmmm ssssssnnnnnddddd 4B00 0000 Rm {LSL,LSR,ASR} imm(0-63) // sub Rd,Rn,(Rm,ext,shl) DR_3C X1001011001mmmmm ooosssnnnnnddddd 4B20 0000 ext(Rm) LSL imm(0-4) @@ -85,1776 +88,1772 @@ INST6(sub, "sub", 0, 0, IF_EN6A, 0x4B000000, 0x4B000000, 0x4B200000, // sub Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 100001nnnnnddddd 2E20 8400 Vd,Vn,Vm (vector) // sub Vd,Vn,Vm DV_3E 01111110111mmmmm 100001nnnnnddddd 7EE0 8400 Vd,Vn,Vm (scalar) -// enum name FP LD/ST LS_2D LS_3F LS_2E LS_2F LS_3G LS_2G -INST6(ld1, "ld1", 0, LD, IF_EN6B, 0x0C407000, 0x0CC07000, 0x0CDF7000, 0x0D400000, 0x0DC00000, 0x0DDF0000) - // C7.2.170 LD1 (multiple structures, one register variant) +// enum name info LS_2D LS_3F LS_2E LS_2F LS_3G LS_2G +INST6(ld1, "ld1", LD, IF_EN6B, 0x0C407000, 0x0CC07000, 0x0CDF7000, 0x0D400000, 0x0DC00000, 0x0DDF0000) + // LD1 (multiple structures, one register variant) // ld1 {Vt},[Xn] LS_2D 0Q00110001000000 0111ssnnnnnttttt 0C40 7000 base register // ld1 {Vt},[Xn],Xm LS_3F 0Q001100110mmmmm 0111ssnnnnnttttt 0CC0 7000 post-indexed by a register // ld1 {Vt},[Xn],#imm LS_2E 0Q00110011011111 0111ssnnnnnttttt 0CDF 7000 post-indexed by an immediate - // C7.2.171 LD1 (single structure) + // LD1 (single structure) // ld1 {Vt}[],[Xn] LS_2F 0Q00110101000000 xx0Sssnnnnnttttt 0D40 0000 base register // ld1 {Vt}[],[Xn],Xm LS_3G 0Q001101110mmmmm xx0Sssnnnnnttttt 0DC0 0000 post-indexed by a register // ld1 {Vt}[],[Xn],#imm LS_2G 0Q00110111011111 xx0Sssnnnnnttttt 0DDF 0000 post-indexed by an immediate -INST6(ld2, "ld2", 0, LD, IF_EN6B, 0x0C408000, 0x0CC08000, 0x0CDF8000, 0x0D600000, 0x0DE00000, 0x0DFF0000) - // C7.2.173 LD2 (multiple structures) +INST6(ld2, "ld2", LD, IF_EN6B, 0x0C408000, 0x0CC08000, 0x0CDF8000, 0x0D600000, 0x0DE00000, 0x0DFF0000) + // LD2 (multiple structures) // ld2 {Vt,Vt2},[Xn] LS_2D 0Q00110001000000 1000ssnnnnnttttt 0C40 8000 base register // ld2 {Vt,Vt2},[Xn],Xm LS_3F 0Q001100110mmmmm 1000ssnnnnnttttt 0CC0 8000 post-indexed by a register // ld2 {Vt,Vt2},[Xn],#imm LS_2E 0Q001100110mmmmm 1000ssnnnnnttttt 0CDF 8000 post-indexed by an immediate - // C7.2.174 LD2 (single structure) + // LD2 (single structure) // ld2 {Vt,Vt2}[],[Xn] LS_2F 0Q00110101100000 xx0Sssnnnnnttttt 0D60 0000 base register // ld2 {Vt,Vt2}[],[Xn],Xm LS_3G 0Q001101111mmmmm xx0Sssnnnnnttttt 0DE0 0000 post-indexed by a register // ld2 {Vt,Vt2}[],[Xn],#imm LS_2G 0Q00110111111111 xx0Sssnnnnnttttt 0DFF 0000 post-indexed by an immediate -INST6(ld3, "ld3", 0, LD, IF_EN6B, 0x0C404000, 0x0CC04000, 0x0CDF4000, 0x0D402000, 0x0DC02000, 0x0DDF2000) - // C7.2.176 LD3 (multiple structures) +INST6(ld3, "ld3", LD, IF_EN6B, 0x0C404000, 0x0CC04000, 0x0CDF4000, 0x0D402000, 0x0DC02000, 0x0DDF2000) + // LD3 (multiple structures) // ld3 {Vt-Vt3},[Xn] LS_2D 0Q00110001000000 0100ssnnnnnttttt 0C40 4000 base register // ld3 {Vt-Vt3},[Xn],Xm LS_3F 0Q001100110mmmmm 0100ssnnnnnttttt 0CC0 4000 post-indexed by a register // ld3 {Vt-Vt3},[Xn],#imm LS_2E 0Q001100110mmmmm 0100ssnnnnnttttt 0CDF 4000 post-indexed by an immediate - // C7.2.177 LD3 (single structure) + // LD3 (single structure) // ld3 {Vt-Vt3}[],[Xn] LS_2F 0Q00110101000000 xx1Sssnnnnnttttt 0D40 2000 base register // ld3 {Vt-Vt3}[],[Xn],Xm LS_3G 0Q001101110mmmmm xx1Sssnnnnnttttt 0DC0 2000 post-indexed by a register // ld3 {Vt-Vt3}[],[Xn],#imm LS_2G 0Q00110111011111 xx1Sssnnnnnttttt 0DDF 2000 post-indexed by an immediate -INST6(ld4, "ld4", 0, LD, IF_EN6B, 0x0C400000, 0x0CC00000, 0x0CDF0000, 0x0D602000, 0x0DE02000, 0x0DFF2000) - // C7.2.179 LD4 (multiple structures) +INST6(ld4, "ld4", LD, IF_EN6B, 0x0C400000, 0x0CC00000, 0x0CDF0000, 0x0D602000, 0x0DE02000, 0x0DFF2000) + // LD4 (multiple structures) // ld4 {Vt-Vt4},[Xn] LS_2D 0Q00110001000000 0000ssnnnnnttttt 0C40 0000 base register // ld4 {Vt-Vt4},[Xn],Xm LS_3F 0Q001100110mmmmm 0000ssnnnnnttttt 0CC0 0000 post-indexed by a register // ld4 {Vt-Vt4},[Xn],#imm LS_2E 0Q00110011011111 0000ssnnnnnttttt 0CDF 0000 post-indexed by an immediate - // C7.2.180 LD4 (single structure) + // LD4 (single structure) // ld4 {Vt-Vt4}[],[Xn] LS_2F 0Q00110101100000 xx1Sssnnnnnttttt 0D60 2000 base register // ld4 {Vt-Vt4}[],[Xn],Xm LS_3G 0Q001101111mmmmm xx1Sssnnnnnttttt 0DE0 2000 post-indexed by a register // ld4 {Vt-Vt4}[],[Xn],#imm LS_2G 0Q00110111111111 xx1Sssnnnnnttttt 0DFF 2000 post-indexed by an immediate -INST6(st1, "st1", 0, LD, IF_EN6B, 0x0C007000, 0x0C807000, 0x0C9F7000, 0x0D000000, 0x0D800000, 0x0D9F0000) - // C7.2.313 ST1 (multiple structures, one register variant) +INST6(st1, "st1", LD, IF_EN6B, 0x0C007000, 0x0C807000, 0x0C9F7000, 0x0D000000, 0x0D800000, 0x0D9F0000) + // ST1 (multiple structures, one register variant) // st1 {Vt},[Xn] LS_2D 0Q00110000000000 0111ssnnnnnttttt 0C00 7000 base register // st1 {Vt},[Xn],Xm LS_3F 0Q001100100mmmmm 0111ssnnnnnttttt 0C80 7000 post-indexed by a register // st1 {Vt},[Xn],#imm LS_2E 0Q00110010011111 0111ssnnnnnttttt 0C9F 7000 post-indexed by an immediate - // C7.2.314 ST1 (single structure) + // ST1 (single structure) // st1 {Vt}[],[Xn] LS_2F 0Q00110100000000 xx0Sssnnnnnttttt 0D00 0000 base register // st1 {Vt}[],[Xn],Xm LS_3G 0Q001101100mmmmm xx0Sssnnnnnttttt 0D80 0000 post-indexed by a register // st1 {Vt}[],[Xn],#imm LS_2G 0Q00110110011111 xx0Sssnnnnnttttt 0D9F 0000 post-indexed by an immediate -INST6(st2, "st2", 0, ST, IF_EN6B, 0x0C008000, 0x0C808000, 0x0C9F8000, 0x0D200000, 0x0DA00000, 0x0DBF0000) - // C7.2.315 ST2 (multiple structures) +INST6(st2, "st2", ST, IF_EN6B, 0x0C008000, 0x0C808000, 0x0C9F8000, 0x0D200000, 0x0DA00000, 0x0DBF0000) + // ST2 (multiple structures) // st2 {Vt,Vt2},[Xn] LS_2D 0Q00110000000000 1000ssnnnnnttttt 0C00 8000 base register // st2 {Vt,Vt2},[Xn],Xm LS_3F 0Q001100100mmmmm 1000ssnnnnnttttt 0C80 8000 post-indexed by a register // st2 {Vt,Vt2},[Xn],#imm LS_2E 0Q00110010011111 1000ssnnnnnttttt 0C9F 8000 post-indexed by an immediate - // C7.2.316 ST2 (single structure) + // ST2 (single structure) // st2 {Vt,Vt2}[],[Xn] LS_2F 0Q00110100100000 xx0Sssnnnnnttttt 0D20 0000 base register // st2 {Vt,Vt2}[],[Xn],Xm LS_3G 0Q001101101mmmmm xx0Sssnnnnnttttt 0DA0 0000 post-indexed by a register // st2 {Vt,Vt2}[],[Xn],#imm LS_2G 0Q00110110111111 xx0Sssnnnnnttttt 0DBF 0000 post-indexed by an immediate -INST6(st3, "st3", 0, ST, IF_EN6B, 0x0C004000, 0x0C804000, 0x0C9F4000, 0x0D002000, 0x0D802000, 0x0D9F2000) - // C7.2.317 ST3 (multiple structures) +INST6(st3, "st3", ST, IF_EN6B, 0x0C004000, 0x0C804000, 0x0C9F4000, 0x0D002000, 0x0D802000, 0x0D9F2000) + // ST3 (multiple structures) // st3 {Vt-Vt3},[Xn] LS_2D 0Q00110000000000 0100ssnnnnnttttt 0C00 4000 base register // st3 {Vt-Vt3},[Xn],Xm LS_3F 0Q001100100mmmmm 0100ssnnnnnttttt 0C80 4000 post-indexed by a register // st3 {Vt-Vt3},[Xn],#imm LS_2E 0Q00110010011111 0100ssnnnnnttttt 0C9F 4000 post-indexed by an immediate - // C7.2.318 ST3 (single structure) + // ST3 (single structure) // st3 {Vt-Vt3}[],[Xn] LS_2F 0Q00110100000000 xx1Sssnnnnnttttt 0D00 2000 base register // st3 {Vt-Vt3}[],[Xn],Xm LS_3G 0Q001101100mmmmm xx1Sssnnnnnttttt 0D80 2000 post-indexed by a register // st3 {Vt-Vt3}[],[Xn],#imm LS_2G 0Q00110110011111 xx1Sssnnnnnttttt 0D9F 2000 post-indexed by an immediate -INST6(st4, "st4", 0, ST, IF_EN6B, 0x0C000000, 0x0C800000, 0x0C9F0000, 0x0D202000, 0x0DA02000, 0x0DBF2000) - // C7.2.319 ST4 (multiple structures) +INST6(st4, "st4", ST, IF_EN6B, 0x0C000000, 0x0C800000, 0x0C9F0000, 0x0D202000, 0x0DA02000, 0x0DBF2000) + // ST4 (multiple structures) // st4 {Vt-Vt4},[Xn] LS_2D 0Q00110000000000 0000ssnnnnnttttt 0C00 0000 base register // st4 {Vt-Vt4},[Xn],Xm LS_3F 0Q001100100mmmmm 0000ssnnnnnttttt 0C80 0000 post-indexed by a register // st4 {Vt-Vt4},[Xn],#imm LS_2E 0Q00110010011111 0000ssnnnnnttttt 0C9F 0000 post-indexed by an immediate - // C7.2.320 ST4 (single structure) + // ST4 (single structure) // st4 {Vt-Vt4}[],[Xn] LS_2F 0Q00110100100000 xx1Sssnnnnnttttt 0D20 2000 base register // st4 {Vt-Vt4}[],[Xn],Xm LS_3G 0Q001101101mmmmm xx1Sssnnnnnttttt 0DA0 2000 post-indexed by a register // st4 {Vt-Vt4}[],[Xn],#imm LS_2G 0Q00110110111111 xx1Sssnnnnnttttt 0DBF 2000 post-indexed by an immediate -// enum name FP LD/ST LS_2A LS_2B LS_2C LS_3A LS_1A -INST5(ldr, "ldr", 0,LD, IF_EN5A, 0xB9400000, 0xB9400000, 0xB8400000, 0xB8600800, 0x18000000) +// enum name info LS_2A LS_2B LS_2C LS_3A LS_1A +INST5(ldr, "ldr", LD, IF_EN5A, 0xB9400000, 0xB9400000, 0xB8400000, 0xB8600800, 0x18000000) // ldr Rt,[Xn] LS_2A 1X11100101000000 000000nnnnnttttt B940 0000 // ldr Rt,[Xn+pimm12] LS_2B 1X11100101iiiiii iiiiiinnnnnttttt B940 0000 imm(0-4095<<{2,3}) // ldr Rt,[Xn+simm9] LS_2C 1X111000010iiiii iiiiPPnnnnnttttt B840 0000 [Xn imm(-256..+255) pre/post/no inc] // ldr Rt,[Xn,(Rm,ext,shl)] LS_3A 1X111000011mmmmm oooS10nnnnnttttt B860 0800 [Xn, ext(Rm) LSL {0,2,3}] // ldr Vt/Rt,[PC+simm19<<2] LS_1A XX011V00iiiiiiii iiiiiiiiiiittttt 1800 0000 [PC +- imm(1MB)] -INST5(ldrsw, "ldrsw", 0,LD, IF_EN5A, 0xB9800000, 0xB9800000, 0xB8800000, 0xB8A00800, 0x98000000) +INST5(ldrsw, "ldrsw", LD, IF_EN5A, 0xB9800000, 0xB9800000, 0xB8800000, 0xB8A00800, 0x98000000) // ldrsw Rt,[Xn] LS_2A 1011100110000000 000000nnnnnttttt B980 0000 // ldrsw Rt,[Xn+pimm12] LS_2B 1011100110iiiiii iiiiiinnnnnttttt B980 0000 imm(0-4095<<2) // ldrsw Rt,[Xn+simm9] LS_2C 10111000100iiiii iiiiPPnnnnnttttt B880 0000 [Xn imm(-256..+255) pre/post/no inc] // ldrsw Rt,[Xn,(Rm,ext,shl)] LS_3A 10111000101mmmmm oooS10nnnnnttttt B8A0 0800 [Xn, ext(Rm) LSL {0,2}] // ldrsw Rt,[PC+simm19<<2] LS_1A 10011000iiiiiiii iiiiiiiiiiittttt 9800 0000 [PC +- imm(1MB)] -// enum name FP LD/ST DV_2G DV_2H DV_2I DV_1A DV_1B -INST5(fmov, "fmov", 0, 0, IF_EN5B, 0x1E204000, 0x1E260000, 0x1E270000, 0x1E201000, 0x0F00F400) +// enum name info DV_2G DV_2H DV_2I DV_1A DV_1B +INST5(fmov, "fmov", 0, IF_EN5B, 0x1E204000, 0x1E260000, 0x1E270000, 0x1E201000, 0x0F00F400) // fmov Vd,Vn DV_2G 000111100X100000 010000nnnnnddddd 1E20 4000 Vd,Vn (scalar) // fmov Rd,Vn DV_2H X00111100X100110 000000nnnnnddddd 1E26 0000 Rd,Vn (scalar, to general) // fmov Vd,Rn DV_2I X00111100X100111 000000nnnnnddddd 1E27 0000 Vd,Rn (scalar, from general) // fmov Vd,immfp DV_1A 000111100X1iiiii iii10000000ddddd 1E20 1000 Vd,immfp (scalar) // fmov Vd,immfp DV_1B 0QX0111100000iii 111101iiiiiddddd 0F00 F400 Vd,immfp (immediate vector) -// enum name FP LD/ST DR_3A DR_3B DI_2C DV_3C DV_1B -INST5(orr, "orr", 0, 0, IF_EN5C, 0x2A000000, 0x2A000000, 0x32000000, 0x0EA01C00, 0x0F001400) +// enum name info DR_3A DR_3B DI_2C DV_3C DV_1B +INST5(orr, "orr", 0, IF_EN5C, 0x2A000000, 0x2A000000, 0x32000000, 0x0EA01C00, 0x0F001400) // orr Rd,Rn,Rm DR_3A X0101010000mmmmm 000000nnnnnddddd 2A00 0000 // orr Rd,Rn,(Rm,shk,imm) DR_3B X0101010sh0mmmmm iiiiiinnnnnddddd 2A00 0000 Rm {LSL,LSR,ASR,ROR} imm(0-63) // orr Rd,Rn,imm(N,r,s) DI_2C X01100100Nrrrrrr ssssssnnnnnddddd 3200 0000 imm(N,r,s) // orr Vd,Vn,Vm DV_3C 0Q001110101mmmmm 000111nnnnnddddd 0EA0 1C00 Vd,Vn,Vm // orr Vd,imm8 DV_1B 0Q00111100000iii ---101iiiiiddddd 0F00 1400 Vd imm8 (immediate vector) -// enum name FP LD/ST LS_2A LS_2B LS_2C LS_3A -INST4(ldrb, "ldrb", 0,LD, IF_EN4A, 0x39400000, 0x39400000, 0x38400000, 0x38600800) +// enum name info LS_2A LS_2B LS_2C LS_3A +INST4(ldrb, "ldrb", LD, IF_EN4A, 0x39400000, 0x39400000, 0x38400000, 0x38600800) // ldrb Rt,[Xn] LS_2A 0011100101000000 000000nnnnnttttt 3940 0000 // ldrb Rt,[Xn+pimm12] LS_2B 0011100101iiiiii iiiiiinnnnnttttt 3940 0000 imm(0-4095) // ldrb Rt,[Xn+simm9] LS_2C 00111000010iiiii iiiiPPnnnnnttttt 3840 0000 [Xn imm(-256..+255) pre/post/no inc] // ldrb Rt,[Xn,(Rm,ext,shl)] LS_3A 00111000011mmmmm oooS10nnnnnttttt 3860 0800 [Xn, ext(Rm)] -INST4(ldrh, "ldrh", 0,LD, IF_EN4A, 0x79400000, 0x79400000, 0x78400000, 0x78600800) +INST4(ldrh, "ldrh", LD, IF_EN4A, 0x79400000, 0x79400000, 0x78400000, 0x78600800) // ldrh Rt,[Xn] LS_2A 0111100101000000 000000nnnnnttttt 7940 0000 // ldrh Rt,[Xn+pimm12] LS_2B 0111100101iiiiii iiiiiinnnnnttttt 7940 0000 imm(0-4095<<1) // ldrh Rt,[Xn+simm9] LS_2C 01111000010iiiii iiiiPPnnnnnttttt 7840 0000 [Xn imm(-256..+255) pre/post/no inc] // ldrh Rt,[Xn,(Rm,ext,shl)] LS_3A 01111000011mmmmm oooS10nnnnnttttt 7860 0800 [Xn, ext(Rm) LSL {0,1}] -INST4(ldrsb, "ldrsb", 0,LD, IF_EN4A, 0x39800000, 0x39800000, 0x38800000, 0x38A00800) +INST4(ldrsb, "ldrsb", LD, IF_EN4A, 0x39800000, 0x39800000, 0x38800000, 0x38A00800) // ldrsb Rt,[Xn] LS_2A 001110011X000000 000000nnnnnttttt 3980 0000 // ldrsb Rt,[Xn+pimm12] LS_2B 001110011Xiiiiii iiiiiinnnnnttttt 3980 0000 imm(0-4095) // ldrsb Rt,[Xn+simm9] LS_2C 001110001X0iiiii iiii01nnnnnttttt 3880 0000 [Xn imm(-256..+255) pre/post/no inc] // ldrsb Rt,[Xn,(Rm,ext,shl)] LS_3A 001110001X1mmmmm oooS10nnnnnttttt 38A0 0800 [Xn, ext(Rm)] -INST4(ldrsh, "ldrsh", 0,LD, IF_EN4A, 0x79800000, 0x79800000, 0x78800000, 0x78A00800) +INST4(ldrsh, "ldrsh", LD, IF_EN4A, 0x79800000, 0x79800000, 0x78800000, 0x78A00800) // ldrsh Rt,[Xn] LS_2A 011110011X000000 000000nnnnnttttt 7980 0000 // ldrsh Rt,[Xn+pimm12] LS_2B 011110011Xiiiiii iiiiiinnnnnttttt 7980 0000 imm(0-4095<<1) // ldrsh Rt,[Xn+simm9] LS_2C 011110001X0iiiii iiiiPPnnnnnttttt 7880 0000 [Xn imm(-256..+255) pre/post/no inc] // ldrsh Rt,[Xn,(Rm,ext,shl)] LS_3A 011110001X1mmmmm oooS10nnnnnttttt 78A0 0800 [Xn, ext(Rm) LSL {0,1}] -INST4(str, "str", 0,ST, IF_EN4A, 0xB9000000, 0xB9000000, 0xB8000000, 0xB8200800) +INST4(str, "str", ST, IF_EN4A, 0xB9000000, 0xB9000000, 0xB8000000, 0xB8200800) // str Rt,[Xn] LS_2A 1X11100100000000 000000nnnnnttttt B900 0000 // str Rt,[Xn+pimm12] LS_2B 1X11100100iiiiii iiiiiinnnnnttttt B900 0000 imm(0-4095<<{2,3}) // str Rt,[Xn+simm9] LS_2C 1X111000000iiiii iiiiPPnnnnnttttt B800 0000 [Xn imm(-256..+255) pre/post/no inc] // str Rt,[Xn,(Rm,ext,shl)] LS_3A 1X111000001mmmmm oooS10nnnnnttttt B820 0800 [Xn, ext(Rm)] -INST4(strb, "strb", 0,ST, IF_EN4A, 0x39000000, 0x39000000, 0x38000000, 0x38200800) +INST4(strb, "strb", ST, IF_EN4A, 0x39000000, 0x39000000, 0x38000000, 0x38200800) // strb Rt,[Xn] LS_2A 0011100100000000 000000nnnnnttttt 3900 0000 // strb Rt,[Xn+pimm12] LS_2B 0011100100iiiiii iiiiiinnnnnttttt 3900 0000 imm(0-4095) // strb Rt,[Xn+simm9] LS_2C 00111000000iiiii iiiiPPnnnnnttttt 3800 0000 [Xn imm(-256..+255) pre/post/no inc] // strb Rt,[Xn,(Rm,ext,shl)] LS_3A 00111000001mmmmm oooS10nnnnnttttt 3820 0800 [Xn, ext(Rm)] -INST4(strh, "strh", 0,ST, IF_EN4A, 0x79000000, 0x79000000, 0x78000000, 0x78200800) +INST4(strh, "strh", ST, IF_EN4A, 0x79000000, 0x79000000, 0x78000000, 0x78200800) // strh Rt,[Xn] LS_2A 0111100100000000 000000nnnnnttttt 7900 0000 // strh Rt,[Xn+pimm12] LS_2B 0111100100iiiiii iiiiiinnnnnttttt 7900 0000 imm(0-4095<<1) // strh Rt,[Xn+simm9] LS_2C 01111000000iiiii iiiiPPnnnnnttttt 7800 0000 [Xn imm(-256..+255) pre/post/no inc] // strh Rt,[Xn,(Rm,ext,shl)] LS_3A 01111000001mmmmm oooS10nnnnnttttt 7820 0800 [Xn, ext(Rm)] -// enum name FP LD/ST DR_3A DR_3B DR_3C DI_2A -INST4(adds, "adds", 0, 0, IF_EN4B, 0x2B000000, 0x2B000000, 0x2B200000, 0x31000000) +// enum name info DR_3A DR_3B DR_3C DI_2A +INST4(adds, "adds", 0, IF_EN4B, 0x2B000000, 0x2B000000, 0x2B200000, 0x31000000) // adds Rd,Rn,Rm DR_3A X0101011000mmmmm 000000nnnnnddddd 2B00 0000 // adds Rd,Rn,(Rm,shk,imm) DR_3B X0101011sh0mmmmm ssssssnnnnnddddd 2B00 0000 Rm {LSL,LSR,ASR} imm(0-63) // adds Rd,Rn,(Rm,ext,shl) DR_3C X0101011001mmmmm ooosssnnnnnddddd 2B20 0000 ext(Rm) LSL imm(0-4) // adds Rd,Rn,i12 DI_2A X0110001shiiiiii iiiiiinnnnnddddd 3100 0000 imm(i12,sh) -INST4(subs, "subs", 0, 0, IF_EN4B, 0x6B000000, 0x6B000000, 0x6B200000, 0x71000000) +INST4(subs, "subs", 0, IF_EN4B, 0x6B000000, 0x6B000000, 0x6B200000, 0x71000000) // subs Rd,Rn,Rm DR_3A X1101011000mmmmm 000000nnnnnddddd 6B00 0000 // subs Rd,Rn,(Rm,shk,imm) DR_3B X1101011sh0mmmmm ssssssnnnnnddddd 6B00 0000 Rm {LSL,LSR,ASR} imm(0-63) // subs Rd,Rn,(Rm,ext,shl) DR_3C X1101011001mmmmm ooosssnnnnnddddd 6B20 0000 ext(Rm) LSL imm(0-4) // subs Rd,Rn,i12 DI_2A X1110001shiiiiii iiiiiinnnnnddddd 7100 0000 imm(i12,sh) -// enum name FP LD/ST DR_2A DR_2B DR_2C DI_1A -INST4(cmp, "cmp", 0,CMP,IF_EN4C, 0x6B00001F, 0x6B00001F, 0x6B20001F, 0x7100001F) +// enum name info DR_2A DR_2B DR_2C DI_1A +INST4(cmp, "cmp", CMP, IF_EN4C, 0x6B00001F, 0x6B00001F, 0x6B20001F, 0x7100001F) // cmp Rn,Rm DR_2A X1101011000mmmmm 000000nnnnn11111 6B00 001F // cmp Rn,(Rm,shk,imm) DR_2B X1101011sh0mmmmm ssssssnnnnn11111 6B00 001F Rm {LSL,LSR,ASR} imm(0-63) // cmp Rn,(Rm,ext,shl) DR_2C X1101011001mmmmm ooosssnnnnn11111 6B20 001F ext(Rm) LSL imm(0-4) // cmp Rn,i12 DI_1A X111000100iiiiii iiiiiinnnnn11111 7100 001F imm(i12,sh) -INST4(cmn, "cmn", 0,CMP,IF_EN4C, 0x2B00001F, 0x2B00001F, 0x2B20001F, 0x3100001F) +INST4(cmn, "cmn", CMP, IF_EN4C, 0x2B00001F, 0x2B00001F, 0x2B20001F, 0x3100001F) // cmn Rn,Rm DR_2A X0101011000mmmmm 000000nnnnn11111 2B00 001F // cmn Rn,(Rm,shk,imm) DR_2B X0101011sh0mmmmm ssssssnnnnn11111 2B00 001F Rm {LSL,LSR,ASR} imm(0-63) // cmn Rn,(Rm,ext,shl) DR_2C X0101011001mmmmm ooosssnnnnn11111 2B20 001F ext(Rm) LSL imm(0-4) // cmn Rn,i12 DI_1A X0110001shiiiiii iiiiiinnnnn11111 3100 001F imm(0-4095) -// enum name FP LD/ST DV_3B DV_3D DV_3BI DV_3DI -INST4(fmul, "fmul", 0, 0, IF_EN4D, 0x2E20DC00, 0x1E200800, 0x0F809000, 0x5F809000) +// enum name info DV_3B DV_3D DV_3BI DV_3DI +INST4(fmul, "fmul", 0, IF_EN4D, 0x2E20DC00, 0x1E200800, 0x0F809000, 0x5F809000) // fmul Vd,Vn,Vm DV_3B 0Q1011100X1mmmmm 110111nnnnnddddd 2E20 DC00 Vd,Vn,Vm (vector) // fmul Vd,Vn,Vm DV_3D 000111100X1mmmmm 000010nnnnnddddd 1E20 0800 Vd,Vn,Vm (scalar) // fmul Vd,Vn,Vm[] DV_3BI 0Q0011111XLmmmmm 1001H0nnnnnddddd 0F80 9000 Vd,Vn,Vm[] (vector by elem) // fmul Vd,Vn,Vm[] DV_3DI 010111111XLmmmmm 1001H0nnnnnddddd 5F80 9000 Vd,Vn,Vm[] (scalar by elem) -INST4(fmulx, "fmulx", 0, 0, IF_EN4D, 0x0E20DC00, 0x5E20DC00, 0x2F809000, 0x7F809000) +INST4(fmulx, "fmulx", 0, IF_EN4D, 0x0E20DC00, 0x5E20DC00, 0x2F809000, 0x7F809000) // fmulx Vd,Vn,Vm DV_3B 0Q0011100X1mmmmm 110111nnnnnddddd 0E20 DC00 Vd,Vn,Vm (vector) // fmulx Vd,Vn,Vm DV_3D 010111100X1mmmmm 110111nnnnnddddd 5E20 DC00 Vd,Vn,Vm (scalar) // fmulx Vd,Vn,Vm[] DV_3BI 0Q1011111XLmmmmm 1001H0nnnnnddddd 2F80 9000 Vd,Vn,Vm[] (vector by elem) // fmulx Vd,Vn,Vm[] DV_3DI 011111111XLmmmmm 1001H0nnnnnddddd 7F80 9000 Vd,Vn,Vm[] (scalar by elem) -// enum name FP LD/ST DR_3A DR_3B DI_2C DV_3C -INST4(and, "and", 0, 0, IF_EN4E, 0x0A000000, 0x0A000000, 0x12000000, 0x0E201C00) +// enum name info DR_3A DR_3B DI_2C DV_3C +INST4(and, "and", 0, IF_EN4E, 0x0A000000, 0x0A000000, 0x12000000, 0x0E201C00) // and Rd,Rn,Rm DR_3A X0001010000mmmmm 000000nnnnnddddd 0A00 0000 // and Rd,Rn,(Rm,shk,imm) DR_3B X0001010sh0mmmmm iiiiiinnnnnddddd 0A00 0000 Rm {LSL,LSR,ASR,ROR} imm(0-63) // and Rd,Rn,imm(N,r,s) DI_2C X00100100Nrrrrrr ssssssnnnnnddddd 1200 0000 imm(N,r,s) // and Vd,Vn,Vm DV_3C 0Q001110001mmmmm 000111nnnnnddddd 0E20 1C00 Vd,Vn,Vm -INST4(eor, "eor", 0, 0, IF_EN4E, 0x4A000000, 0x4A000000, 0x52000000, 0x2E201C00) +INST4(eor, "eor", 0, IF_EN4E, 0x4A000000, 0x4A000000, 0x52000000, 0x2E201C00) // eor Rd,Rn,Rm DR_3A X1001010000mmmmm 000000nnnnnddddd 4A00 0000 // eor Rd,Rn,(Rm,shk,imm) DR_3B X1001010sh0mmmmm iiiiiinnnnnddddd 4A00 0000 Rm {LSL,LSR,ASR,ROR} imm(0-63) // eor Rd,Rn,imm(N,r,s) DI_2C X10100100Nrrrrrr ssssssnnnnnddddd 5200 0000 imm(N,r,s) // eor Vd,Vn,Vm DV_3C 0Q101110001mmmmm 000111nnnnnddddd 2E20 1C00 Vd,Vn,Vm -// enum name FP LD/ST DR_3A DR_3B DV_3C DV_1B -INST4(bic, "bic", 0, 0, IF_EN4F, 0x0A200000, 0x0A200000, 0x0E601C00, 0x2F001400) +// enum name info DR_3A DR_3B DV_3C DV_1B +INST4(bic, "bic", 0, IF_EN4F, 0x0A200000, 0x0A200000, 0x0E601C00, 0x2F001400) // bic Rd,Rn,Rm DR_3A X0001010001mmmmm 000000nnnnnddddd 0A20 0000 // bic Rd,Rn,(Rm,shk,imm) DR_3B X0001010sh1mmmmm iiiiiinnnnnddddd 0A20 0000 Rm {LSL,LSR,ASR,ROR} imm(0-63) // bic Vd,Vn,Vm DV_3C 0Q001110011mmmmm 000111nnnnnddddd 0E60 1C00 Vd,Vn,Vm // bic Vd,imm8 DV_1B 0Q10111100000iii ---101iiiiiddddd 2F00 1400 Vd imm8 (immediate vector) -// enum name FP LD/ST DR_2E DR_2F DV_2M DV_2L -INST4(neg, "neg", 0, 0, IF_EN4G, 0x4B0003E0, 0x4B0003E0, 0x2E20B800, 0x7E20B800) +// enum name info DR_2E DR_2F DV_2M DV_2L +INST4(neg, "neg", 0, IF_EN4G, 0x4B0003E0, 0x4B0003E0, 0x2E20B800, 0x7E20B800) // neg Rd,Rm DR_2E X1001011000mmmmm 00000011111ddddd 4B00 03E0 // neg Rd,(Rm,shk,imm) DR_2F X1001011sh0mmmmm ssssss11111ddddd 4B00 03E0 Rm {LSL,LSR,ASR} imm(0-63) // neg Vd,Vn DV_2M 0Q101110XX100000 101110nnnnnddddd 2E20 B800 Vd,Vn (vector) // neg Vd,Vn DV_2L 01111110XX100000 101110nnnnnddddd 7E20 B800 Vd,Vn (scalar) -// enum name FP LD/ST DV_3E DV_3A DV_2L DV_2M -INST4(cmeq, "cmeq", 0, 0, IF_EN4H, 0x7EE08C00, 0x2E208C00, 0x5E209800, 0x0E209800) +// enum name info DV_3E DV_3A DV_2L DV_2M +INST4(cmeq, "cmeq", 0, IF_EN4H, 0x7EE08C00, 0x2E208C00, 0x5E209800, 0x0E209800) // cmeq Vd,Vn,Vm DV_3E 01111110111mmmmm 100011nnnnnddddd 7EE0 8C00 Vd,Vn,Vm (scalar) // cmeq Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 100011nnnnnddddd 2E20 8C00 Vd,Vn,Vm (vector) // cmeq Vd,Vn DV_2L 01011110XX100000 100110nnnnnddddd 5E20 9800 Vd,Vn (scalar) // cmeq Vd,Vn DV_2M 0Q001110XX100000 100110nnnnnddddd 0E20 9800 Vd,Vn (vector) -INST4(cmge, "cmge", 0, 0, IF_EN4H, 0x5EE03C00, 0x0E203C00, 0x7E208800, 0x2E208800) +INST4(cmge, "cmge", 0, IF_EN4H, 0x5EE03C00, 0x0E203C00, 0x7E208800, 0x2E208800) // cmge Vd,Vn,Vm DV_3E 01011110111mmmmm 001111nnnnnddddd 5EE0 3C00 Vd,Vn,Vm (scalar) // cmge Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 001111nnnnnddddd 0E20 3C00 Vd,Vn,Vm (vector) // cmge Vd,Vn DV_2L 01111110XX100000 100010nnnnnddddd 5E20 8800 Vd,Vn (scalar) // cmge Vd,Vn DV_2M 0Q101110XX100000 100010nnnnnddddd 2E20 8800 Vd,Vn (vector) -INST4(cmgt, "cmgt", 0, 0, IF_EN4H, 0x5EE03400, 0x0E203400, 0x5E208800, 0x0E208800) +INST4(cmgt, "cmgt", 0, IF_EN4H, 0x5EE03400, 0x0E203400, 0x5E208800, 0x0E208800) // cmgt Vd,Vn,Vm DV_3E 01011110111mmmmm 001101nnnnnddddd 5EE0 3400 Vd,Vn,Vm (scalar) // cmgt Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 001101nnnnnddddd 0E20 3400 Vd,Vn,Vm (vector) // cmgt Vd,Vn DV_2L 01011110XX100000 100010nnnnnddddd 5E20 8800 Vd,Vn (scalar) // cmgt Vd,Vn DV_2M 0Q001110XX100000 101110nnnnnddddd 0E20 8800 Vd,Vn (vector) -// enum name FP LD/ST DV_3D DV_3B DV_2G DV_2A -INST4(fcmeq, "fcmeq", 0, 0, IF_EN4I, 0x5E20E400, 0x0E20E400, 0x5EA0D800, 0x0EA0D800) +// enum name info DV_3D DV_3B DV_2G DV_2A +INST4(fcmeq, "fcmeq", 0, IF_EN4I, 0x5E20E400, 0x0E20E400, 0x5EA0D800, 0x0EA0D800) // fcmeq Vd,Vn,Vm DV_3D 010111100X1mmmmm 111001nnnnnddddd 5E20 E400 Vd Vn Vm (scalar) // fcmeq Vd,Vn,Vm DV_3B 0Q0011100X1mmmmm 111001nnnnnddddd 0E20 E400 Vd,Vn,Vm (vector) // fcmeq Vd,Vn DV_2G 010111101X100000 110110nnnnnddddd 5EA0 D800 Vd Vn (scalar) // fcmeq Vd,Vn DV_2A 0Q0011101X100000 110110nnnnnddddd 0EA0 D800 Vd Vn (vector) -INST4(fcmge, "fcmge", 0, 0, IF_EN4I, 0x7E20E400, 0x2E20E400, 0x7EA0C800, 0x2EA0C800) +INST4(fcmge, "fcmge", 0, IF_EN4I, 0x7E20E400, 0x2E20E400, 0x7EA0C800, 0x2EA0C800) // fcmge Vd,Vn,Vm DV_3D 011111100X1mmmmm 111001nnnnnddddd 7E20 E400 Vd Vn Vm (scalar) // fcmge Vd,Vn,Vm DV_3B 0Q1011100X1mmmmm 111001nnnnnddddd 2E20 E400 Vd,Vn,Vm (vector) // fcmge Vd,Vn DV_2G 011111101X100000 110010nnnnnddddd 7EA0 E800 Vd Vn (scalar) // fcmge Vd,Vn DV_2A 0Q1011101X100000 110010nnnnnddddd 2EA0 C800 Vd Vn (vector) -INST4(fcmgt, "fcmgt", 0, 0, IF_EN4I, 0x7EA0E400, 0x2EA0E400, 0x5EA0C800, 0x0EA0C800) +INST4(fcmgt, "fcmgt", 0, IF_EN4I, 0x7EA0E400, 0x2EA0E400, 0x5EA0C800, 0x0EA0C800) // fcmgt Vd,Vn,Vm DV_3D 011111101X1mmmmm 111001nnnnnddddd 7EA0 E400 Vd Vn Vm (scalar) // fcmgt Vd,Vn,Vm DV_3B 0Q1011101X1mmmmm 111001nnnnnddddd 2EA0 E400 Vd,Vn,Vm (vector) // fcmgt Vd,Vn DV_2G 010111101X100000 110010nnnnnddddd 5EA0 E800 Vd Vn (scalar) // fcmgt Vd,Vn DV_2A 0Q0011101X100000 110010nnnnnddddd 0EA0 C800 Vd Vn (vector) -// enum name FP LD/ST DR_3A DR_3B DI_2C -INST3(ands, "ands", 0, 0, IF_EN3A, 0x6A000000, 0x6A000000, 0x72000000) +// enum name info DV_2N DV_2O DV_3E DV_3A +INST4(sqshl, "sqshl", 0, IF_EN4J, 0x5F007400, 0x0F007400, 0x5E204C00, 0x0E204C00) + // sqshl Vd,Vn,imm DV_2N 010111110iiiiiii 011101nnnnnddddd 5F00 7400 Vd Vn imm (left shift - scalar) + // sqshl Vd,Vn,imm DV_2O 0Q0011110iiiiiii 011101nnnnnddddd 0F00 7400 Vd Vn imm (left shift - vector) + // sqshl Vd,Vn,Vm DV_3E 01011110XX1mmmmm 010011nnnnnddddd 5E20 4C00 Vd Vn Vm (scalar) + // sqshl Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 010011nnnnnddddd 0E20 4C00 Vd Vn Vm (vector) + +INST4(uqshl, "uqshl", 0, IF_EN4J, 0x7F007400, 0x2F007400, 0x7E204C00, 0x2E204C00) + // uqshl Vd,Vn,imm DV_2N 011111110iiiiiii 011101nnnnnddddd 7F00 7400 Vd Vn imm (left shift - scalar) + // uqshl Vd,Vn,imm DV_2O 0Q1011110iiiiiii 011101nnnnnddddd 2F00 7400 Vd Vn imm (left shift - vector) + // uqshl Vd,Vn,Vm DV_3E 01111110XX1mmmmm 010011nnnnnddddd 7E20 4C00 Vd Vn Vm (scalar) + // uqshl Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 010011nnnnnddddd 2E20 4C00 Vd Vn Vm (vector) + +// enum name info DR_3A DR_3B DI_2C +INST3(ands, "ands", 0, IF_EN3A, 0x6A000000, 0x6A000000, 0x72000000) // ands Rd,Rn,Rm DR_3A X1101010000mmmmm 000000nnnnnddddd 6A00 0000 // ands Rd,Rn,(Rm,shk,imm) DR_3B X1101010sh0mmmmm iiiiiinnnnnddddd 6A00 0000 Rm {LSL,LSR,ASR,ROR} imm(0-63) // ands Rd,Rn,imm(N,r,s) DI_2C X11100100Nrrrrrr ssssssnnnnnddddd 7200 0000 imm(N,r,s) -// enum name FP LD/ST DR_2A DR_2B DI_1C -INST3(tst, "tst", 0, 0, IF_EN3B, 0x6A00001F, 0x6A00001F, 0x7200001F) +// enum name info DR_2A DR_2B DI_1C +INST3(tst, "tst", 0, IF_EN3B, 0x6A00001F, 0x6A00001F, 0x7200001F) // tst Rn,Rm DR_2A X1101010000mmmmm 000000nnnnn11111 6A00 001F // tst Rn,(Rm,shk,imm) DR_2B X1101010sh0mmmmm iiiiiinnnnn11111 6A00 001F Rm {LSL,LSR,ASR,ROR} imm(0-63) // tst Rn,imm(N,r,s) DI_1C X11100100Nrrrrrr ssssssnnnnn11111 7200 001F imm(N,r,s) -// enum name FP LD/ST DR_3A DR_3B DV_3C -INST3(orn, "orn", 0, 0, IF_EN3C, 0x2A200000, 0x2A200000, 0x0EE01C00) +// enum name info DR_3A DR_3B DV_3C +INST3(orn, "orn", 0, IF_EN3C, 0x2A200000, 0x2A200000, 0x0EE01C00) // orn Rd,Rn,Rm DR_3A X0101010001mmmmm 000000nnnnnddddd 2A20 0000 // orn Rd,Rn,(Rm,shk,imm) DR_3B X0101010sh1mmmmm iiiiiinnnnnddddd 2A20 0000 Rm {LSL,LSR,ASR,ROR} imm(0-63) // orn Vd,Vn,Vm DV_3C 0Q001110111mmmmm 000111nnnnnddddd 0EE0 1C00 Vd,Vn,Vm -// enum name FP LD/ST DV_2C DV_2D DV_2E -INST3(dup, "dup", 0, 0, IF_EN3D, 0x0E000C00, 0x0E000400, 0x5E000400) +// enum name info DV_2C DV_2D DV_2E +INST3(dup, "dup", 0, IF_EN3D, 0x0E000C00, 0x0E000400, 0x5E000400) // dup Vd,Rn DV_2C 0Q001110000iiiii 000011nnnnnddddd 0E00 0C00 Vd,Rn (vector from general) // dup Vd,Vn[] DV_2D 0Q001110000iiiii 000001nnnnnddddd 0E00 0400 Vd,Vn[] (vector by elem) // dup Vd,Vn[] DV_2E 01011110000iiiii 000001nnnnnddddd 5E00 0400 Vd,Vn[] (scalar by elem) -// enum name FP LD/ST DV_3B DV_3BI DV_3DI -INST3(fmla, "fmla", 0, 0, IF_EN3E, 0x0E20CC00, 0x0F801000, 0x5F801000) +// enum name info DV_3B DV_3BI DV_3DI +INST3(fmla, "fmla", 0, IF_EN3E, 0x0E20CC00, 0x0F801000, 0x5F801000) // fmla Vd,Vn,Vm DV_3B 0Q0011100X1mmmmm 110011nnnnnddddd 0E20 CC00 Vd,Vn,Vm (vector) // fmla Vd,Vn,Vm[] DV_3BI 0Q0011111XLmmmmm 0001H0nnnnnddddd 0F80 1000 Vd,Vn,Vm[] (vector by elem) // fmla Vd,Vn,Vm[] DV_3DI 010111111XLmmmmm 0001H0nnnnnddddd 5F80 1000 Vd,Vn,Vm[] (scalar by elem) -INST3(fmls, "fmls", 0, 0, IF_EN3E, 0x0EA0CC00, 0x0F805000, 0x5F805000) +INST3(fmls, "fmls", 0, IF_EN3E, 0x0EA0CC00, 0x0F805000, 0x5F805000) // fmls Vd,Vn,Vm DV_3B 0Q0011101X1mmmmm 110011nnnnnddddd 0EA0 CC00 Vd,Vn,Vm (vector) // fmls Vd,Vn,Vm[] DV_3BI 0Q0011111XLmmmmm 0101H0nnnnnddddd 0F80 5000 Vd,Vn,Vm[] (vector by elem) // fmls Vd,Vn,Vm[] DV_3DI 010111111XLmmmmm 0101H0nnnnnddddd 5F80 5000 Vd,Vn,Vm[] (scalar by elem) -// enum name FP LD/ST DV_2A DV_2G DV_2H -INST3(fcvtas, "fcvtas", 0, 0, IF_EN3F, 0x0E21C800, 0x5E21C800, 0x1E240000) +// enum name info DV_2A DV_2G DV_2H +INST3(fcvtas, "fcvtas", 0, IF_EN3F, 0x0E21C800, 0x5E21C800, 0x1E240000) // fcvtas Vd,Vn DV_2A 0Q0011100X100001 110010nnnnnddddd 0E21 C800 Vd,Vn (vector) // fcvtas Vd,Vn DV_2G 010111100X100001 110010nnnnnddddd 5E21 C800 Vd,Vn (scalar) // fcvtas Rd,Vn DV_2H X00111100X100100 000000nnnnnddddd 1E24 0000 Rd,Vn (scalar, to general) -INST3(fcvtau, "fcvtau", 0, 0, IF_EN3F, 0x2E21C800, 0x7E21C800, 0x1E250000) +INST3(fcvtau, "fcvtau", 0, IF_EN3F, 0x2E21C800, 0x7E21C800, 0x1E250000) // fcvtau Vd,Vn DV_2A 0Q1011100X100001 111010nnnnnddddd 2E21 C800 Vd,Vn (vector) // fcvtau Vd,Vn DV_2G 011111100X100001 111010nnnnnddddd 7E21 C800 Vd,Vn (scalar) // fcvtau Rd,Vn DV_2H X00111100X100101 000000nnnnnddddd 1E25 0000 Rd,Vn (scalar, to general) -INST3(fcvtms, "fcvtms", 0, 0, IF_EN3F, 0x0E21B800, 0x5E21B800, 0x1E300000) +INST3(fcvtms, "fcvtms", 0, IF_EN3F, 0x0E21B800, 0x5E21B800, 0x1E300000) // fcvtms Vd,Vn DV_2A 0Q0011100X100001 101110nnnnnddddd 0E21 B800 Vd,Vn (vector) // fcvtms Vd,Vn DV_2G 010111100X100001 101110nnnnnddddd 5E21 B800 Vd,Vn (scalar) // fcvtms Rd,Vn DV_2H X00111100X110000 000000nnnnnddddd 1E30 0000 Rd,Vn (scalar, to general) -INST3(fcvtmu, "fcvtmu", 0, 0, IF_EN3F, 0x2E21B800, 0x7E21B800, 0x1E310000) +INST3(fcvtmu, "fcvtmu", 0, IF_EN3F, 0x2E21B800, 0x7E21B800, 0x1E310000) // fcvtmu Vd,Vn DV_2A 0Q1011100X100001 101110nnnnnddddd 2E21 B800 Vd,Vn (vector) // fcvtmu Vd,Vn DV_2G 011111100X100001 101110nnnnnddddd 7E21 B800 Vd,Vn (scalar) // fcvtmu Rd,Vn DV_2H X00111100X110001 000000nnnnnddddd 1E31 0000 Rd,Vn (scalar, to general) -INST3(fcvtns, "fcvtns", 0, 0, IF_EN3F, 0x0E21A800, 0x5E21A800, 0x1E200000) +INST3(fcvtns, "fcvtns", 0, IF_EN3F, 0x0E21A800, 0x5E21A800, 0x1E200000) // fcvtns Vd,Vn DV_2A 0Q0011100X100001 101010nnnnnddddd 0E21 A800 Vd,Vn (vector) // fcvtns Vd,Vn DV_2G 010111100X100001 101010nnnnnddddd 5E21 A800 Vd,Vn (scalar) // fcvtns Rd,Vn DV_2H X00111100X100000 000000nnnnnddddd 1E20 0000 Rd,Vn (scalar, to general) -INST3(fcvtnu, "fcvtnu", 0, 0, IF_EN3F, 0x2E21A800, 0x7E21A800, 0x1E210000) +INST3(fcvtnu, "fcvtnu", 0, IF_EN3F, 0x2E21A800, 0x7E21A800, 0x1E210000) // fcvtnu Vd,Vn DV_2A 0Q1011100X100001 101010nnnnnddddd 2E21 A800 Vd,Vn (vector) // fcvtnu Vd,Vn DV_2G 011111100X100001 101010nnnnnddddd 7E21 A800 Vd,Vn (scalar) // fcvtnu Rd,Vn DV_2H X00111100X100001 000000nnnnnddddd 1E21 0000 Rd,Vn (scalar, to general) -INST3(fcvtps, "fcvtps", 0, 0, IF_EN3F, 0x0EA1A800, 0x5EA1A800, 0x1E280000) +INST3(fcvtps, "fcvtps", 0, IF_EN3F, 0x0EA1A800, 0x5EA1A800, 0x1E280000) // fcvtps Vd,Vn DV_2A 0Q0011101X100001 101010nnnnnddddd 0EA1 A800 Vd,Vn (vector) // fcvtps Vd,Vn DV_2G 010111101X100001 101010nnnnnddddd 5EA1 A800 Vd,Vn (scalar) // fcvtps Rd,Vn DV_2H X00111100X101000 000000nnnnnddddd 1E28 0000 Rd,Vn (scalar, to general) -INST3(fcvtpu, "fcvtpu", 0, 0, IF_EN3F, 0x2EA1A800, 0x7EA1A800, 0x1E290000) +INST3(fcvtpu, "fcvtpu", 0, IF_EN3F, 0x2EA1A800, 0x7EA1A800, 0x1E290000) // fcvtpu Vd,Vn DV_2A 0Q1011101X100001 101010nnnnnddddd 2EA1 A800 Vd,Vn (vector) // fcvtpu Vd,Vn DV_2G 011111101X100001 101010nnnnnddddd 7EA1 A800 Vd,Vn (scalar) // fcvtpu Rd,Vn DV_2H X00111100X101001 000000nnnnnddddd 1E29 0000 Rd,Vn (scalar, to general) -INST3(fcvtzs, "fcvtzs", 0, 0, IF_EN3F, 0x0EA1B800, 0x5EA1B800, 0x1E380000) +INST3(fcvtzs, "fcvtzs", 0, IF_EN3F, 0x0EA1B800, 0x5EA1B800, 0x1E380000) // fcvtzs Vd,Vn DV_2A 0Q0011101X100001 101110nnnnnddddd 0EA1 B800 Vd,Vn (vector) // fcvtzs Vd,Vn DV_2G 010111101X100001 101110nnnnnddddd 5EA1 B800 Vd,Vn (scalar) // fcvtzs Rd,Vn DV_2H X00111100X111000 000000nnnnnddddd 1E38 0000 Rd,Vn (scalar, to general) -INST3(fcvtzu, "fcvtzu", 0, 0, IF_EN3F, 0x2EA1B800, 0x7EA1B800, 0x1E390000) +INST3(fcvtzu, "fcvtzu", 0, IF_EN3F, 0x2EA1B800, 0x7EA1B800, 0x1E390000) // fcvtzu Vd,Vn DV_2A 0Q1011101X100001 101110nnnnnddddd 2EA1 B800 Vd,Vn (vector) // fcvtzu Vd,Vn DV_2G 011111101X100001 101110nnnnnddddd 7EA1 B800 Vd,Vn (scalar) // fcvtzu Rd,Vn DV_2H X00111100X111001 000000nnnnnddddd 1E39 0000 Rd,Vn (scalar, to general) -// enum name FP LD/ST DV_2A DV_2G DV_2I -INST3(scvtf, "scvtf", 0, 0, IF_EN3G, 0x0E21D800, 0x5E21D800, 0x1E220000) +// enum name info DV_2A DV_2G DV_2I +INST3(scvtf, "scvtf", 0, IF_EN3G, 0x0E21D800, 0x5E21D800, 0x1E220000) // scvtf Vd,Vn DV_2A 0Q0011100X100001 110110nnnnnddddd 0E21 D800 Vd,Vn (vector) // scvtf Vd,Vn DV_2G 010111100X100001 110110nnnnnddddd 7E21 D800 Vd,Vn (scalar) // scvtf Rd,Vn DV_2I X00111100X100010 000000nnnnnddddd 1E22 0000 Vd,Rn (scalar, from general) -INST3(ucvtf, "ucvtf", 0, 0, IF_EN3G, 0x2E21D800, 0x7E21D800, 0x1E230000) +INST3(ucvtf, "ucvtf", 0, IF_EN3G, 0x2E21D800, 0x7E21D800, 0x1E230000) // ucvtf Vd,Vn DV_2A 0Q1011100X100001 110110nnnnnddddd 2E21 D800 Vd,Vn (vector) // ucvtf Vd,Vn DV_2G 011111100X100001 110110nnnnnddddd 7E21 D800 Vd,Vn (scalar) // ucvtf Rd,Vn DV_2I X00111100X100011 000000nnnnnddddd 1E23 0000 Vd,Rn (scalar, from general) -INST3(mul, "mul", 0, 0, IF_EN3H, 0x1B007C00, 0x0E209C00, 0x0F008000) +INST3(mul, "mul", 0, IF_EN3H, 0x1B007C00, 0x0E209C00, 0x0F008000) // mul Rd,Rn,Rm DR_3A X0011011000mmmmm 011111nnnnnddddd 1B00 7C00 // mul Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 100111nnnnnddddd 0E20 9C00 Vd,Vn,Vm (vector) // mul Vd,Vn,Vm[] DV_3AI 0Q001111XXLMmmmm 1000H0nnnnnddddd 0F00 8000 Vd,Vn,Vm[] (vector by elem) -// enum name FP LD/ST DR_2E DR_2F DV_2M -INST3(mvn, "mvn", 0, 0, IF_EN3I, 0x2A2003E0, 0x2A2003E0, 0x2E205800) +// enum name info DR_2E DR_2F DV_2M +INST3(mvn, "mvn", 0, IF_EN3I, 0x2A2003E0, 0x2A2003E0, 0x2E205800) // mvn Rd,Rm DR_2E X0101010001mmmmm 00000011111ddddd 2A20 03E0 // mvn Rd,(Rm,shk,imm) DR_2F X0101010sh1mmmmm iiiiii11111ddddd 2A20 03E0 Rm {LSL,LSR,ASR} imm(0-63) // mvn Vd,Vn DV_2M 0Q10111000100000 010110nnnnnddddd 2E20 5800 Vd,Vn (vector) -// enum name FP LD/ST LS_2D LS_3F LS_2E -INST3(ld1_2regs,"ld1", 0,LD, IF_EN3J, 0x0C40A000, 0x0CC0A000, 0x0CDFA000) - // C7.2.170 LD1 (multiple structures, two registers variant) +// enum name info LS_2D LS_3F LS_2E +INST3(ld1_2regs, "ld1", LD, IF_EN3J, 0x0C40A000, 0x0CC0A000, 0x0CDFA000) + // LD1 (multiple structures, two registers variant) // ld1 {Vt,Vt2},[Xn] LS_2D 0Q00110001000000 1010ssnnnnnttttt 0C40 A000 base register // ld1 {Vt,Vt2},[Xn],Xm LS_3F 0Q001100110mmmmm 1010ssnnnnnttttt 0CC0 A000 post-indexed by a register // ld1 {Vt,Vt2},[Xn],#imm LS_2E 0Q00110011011111 1010ssnnnnnttttt 0CDF A000 post-indexed by an immediate -INST3(ld1_3regs,"ld1", 0,LD, IF_EN3J, 0x0C406000, 0x0CC06000, 0x0CDF6000) - // C7.2.170 LD1 (multiple structures, three registers variant) +INST3(ld1_3regs, "ld1", LD, IF_EN3J, 0x0C406000, 0x0CC06000, 0x0CDF6000) + // LD1 (multiple structures, three registers variant) // ld1 {Vt-Vt3},[Xn] LS_2D 0Q00110001000000 0110ssnnnnnttttt 0C40 6000 base register // ld1 {Vt-Vt3},[Xn],Xm LS_3F 0Q001100110mmmmm 0110ssnnnnnttttt 0CC0 6000 post-indexed by a register // ld1 {Vt-Vt3},[Xn],#imm LS_2E 0Q00110011011111 0110ssnnnnnttttt 0CDF 6000 post-indexed by an immediate -INST3(ld1_4regs,"ld1", 0,LD, IF_EN3J, 0x0C402000, 0x0CC02000, 0x0CDF2000) - // C7.2.170 LD1 (multiple structures, four registers variant) +INST3(ld1_4regs, "ld1", LD, IF_EN3J, 0x0C402000, 0x0CC02000, 0x0CDF2000) + // LD1 (multiple structures, four registers variant) // ld1 {Vt-Vt4},[Xn] LS_2D 0Q00110001000000 0010ssnnnnnttttt 0C40 2000 base register // ld1 {Vt-Vt4},[Xn],Xm LS_3F 0Q001100110mmmmm 0010ssnnnnnttttt 0CC0 2000 post-indexed by a register // ld1 {Vt-Vt4},[Xn],#imm LS_2E 0Q00110011011111 0010ssnnnnnttttt 0CDF 2000 post-indexed by an immediate -INST3(st1_2regs,"st1", 0,ST, IF_EN3J, 0x0C00A000, 0x0C80A000, 0x0C9FA000) - // C7.2.313 ST1 (multiple structures, two registers variant) +INST3(st1_2regs, "st1", ST, IF_EN3J, 0x0C00A000, 0x0C80A000, 0x0C9FA000) + // ST1 (multiple structures, two registers variant) // st1 {Vt,Vt2},[Xn] LS_2D 0Q00110000000000 1010ssnnnnnttttt 0C00 A000 base register // st1 {Vt,Vt2},[Xn],Xm LS_3F 0Q001100100mmmmm 1010ssnnnnnttttt 0C80 A000 post-indexed by a register // st1 {Vt,Vt2},[Xn],#imm LS_2E 0Q00110010011111 1010ssnnnnnttttt 0C9F A000 post-indexed by an immediate -INST3(st1_3regs,"st1", 0,ST, IF_EN3J, 0x0C006000, 0x0C806000, 0x0C9F6000) - // C7.2.313 ST1 (multiple structures, three registers variant) +INST3(st1_3regs, "st1", ST, IF_EN3J, 0x0C006000, 0x0C806000, 0x0C9F6000) + // ST1 (multiple structures, three registers variant) // st1 {Vt-Vt3},[Xn] LS_2D 0Q00110000000000 0110ssnnnnnttttt 0C00 6000 base register // st1 {Vt-Vt3},[Xn],Xm LS_3F 0Q001100100mmmmm 0110XXnnnnnttttt 0C80 6000 post-indexed by a register // st1 {Vt-Vt3},[Xn],#imm LS_2E 0Q00110010011111 0110XXnnnnnttttt 0C9F 6000 post-indexed by an immediate -INST3(st1_4regs,"st1", 0,ST, IF_EN3J, 0x0C002000, 0x0C802000, 0x0C9F2000) - // C7.2.313 ST1 (multiple structures, four registers variant) +INST3(st1_4regs, "st1", ST, IF_EN3J, 0x0C002000, 0x0C802000, 0x0C9F2000) + // ST1 (multiple structures, four registers variant) // st1 {Vt-Vt4},[Xn] LS_2D 0Q00110000000000 0010XXnnnnnttttt 0C00 2000 base register // st1 {Vt-Vt4},[Xn],Xm LS_3F 0Q001100100mmmmm 0010XXnnnnnttttt 0C80 2000 post-indexed by a register // st1 {Vt-Vt4},[Xn],#imm LS_2E 0Q00110010011111 0010XXnnnnnttttt 0C9F 2000 post-indexed by an immediate -INST3(ld1r, "ld1r", 0,LD, IF_EN3J, 0x0D40C000, 0x0DC0C000, 0x0DDFC000) - // C7.2.172 LD1R +INST3(ld1r, "ld1r", LD, IF_EN3J, 0x0D40C000, 0x0DC0C000, 0x0DDFC000) // ld1r {Vt},[Xn] LS_2D 0Q00110101000000 1100ssnnnnnttttt 0D40 C000 base register // ld1r {Vt},[Xn],Xm LS_3F 0Q001101110mmmmm 1100ssnnnnnttttt 0DC0 C000 post-indexed by a register // ld1r {Vt},[Xn],#1 LS_2E 0Q00110111011111 1100ssnnnnnttttt 0DDF C000 post-indexed by an immediate -INST3(ld2r, "ld2r", 0,LD, IF_EN3J, 0x0D60C000, 0x0DE0C000, 0x0DFFC000) - // C7.2.175 LD2R +INST3(ld2r, "ld2r", LD, IF_EN3J, 0x0D60C000, 0x0DE0C000, 0x0DFFC000) // ld2r {Vt,Vt2},[Xn] LS_2D 0Q00110101100000 1100ssnnnnnttttt 0D60 C000 base register // ld2r {Vt,Vt2},[Xn],Xm LS_3F 0Q001101111mmmmm 1100ssnnnnnttttt 0DE0 C000 post-indexed by a register // ld2r {Vt,Vt2},[Xn],#2 LS_2E 0Q00110111111111 1100ssnnnnnttttt 0DFF C000 post-indexed by an immediate -INST3(ld3r, "ld3r", 0,LD, IF_EN3J, 0x0D40E000, 0x0DC0E000, 0x0DDFE000) - // C7.2.178 LD3R +INST3(ld3r, "ld3r", LD, IF_EN3J, 0x0D40E000, 0x0DC0E000, 0x0DDFE000) // ld3r {Vt-Vt3},[Xn] LS_2D 0Q00110101000000 1110ssnnnnnttttt 0D40 E000 base register // ld3r {Vt-Vt3},[Xn],Xm LS_3F 0Q001101110mmmmm 1110ssnnnnnttttt 0DC0 E000 post-indexed by a register // ld3r {Vt-Vt3},[Xn],#4 LS_2E 0Q00110111011111 1110ssnnnnnttttt 0DDF E000 post-indexed by an immediate -INST3(ld4r, "ld4r", 0,LD, IF_EN3J, 0x0D60E000, 0x0DE0E000, 0x0DFFE000) - // C7.2.181 LD4R +INST3(ld4r, "ld4r", LD, IF_EN3J, 0x0D60E000, 0x0DE0E000, 0x0DFFE000) // ld4r {Vt-Vt4},[Xn] LS_2D 0Q00110101100000 1110ssnnnnnttttt 0D60 E000 base register // ld4r {Vt-Vt4},[Xn],Xm LS_3F 0Q001101111mmmmm 1110ssnnnnnttttt 0DE0 E000 post-indexed by a register // ld4r {Vt-Vt4},[Xn],#8 LS_2E 0Q00110111111111 1110ssnnnnnttttt 0DFF E000 post-indexed by an immediate -INST3(smull, "smull", 0, 0, IF_EN3K, 0x9B207C00, 0x0E20C000, 0x0F00A000) - // C6.2.243 SMULL - // C7.2.272 SMULL, SMULL2 (by element) - // C7.2.273 SMULL, SMULL2 (vector) +INST3(smull, "smull", 0, IF_EN3K, 0x9B207C00, 0x0E20C000, 0x0F00A000) // smull Rd,Rn,Rm DR_3A 10011011001mmmmm 011111nnnnnddddd 9B20 7C00 // smull Vd,Vn,Vm DV_3H 0000111000100000 1100000000000000 0E20 C000 Vd,Vn,Vm (vector) // smull Vd,Vn,Vm[] DV_3HI 00001111XXLMmmmm 1010H0nnnnnddddd 0F00 A000 Vd,Vn,Vm[] (vector by elem) -INST3(umull, "umull", 0, 0, IF_EN3K, 0x9BA07C00, 0x2E20C000, 0x2F00A000) - // C6.2.340 UMULL - // C7.2.362 UMULL, UMULL2 (by element) - // C7.2.363 UMULL, UMULL2 (vector) +INST3(umull, "umull", 0, IF_EN3K, 0x9BA07C00, 0x2E20C000, 0x2F00A000) // umull Rd,Rn,Rm DR_3A 10011011101mmmmm 011111nnnnnddddd 9BA0 7C00 // umull Vd,Vn,Vm DV_3H 00101110XX1mmmmm 110000nnnnnddddd 2E20 C000 Vd,Vn,Vm (vector) // umull Vd,Vn,Vm[] DV_3HI 00101111XXLMmmmm 1010H0nnnnnddddd 2F00 A000 Vd,Vn,Vm[] (vector by elem) -// enum name FP LD/ST DR_2E DR_2F -INST2(negs, "negs", 0, 0, IF_EN2A, 0x6B0003E0, 0x6B0003E0) +// enum name info DR_2E DR_2F +INST2(negs, "negs", 0, IF_EN2A, 0x6B0003E0, 0x6B0003E0) // negs Rd,Rm DR_2E X1101011000mmmmm 00000011111ddddd 6B00 03E0 // negs Rd,(Rm,shk,imm) DR_2F X1101011sh0mmmmm ssssss11111ddddd 6B00 03E0 Rm {LSL,LSR,ASR} imm(0-63) -// enum name FP LD/ST DR_3A DR_3B -INST2(bics, "bics", 0, 0, IF_EN2B, 0x6A200000, 0x6A200000) +// enum name info DR_3A DR_3B +INST2(bics, "bics", 0, IF_EN2B, 0x6A200000, 0x6A200000) // bics Rd,Rn,Rm DR_3A X1101010001mmmmm 000000nnnnnddddd 6A20 0000 // bics Rd,Rn,(Rm,shk,imm) DR_3B X1101010sh1mmmmm iiiiiinnnnnddddd 6A20 0000 Rm {LSL,LSR,ASR,ROR} imm(0-63) -INST2(eon, "eon", 0, 0, IF_EN2B, 0x4A200000, 0x4A200000) +INST2(eon, "eon", 0, IF_EN2B, 0x4A200000, 0x4A200000) // eon Rd,Rn,Rm DR_3A X1001010001mmmmm 000000nnnnnddddd 4A20 0000 // eon Rd,Rn,(Rm,shk,imm) DR_3B X1001010sh1mmmmm iiiiiinnnnnddddd 4A20 0000 Rm {LSL,LSR,ASR,ROR} imm(0-63) -// enum name FP LD/ST DR_3A DI_2C -INST2(lsl, "lsl", 0, 0, IF_EN2C, 0x1AC02000, 0x53000000) +// enum name info DR_3A DI_2C +INST2(lsl, "lsl", 0, IF_EN2C, 0x1AC02000, 0x53000000) // lsl Rd,Rn,Rm DR_3A X0011010110mmmmm 001000nnnnnddddd 1AC0 2000 // lsl Rd,Rn,imm6 DI_2D X10100110Xrrrrrr ssssssnnnnnddddd 5300 0000 imm(N,r,s) -INST2(lsr, "lsr", 0, 0, IF_EN2C, 0x1AC02400, 0x53000000) +INST2(lsr, "lsr", 0, IF_EN2C, 0x1AC02400, 0x53000000) // lsr Rd,Rn,Rm DR_3A X0011010110mmmmm 001001nnnnnddddd 1AC0 2400 // lsr Rd,Rn,imm6 DI_2D X10100110Xrrrrrr ssssssnnnnnddddd 5300 0000 imm(N,r,s) -INST2(asr, "asr", 0, 0, IF_EN2C, 0x1AC02800, 0x13000000) +INST2(asr, "asr", 0, IF_EN2C, 0x1AC02800, 0x13000000) // asr Rd,Rn,Rm DR_3A X0011010110mmmmm 001010nnnnnddddd 1AC0 2800 // asr Rd,Rn,imm6 DI_2D X00100110Xrrrrrr ssssssnnnnnddddd 1300 0000 imm(N,r,s) -// enum name FP LD/ST DR_3A DI_2B -INST2(ror, "ror", 0, 0, IF_EN2D, 0x1AC02C00, 0x13800000) +// enum name info DR_3A DI_2B +INST2(ror, "ror", 0, IF_EN2D, 0x1AC02C00, 0x13800000) // ror Rd,Rn,Rm DR_3A X0011010110mmmmm 001011nnnnnddddd 1AC0 2C00 // ror Rd,Rn,imm6 DI_2B X00100111X0nnnnn ssssssnnnnnddddd 1380 0000 imm(0-63) -// enum name FP LD/ST LS_3B LS_3C -INST2(ldp, "ldp", 0,LD, IF_EN2E, 0x29400000, 0x28400000) +// enum name info LS_3B LS_3C +INST2(ldp, "ldp", LD, IF_EN2E, 0x29400000, 0x28400000) // ldp Rt,Ra,[Xn] LS_3B X010100101000000 0aaaaannnnnttttt 2940 0000 [Xn imm7] // ldp Rt,Ra,[Xn+simm7] LS_3C X010100PP1iiiiii iaaaaannnnnttttt 2840 0000 [Xn imm7 LSL {} pre/post/no inc] -INST2(ldpsw, "ldpsw", 0,LD, IF_EN2E, 0x69400000, 0x68400000) +INST2(ldpsw, "ldpsw", LD, IF_EN2E, 0x69400000, 0x68400000) // ldpsw Rt,Ra,[Xn] LS_3B 0110100101000000 0aaaaannnnnttttt 6940 0000 [Xn imm7] // ldpsw Rt,Ra,[Xn+simm7] LS_3C 0110100PP1iiiiii iaaaaannnnnttttt 6840 0000 [Xn imm7 LSL {} pre/post/no inc] -INST2(stp, "stp", 0,ST, IF_EN2E, 0x29000000, 0x28000000) +INST2(stp, "stp", ST, IF_EN2E, 0x29000000, 0x28000000) // stp Rt,Ra,[Xn] LS_3B X010100100000000 0aaaaannnnnttttt 2900 0000 [Xn imm7] // stp Rt,Ra,[Xn+simm7] LS_3C X010100PP0iiiiii iaaaaannnnnttttt 2800 0000 [Xn imm7 LSL {} pre/post/no inc] -INST2(ldnp, "ldnp", 0,LD, IF_EN2E, 0x28400000, 0x28400000) +INST2(ldnp, "ldnp", LD, IF_EN2E, 0x28400000, 0x28400000) // ldnp Rt,Ra,[Xn] LS_3B X010100001000000 0aaaaannnnnttttt 2840 0000 [Xn imm7] // ldnp Rt,Ra,[Xn+simm7] LS_3C X010100001iiiiii iaaaaannnnnttttt 2840 0000 [Xn imm7 LSL {}] -INST2(stnp, "stnp", 0,ST, IF_EN2E, 0x28000000, 0x28000000) +INST2(stnp, "stnp", ST, IF_EN2E, 0x28000000, 0x28000000) // stnp Rt,Ra,[Xn] LS_3B X010100000000000 0aaaaannnnnttttt 2800 0000 [Xn imm7] // stnp Rt,Ra,[Xn+simm7] LS_3C X010100000iiiiii iaaaaannnnnttttt 2800 0000 [Xn imm7 LSL {}] -INST2(ccmp, "ccmp", 0,CMP,IF_EN2F, 0x7A400000, 0x7A400800) +INST2(ccmp, "ccmp", CMP, IF_EN2F, 0x7A400000, 0x7A400800) // ccmp Rn,Rm, nzcv,cond DR_2I X1111010010mmmmm cccc00nnnnn0nzcv 7A40 0000 nzcv, cond // ccmp Rn,imm5,nzcv,cond DI_1F X1111010010iiiii cccc10nnnnn0nzcv 7A40 0800 imm5, nzcv, cond -INST2(ccmn, "ccmn", 0,CMP,IF_EN2F, 0x3A400000, 0x3A400800) +INST2(ccmn, "ccmn", CMP, IF_EN2F, 0x3A400000, 0x3A400800) // ccmn Rn,Rm, nzcv,cond DR_2I X0111010010mmmmm cccc00nnnnn0nzcv 3A40 0000 nzcv, cond // ccmn Rn,imm5,nzcv,cond DI_1F X0111010910iiiii cccc10nnnnn0nzcv 3A40 0800 imm5, nzcv, cond -// enum name FP LD/ST DV_2C DV_2F -INST2(ins, "ins", 0, 0, IF_EN2H, 0x4E001C00, 0x6E000400) +// enum name info DV_2C DV_2F +INST2(ins, "ins", 0, IF_EN2H, 0x4E001C00, 0x6E000400) // ins Vd[],Rn DV_2C 01001110000iiiii 000111nnnnnddddd 4E00 1C00 Vd[],Rn (from general) // ins Vd[],Vn[] DV_2F 01101110000iiiii 0jjjj1nnnnnddddd 6E00 0400 Vd[],Vn[] (from/to elem) -// enum name FP LD/ST DV_3B DV_3D -INST2(fadd, "fadd", 0, 0, IF_EN2G, 0x0E20D400, 0x1E202800) +// enum name info DV_3B DV_3D +INST2(fadd, "fadd", 0, IF_EN2G, 0x0E20D400, 0x1E202800) // fadd Vd,Vn,Vm DV_3B 0Q0011100X1mmmmm 110101nnnnnddddd 0E20 D400 Vd,Vn,Vm (vector) // fadd Vd,Vn,Vm DV_3D 000111100X1mmmmm 001010nnnnnddddd 1E20 2800 Vd,Vn,Vm (scalar) -INST2(fsub, "fsub", 0, 0, IF_EN2G, 0x0EA0D400, 0x1E203800) +INST2(fsub, "fsub", 0, IF_EN2G, 0x0EA0D400, 0x1E203800) // fsub Vd,Vn,Vm DV_3B 0Q0011101X1mmmmm 110101nnnnnddddd 0EA0 D400 Vd,Vn,Vm (vector) // fsub Vd,Vn,Vm DV_3D 000111100X1mmmmm 001110nnnnnddddd 1E20 3800 Vd,Vn,Vm (scalar) -INST2(fdiv, "fdiv", 0, 0, IF_EN2G, 0x2E20FC00, 0x1E201800) +INST2(fdiv, "fdiv", 0, IF_EN2G, 0x2E20FC00, 0x1E201800) // fdiv Vd,Vn,Vm DV_3B 0Q1011100X1mmmmm 111111nnnnnddddd 2E20 FC00 Vd,Vn,Vm (vector) // fdiv Vd,Vn,Vm DV_3D 000111100X1mmmmm 000110nnnnnddddd 1E20 1800 Vd,Vn,Vm (scalar) -INST2(fmax, "fmax", 0, 0, IF_EN2G, 0x0E20F400, 0x1E204800) +INST2(fmax, "fmax", 0, IF_EN2G, 0x0E20F400, 0x1E204800) // fmax Vd,Vn,Vm DV_3B 0Q0011100X1mmmmm 111101nnnnnddddd 0E20 F400 Vd,Vn,Vm (vector) // fmax Vd,Vn,Vm DV_3D 000111100X1mmmmm 010010nnnnnddddd 1E20 4800 Vd,Vn,Vm (scalar) -INST2(fmaxnm, "fmaxnm", 0, 0, IF_EN2G, 0x0E20C400, 0x1E206800) +INST2(fmaxnm, "fmaxnm", 0, IF_EN2G, 0x0E20C400, 0x1E206800) // fmaxnm Vd,Vn,Vm DV_3B 0Q0011100X1mmmmm 110001nnnnnddddd 0E20 C400 Vd,Vn,Vm (vector) // fmaxnm Vd,Vn,Vm DV_3D 000111100X1mmmmm 011010nnnnnddddd 1E20 6800 Vd,Vn,Vm (scalar) -INST2(fmin, "fmin", 0, 0, IF_EN2G, 0x0EA0F400, 0x1E205800) +INST2(fmin, "fmin", 0, IF_EN2G, 0x0EA0F400, 0x1E205800) // fmin Vd,Vn,Vm DV_3B 0Q0011101X1mmmmm 111101nnnnnddddd 0EA0 F400 Vd,Vn,Vm (vector) // fmin Vd,Vn,Vm DV_3D 000111100X1mmmmm 010110nnnnnddddd 1E20 5800 Vd,Vn,Vm (scalar) -INST2(fminnm, "fminnm", 0, 0, IF_EN2G, 0x0EA0C400, 0x1E207800) +INST2(fminnm, "fminnm", 0, IF_EN2G, 0x0EA0C400, 0x1E207800) // fminnm Vd,Vn,Vm DV_3B 0Q0011101X1mmmmm 110001nnnnnddddd 0EA0 C400 Vd,Vn,Vm (vector) // fminnm Vd,Vn,Vm DV_3D 000111100X1mmmmm 011110nnnnnddddd 1E20 7800 Vd,Vn,Vm (scalar) -INST2(fabd, "fabd", 0, 0, IF_EN2G, 0x2EA0D400, 0x7EA0D400) +INST2(fabd, "fabd", 0, IF_EN2G, 0x2EA0D400, 0x7EA0D400) // fabd Vd,Vn,Vm DV_3B 0Q1011101X1mmmmm 110101nnnnnddddd 2EA0 D400 Vd,Vn,Vm (vector) // fabd Vd,Vn,Vm DV_3D 011111101X1mmmmm 110101nnnnnddddd 7EA0 D400 Vd,Vn,Vm (scalar) -INST2(facge, "facge", 0, 0, IF_EN2G, 0x2E20EC00, 0x7E20EC00) +INST2(facge, "facge", 0, IF_EN2G, 0x2E20EC00, 0x7E20EC00) // facge Vd,Vn,Vm DV_3B 0Q1011100X1mmmmm 111011nnnnnddddd 2E20 EC00 Vd,Vn,Vm (vector) // facge Vd,Vn,Vm DV_3D 011111100X1mmmmm 111011nnnnnddddd 7E20 EC00 Vd,Vn,Vm (scalar) -INST2(facgt, "facgt", 0, 0, IF_EN2G, 0x2EA0EC00, 0x7EA0EC00) +INST2(facgt, "facgt", 0, IF_EN2G, 0x2EA0EC00, 0x7EA0EC00) // facgt Vd,Vn,Vm DV_3B 0Q1011101X1mmmmm 111011nnnnnddddd 2EA0 EC00 Vd,Vn,Vm (vector) // facgt Vd,Vn,Vm DV_3D 011111101X1mmmmm 111011nnnnnddddd 7EA0 EC00 Vd,Vn,Vm (scalar) -INST2(frecps, "frecps", 0, 0, IF_EN2G, 0x0E20FC00, 0x5E20FC00) - // C7.2.138 FRECPS +INST2(frecps, "frecps", 0, IF_EN2G, 0x0E20FC00, 0x5E20FC00) // frecps Vd,Vn,Vm DV_3B 0Q0011100X1mmmmm 111111nnnnnddddd 0E20 FC00 Vd,Vn,Vm (vector) // frecps Vd,Vn,Vm DV_3D 010111100X1mmmmm 111111nnnnnddddd 5E20 FC00 Vd,Vn,Vm (scalar) -INST2(frsqrts, "frsqrts",0, 0, IF_EN2G, 0x0EA0FC00, 0x5EA0FC00) - // C7.2.163 FRSQRTS +INST2(frsqrts, "frsqrts", 0, IF_EN2G, 0x0EA0FC00, 0x5EA0FC00) // frsqrts Vd,Vn,Vm DV_3B 0Q0011101X1mmmmm 111111nnnnnddddd 0EA0 FC00 Vd,Vn,Vm (vector) // frsqrts Vd,Vn,Vm DV_3D 010111101X1mmmmm 111111nnnnnddddd 5EA0 FC00 Vd,Vn,Vm (scalar) -// enum name FP LD/ST DV_2K DV_1C -INST2(fcmp, "fcmp", 0, 0, IF_EN2I, 0x1E202000, 0x1E202008) +// enum name info DV_2K DV_1C +INST2(fcmp, "fcmp", 0, IF_EN2I, 0x1E202000, 0x1E202008) // fcmp Vn,Vm DV_2K 000111100X1mmmmm 001000nnnnn00000 1E20 2000 Vn Vm // fcmp Vn,#0.0 DV_1C 000111100X100000 001000nnnnn01000 1E20 2008 Vn #0.0 -INST2(fcmpe, "fcmpe", 0, 0, IF_EN2I, 0x1E202010, 0x1E202018) +INST2(fcmpe, "fcmpe", 0, IF_EN2I, 0x1E202010, 0x1E202018) // fcmpe Vn,Vm DV_2K 000111100X1mmmmm 001000nnnnn10000 1E20 2010 Vn Vm // fcmpe Vn,#0.0 DV_1C 000111100X100000 001000nnnnn11000 1E20 2018 Vn #0.0 -// enum name FP LD/ST DV_2A DV_2G -INST2(fabs, "fabs", 0, 0, IF_EN2J, 0x0EA0F800, 0x1E20C000) +// enum name info DV_2A DV_2G +INST2(fabs, "fabs", 0, IF_EN2J, 0x0EA0F800, 0x1E20C000) // fabs Vd,Vn DV_2A 0Q0011101X100000 111110nnnnnddddd 0EA0 F800 Vd,Vn (vector) // fabs Vd,Vn DV_2G 000111100X100000 110000nnnnnddddd 1E20 C000 Vd,Vn (scalar) -INST2(fcmle, "fcmle", 0, 0, IF_EN2J, 0x2EA0D800, 0x7EA0D800) +INST2(fcmle, "fcmle", 0, IF_EN2J, 0x2EA0D800, 0x7EA0D800) // fcmle Vd,Vn DV_2A 0Q1011101X100000 111110nnnnnddddd 2EA0 D800 Vd,Vn (vector) // fcmle Vd,Vn DV_2G 011111101X100000 110110nnnnnddddd 7EA0 D800 Vd,Vn (scalar) -INST2(fcmlt, "fcmlt", 0, 0, IF_EN2J, 0x0EA0E800, 0x5EA0E800) +INST2(fcmlt, "fcmlt", 0, IF_EN2J, 0x0EA0E800, 0x5EA0E800) // fcmlt Vd,Vn DV_2A 0Q0011101X100000 111110nnnnnddddd 0EA0 E800 Vd,Vn (vector) // fcmlt Vd,Vn DV_2G 010111101X100000 111010nnnnnddddd 5EA0 E800 Vd,Vn (scalar) -INST2(fneg, "fneg", 0, 0, IF_EN2J, 0x2EA0F800, 0x1E214000) +INST2(fneg, "fneg", 0, IF_EN2J, 0x2EA0F800, 0x1E214000) // fneg Vd,Vn DV_2A 0Q1011101X100000 111110nnnnnddddd 2EA0 F800 Vd,Vn (vector) // fneg Vd,Vn DV_2G 000111100X100001 010000nnnnnddddd 1E21 4000 Vd,Vn (scalar) -INST2(frecpe, "frecpe", 0, 0, IF_EN2J, 0x0EA1D800, 0x5EA1D800) +INST2(frecpe, "frecpe", 0, IF_EN2J, 0x0EA1D800, 0x5EA1D800) // frecpe Vd,Vn DV_2A 0Q0011101X100001 110110nnnnnddddd 0EA1 D800 Vd,Vn (vector) // frecpe Vd,Vn DV_2G 010111101X100001 110110nnnnnddddd 5EA1 D800 Vd,Vn (scalar) -INST2(frintn, "frintn", 0, 0, IF_EN2J, 0x0E218800, 0x1E244000) +INST2(frintn, "frintn", 0, IF_EN2J, 0x0E218800, 0x1E244000) // frintn Vd,Vn DV_2A 0Q0011100X100001 100010nnnnnddddd 0E21 8800 Vd,Vn (vector) // frintn Vd,Vn DV_2G 000111100X100100 010000nnnnnddddd 1E24 4000 Vd,Vn (scalar) -INST2(frintp, "frintp", 0, 0, IF_EN2J, 0x0EA18800, 0x1E24C000) +INST2(frintp, "frintp", 0, IF_EN2J, 0x0EA18800, 0x1E24C000) // frintp Vd,Vn DV_2A 0Q0011101X100001 100010nnnnnddddd 0EA1 8800 Vd,Vn (vector) // frintp Vd,Vn DV_2G 000111100X100100 110000nnnnnddddd 1E24 C000 Vd,Vn (scalar) -INST2(frintm, "frintm", 0, 0, IF_EN2J, 0x0E219800, 0x1E254000) +INST2(frintm, "frintm", 0, IF_EN2J, 0x0E219800, 0x1E254000) // frintm Vd,Vn DV_2A 0Q0011100X100001 100110nnnnnddddd 0E21 9800 Vd,Vn (vector) // frintm Vd,Vn DV_2G 000111100X100101 010000nnnnnddddd 1E25 4000 Vd,Vn (scalar) -INST2(frintz, "frintz", 0, 0, IF_EN2J, 0x0EA19800, 0x1E25C000) +INST2(frintz, "frintz", 0, IF_EN2J, 0x0EA19800, 0x1E25C000) // frintz Vd,Vn DV_2A 0Q0011101X100001 100110nnnnnddddd 0EA1 9800 Vd,Vn (vector) // frintz Vd,Vn DV_2G 000111100X100101 110000nnnnnddddd 1E25 C000 Vd,Vn (scalar) -INST2(frinta, "frinta", 0, 0, IF_EN2J, 0x2E218800, 0x1E264000) +INST2(frinta, "frinta", 0, IF_EN2J, 0x2E218800, 0x1E264000) // frinta Vd,Vn DV_2A 0Q1011100X100001 100010nnnnnddddd 2E21 8800 Vd,Vn (vector) // frinta Vd,Vn DV_2G 000111100X100110 010000nnnnnddddd 1E26 4000 Vd,Vn (scalar) -INST2(frintx, "frintx", 0, 0, IF_EN2J, 0x2E219800, 0x1E274000) +INST2(frintx, "frintx", 0, IF_EN2J, 0x2E219800, 0x1E274000) // frintx Vd,Vn DV_2A 0Q1011100X100001 100110nnnnnddddd 2E21 9800 Vd,Vn (vector) // frintx Vd,Vn DV_2G 000111100X100111 010000nnnnnddddd 1E27 4000 Vd,Vn (scalar) -INST2(frinti, "frinti", 0, 0, IF_EN2J, 0x2EA19800, 0x1E27C000) +INST2(frinti, "frinti", 0, IF_EN2J, 0x2EA19800, 0x1E27C000) // frinti Vd,Vn DV_2A 0Q1011101X100001 100110nnnnnddddd 2EA1 9800 Vd,Vn (vector) // frinti Vd,Vn DV_2G 000111100X100111 110000nnnnnddddd 1E27 C000 Vd,Vn (scalar) -INST2(frsqrte, "frsqrte",0, 0, IF_EN2J, 0x2EA1D800, 0x7EA1D800) - // C7.2.162 FRSQRTE +INST2(frsqrte, "frsqrte", 0, IF_EN2J, 0x2EA1D800, 0x7EA1D800) // frsqrte Vd,Vn DV_2A 0Q1011101X100001 110110nnnnnddddd 2EA1 D800 Vd,Vn (vector) // frsqrte Vd,Vn DV_2G 011111101X100001 110110nnnnnddddd 7EA1 D800 Vd,Vn (scalar) -INST2(fsqrt, "fsqrt", 0, 0, IF_EN2J, 0x2EA1F800, 0x1E21C000) - // C7.2.164 FSQRT (vector) +INST2(fsqrt, "fsqrt", 0, IF_EN2J, 0x2EA1F800, 0x1E21C000) // fsqrt Vd,Vn DV_2A 0Q1011101X100001 111110nnnnnddddd 2EA1 F800 Vd,Vn (vector) - // C7.2.165 FSQRT (scalar) // fsqrt Vd,Vn DV_2G 000111100X100001 110000nnnnnddddd 1E21 C000 Vd,Vn (scalar) -// enum name FP LD/ST DV_2M DV_2L -INST2(abs, "abs", 0, 0, IF_EN2K, 0x0E20B800, 0x5E20B800) +// enum name info DV_2M DV_2L +INST2(abs, "abs", 0, IF_EN2K, 0x0E20B800, 0x5E20B800) // abs Vd,Vn DV_2M 0Q001110XX100000 101110nnnnnddddd 0E20 B800 Vd,Vn (vector) // abs Vd,Vn DV_2L 01011110XX100000 101110nnnnnddddd 5E20 B800 Vd,Vn (scalar) -INST2(cmle, "cmle", 0, 0, IF_EN2K, 0x2E209800, 0x7E209800) +INST2(cmle, "cmle", 0, IF_EN2K, 0x2E209800, 0x7E209800) // cmle Vd,Vn DV_2M 0Q101110XX100000 100110nnnnnddddd 2E20 9800 Vd,Vn (vector) // cmle Vd,Vn DV_2L 01111110XX100000 100110nnnnnddddd 7E20 9800 Vd,Vn (scalar) -INST2(cmlt, "cmlt", 0, 0, IF_EN2K, 0x0E20A800, 0x5E20A800) +INST2(cmlt, "cmlt", 0, IF_EN2K, 0x0E20A800, 0x5E20A800) // cmlt Vd,Vn DV_2M 0Q101110XX100000 101010nnnnnddddd 0E20 A800 Vd,Vn (vector) // cmlt Vd,Vn DV_2L 01011110XX100000 101010nnnnnddddd 5E20 A800 Vd,Vn (scalar) -// enum name FP LD/ST DR_2G DV_2M -INST2(cls, "cls", 0, 0, IF_EN2L, 0x5AC01400, 0x0E204800) +// enum name info DR_2G DV_2M +INST2(cls, "cls", 0, IF_EN2L, 0x5AC01400, 0x0E204800) // cls Rd,Rm DR_2G X101101011000000 000101nnnnnddddd 5AC0 1400 Rd Rn (general) // cls Vd,Vn DV_2M 0Q00111000100000 010010nnnnnddddd 0E20 4800 Vd,Vn (vector) -INST2(clz, "clz", 0, 0, IF_EN2L, 0x5AC01000, 0x2E204800) +INST2(clz, "clz", 0, IF_EN2L, 0x5AC01000, 0x2E204800) // clz Rd,Rm DR_2G X101101011000000 000100nnnnnddddd 5AC0 1000 Rd Rn (general) // clz Vd,Vn DV_2M 0Q10111000100000 010010nnnnnddddd 2E20 4800 Vd,Vn (vector) -INST2(rbit, "rbit", 0, 0, IF_EN2L, 0x5AC00000, 0x2E605800) +INST2(rbit, "rbit", 0, IF_EN2L, 0x5AC00000, 0x2E605800) // rbit Rd,Rm DR_2G X101101011000000 000000nnnnnddddd 5AC0 0000 Rd Rn (general) // rbit Vd,Vn DV_2M 0Q10111001100000 010110nnnnnddddd 2E60 5800 Vd,Vn (vector) -INST2(rev16, "rev16", 0, 0, IF_EN2L, 0x5AC00400, 0x0E201800) +INST2(rev16, "rev16", 0, IF_EN2L, 0x5AC00400, 0x0E201800) // rev16 Rd,Rm DR_2G X101101011000000 000001nnnnnddddd 5AC0 0400 Rd Rn (general) // rev16 Vd,Vn DV_2M 0Q001110XX100000 000110nnnnnddddd 0E20 1800 Vd,Vn (vector) -INST2(rev32, "rev32", 0, 0, IF_EN2L, 0xDAC00800, 0x2E200800) +INST2(rev32, "rev32", 0, IF_EN2L, 0xDAC00800, 0x2E200800) // rev32 Rd,Rm DR_2G 1101101011000000 000010nnnnnddddd DAC0 0800 Rd Rn (general) // rev32 Vd,Vn DV_2M 0Q101110XX100000 000010nnnnnddddd 2E20 0800 Vd,Vn (vector) -// enum name FP LD/ST DV_3A DV_3AI -INST2(mla, "mla", 0, 0, IF_EN2M, 0x0E209400, 0x2F000000) +// enum name info DV_3A DV_3AI +INST2(mla, "mla", 0, IF_EN2M, 0x0E209400, 0x2F000000) // mla Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 100101nnnnnddddd 0E20 9400 Vd,Vn,Vm (vector) // mla Vd,Vn,Vm[] DV_3AI 0Q101111XXLMmmmm 0000H0nnnnnddddd 2F00 0000 Vd,Vn,Vm[] (vector by elem) -INST2(mls, "mls", 0, 0, IF_EN2M, 0x2E209400, 0x2F004000) +INST2(mls, "mls", 0, IF_EN2M, 0x2E209400, 0x2F004000) // mls Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 100101nnnnnddddd 2E20 9400 Vd,Vn,Vm (vector) // mls Vd,Vn,Vm[] DV_3AI 0Q101111XXLMmmmm 0100H0nnnnnddddd 2F00 4000 Vd,Vn,Vm[] (vector by elem) -INST2(smlal, "smlal", 0, 0, IF_EN2R, 0x0E208000, 0x0F002000) - // C7.2.267 SMLAL, SMLAL2 (by element) - // C7.2.268 SMLAL, SMLAL2 (vector) +INST2(smlal, "smlal", 0, IF_EN2R, 0x0E208000, 0x0F002000) // smlal Vd,Vn,Vm DV_3H 00001110XX1mmmmm 100000nnnnnddddd 0E20 8000 Vd,Vn,Vm (vector) // smlal Vd,Vn,Vm[] DV_3HI 00001111XXLMmmmm 0010H0nnnnnddddd 0F00 2000 Vd,Vn,Vm[] (vector by elem) -INST2(smlal2, "smlal2", 0, 0, IF_EN2R, 0x4E208000, 0x4F002000) - // C7.2.267 SMLAL, SMLAL2 (by element) - // C7.2.268 SMLAL, SMLAL2 (vector) +INST2(smlal2, "smlal2", 0, IF_EN2R, 0x4E208000, 0x4F002000) // smlal2 Vd,Vn,Vm DV_3H 01001110XX1mmmmm 100000nnnnnddddd 4E20 8000 Vd,Vn,Vm (vector) // smlal2 Vd,Vn,Vm[] DV_3HI 01001111XXLMmmmm 0010H0nnnnnddddd 4F00 2000 Vd,Vn,Vm[] (vector by elem) -INST2(smlsl, "smlsl", 0, 0, IF_EN2R, 0x0E20A000, 0x0F006000) - // C7.2.269 SMLSL, SMLSL2 (by element) - // C7.2.270 SMLSL, SMLSL2 (vector) +INST2(smlsl, "smlsl", 0, IF_EN2R, 0x0E20A000, 0x0F006000) // smlsl Vd,Vn,Vm DV_3H 00001110XX1mmmmm 101000nnnnnddddd 0E20 A000 Vd,Vn,Vm (vector) // smlsl Vd,Vn,Vm[] DV_3HI 00001111XXLMmmmm 0110H0nnnnnddddd 0F00 6000 Vd,Vn,Vm[] (vector by elem) -INST2(smlsl2, "smlsl2", 0, 0, IF_EN2R, 0x4E20A000, 0x4F006000) - // C7.2.269 SMLSL, SMLSL2 (by element) - // C7.2.270 SMLSL, SMLSL2 (vector) +INST2(smlsl2, "smlsl2", 0, IF_EN2R, 0x4E20A000, 0x4F006000) // smlsl2 Vd,Vn,Vm DV_3H 01001110XX1mmmmm 101000nnnnnddddd 4E20 A000 Vd,Vn,Vm (vector) // smlsl2 Vd,Vn,Vm[] DV_3HI 01001111XXLMmmmm 0110H0nnnnnddddd 4F00 6000 Vd,Vn,Vm[] (vector by elem) -INST2(smull2, "smull2", 0, 0, IF_EN2R, 0x4E20C000, 0x4F00A000) - // C7.2.272 SMULL, SMULL2 (by element) - // C7.2.273 SMULL, SMULL2 (vector) +INST2(smull2, "smull2", 0, IF_EN2R, 0x4E20C000, 0x4F00A000) // smull2 Vd,Vn,Vm DV_3H 01001110XX1mmmmm 110000nnnnnddddd 4E20 C000 Vd,Vn,Vm (vector) // smull2 Vd,Vn,Vm[] DV_3HI 01001111XXLMmmmm 1010H0nnnnnddddd 4F00 A000 Vd,Vn,Vm[] (vector by elem) -INST2(umlal, "umlal", 0, 0, IF_EN2R, 0x2E208000, 0x2F002000) - // C7.2.357 UMLAL, UMLAL2 (by element) - // C7.2.358 UMLAL, UMLAL2 (vector) +INST2(umlal, "umlal", 0, IF_EN2R, 0x2E208000, 0x2F002000) // umlal Vd,Vn,Vm DV_3H 00101110XX1mmmmm 100000nnnnnddddd 2E20 8000 Vd,Vn,Vm (vector) // umlal Vd,Vn,Vm[] DV_3HI 00101111XXLMmmmm 0010H0nnnnnddddd 2F00 2000 Vd,Vn,Vm[] (vector by elem) -INST2(umlal2, "umlal2", 0, 0, IF_EN2R, 0x6E208000, 0x6F002000) - // C7.2.357 UMLAL, UMLAL2 (by element) - // C7.2.358 UMLAL, UMLAL2 (vector) +INST2(umlal2, "umlal2", 0, IF_EN2R, 0x6E208000, 0x6F002000) // umlal2 Vd,Vn,Vm DV_3H 01101110XX1mmmmm 100000nnnnnddddd 6E20 8000 Vd,Vn,Vm (vector) // umlal2 Vd,Vn,Vm[] DV_3HI 01101111XXLMmmmm 0010H0nnnnnddddd 6F00 2000 Vd,Vn,Vm[] (vector by elem) -INST2(umlsl, "umlsl", 0, 0, IF_EN2R, 0x2E20A000, 0x2F006000) - // C7.2.359 UMLSL, UMLSL2 (by element) - // C7.2.360 UMLSL, UMLSL2 (vector) +INST2(umlsl, "umlsl", 0, IF_EN2R, 0x2E20A000, 0x2F006000) // umlsl Vd,Vn,Vm DV_3H 00101110XX1mmmmm 101000nnnnnddddd 2E20 A000 Vd,Vn,Vm (vector) // umlsl Vd,Vn,Vm[] DV_3HI 00101111XXLMmmmm 0110H0nnnnnddddd 2F00 6000 Vd,Vn,Vm[] (vector by elem) -INST2(umlsl2, "umlsl2", 0, 0, IF_EN2R, 0x6E20A000, 0x6F006000) - // C7.2.359 UMLSL, UMLSL2 (by element) - // C7.2.360 UMLSL, UMLSL2 (vector) +INST2(umlsl2, "umlsl2", 0, IF_EN2R, 0x6E20A000, 0x6F006000) // umlsl2 Vd,Vn,Vm DV_3H 01101110XX1mmmmm 101000nnnnnddddd 6E20 A000 Vd,Vn,Vm (vector) // umlsl2 Vd,Vn,Vm[] DV_3HI 01101111XXLMmmmm 0110H0nnnnnddddd 6F00 6000 Vd,Vn,Vm[] (vector by elem) -INST2(umull2, "umull2", 0, 0, IF_EN2R, 0x6E20C000, 0x6F00A000) - // C7.2.362 UMULL, UMULL2 (by element) - // C7.2.363 UMULL, UMULL2 (vector) +INST2(umull2, "umull2", 0, IF_EN2R, 0x6E20C000, 0x6F00A000) // umull2 Vd,Vn,Vm DV_3H 01101110XX1mmmmm 110000nnnnnddddd 6E20 C000 Vd,Vn,Vm (vector) // umull2 Vd,Vn,Vm[] DV_3HI 01101111XXLMmmmm 1010H0nnnnnddddd 6F00 A000 Vd,Vn,Vm[] (vector by elem) -// enum name FP LD/ST DV_2N DV_2O -INST2(sshr, "sshr", 0, 0, IF_EN2N, 0x5F000400, 0x0F000400) - // sshr Vd,Vn,imm DV_2N 010111110iiiiiii 000001nnnnnddddd 5F00 0400 Vd Vn imm (shift - scalar) - // sshr Vd,Vn,imm DV_2O 0Q0011110iiiiiii 000001nnnnnddddd 0F00 0400 Vd,Vn imm (shift - vector) +// enum name info DV_2N DV_2O +INST2(sshr, "sshr", RSH, IF_EN2N, 0x5F000400, 0x0F000400) + // sshr Vd,Vn,imm DV_2N 010111110iiiiiii 000001nnnnnddddd 5F00 0400 Vd Vn imm (right shift - scalar) + // sshr Vd,Vn,imm DV_2O 0Q0011110iiiiiii 000001nnnnnddddd 0F00 0400 Vd,Vn imm (right shift - vector) -INST2(ssra, "ssra", 0, 0, IF_EN2N, 0x5F001400, 0x0F001400) - // ssra Vd,Vn,imm DV_2N 010111110iiiiiii 000101nnnnnddddd 5F00 1400 Vd Vn imm (shift - scalar) - // ssra Vd,Vn,imm DV_2O 0Q0011110iiiiiii 000101nnnnnddddd 0F00 1400 Vd,Vn imm (shift - vector) +INST2(ssra, "ssra", RSH, IF_EN2N, 0x5F001400, 0x0F001400) + // ssra Vd,Vn,imm DV_2N 010111110iiiiiii 000101nnnnnddddd 5F00 1400 Vd Vn imm (right shift - scalar) + // ssra Vd,Vn,imm DV_2O 0Q0011110iiiiiii 000101nnnnnddddd 0F00 1400 Vd,Vn imm (right shift - vector) -INST2(srshr, "srshr", 0, 0, IF_EN2N, 0x5F002400, 0x0F002400) - // srshr Vd,Vn,imm DV_2N 010111110iiiiiii 001001nnnnnddddd 5F00 0400 Vd Vn imm (shift - scalar) - // srshr Vd,Vn,imm DV_2O 0Q0011110iiiiiii 001001nnnnnddddd 0F00 0400 Vd,Vn imm (shift - vector) +INST2(srshr, "srshr", RSH, IF_EN2N, 0x5F002400, 0x0F002400) + // srshr Vd,Vn,imm DV_2N 010111110iiiiiii 001001nnnnnddddd 5F00 0400 Vd Vn imm (right shift - scalar) + // srshr Vd,Vn,imm DV_2O 0Q0011110iiiiiii 001001nnnnnddddd 0F00 0400 Vd,Vn imm (right shift - vector) -INST2(srsra, "srsra", 0, 0, IF_EN2N, 0x5F003400, 0x0F003400) - // srsra Vd,Vn,imm DV_2N 010111110iiiiiii 001101nnnnnddddd 5F00 1400 Vd Vn imm (shift - scalar) - // srsra Vd,Vn,imm DV_2O 0Q0011110iiiiiii 001101nnnnnddddd 0F00 1400 Vd,Vn imm (shift - vector) +INST2(srsra, "srsra", RSH, IF_EN2N, 0x5F003400, 0x0F003400) + // srsra Vd,Vn,imm DV_2N 010111110iiiiiii 001101nnnnnddddd 5F00 1400 Vd Vn imm (right shift - scalar) + // srsra Vd,Vn,imm DV_2O 0Q0011110iiiiiii 001101nnnnnddddd 0F00 1400 Vd,Vn imm (right shift - vector) -INST2(shl, "shl", 0, 0, IF_EN2N, 0x5F005400, 0x0F005400) - // shl Vd,Vn,imm DV_2N 010111110iiiiiii 010101nnnnnddddd 5F00 5400 Vd Vn imm (shift - scalar) - // shl Vd,Vn,imm DV_2O 0Q0011110iiiiiii 010101nnnnnddddd 0F00 5400 Vd,Vn imm (shift - vector) +INST2(shl, "shl", 0, IF_EN2N, 0x5F005400, 0x0F005400) + // shl Vd,Vn,imm DV_2N 010111110iiiiiii 010101nnnnnddddd 5F00 5400 Vd Vn imm (left shift - scalar) + // shl Vd,Vn,imm DV_2O 0Q0011110iiiiiii 010101nnnnnddddd 0F00 5400 Vd,Vn imm (left shift - vector) -INST2(ushr, "ushr", 0, 0, IF_EN2N, 0x7F000400, 0x2F000400) - // ushr Vd,Vn,imm DV_2N 011111110iiiiiii 000001nnnnnddddd 7F00 0400 Vd Vn imm (shift - scalar) - // ushr Vd,Vn,imm DV_2O 0Q1011110iiiiiii 000001nnnnnddddd 2F00 0400 Vd,Vn imm (shift - vector) +INST2(ushr, "ushr", RSH, IF_EN2N, 0x7F000400, 0x2F000400) + // ushr Vd,Vn,imm DV_2N 011111110iiiiiii 000001nnnnnddddd 7F00 0400 Vd Vn imm (right shift - scalar) + // ushr Vd,Vn,imm DV_2O 0Q1011110iiiiiii 000001nnnnnddddd 2F00 0400 Vd,Vn imm (right shift - vector) -INST2(usra, "usra", 0, 0, IF_EN2N, 0x7F001400, 0x2F001400) - // usra Vd,Vn,imm DV_2N 011111110iiiiiii 000101nnnnnddddd 7F00 1400 Vd Vn imm (shift - scalar) - // usra Vd,Vn,imm DV_2O 0Q1011110iiiiiii 000101nnnnnddddd 2F00 1400 Vd,Vn imm (shift - vector) +INST2(usra, "usra", RSH, IF_EN2N, 0x7F001400, 0x2F001400) + // usra Vd,Vn,imm DV_2N 011111110iiiiiii 000101nnnnnddddd 7F00 1400 Vd Vn imm (right shift - scalar) + // usra Vd,Vn,imm DV_2O 0Q1011110iiiiiii 000101nnnnnddddd 2F00 1400 Vd,Vn imm (right shift - vector) -INST2(urshr, "urshr", 0, 0, IF_EN2N, 0x7F002400, 0x2F002400) - // urshr Vd,Vn,imm DV_2N 011111110iiiiiii 001001nnnnnddddd 7F00 2400 Vd Vn imm (shift - scalar) - // urshr Vd,Vn,imm DV_2O 0Q1011110iiiiiii 001001nnnnnddddd 2F00 2400 Vd,Vn imm (shift - vector) +INST2(urshr, "urshr", RSH, IF_EN2N, 0x7F002400, 0x2F002400) + // urshr Vd,Vn,imm DV_2N 011111110iiiiiii 001001nnnnnddddd 7F00 2400 Vd Vn imm (right shift - scalar) + // urshr Vd,Vn,imm DV_2O 0Q1011110iiiiiii 001001nnnnnddddd 2F00 2400 Vd,Vn imm (right shift - vector) -INST2(ursra, "ursra", 0, 0, IF_EN2N, 0x7F003400, 0x2F003400) - // ursra Vd,Vn,imm DV_2N 011111110iiiiiii 001101nnnnnddddd 7F00 3400 Vd Vn imm (shift - scalar) - // ursra Vd,Vn,imm DV_2O 0Q1011110iiiiiii 001101nnnnnddddd 2F00 3400 Vd,Vn imm (shift - vector) +INST2(ursra, "ursra", RSH, IF_EN2N, 0x7F003400, 0x2F003400) + // ursra Vd,Vn,imm DV_2N 011111110iiiiiii 001101nnnnnddddd 7F00 3400 Vd Vn imm (right shift - scalar) + // ursra Vd,Vn,imm DV_2O 0Q1011110iiiiiii 001101nnnnnddddd 2F00 3400 Vd,Vn imm (right shift - vector) -INST2(sri, "sri", 0, 0, IF_EN2N, 0x7F004400, 0x2F004400) - // sri Vd,Vn,imm DV_2N 011111110iiiiiii 010001nnnnnddddd 7F00 4400 Vd Vn imm (shift - scalar) - // sri Vd,Vn,imm DV_2O 0Q1011110iiiiiii 010001nnnnnddddd 2F00 4400 Vd,Vn imm (shift - vector) +INST2(sri, "sri", RSH, IF_EN2N, 0x7F004400, 0x2F004400) + // sri Vd,Vn,imm DV_2N 011111110iiiiiii 010001nnnnnddddd 7F00 4400 Vd Vn imm (right shift - scalar) + // sri Vd,Vn,imm DV_2O 0Q1011110iiiiiii 010001nnnnnddddd 2F00 4400 Vd,Vn imm (right shift - vector) -INST2(sli, "sli", 0, 0, IF_EN2N, 0x7F005400, 0x2F005400) - // sli Vd,Vn,imm DV_2N 011111110iiiiiii 010101nnnnnddddd 7F00 5400 Vd Vn imm (shift - scalar) - // sli Vd,Vn,imm DV_2O 0Q1011110iiiiiii 010101nnnnnddddd 2F00 5400 Vd,Vn imm (shift - vector) +INST2(sli, "sli", 0, IF_EN2N, 0x7F005400, 0x2F005400) + // sli Vd,Vn,imm DV_2N 011111110iiiiiii 010101nnnnnddddd 7F00 5400 Vd Vn imm (left shift - scalar) + // sli Vd,Vn,imm DV_2O 0Q1011110iiiiiii 010101nnnnnddddd 2F00 5400 Vd,Vn imm (left shift - vector) -// enum name FP LD/ST DV_3E DV_3A -INST2(cmhi, "cmhi", 0, 0, IF_EN2O, 0x7EE03400, 0x2E203400) +INST2(sqshlu, "sqshlu", 0, IF_EN2N, 0x7F006400, 0x2F006400) + // sqshlu Vd,Vn,imm DV_2N 011111110iiiiiii 011001nnnnnddddd 7F00 6400 Vd Vn imm (left shift - scalar) + // sqshlu Vd,Vn,imm DV_2O 0Q1011110iiiiiii 011001nnnnnddddd 2F00 6400 Vd Vn imm (left shift - vector) + +INST2(sqrshrn, "sqrshrn", RSH, IF_EN2N, 0x5F009C00, 0x0F009C00) + // sqrshrn Vd,Vn,imm DV_2N 010111110iiiiiii 100111nnnnnddddd 5F00 9C00 Vd Vn imm (right shift - scalar) + // sqrshrn Vd,Vn,imm DV_2O 0Q0011110iiiiiii 100111nnnnnddddd 0F00 9C00 Vd Vn imm (right shift - vector) + +INST2(sqrshrun, "sqrshrun", RSH, IF_EN2N, 0x7F008C00, 0x2F008C00) + // sqrshrun Vd,Vn,imm DV_2N 011111110iiiiiii 100011nnnnnddddd 7F00 8C00 Vd Vn imm (right shift - scalar) + // sqrshrun Vd,Vn,imm DV_2O 0Q1011110iiiiiii 100011nnnnnddddd 2F00 8C00 Vd Vn imm (right shift - vector) + +INST2(sqshrn, "sqshrn", RSH, IF_EN2N, 0x5F009400, 0x0F009400) + // sqshrn Vd,Vn,imm DV_2N 010111110iiiiiii 100101nnnnnddddd 5F00 9400 Vd Vn imm (right shift - scalar) + // sqshrn Vd,Vn,imm DV_2O 0Q0011110iiiiiii 100101nnnnnddddd 0F00 9400 Vd Vn imm (right shift - vector) + +INST2(sqshrun, "sqshrun", RSH, IF_EN2N, 0x7F008400, 0x2F008400) + // sqshrun Vd,Vn,imm DV_2N 011111110iiiiiii 100001nnnnnddddd 7F00 8400 Vd Vn imm (right shift - scalar) + // sqshrun Vd,Vn,imm DV_2O 0Q1011110iiiiiii 100001nnnnnddddd 2F00 8400 Vd Vn imm (right shift - vector) + +INST2(uqrshrn, "uqrshrn", RSH, IF_EN2N, 0x7F009C00, 0x2F009C00) + // uqrshrn Vd,Vn,imm DV_2N 011111110iiiiiii 100111nnnnnddddd 7F00 9C00 Vd Vn imm (right shift - scalar) + // uqrshrn Vd,Vn,imm DV_2O 0Q1011110iiiiiii 100111nnnnnddddd 2F00 9C00 Vd Vn imm (right shift - vector) + +INST2(uqshrn, "uqshrn", RSH, IF_EN2N, 0x7F009400, 0x2F009400) + // usqhrn Vd,Vn,imm DV_2N 011111110iiiiiii 100101nnnnnddddd 7F00 9400 Vd Vn imm (right shift - scalar) + // usqhrn Vd,Vn,imm DV_2O 0Q1011110iiiiiii 100101nnnnnddddd 2F00 9400 Vd Vn imm (right shift - vector) + +// enum name info DV_3E DV_3A +INST2(cmhi, "cmhi", 0, IF_EN2O, 0x7EE03400, 0x2E203400) // cmhi Vd,Vn,Vm DV_3E 01111110111mmmmm 001101nnnnnddddd 7EE0 3400 Vd,Vn,Vm (scalar) // cmhi Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 001101nnnnnddddd 2E20 3400 Vd,Vn,Vm (vector) -INST2(cmhs, "cmhs", 0, 0, IF_EN2O, 0x7EE03C00, 0x2E203C00) +INST2(cmhs, "cmhs", 0, IF_EN2O, 0x7EE03C00, 0x2E203C00) // cmhs Vd,Vn,Vm DV_3E 01111110111mmmmm 001111nnnnnddddd 7EE0 3C00 Vd,Vn,Vm (scalar) // cmhs Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 001111nnnnnddddd 2E20 3C00 Vd,Vn,Vm (vector) -INST2(cmtst, "cmtst", 0, 0, IF_EN2O, 0x5EE08C00, 0x0E208C00) +INST2(cmtst, "cmtst", 0, IF_EN2O, 0x5EE08C00, 0x0E208C00) // cmtst Vd,Vn,Vm DV_3E 01011110111mmmmm 100011nnnnnddddd 5EE0 8C00 Vd,Vn,Vm (scalar) // cmtst Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 100011nnnnnddddd 0E20 8C00 Vd,Vn,Vm (vector) -INST2(sqadd, "sqadd", 0, 0, IF_EN2O, 0x5E200C00, 0x0E200C00) - // C7.2.275 SQADD +INST2(sqadd, "sqadd", 0, IF_EN2O, 0x5E200C00, 0x0E200C00) // sqadd Vd,Vn,Vm DV_3E 01011110XX1mmmmm 000011nnnnnddddd 5E20 0C00 Vd,Vn,Vm (scalar) // sqadd Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 000011nnnnnddddd 0E20 0C00 Vd,Vn,Vm (vector) -INST2(sqsub, "sqsub", 0, 0, IF_EN2O, 0x5E202C00, 0x0E202C00) - // C7.2.299 SQSUB +INST2(sqrshl, "sqrshl", 0, IF_EN2O, 0x5E205C00, 0x0E205C00) + // sqrshl Vd,Vn,Vm DV_3E 01011110XX1mmmmm 010111nnnnnddddd 5E20 5C00 Vd,Vn,Vm (scalar) + // sqrshl Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 010111nnnnnddddd 0E20 5C00 Vd,Vn,Vm (vector) + +INST2(sqsub, "sqsub", 0, IF_EN2O, 0x5E202C00, 0x0E202C00) // sqsub Vd,Vn,Vm DV_3E 01011110XX1mmmmm 001011nnnnnddddd 5E20 2C00 Vd,Vn,Vm (scalar) // sqsub Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 001011nnnnnddddd 0E20 2C00 Vd,Vn,Vm (vector) -INST2(uqadd, "uqadd", 0, 0, IF_EN2O, 0x7E200C00, 0x2E200C00) - // C7.2.364 UQADD +INST2(srshl, "srshl", 0, IF_EN2O, 0x5E205400, 0x0E205400) + // srshl Vd,Vn,Vm DV_3E 01011110XX1mmmmm 010101nnnnnddddd 5E20 5400 Vd,Vn,Vm (scalar) + // srshl Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 010101nnnnnddddd 0E20 5400 Vd,Vn,Vm (vector) + +INST2(sshl, "sshl", 0, IF_EN2O, 0x5E204400, 0x0E204400) + // sshl Vd,Vn,Vm DV_3E 01011110XX1mmmmm 010001nnnnnddddd 5E20 4400 Vd,Vn,Vm (scalar) + // sshl Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 010001nnnnnddddd 0E20 4400 Vd,Vn,Vm (vector) + +INST2(uqadd, "uqadd", 0, IF_EN2O, 0x7E200C00, 0x2E200C00) // uqadd Vd,Vn,Vm DV_3E 01111110XX1mmmmm 000011nnnnnddddd 7E20 0C00 Vd,Vn,Vm (scalar) // uqadd Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 000011nnnnnddddd 2E20 0C00 Vd,Vn,Vm (vector) -INST2(uqsub, "uqsub", 0, 0, IF_EN2O, 0x7E202C00, 0x2E202C00) - // C7.2.370 UQSUB +INST2(uqrshl, "uqrshl", 0, IF_EN2O, 0x7E205C00, 0x2E205C00) + // uqrshl Vd,Vn,Vm DV_3E 01111110XX1mmmmm 010111nnnnnddddd 7E20 5C00 Vd,Vn,Vm (scalar) + // uqrshl Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 010111nnnnnddddd 2E20 5C00 Vd,Vn,Vm (vector) + +INST2(uqsub, "uqsub", 0, IF_EN2O, 0x7E202C00, 0x2E202C00) // uqsub Vd,Vn,Vm DV_3E 01111110XX1mmmmm 001011nnnnnddddd 7E20 2C00 Vd,Vn,Vm (scalar) // uqsub Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 001011nnnnnddddd 2E20 2C00 Vd,Vn,Vm (vector) -// enum name FP LD/ST DV_2Q DV_3B -INST2(faddp, "faddp", 0, 0, IF_EN2P, 0x7E30D800, 0x2E20D400) +INST2(urshl, "urshl", 0, IF_EN2O, 0x7E205400, 0x2E205400) + // urshl Vd,Vn,Vm DV_3E 01111110XX1mmmmm 010101nnnnnddddd 7E20 5400 Vd,Vn,Vm (scalar) + // urshl Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 010101nnnnnddddd 2E20 5400 Vd,Vn,Vm (vector) + +INST2(ushl, "ushl", 0, IF_EN2O, 0x7E204400, 0x2E204400) + // ushl Vd,Vn,Vm DV_3E 01111110XX1mmmmm 010001nnnnnddddd 7E20 4400 Vd,Vn,Vm (scalar) + // ushl Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 010001nnnnnddddd 2E20 4400 Vd,Vn,Vm (vector) + +// enum name info DV_2Q DV_3B +INST2(faddp, "faddp", 0, IF_EN2P, 0x7E30D800, 0x2E20D400) // faddp Vd,Vn DV_2Q 011111100X110000 110110nnnnnddddd 7E30 D800 Vd,Vn (scalar) // faddp Vd,Vn,Vm DV_3B 0Q1011100X1mmmmm 110101nnnnnddddd 2E20 D400 Vd,Vn,Vm (vector) -INST2(fmaxnmp, "fmaxnmp",0, 0, IF_EN2P, 0x7E30C800, 0x2E20C400) +INST2(fmaxnmp, "fmaxnmp", 0, IF_EN2P, 0x7E30C800, 0x2E20C400) // fmaxnmp Vd,Vn DV_2Q 011111100X110000 110010nnnnnddddd 7E30 C800 Vd,Vn (scalar) // fmaxnmp Vd,Vn,Vm DV_3B 0Q1011100X1mmmmm 110001nnnnnddddd 2E20 C400 Vd,Vn,Vm (vector) -INST2(fmaxp, "fmaxp", 0, 0, IF_EN2P, 0x7E30F800, 0x2E20F400) +INST2(fmaxp, "fmaxp", 0, IF_EN2P, 0x7E30F800, 0x2E20F400) // fmaxp Vd,Vn DV_2Q 011111100X110000 111110nnnnnddddd 7E30 F800 Vd,Vn (scalar) // fmaxp Vd,Vn,Vm DV_3B 0Q1011100X1mmmmm 111101nnnnnddddd 2E20 F400 Vd,Vn,Vm (vector) -INST2(fminnmp, "fminnmp",0, 0, IF_EN2P, 0x7EB0C800, 0x2EA0C400) +INST2(fminnmp, "fminnmp", 0, IF_EN2P, 0x7EB0C800, 0x2EA0C400) // fminnmp Vd,Vn DV_2Q 011111101X110000 110010nnnnnddddd 7EB0 C800 Vd,Vn (scalar) // fminnmp Vd,Vn,Vm DV_3B 0Q1011101X1mmmmm 110001nnnnnddddd 2EA0 C400 Vd,Vn,Vm (vector) -INST2(fminp, "fminp", 0, 0, IF_EN2P, 0x7EB0F800, 0x2EA0F400) +INST2(fminp, "fminp", 0, IF_EN2P, 0x7EB0F800, 0x2EA0F400) // fminp Vd,Vn DV_2Q 011111101X110000 111110nnnnnddddd 7EB0 F800 Vd,Vn (scalar) // fminp Vd,Vn,Vm DV_3B 0Q1011101X1mmmmm 111101nnnnnddddd 2EA0 F400 Vd,Vn,Vm (vector) -INST2(addp, "addp", 0, 0, IF_EN2Q, 0x5E31B800, 0x0E20BC00) +INST2(addp, "addp", 0, IF_EN2Q, 0x5E31B800, 0x0E20BC00) // addp Vd,Vn DV_2S 01011110XX110001 101110nnnnnddddd 5E31 B800 Vd,Vn (scalar) // addp Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 101111nnnnnddddd 0E20 BC00 Vd,Vn,Vm (vector) -INST1(ldar, "ldar", 0,LD, IF_LS_2A, 0x88DFFC00) +INST1(ldar, "ldar", LD, IF_LS_2A, 0x88DFFC00) // ldar Rt,[Xn] LS_2A 1X00100011011111 111111nnnnnttttt 88DF FC00 -INST1(ldarb, "ldarb", 0,LD, IF_LS_2A, 0x08DFFC00) +INST1(ldarb, "ldarb", LD, IF_LS_2A, 0x08DFFC00) // ldarb Rt,[Xn] LS_2A 0000100011011111 111111nnnnnttttt 08DF FC00 -INST1(ldarh, "ldarh", 0,LD, IF_LS_2A, 0x48DFFC00) +INST1(ldarh, "ldarh", LD, IF_LS_2A, 0x48DFFC00) // ldarh Rt,[Xn] LS_2A 0100100011011111 111111nnnnnttttt 48DF FC00 -INST1(ldxr, "ldxr", 0,LD, IF_LS_2A, 0x885F7C00) +INST1(ldxr, "ldxr", LD, IF_LS_2A, 0x885F7C00) // ldxr Rt,[Xn] LS_2A 1X00100001011111 011111nnnnnttttt 885F 7C00 -INST1(ldxrb, "ldxrb", 0,LD, IF_LS_2A, 0x085F7C00) +INST1(ldxrb, "ldxrb", LD, IF_LS_2A, 0x085F7C00) // ldxrb Rt,[Xn] LS_2A 0000100001011111 011111nnnnnttttt 085F 7C00 -INST1(ldxrh, "ldxrh", 0,LD, IF_LS_2A, 0x485F7C00) +INST1(ldxrh, "ldxrh", LD, IF_LS_2A, 0x485F7C00) // ldxrh Rt,[Xn] LS_2A 0100100001011111 011111nnnnnttttt 485F 7C00 -INST1(ldaxr, "ldaxr", 0,LD, IF_LS_2A, 0x885FFC00) +INST1(ldaxr, "ldaxr", LD, IF_LS_2A, 0x885FFC00) // ldaxr Rt,[Xn] LS_2A 1X00100001011111 111111nnnnnttttt 885F FC00 -INST1(ldaxrb, "ldaxrb", 0,LD, IF_LS_2A, 0x085FFC00) +INST1(ldaxrb, "ldaxrb", LD, IF_LS_2A, 0x085FFC00) // ldaxrb Rt,[Xn] LS_2A 0000100001011111 111111nnnnnttttt 085F FC00 -INST1(ldaxrh, "ldaxrh", 0,LD, IF_LS_2A, 0x485FFC00) +INST1(ldaxrh, "ldaxrh", LD, IF_LS_2A, 0x485FFC00) // ldaxrh Rt,[Xn] LS_2A 0100100001011111 111111nnnnnttttt 485F FC00 -INST1(ldur, "ldur", 0,LD, IF_LS_2C, 0xB8400000) +INST1(ldur, "ldur", LD, IF_LS_2C, 0xB8400000) // ldur Rt,[Xn+simm9] LS_2C 1X111000010iiiii iiii00nnnnnttttt B840 0000 [Xn imm(-256..+255)] -INST1(ldurb, "ldurb", 0,LD, IF_LS_2C, 0x38400000) +INST1(ldurb, "ldurb", LD, IF_LS_2C, 0x38400000) // ldurb Rt,[Xn+simm9] LS_2C 00111000010iiiii iiii00nnnnnttttt 3840 0000 [Xn imm(-256..+255)] -INST1(ldurh, "ldurh", 0,LD, IF_LS_2C, 0x78400000) +INST1(ldurh, "ldurh", LD, IF_LS_2C, 0x78400000) // ldurh Rt,[Xn+simm9] LS_2C 01111000010iiiii iiii00nnnnnttttt 7840 0000 [Xn imm(-256..+255)] -INST1(ldursb, "ldursb", 0,LD, IF_LS_2C, 0x38800000) +INST1(ldursb, "ldursb", LD, IF_LS_2C, 0x38800000) // ldursb Rt,[Xn+simm9] LS_2C 001110001X0iiiii iiii00nnnnnttttt 3880 0000 [Xn imm(-256..+255)] -INST1(ldursh, "ldursh", 0,LD, IF_LS_2C, 0x78800000) +INST1(ldursh, "ldursh", LD, IF_LS_2C, 0x78800000) // ldursh Rt,[Xn+simm9] LS_2C 011110001X0iiiii iiii00nnnnnttttt 7880 0000 [Xn imm(-256..+255)] -INST1(ldursw, "ldursw", 0,LD, IF_LS_2C, 0xB8800000) +INST1(ldursw, "ldursw", LD, IF_LS_2C, 0xB8800000) // ldursw Rt,[Xn+simm9] LS_2C 10111000100iiiii iiii00nnnnnttttt B880 0000 [Xn imm(-256..+255)] -INST1(stlr, "stlr", 0,ST, IF_LS_2A, 0x889FFC00) +INST1(stlr, "stlr", ST, IF_LS_2A, 0x889FFC00) // stlr Rt,[Xn] LS_2A 1X00100010011111 111111nnnnnttttt 889F FC00 -INST1(stlrb, "stlrb", 0,ST, IF_LS_2A, 0x089FFC00) +INST1(stlrb, "stlrb", ST, IF_LS_2A, 0x089FFC00) // stlrb Rt,[Xn] LS_2A 0000100010011111 111111nnnnnttttt 089F FC00 -INST1(stlrh, "stlrh", 0,ST, IF_LS_2A, 0x489FFC00) +INST1(stlrh, "stlrh", ST, IF_LS_2A, 0x489FFC00) // stlrh Rt,[Xn] LS_2A 0100100010011111 111111nnnnnttttt 489F FC00 -INST1(stxr, "stxr", 0,ST, IF_LS_3D, 0x88007C00) +INST1(stxr, "stxr", ST, IF_LS_3D, 0x88007C00) // stxr Ws, Rt,[Xn] LS_3D 1X001000000sssss 011111nnnnnttttt 8800 7C00 -INST1(stxrb, "stxrb", 0,ST, IF_LS_3D, 0x08007C00) +INST1(stxrb, "stxrb", ST, IF_LS_3D, 0x08007C00) // stxrb Ws, Rt,[Xn] LS_3D 00001000000sssss 011111nnnnnttttt 0800 7C00 -INST1(stxrh, "stxrh", 0,ST, IF_LS_3D, 0x48007C00) +INST1(stxrh, "stxrh", ST, IF_LS_3D, 0x48007C00) // stxrh Ws, Rt,[Xn] LS_3D 01001000000sssss 011111nnnnnttttt 4800 7C00 -INST1(stlxr, "stlxr", 0,ST, IF_LS_3D, 0x8800FC00) +INST1(stlxr, "stlxr", ST, IF_LS_3D, 0x8800FC00) // stlxr Ws, Rt,[Xn] LS_3D 1X001000000sssss 111111nnnnnttttt 8800 FC00 -INST1(stlxrb, "stlxrb", 0,ST, IF_LS_3D, 0x0800FC00) +INST1(stlxrb, "stlxrb", ST, IF_LS_3D, 0x0800FC00) // stlxrb Ws, Rt,[Xn] LS_3D 00001000000sssss 111111nnnnnttttt 0800 FC00 -INST1(stlxrh, "stlxrh", 0,ST, IF_LS_3D, 0x4800FC00) +INST1(stlxrh, "stlxrh", ST, IF_LS_3D, 0x4800FC00) // stlxrh Ws, Rt,[Xn] LS_3D 01001000000sssss 111111nnnnnttttt 4800 FC00 -INST1(stur, "stur", 0,ST, IF_LS_2C, 0xB8000000) +INST1(stur, "stur", ST, IF_LS_2C, 0xB8000000) // stur Rt,[Xn+simm9] LS_2C 1X111000000iiiii iiii00nnnnnttttt B800 0000 [Xn imm(-256..+255)] -INST1(sturb, "sturb", 0,ST, IF_LS_2C, 0x38000000) +INST1(sturb, "sturb", ST, IF_LS_2C, 0x38000000) // sturb Rt,[Xn+simm9] LS_2C 00111000000iiiii iiii00nnnnnttttt 3800 0000 [Xn imm(-256..+255)] -INST1(sturh, "sturh", 0,ST, IF_LS_2C, 0x78000000) +INST1(sturh, "sturh", ST, IF_LS_2C, 0x78000000) // sturh Rt,[Xn+simm9] LS_2C 01111000000iiiii iiii00nnnnnttttt 7800 0000 [Xn imm(-256..+255)] -INST1(casb, "casb", 0, LD|ST, IF_LS_3E, 0x08A07C00) +INST1(casb, "casb", LD|ST, IF_LS_3E, 0x08A07C00) // casb Wm, Wt, [Xn] LS_3E 00001000101mmmmm 011111nnnnnttttt 08A0 7C00 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(casab, "casab", 0, LD|ST, IF_LS_3E, 0x08E07C00) +INST1(casab, "casab", LD|ST, IF_LS_3E, 0x08E07C00) // casab Wm, Wt, [Xn] LS_3E 00001000111mmmmm 011111nnnnnttttt 08E0 7C00 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(casalb, "casalb", 0, LD|ST, IF_LS_3E, 0x08E0FC00) +INST1(casalb, "casalb", LD|ST, IF_LS_3E, 0x08E0FC00) // casalb Wm, Wt, [Xn] LS_3E 00001000111mmmmm 111111nnnnnttttt 08E0 FC00 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(caslb, "caslb", 0, LD|ST, IF_LS_3E, 0x08A0FC00) +INST1(caslb, "caslb", LD|ST, IF_LS_3E, 0x08A0FC00) // caslb Wm, Wt, [Xn] LS_3E 00001000101mmmmm 111111nnnnnttttt 08A0 FC00 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(cash, "cash", 0, LD|ST, IF_LS_3E, 0x48A07C00) +INST1(cash, "cash", LD|ST, IF_LS_3E, 0x48A07C00) // cash Wm, Wt, [Xn] LS_3E 01001000101mmmmm 011111nnnnnttttt 48A0 7C00 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(casah, "casah", 0, LD|ST, IF_LS_3E, 0x48E07C00) +INST1(casah, "casah", LD|ST, IF_LS_3E, 0x48E07C00) // casah Wm, Wt, [Xn] LS_3E 01001000111mmmmm 011111nnnnnttttt 48E0 7C00 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(casalh, "casalh", 0, LD|ST, IF_LS_3E, 0x48E0FC00) +INST1(casalh, "casalh", LD|ST, IF_LS_3E, 0x48E0FC00) // casalh Wm, Wt, [Xn] LS_3E 01001000111mmmmm 111111nnnnnttttt 48E0 FC00 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(caslh, "caslh", 0, LD|ST, IF_LS_3E, 0x48A0FC00) +INST1(caslh, "caslh", LD|ST, IF_LS_3E, 0x48A0FC00) // caslh Wm, Wt, [Xn] LS_3E 01001000101mmmmm 111111nnnnnttttt 48A0 FC00 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(cas, "cas", 0, LD|ST, IF_LS_3E, 0x88A07C00) +INST1(cas, "cas", LD|ST, IF_LS_3E, 0x88A07C00) // cas Rm, Rt, [Xn] LS_3E 1X001000101mmmmm 011111nnnnnttttt 88A0 7C00 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(casa, "casa", 0, LD|ST, IF_LS_3E, 0x88E07C00) +INST1(casa, "casa", LD|ST, IF_LS_3E, 0x88E07C00) // casa Rm, Rt, [Xn] LS_3E 1X001000111mmmmm 011111nnnnnttttt 88E0 7C00 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(casal, "casal", 0, LD|ST, IF_LS_3E, 0x88E0FC00) +INST1(casal, "casal", LD|ST, IF_LS_3E, 0x88E0FC00) // casal Rm, Rt, [Xn] LS_3E 1X001000111mmmmm 111111nnnnnttttt 88E0 FC00 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(casl, "casl", 0, LD|ST, IF_LS_3E, 0x88A0FC00) +INST1(casl, "casl", LD|ST, IF_LS_3E, 0x88A0FC00) // casl Rm, Rt, [Xn] LS_3E 1X001000101mmmmm 111111nnnnnttttt 88A0 FC00 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(ldaddb, "ldaddb", 0, LD|ST, IF_LS_3E, 0x38200000) +INST1(ldaddb, "ldaddb", LD|ST, IF_LS_3E, 0x38200000) // ldaddb Wm, Wt, [Xn] LS_3E 00111000001mmmmm 000000nnnnnttttt 3820 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(ldaddab, "ldaddab", 0, LD|ST, IF_LS_3E, 0x38A00000) +INST1(ldaddab, "ldaddab", LD|ST, IF_LS_3E, 0x38A00000) // ldaddab Wm, Wt, [Xn] LS_3E 00111000101mmmmm 000000nnnnnttttt 38A0 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(ldaddalb,"ldaddalb",0, LD|ST, IF_LS_3E, 0x38E00000) +INST1(ldaddalb, "ldaddalb", LD|ST, IF_LS_3E, 0x38E00000) // ldaddalb Wm, Wt, [Xn] LS_3E 00111000111mmmmm 000000nnnnnttttt 38E0 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(ldaddlb, "ldaddlb", 0, LD|ST, IF_LS_3E, 0x38600000) +INST1(ldaddlb, "ldaddlb", LD|ST, IF_LS_3E, 0x38600000) // ldaddlb Wm, Wt, [Xn] LS_3E 00111000011mmmmm 000000nnnnnttttt 3860 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(ldaddh, "ldaddh", 0, LD|ST, IF_LS_3E, 0x78200000) +INST1(ldaddh, "ldaddh", LD|ST, IF_LS_3E, 0x78200000) // ldaddh Wm, Wt, [Xn] LS_3E 01111000001mmmmm 000000nnnnnttttt 7820 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(ldaddah, "ldaddah", 0, LD|ST, IF_LS_3E, 0x78A00000) +INST1(ldaddah, "ldaddah", LD|ST, IF_LS_3E, 0x78A00000) // ldaddah Wm, Wt, [Xn] LS_3E 01111000101mmmmm 000000nnnnnttttt 78A0 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(ldaddalh,"ldaddalh",0, LD|ST, IF_LS_3E, 0x78E00000) +INST1(ldaddalh, "ldaddalh", LD|ST, IF_LS_3E, 0x78E00000) // ldaddalh Wm, Wt, [Xn] LS_3E 01111000111mmmmm 000000nnnnnttttt 78E0 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(ldaddlh, "ldaddlh", 0, LD|ST, IF_LS_3E, 0x78600000) +INST1(ldaddlh, "ldaddlh", LD|ST, IF_LS_3E, 0x78600000) // ldaddlh Wm, Wt, [Xn] LS_3E 01111000011mmmmm 000000nnnnnttttt 7860 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(ldadd, "ldadd", 0, LD|ST, IF_LS_3E, 0xB8200000) +INST1(ldadd, "ldadd", LD|ST, IF_LS_3E, 0xB8200000) // ldadd Rm, Rt, [Xn] LS_3E 1X111000001mmmmm 000000nnnnnttttt B820 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(ldadda, "ldadda", 0, LD|ST, IF_LS_3E, 0xB8A00000) +INST1(ldadda, "ldadda", LD|ST, IF_LS_3E, 0xB8A00000) // ldadda Rm, Rt, [Xn] LS_3E 1X111000101mmmmm 000000nnnnnttttt B8A0 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(ldaddal, "ldaddal", 0, LD|ST, IF_LS_3E, 0xB8E00000) +INST1(ldaddal, "ldaddal", LD|ST, IF_LS_3E, 0xB8E00000) // ldaddal Rm, Rt, [Xn] LS_3E 1X111000111mmmmm 000000nnnnnttttt B8E0 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(ldaddl, "ldaddl", 0, LD|ST, IF_LS_3E, 0xB8600000) +INST1(ldaddl, "ldaddl", LD|ST, IF_LS_3E, 0xB8600000) // ldaddl Rm, Rt, [Xn] LS_3E 1X111000011mmmmm 000000nnnnnttttt B860 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(staddb, "staddb", 0, ST, IF_LS_3E, 0x38200000) +INST1(staddb, "staddb", ST, IF_LS_3E, 0x38200000) // staddb Wm, [Xn] LS_3E 00111000001mmmmm 000000nnnnnttttt 3820 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(staddlb, "staddlb", 0, ST, IF_LS_3E, 0x38600000) +INST1(staddlb, "staddlb", ST, IF_LS_3E, 0x38600000) // staddlb Wm, [Xn] LS_3E 00111000011mmmmm 000000nnnnnttttt 3860 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(staddh, "staddh", 0, ST, IF_LS_3E, 0x78200000) +INST1(staddh, "staddh", ST, IF_LS_3E, 0x78200000) // staddh Wm, [Xn] LS_3E 01111000001mmmmm 000000nnnnnttttt 7820 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(staddlh, "staddlh", 0, ST, IF_LS_3E, 0x78600000) +INST1(staddlh, "staddlh", ST, IF_LS_3E, 0x78600000) // staddlh Wm, [Xn] LS_3E 01111000011mmmmm 000000nnnnnttttt 7860 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(stadd, "stadd", 0, ST, IF_LS_3E, 0xB8200000) +INST1(stadd, "stadd", ST, IF_LS_3E, 0xB8200000) // stadd Rm, [Xn] LS_3E 1X111000001mmmmm 000000nnnnnttttt B820 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(staddl, "staddl", 0, ST, IF_LS_3E, 0xB8600000) +INST1(staddl, "staddl", ST, IF_LS_3E, 0xB8600000) // staddl Rm, [Xn] LS_3E 1X111000011mmmmm 000000nnnnnttttt B860 0000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(swpb, "swpb", 0, LD|ST, IF_LS_3E, 0x38208000) +INST1(swpb, "swpb", LD|ST, IF_LS_3E, 0x38208000) // swpb Wm, Wt, [Xn] LS_3E 00111000001mmmmm 100000nnnnnttttt 3820 8000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(swpab, "swpab", 0, LD|ST, IF_LS_3E, 0x38A08000) +INST1(swpab, "swpab", LD|ST, IF_LS_3E, 0x38A08000) // swpab Wm, Wt, [Xn] LS_3E 00111000101mmmmm 100000nnnnnttttt 38A0 8000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(swpalb, "swpalb", 0, LD|ST, IF_LS_3E, 0x38E08000) +INST1(swpalb, "swpalb", LD|ST, IF_LS_3E, 0x38E08000) // swpalb Wm, Wt, [Xn] LS_3E 00111000111mmmmm 100000nnnnnttttt 38E0 8000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(swplb, "swplb", 0, LD|ST, IF_LS_3E, 0x38608000) +INST1(swplb, "swplb", LD|ST, IF_LS_3E, 0x38608000) // swplb Wm, Wt, [Xn] LS_3E 00111000011mmmmm 100000nnnnnttttt 3860 8000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(swph, "swph", 0, LD|ST, IF_LS_3E, 0x78208000) +INST1(swph, "swph", LD|ST, IF_LS_3E, 0x78208000) // swph Wm, Wt, [Xn] LS_3E 01111000001mmmmm 100000nnnnnttttt 7820 8000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(swpah, "swpah", 0, LD|ST, IF_LS_3E, 0x78A08000) +INST1(swpah, "swpah", LD|ST, IF_LS_3E, 0x78A08000) // swpah Wm, Wt, [Xn] LS_3E 01111000101mmmmm 100000nnnnnttttt 78A0 8000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(swpalh, "swpalh", 0, LD|ST, IF_LS_3E, 0x78E08000) +INST1(swpalh, "swpalh", LD|ST, IF_LS_3E, 0x78E08000) // swpalh Wm, Wt, [Xn] LS_3E 01111000111mmmmm 100000nnnnnttttt 78E0 8000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(swplh, "swplh", 0, LD|ST, IF_LS_3E, 0x78608000) +INST1(swplh, "swplh", LD|ST, IF_LS_3E, 0x78608000) // swplh Wm, Wt, [Xn] LS_3E 01111000011mmmmm 100000nnnnnttttt 7860 8000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(swp, "swp", 0, LD|ST, IF_LS_3E, 0xB8208000) +INST1(swp, "swp", LD|ST, IF_LS_3E, 0xB8208000) // swp Rm, Rt, [Xn] LS_3E 1X111000001mmmmm 100000nnnnnttttt B820 8000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(swpa, "swpa", 0, LD|ST, IF_LS_3E, 0xB8A08000) +INST1(swpa, "swpa", LD|ST, IF_LS_3E, 0xB8A08000) // swpa Rm, Rt, [Xn] LS_3E 1X111000101mmmmm 100000nnnnnttttt B8A0 8000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(swpal, "swpal", 0, LD|ST, IF_LS_3E, 0xB8E08000) +INST1(swpal, "swpal", LD|ST, IF_LS_3E, 0xB8E08000) // swpal Rm, Rt, [Xn] LS_3E 1X111000111mmmmm 100000nnnnnttttt B8E0 8000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(swpl, "swpl", 0, LD|ST, IF_LS_3E, 0xB8608000) +INST1(swpl, "swpl", LD|ST, IF_LS_3E, 0xB8608000) // swpl Rm, Rt, [Xn] LS_3E 1X111000011mmmmm 100000nnnnnttttt B860 8000 Rm Rt Rn ARMv8.1 LSE Atomics -INST1(adr, "adr", 0, 0, IF_DI_1E, 0x10000000) +INST1(adr, "adr", 0, IF_DI_1E, 0x10000000) // adr Rd, simm21 DI_1E 0ii10000iiiiiiii iiiiiiiiiiiddddd 1000 0000 Rd simm21 -INST1(adrp, "adrp", 0, 0, IF_DI_1E, 0x90000000) +INST1(adrp, "adrp", 0, IF_DI_1E, 0x90000000) // adrp Rd, simm21 DI_1E 1ii10000iiiiiiii iiiiiiiiiiiddddd 9000 0000 Rd simm21 -INST1(b, "b", 0, 0, IF_BI_0A, 0x14000000) +INST1(b, "b", 0, IF_BI_0A, 0x14000000) // b simm26 BI_0A 000101iiiiiiiiii iiiiiiiiiiiiiiii 1400 0000 simm26:00 -INST1(b_tail, "b", 0, 0, IF_BI_0C, 0x14000000) +INST1(b_tail, "b", 0, IF_BI_0C, 0x14000000) // b simm26 BI_0A 000101iiiiiiiiii iiiiiiiiiiiiiiii 1400 0000 simm26:00, same as b representing a tail call of bl. -INST1(bl_local,"bl", 0, 0, IF_BI_0A, 0x94000000) +INST1(bl_local, "bl", 0, IF_BI_0A, 0x94000000) // bl simm26 BI_0A 100101iiiiiiiiii iiiiiiiiiiiiiiii 9400 0000 simm26:00, same as bl, but with a BasicBlock target. -INST1(bl, "bl", 0, 0, IF_BI_0C, 0x94000000) +INST1(bl, "bl", 0, IF_BI_0C, 0x94000000) // bl simm26 BI_0C 100101iiiiiiiiii iiiiiiiiiiiiiiii 9400 0000 simm26:00 -INST1(br, "br", 0, 0, IF_BR_1A, 0xD61F0000) +INST1(br, "br", 0, IF_BR_1A, 0xD61F0000) // br Rn BR_1A 1101011000011111 000000nnnnn00000 D61F 0000, an indirect branch like switch expansion -INST1(br_tail, "br", 0, 0, IF_BR_1B, 0xD61F0000) +INST1(br_tail, "br", 0, IF_BR_1B, 0xD61F0000) // br Rn BR_1B 1101011000011111 000000nnnnn00000 D61F 0000, same as br representing a tail call of blr. Encode target with Reg3. -INST1(blr, "blr", 0, 0, IF_BR_1B, 0xD63F0000) +INST1(blr, "blr", 0, IF_BR_1B, 0xD63F0000) // blr Rn BR_1B 1101011000111111 000000nnnnn00000 D63F 0000, Encode target with Reg3. -INST1(ret, "ret", 0, 0, IF_BR_1A, 0xD65F0000) +INST1(ret, "ret", 0, IF_BR_1A, 0xD65F0000) // ret Rn BR_1A 1101011001011111 000000nnnnn00000 D65F 0000 -INST1(beq, "beq", 0, 0, IF_BI_0B, 0x54000000) +INST1(beq, "beq", 0, IF_BI_0B, 0x54000000) // beq simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii00000 5400 0000 simm19:00 -INST1(bne, "bne", 0, 0, IF_BI_0B, 0x54000001) +INST1(bne, "bne", 0, IF_BI_0B, 0x54000001) // bne simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii00001 5400 0001 simm19:00 -INST1(bhs, "bhs", 0, 0, IF_BI_0B, 0x54000002) +INST1(bhs, "bhs", 0, IF_BI_0B, 0x54000002) // bhs simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii00010 5400 0002 simm19:00 -INST1(blo, "blo", 0, 0, IF_BI_0B, 0x54000003) +INST1(blo, "blo", 0, IF_BI_0B, 0x54000003) // blo simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii00011 5400 0003 simm19:00 -INST1(bmi, "bmi", 0, 0, IF_BI_0B, 0x54000004) +INST1(bmi, "bmi", 0, IF_BI_0B, 0x54000004) // bmi simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii00100 5400 0004 simm19:00 -INST1(bpl, "bpl", 0, 0, IF_BI_0B, 0x54000005) +INST1(bpl, "bpl", 0, IF_BI_0B, 0x54000005) // bpl simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii00101 5400 0005 simm19:00 -INST1(bvs, "bvs", 0, 0, IF_BI_0B, 0x54000006) +INST1(bvs, "bvs", 0, IF_BI_0B, 0x54000006) // bvs simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii00110 5400 0006 simm19:00 -INST1(bvc, "bvc", 0, 0, IF_BI_0B, 0x54000007) +INST1(bvc, "bvc", 0, IF_BI_0B, 0x54000007) // bvc simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii00111 5400 0007 simm19:00 -INST1(bhi, "bhi", 0, 0, IF_BI_0B, 0x54000008) +INST1(bhi, "bhi", 0, IF_BI_0B, 0x54000008) // bhi simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii01000 5400 0008 simm19:00 -INST1(bls, "bls", 0, 0, IF_BI_0B, 0x54000009) +INST1(bls, "bls", 0, IF_BI_0B, 0x54000009) // bls simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii01001 5400 0009 simm19:00 -INST1(bge, "bge", 0, 0, IF_BI_0B, 0x5400000A) +INST1(bge, "bge", 0, IF_BI_0B, 0x5400000A) // bge simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii01010 5400 000A simm19:00 -INST1(blt, "blt", 0, 0, IF_BI_0B, 0x5400000B) +INST1(blt, "blt", 0, IF_BI_0B, 0x5400000B) // blt simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii01011 5400 000B simm19:00 -INST1(bgt, "bgt", 0, 0, IF_BI_0B, 0x5400000C) +INST1(bgt, "bgt", 0, IF_BI_0B, 0x5400000C) // bgt simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii01100 5400 000C simm19:00 -INST1(ble, "ble", 0, 0, IF_BI_0B, 0x5400000D) +INST1(ble, "ble", 0, IF_BI_0B, 0x5400000D) // ble simm19 BI_0B 01010100iiiiiiii iiiiiiiiiii01101 5400 000D simm19:00 -INST1(cbz, "cbz", 0, 0, IF_BI_1A, 0x34000000) +INST1(cbz, "cbz", 0, IF_BI_1A, 0x34000000) // cbz Rt, simm19 BI_1A X0110100iiiiiiii iiiiiiiiiiittttt 3400 0000 Rt simm19:00 -INST1(cbnz, "cbnz", 0, 0, IF_BI_1A, 0x35000000) +INST1(cbnz, "cbnz", 0, IF_BI_1A, 0x35000000) // cbnz Rt, simm19 BI_1A X0110101iiiiiiii iiiiiiiiiiittttt 3500 0000 Rt simm19:00 -INST1(tbz, "tbz", 0, 0, IF_BI_1B, 0x36000000) +INST1(tbz, "tbz", 0, IF_BI_1B, 0x36000000) // tbz Rt, imm6, simm14 BI_1B B0110110bbbbbiii iiiiiiiiiiittttt 3600 0000 Rt imm6, simm14:00 -INST1(tbnz, "tbnz", 0, 0, IF_BI_1B, 0x37000000) +INST1(tbnz, "tbnz", 0, IF_BI_1B, 0x37000000) // tbnz Rt, imm6, simm14 BI_1B B0110111bbbbbiii iiiiiiiiiiittttt 3700 0000 Rt imm6, simm14:00 -INST1(movk, "movk", 0, 0, IF_DI_1B, 0x72800000) +INST1(movk, "movk", 0, IF_DI_1B, 0x72800000) // movk Rd,imm(i16,hw) DI_1B X11100101hwiiiii iiiiiiiiiiiddddd 7280 0000 imm(i16,hw) -INST1(movn, "movn", 0, 0, IF_DI_1B, 0x12800000) +INST1(movn, "movn", 0, IF_DI_1B, 0x12800000) // movn Rd,imm(i16,hw) DI_1B X00100101hwiiiii iiiiiiiiiiiddddd 1280 0000 imm(i16,hw) -INST1(movz, "movz", 0, 0, IF_DI_1B, 0x52800000) +INST1(movz, "movz", 0, IF_DI_1B, 0x52800000) // movz Rd,imm(i16,hw) DI_1B X10100101hwiiiii iiiiiiiiiiiddddd 5280 0000 imm(i16,hw) -INST1(csel, "csel", 0, 0, IF_DR_3D, 0x1A800000) +INST1(csel, "csel", 0, IF_DR_3D, 0x1A800000) // csel Rd,Rn,Rm,cond DR_3D X0011010100mmmmm cccc00nnnnnddddd 1A80 0000 cond -INST1(csinc, "csinc", 0, 0, IF_DR_3D, 0x1A800400) +INST1(csinc, "csinc", 0, IF_DR_3D, 0x1A800400) // csinc Rd,Rn,Rm,cond DR_3D X0011010100mmmmm cccc01nnnnnddddd 1A80 0400 cond -INST1(csinv, "csinv", 0, 0, IF_DR_3D, 0x5A800000) +INST1(csinv, "csinv", 0, IF_DR_3D, 0x5A800000) // csinv Rd,Rn,Rm,cond DR_3D X1011010100mmmmm cccc00nnnnnddddd 5A80 0000 cond -INST1(csneg, "csneg", 0, 0, IF_DR_3D, 0x5A800400) +INST1(csneg, "csneg", 0, IF_DR_3D, 0x5A800400) // csneg Rd,Rn,Rm,cond DR_3D X1011010100mmmmm cccc01nnnnnddddd 5A80 0400 cond -INST1(cinc, "cinc", 0, 0, IF_DR_2D, 0x1A800400) +INST1(cinc, "cinc", 0, IF_DR_2D, 0x1A800400) // cinc Rd,Rn,cond DR_2D X0011010100nnnnn cccc01nnnnnddddd 1A80 0400 cond -INST1(cinv, "cinv", 0, 0, IF_DR_2D, 0x5A800000) +INST1(cinv, "cinv", 0, IF_DR_2D, 0x5A800000) // cinv Rd,Rn,cond DR_2D X1011010100nnnnn cccc00nnnnnddddd 5A80 0000 cond -INST1(cneg, "cneg", 0, 0, IF_DR_2D, 0x5A800400) +INST1(cneg, "cneg", 0, IF_DR_2D, 0x5A800400) // cneg Rd,Rn,cond DR_2D X1011010100nnnnn cccc01nnnnnddddd 5A80 0400 cond -INST1(cset, "cset", 0, 0, IF_DR_1D, 0x1A9F07E0) +INST1(cset, "cset", 0, IF_DR_1D, 0x1A9F07E0) // cset Rd,cond DR_1D X001101010011111 cccc0111111ddddd 1A9F 07E0 Rd cond -INST1(csetm, "csetm", 0, 0, IF_DR_1D, 0x5A9F03E0) +INST1(csetm, "csetm", 0, IF_DR_1D, 0x5A9F03E0) // csetm Rd,cond DR_1D X101101010011111 cccc0011111ddddd 5A9F 03E0 Rd cond -INST1(aese, "aese", 0, 0, IF_DV_2P, 0x4E284800) +INST1(aese, "aese", 0, IF_DV_2P, 0x4E284800) // aese Vd.16B,Vn.16B DV_2P 0100111000101000 010010nnnnnddddd 4E28 4800 Vd.16B Vn.16B (vector) -INST1(aesd, "aesd", 0, 0, IF_DV_2P, 0x4E285800) +INST1(aesd, "aesd", 0, IF_DV_2P, 0x4E285800) // aesd Vd.16B,Vn.16B DV_2P 0100111000101000 010110nnnnnddddd 4E28 5800 Vd.16B Vn.16B (vector) -INST1(aesmc, "aesmc", 0, 0, IF_DV_2P, 0x4E286800) +INST1(aesmc, "aesmc", 0, IF_DV_2P, 0x4E286800) // aesmc Vd.16B,Vn.16B DV_2P 0100111000101000 011010nnnnnddddd 4E28 6800 Vd.16B Vn.16B (vector) -INST1(aesimc, "aesimc", 0, 0, IF_DV_2P, 0x4E287800) +INST1(aesimc, "aesimc", 0, IF_DV_2P, 0x4E287800) // aesimc Vd.16B,Vn.16B DV_2P 0100111000101000 011110nnnnnddddd 4E28 7800 Vd.16B Vn.16B (vector) -INST1(rev, "rev", 0, 0, IF_DR_2G, 0x5AC00800) +INST1(rev, "rev", 0, IF_DR_2G, 0x5AC00800) // rev Rd,Rm DR_2G X101101011000000 00001Xnnnnnddddd 5AC0 0800 Rd Rn -INST1(rev64, "rev64", 0, 0, IF_DV_2M, 0x0E200800) +INST1(rev64, "rev64", 0, IF_DV_2M, 0x0E200800) // rev64 Vd,Vn DV_2M 0Q001110XX100000 000010nnnnnddddd 0E20 0800 Vd,Vn (vector) -INST1(adc, "adc", 0, 0, IF_DR_3A, 0x1A000000) +INST1(adc, "adc", 0, IF_DR_3A, 0x1A000000) // adc Rd,Rn,Rm DR_3A X0011010000mmmmm 000000nnnnnddddd 1A00 0000 -INST1(adcs, "adcs", 0, 0, IF_DR_3A, 0x3A000000) +INST1(adcs, "adcs", 0, IF_DR_3A, 0x3A000000) // adcs Rd,Rn,Rm DR_3A X0111010000mmmmm 000000nnnnnddddd 3A00 0000 -INST1(sbc, "sbc", 0, 0, IF_DR_3A, 0x5A000000) +INST1(sbc, "sbc", 0, IF_DR_3A, 0x5A000000) // sdc Rd,Rn,Rm DR_3A X1011010000mmmmm 000000nnnnnddddd 5A00 0000 -INST1(sbcs, "sbcs", 0, 0, IF_DR_3A, 0x7A000000) +INST1(sbcs, "sbcs", 0, IF_DR_3A, 0x7A000000) // sdcs Rd,Rn,Rm DR_3A X1111010000mmmmm 000000nnnnnddddd 7A00 0000 -INST1(udiv, "udiv", 0, 0, IF_DR_3A, 0x1AC00800) +INST1(udiv, "udiv", 0, IF_DR_3A, 0x1AC00800) // udiv Rd,Rn,Rm DR_3A X0011010110mmmmm 000010nnnnnddddd 1AC0 0800 -INST1(sdiv, "sdiv", 0, 0, IF_DR_3A, 0x1AC00C00) +INST1(sdiv, "sdiv", 0, IF_DR_3A, 0x1AC00C00) // sdiv Rd,Rn,Rm DR_3A X0011010110mmmmm 000011nnnnnddddd 1AC0 0C00 -INST1(mneg, "mneg", 0, 0, IF_DR_3A, 0x1B00FC00) +INST1(mneg, "mneg", 0, IF_DR_3A, 0x1B00FC00) // mneg Rd,Rn,Rm DR_3A X0011011000mmmmm 111111nnnnnddddd 1B00 FC00 -INST1(madd, "madd", 0, 0, IF_DR_4A, 0x1B000000) +INST1(madd, "madd", 0, IF_DR_4A, 0x1B000000) // madd Rd,Rn,Rm,Ra DR_4A X0011011000mmmmm 0aaaaannnnnddddd 1B00 0000 -INST1(msub, "msub", 0, 0, IF_DR_4A, 0x1B008000) +INST1(msub, "msub", 0, IF_DR_4A, 0x1B008000) // msub Rd,Rn,Rm,Ra DR_4A X0011011000mmmmm 1aaaaannnnnddddd 1B00 8000 -INST1(smaddl, "smaddl", 0, 0, IF_DR_4A, 0x9B200000) +INST1(smaddl, "smaddl", 0, IF_DR_4A, 0x9B200000) // smaddl Rd,Rn,Rm,Ra DR_4A 10011011001mmmmm 0aaaaannnnnddddd 9B20 0000 -INST1(smnegl, "smnegl", 0, 0, IF_DR_3A, 0x9B20FC00) +INST1(smnegl, "smnegl", 0, IF_DR_3A, 0x9B20FC00) // smnegl Rd,Rn,Rm DR_3A 10011011001mmmmm 111111nnnnnddddd 9B20 FC00 -INST1(smsubl, "smsubl", 0, 0, IF_DR_4A, 0x9B208000) +INST1(smsubl, "smsubl", 0, IF_DR_4A, 0x9B208000) // smsubl Rd,Rn,Rm,Ra DR_4A 10011011001mmmmm 1aaaaannnnnddddd 9B20 8000 -INST1(smulh, "smulh", 0, 0, IF_DR_3A, 0x9B407C00) +INST1(smulh, "smulh", 0, IF_DR_3A, 0x9B407C00) // smulh Rd,Rn,Rm DR_3A 10011011010mmmmm 011111nnnnnddddd 9B40 7C00 -INST1(umaddl, "umaddl", 0, 0, IF_DR_4A, 0x9BA00000) +INST1(umaddl, "umaddl", 0, IF_DR_4A, 0x9BA00000) // umaddl Rd,Rn,Rm,Ra DR_4A 10011011101mmmmm 0aaaaannnnnddddd 9BA0 0000 -INST1(umnegl, "umnegl", 0, 0, IF_DR_3A, 0x9BA0FC00) +INST1(umnegl, "umnegl", 0, IF_DR_3A, 0x9BA0FC00) // umnegl Rd,Rn,Rm DR_3A 10011011101mmmmm 111111nnnnnddddd 9BA0 FC00 -INST1(umsubl, "umsubl", 0, 0, IF_DR_4A, 0x9BA08000) +INST1(umsubl, "umsubl", 0, IF_DR_4A, 0x9BA08000) // umsubl Rd,Rn,Rm,Ra DR_4A 10011011101mmmmm 1aaaaannnnnddddd 9BA0 8000 -INST1(umulh, "umulh", 0, 0, IF_DR_3A, 0x9BC07C00) +INST1(umulh, "umulh", 0, IF_DR_3A, 0x9BC07C00) // umulh Rd,Rn,Rm DR_3A 10011011110mmmmm 011111nnnnnddddd 9BC0 7C00 -INST1(extr, "extr", 0, 0, IF_DR_3E, 0x13800000) +INST1(extr, "extr", 0, IF_DR_3E, 0x13800000) // extr Rd,Rn,Rm,imm6 DR_3E X00100111X0mmmmm ssssssnnnnnddddd 1380 0000 imm(0-63) -INST1(lslv, "lslv", 0, 0, IF_DR_3A, 0x1AC02000) +INST1(lslv, "lslv", 0, IF_DR_3A, 0x1AC02000) // lslv Rd,Rn,Rm DR_3A X0011010110mmmmm 001000nnnnnddddd 1AC0 2000 -INST1(lsrv, "lsrv", 0, 0, IF_DR_3A, 0x1AC02400) +INST1(lsrv, "lsrv", 0, IF_DR_3A, 0x1AC02400) // lsrv Rd,Rn,Rm DR_3A X0011010110mmmmm 001001nnnnnddddd 1AC0 2400 -INST1(asrv, "asrv", 0, 0, IF_DR_3A, 0x1AC02800) +INST1(asrv, "asrv", 0, IF_DR_3A, 0x1AC02800) // asrv Rd,Rn,Rm DR_3A X0011010110mmmmm 001010nnnnnddddd 1AC0 2800 -INST1(rorv, "rorv", 0, 0, IF_DR_3A, 0x1AC02C00) +INST1(rorv, "rorv", 0, IF_DR_3A, 0x1AC02C00) // rorv Rd,Rn,Rm DR_3A X0011010110mmmmm 001011nnnnnddddd 1AC0 2C00 -INST1(crc32b, "crc32b", 0, 0, IF_DR_3A, 0x1AC04000) +INST1(crc32b, "crc32b", 0, IF_DR_3A, 0x1AC04000) // crc32b Rd,Rn,Rm DR_3A 00011010110mmmmm 010000nnnnnddddd 1AC0 4000 -INST1(crc32h, "crc32h", 0, 0, IF_DR_3A, 0x1AC04400) +INST1(crc32h, "crc32h", 0, IF_DR_3A, 0x1AC04400) // crc32h Rd,Rn,Rm DR_3A 00011010110mmmmm 010001nnnnnddddd 1AC0 4400 -INST1(crc32w, "crc32w", 0, 0, IF_DR_3A, 0x1AC04800) +INST1(crc32w, "crc32w", 0, IF_DR_3A, 0x1AC04800) // crc32w Rd,Rn,Rm DR_3A 00011010110mmmmm 010010nnnnnddddd 1AC0 4800 -INST1(crc32x, "crc32x", 0, 0, IF_DR_3A, 0x9AC04C00) +INST1(crc32x, "crc32x", 0, IF_DR_3A, 0x9AC04C00) // crc32x Rd,Rn,Xm DR_3A 10011010110mmmmm 010011nnnnnddddd 9AC0 4C00 -INST1(crc32cb, "crc32cb",0, 0, IF_DR_3A, 0x1AC05000) +INST1(crc32cb, "crc32cb", 0, IF_DR_3A, 0x1AC05000) // crc32cb Rd,Rn,Rm DR_3A 00011010110mmmmm 010100nnnnnddddd 1AC0 5000 -INST1(crc32ch, "crc32ch",0, 0, IF_DR_3A, 0x1AC05400) +INST1(crc32ch, "crc32ch", 0, IF_DR_3A, 0x1AC05400) // crc32ch Rd,Rn,Rm DR_3A 00011010110mmmmm 010101nnnnnddddd 1AC0 5400 -INST1(crc32cw, "crc32cw",0, 0, IF_DR_3A, 0x1AC05800) +INST1(crc32cw, "crc32cw", 0, IF_DR_3A, 0x1AC05800) // crc32cw Rd,Rn,Rm DR_3A 00011010110mmmmm 010110nnnnnddddd 1AC0 5800 -INST1(crc32cx, "crc32cx",0, 0, IF_DR_3A, 0x9AC05C00) +INST1(crc32cx, "crc32cx", 0, IF_DR_3A, 0x9AC05C00) // crc32cx Rd,Rn,Xm DR_3A 10011010110mmmmm 010111nnnnnddddd 9AC0 5C00 -INST1(sha1c, "sha1c", 0, 0, IF_DV_3F, 0x5E000000) +INST1(sha1c, "sha1c", 0, IF_DV_3F, 0x5E000000) // sha1c Qd, Sn Vm.4S DV_3F 01011110000mmmmm 000000nnnnnddddd 5E00 0000 Qd Sn Vm.4S (vector) -INST1(sha1m, "sha1m", 0, 0, IF_DV_3F, 0x5E002000) +INST1(sha1m, "sha1m", 0, IF_DV_3F, 0x5E002000) // sha1m Qd, Sn Vm.4S DV_3F 01011110000mmmmm 001000nnnnnddddd 5E00 0000 Qd Sn Vm.4S (vector) -INST1(sha1p, "sha1p", 0, 0, IF_DV_3F, 0x5E001000) +INST1(sha1p, "sha1p", 0, IF_DV_3F, 0x5E001000) // sha1m Qd, Sn Vm.4S DV_3F 01011110000mmmmm 000100nnnnnddddd 5E00 0000 Qd Sn Vm.4S (vector) -INST1(sha1h, "sha1h", 0, 0, IF_DV_2U, 0x5E280800) +INST1(sha1h, "sha1h", 0, IF_DV_2U, 0x5E280800) // sha1h Sd, Sn DV_2U 0101111000101000 000010nnnnnddddd 5E28 0800 Sn Sn -INST1(sha1su0, "sha1su0", 0, 0, IF_DV_3F, 0x5E003000) +INST1(sha1su0, "sha1su0", 0, IF_DV_3F, 0x5E003000) // sha1su0 Vd.4S,Vn.4S,Vm.4S DV_3F 01011110000mmmmm 001100nnnnnddddd 5E00 3000 Vd.4S Vn.4S Vm.4S (vector) -INST1(sha1su1, "sha1su1", 0, 0, IF_DV_2P, 0x5E281800) +INST1(sha1su1, "sha1su1", 0, IF_DV_2P, 0x5E281800) // sha1su1 Vd.4S, Vn.4S DV_2P 0101111000101000 000110nnnnnddddd 5E28 1800 Vd.4S Vn.4S (vector) -INST1(sha256h, "sha256h", 0, 0, IF_DV_3F, 0x5E004000) +INST1(sha256h, "sha256h", 0, IF_DV_3F, 0x5E004000) // sha256h Qd,Qn,Vm.4S DV_3F 01011110000mmmmm 010000nnnnnddddd 5E00 4000 Qd Qn Vm.4S (vector) -INST1(sha256h2, "sha256h2", 0, 0, IF_DV_3F, 0x5E005000) +INST1(sha256h2, "sha256h2", 0, IF_DV_3F, 0x5E005000) // sha256h Qd,Qn,Vm.4S DV_3F 01011110000mmmmm 010100nnnnnddddd 5E00 5000 Qd Qn Vm.4S (vector) -INST1(sha256su0, "sha256su0", 0, 0, IF_DV_2P, 0x5E282800) +INST1(sha256su0, "sha256su0", 0, IF_DV_2P, 0x5E282800) // sha256su0 Vd.4S,Vn.4S DV_2P 0101111000101000 001010nnnnnddddd 5E28 2800 Vd.4S Vn.4S (vector) -INST1(sha256su1, "sha256su1", 0, 0, IF_DV_3F, 0x5E006000) +INST1(sha256su1, "sha256su1", 0, IF_DV_3F, 0x5E006000) // sha256su1 Vd.4S,Vn.4S,Vm.4S DV_3F 01011110000mmmmm 011000nnnnnddddd 5E00 6000 Vd.4S Vn.4S Vm.4S (vector) -INST1(ext, "ext", 0, 0, IF_DV_3G, 0x2E000000) - // C7.2.36 EXT +INST1(ext, "ext", 0, IF_DV_3G, 0x2E000000) // ext Vd,Vn,Vm,index DV_3G 0Q101110000mmmmm 0iiii0nnnnnddddd 2E00 0000 Vd Vn Vm index (vector) -INST1(sbfm, "sbfm", 0, 0, IF_DI_2D, 0x13000000) +INST1(sbfm, "sbfm", 0, IF_DI_2D, 0x13000000) // sbfm Rd,Rn,imr,ims DI_2D X00100110Nrrrrrr ssssssnnnnnddddd 1300 0000 imr, ims -INST1(bfm, "bfm", 0, 0, IF_DI_2D, 0x33000000) +INST1(bfm, "bfm", 0, IF_DI_2D, 0x33000000) // bfm Rd,Rn,imr,ims DI_2D X01100110Nrrrrrr ssssssnnnnnddddd 3300 0000 imr, ims -INST1(ubfm, "ubfm", 0, 0, IF_DI_2D, 0x53000000) +INST1(ubfm, "ubfm", 0, IF_DI_2D, 0x53000000) // ubfm Rd,Rn,imr,ims DI_2D X10100110Nrrrrrr ssssssnnnnnddddd 5300 0000 imr, ims -INST1(sbfiz, "sbfiz", 0, 0, IF_DI_2D, 0x13000000) +INST1(sbfiz, "sbfiz", 0, IF_DI_2D, 0x13000000) // sbfiz Rd,Rn,lsb,width DI_2D X00100110Nrrrrrr ssssssnnnnnddddd 1300 0000 imr, ims -INST1(bfi, "bfi", 0, 0, IF_DI_2D, 0x33000000) +INST1(bfi, "bfi", 0, IF_DI_2D, 0x33000000) // bfi Rd,Rn,lsb,width DI_2D X01100110Nrrrrrr ssssssnnnnnddddd 3300 0000 imr, ims -INST1(ubfiz, "ubfiz", 0, 0, IF_DI_2D, 0x53000000) +INST1(ubfiz, "ubfiz", 0, IF_DI_2D, 0x53000000) // ubfiz Rd,Rn,lsb,width DI_2D X10100110Nrrrrrr ssssssnnnnnddddd 5300 0000 imr, ims -INST1(sbfx, "sbfx", 0, 0, IF_DI_2D, 0x13000000) +INST1(sbfx, "sbfx", 0, IF_DI_2D, 0x13000000) // sbfx Rd,Rn,lsb,width DI_2D X00100110Nrrrrrr ssssssnnnnnddddd 1300 0000 imr, ims -INST1(bfxil, "bfxil", 0, 0, IF_DI_2D, 0x33000000) +INST1(bfxil, "bfxil", 0, IF_DI_2D, 0x33000000) // bfxil Rd,Rn,lsb,width DI_2D X01100110Nrrrrrr ssssssnnnnnddddd 3300 0000 imr, ims -INST1(ubfx, "ubfx", 0, 0, IF_DI_2D, 0x53000000) +INST1(ubfx, "ubfx", 0, IF_DI_2D, 0x53000000) // ubfx Rd,Rn,lsb,width DI_2D X10100110Nrrrrrr ssssssnnnnnddddd 5300 0000 imr, ims -INST1(sxtb, "sxtb", 0, 0, IF_DR_2H, 0x13001C00) +INST1(sxtb, "sxtb", 0, IF_DR_2H, 0x13001C00) // sxtb Rd,Rn DR_2H X00100110X000000 000111nnnnnddddd 1300 1C00 -INST1(sxth, "sxth", 0, 0, IF_DR_2H, 0x13003C00) +INST1(sxth, "sxth", 0, IF_DR_2H, 0x13003C00) // sxth Rd,Rn DR_2H X00100110X000000 001111nnnnnddddd 1300 3C00 -INST1(sxtw, "sxtw", 0, 0, IF_DR_2H, 0x13007C00) +INST1(sxtw, "sxtw", 0, IF_DR_2H, 0x13007C00) // sxtw Rd,Rn DR_2H X00100110X000000 011111nnnnnddddd 1300 7C00 -INST1(uxtb, "uxtb", 0, 0, IF_DR_2H, 0x53001C00) +INST1(uxtb, "uxtb", 0, IF_DR_2H, 0x53001C00) // uxtb Rd,Rn DR_2H 0101001100000000 000111nnnnnddddd 5300 1C00 -INST1(uxth, "uxth", 0, 0, IF_DR_2H, 0x53003C00) +INST1(uxth, "uxth", 0, IF_DR_2H, 0x53003C00) // uxth Rd,Rn DR_2H 0101001100000000 001111nnnnnddddd 5300 3C00 -INST1(nop, "nop", 0, 0, IF_SN_0A, 0xD503201F) +INST1(nop, "nop", 0, IF_SN_0A, 0xD503201F) // nop SN_0A 1101010100000011 0010000000011111 D503 201F -INST1(bkpt, "bkpt", 0, 0, IF_SN_0A, 0xD43E0000) +INST1(bkpt, "bkpt", 0, IF_SN_0A, 0xD43E0000) // brpt SN_0A 1101010000111110 0000000000000000 D43E 0000 0xF000 -INST1(brk, "brk", 0, 0, IF_SI_0A, 0xD4200000) +INST1(brk, "brk", 0, IF_SI_0A, 0xD4200000) // brk imm16 SI_0A 11010100001iiiii iiiiiiiiiii00000 D420 0000 imm16 -INST1(dsb, "dsb", 0, 0, IF_SI_0B, 0xD503309F) +INST1(dsb, "dsb", 0, IF_SI_0B, 0xD503309F) // dsb barrierKind SI_0B 1101010100000011 0011bbbb10011111 D503 309F imm4 - barrier kind -INST1(dmb, "dmb", 0, 0, IF_SI_0B, 0xD50330BF) +INST1(dmb, "dmb", 0, IF_SI_0B, 0xD50330BF) // dmb barrierKind SI_0B 1101010100000011 0011bbbb10111111 D503 30BF imm4 - barrier kind -INST1(isb, "isb", 0, 0, IF_SI_0B, 0xD50330DF) +INST1(isb, "isb", 0, IF_SI_0B, 0xD50330DF) // isb barrierKind SI_0B 1101010100000011 0011bbbb11011111 D503 30DF imm4 - barrier kind -INST1(umov, "umov", 0, 0, IF_DV_2B, 0x0E003C00) +INST1(umov, "umov", 0, IF_DV_2B, 0x0E003C00) // umov Rd,Vn[] DV_2B 0Q001110000iiiii 001111nnnnnddddd 0E00 3C00 Rd,Vn[] -INST1(smov, "smov", 0, 0, IF_DV_2B, 0x0E002C00) +INST1(smov, "smov", 0, IF_DV_2B, 0x0E002C00) // smov Rd,Vn[] DV_2B 0Q001110000iiiii 001011nnnnnddddd 0E00 3C00 Rd,Vn[] -INST1(movi, "movi", 0, 0, IF_DV_1B, 0x0F000400) +INST1(movi, "movi", 0, IF_DV_1B, 0x0F000400) // movi Vd,imm8 DV_1B 0QX0111100000iii cmod01iiiiiddddd 0F00 0400 Vd imm8 (immediate vector) -INST1(mvni, "mvni", 0, 0, IF_DV_1B, 0x2F000400) +INST1(mvni, "mvni", 0, IF_DV_1B, 0x2F000400) // mvni Vd,imm8 DV_1B 0Q10111100000iii cmod01iiiiiddddd 2F00 0400 Vd imm8 (immediate vector) -INST1(urecpe, "urecpe", 0, 0, IF_DV_2A, 0x0EA1C800) - // C7.2.372 URECPE +INST1(urecpe, "urecpe", 0, IF_DV_2A, 0x0EA1C800) // urecpe Vd,Vn DV_2A 0Q0011101X100001 110010nnnnnddddd 0EA1 C800 Vd,Vn (vector) -INST1(ursqrte, "ursqrte",0, 0, IF_DV_2A, 0x2EA1C800) - // C7.2.376 URSQRTE +INST1(ursqrte, "ursqrte", 0, IF_DV_2A, 0x2EA1C800) // ursqrte Vd,Vn DV_2A 0Q1011101X100001 110010nnnnnddddd 2EA1 C800 Vd,Vn (vector) -INST1(bsl, "bsl", 0, 0, IF_DV_3C, 0x2E601C00) +INST1(bsl, "bsl", 0, IF_DV_3C, 0x2E601C00) // bsl Vd,Vn,Vm DV_3C 0Q101110011mmmmm 000111nnnnnddddd 2E60 1C00 Vd,Vn,Vm -INST1(bit, "bit", 0, 0, IF_DV_3C, 0x2EA01C00) +INST1(bit, "bit", 0, IF_DV_3C, 0x2EA01C00) // bit Vd,Vn,Vm DV_3C 0Q101110101mmmmm 000111nnnnnddddd 2EA0 1C00 Vd,Vn,Vm -INST1(bif, "bif", 0, 0, IF_DV_3C, 0x2EE01C00) +INST1(bif, "bif", 0, IF_DV_3C, 0x2EE01C00) // bif Vd,Vn,Vm DV_3C 0Q101110111mmmmm 000111nnnnnddddd 2EE0 1C00 Vd,Vn,Vm -INST1(addv, "addv", 0, 0, IF_DV_2T, 0x0E31B800) +INST1(addv, "addv", 0, IF_DV_2T, 0x0E31B800) // addv Vd,Vn DV_2T 0Q001110XX110001 101110nnnnnddddd 0E31 B800 Vd,Vn (vector) -INST1(cnt, "cnt", 0, 0, IF_DV_2M, 0x0E205800) +INST1(cnt, "cnt", 0, IF_DV_2M, 0x0E205800) // cnt Vd,Vn DV_2M 0Q00111000100000 010110nnnnnddddd 0E20 5800 Vd,Vn (vector) -INST1(not, "not", 0, 0, IF_DV_2M, 0x2E205800) +INST1(not, "not", 0, IF_DV_2M, 0x2E205800) // not Vd,Vn DV_2M 0Q10111000100000 010110nnnnnddddd 2E20 5800 Vd,Vn (vector) -INST1(saddlv, "saddlv", 0, 0, IF_DV_2T, 0x0E303800) +INST1(saddlv, "saddlv", 0, IF_DV_2T, 0x0E303800) // saddlv Vd,Vn DV_2T 0Q001110XX110000 001110nnnnnddddd 0E30 3800 Vd,Vn (vector) -INST1(smaxv, "smaxv", 0, 0, IF_DV_2T, 0x0E30A800) +INST1(smaxv, "smaxv", 0, IF_DV_2T, 0x0E30A800) // smaxv Vd,Vn DV_2T 0Q001110XX110000 101010nnnnnddddd 0E30 A800 Vd,Vn (vector) -INST1(sminv, "sminv", 0, 0, IF_DV_2T, 0x0E31A800) +INST1(sminv, "sminv", 0, IF_DV_2T, 0x0E31A800) // sminv Vd,Vn DV_2T 0Q001110XX110001 101010nnnnnddddd 0E31 A800 Vd,Vn (vector) -INST1(uaddlv, "uaddlv", 0, 0, IF_DV_2T, 0x2E303800) +INST1(uaddlv, "uaddlv", 0, IF_DV_2T, 0x2E303800) // uaddlv Vd,Vn DV_2T 0Q101110XX110000 001110nnnnnddddd 2E30 3800 Vd,Vn (vector) -INST1(umaxv, "umaxv", 0, 0, IF_DV_2T, 0x2E30A800) +INST1(umaxv, "umaxv", 0, IF_DV_2T, 0x2E30A800) // umaxv Vd,Vn DV_2T 0Q101110XX110000 101010nnnnnddddd 2E30 A800 Vd,Vn (vector) -INST1(uminv, "uminv", 0, 0, IF_DV_2T, 0x2E31A800) +INST1(uminv, "uminv", 0, IF_DV_2T, 0x2E31A800) // uminv Vd,Vn DV_2T 0Q101110XX110001 101010nnnnnddddd 2E31 A800 Vd,Vn (vector) -INST1(fmaxnmv, "fmaxnmv",0, 0, IF_DV_2R, 0x2E30C800) +INST1(fmaxnmv, "fmaxnmv", 0, IF_DV_2R, 0x2E30C800) // fmaxnmv Vd,Vn DV_2R 0Q1011100X110000 110010nnnnnddddd 2E30 C800 Vd,Vn (vector) -INST1(fmaxv, "fmaxv", 0, 0, IF_DV_2R, 0x2E30F800) +INST1(fmaxv, "fmaxv", 0, IF_DV_2R, 0x2E30F800) // fmaxv Vd,Vn DV_2R 0Q1011100X110000 111110nnnnnddddd 2E30 F800 Vd,Vn (vector) -INST1(fminnmv, "fminnmv",0, 0, IF_DV_2R, 0x2EB0C800) +INST1(fminnmv, "fminnmv", 0, IF_DV_2R, 0x2EB0C800) // fminnmv Vd,Vn DV_2R 0Q1011101X110000 110010nnnnnddddd 2EB0 C800 Vd,Vn (vector) -INST1(fminv, "fminv", 0, 0, IF_DV_2R, 0x2EB0F800) +INST1(fminv, "fminv", 0, IF_DV_2R, 0x2EB0F800) // fminv Vd,Vn DV_2R 0Q1011101X110000 111110nnnnnddddd 2EB0 F800 Vd,Vn (vector) -INST1(uzp1, "uzp1", 0, 0, IF_DV_3A, 0x0E001800) +INST1(uzp1, "uzp1", 0, IF_DV_3A, 0x0E001800) // uzp1 Vd,Vn,Vm DV_3A 0Q001110XX0mmmmm 000110nnnnnddddd 0E00 1800 Vd,Vn,Vm (vector) -INST1(uzp2, "uzp2", 0, 0, IF_DV_3A, 0x0E005800) +INST1(uzp2, "uzp2", 0, IF_DV_3A, 0x0E005800) // upz2 Vd,Vn,Vm DV_3A 0Q001110XX0mmmmm 010110nnnnnddddd 0E00 5800 Vd,Vn,Vm (vector) -INST1(zip1, "zip1", 0, 0, IF_DV_3A, 0x0E003800) +INST1(zip1, "zip1", 0, IF_DV_3A, 0x0E003800) // zip1 Vd,Vn,Vm DV_3A 0Q001110XX0mmmmm 011110nnnnnddddd 0E00 3800 Vd,Vn,Vm (vector) -INST1(zip2, "zip2", 0, 0, IF_DV_3A, 0x0E007800) +INST1(zip2, "zip2", 0, IF_DV_3A, 0x0E007800) // zip2 Vd,Vn,Vm DV_3A 0Q001110XX0mmmmm 001110nnnnnddddd 0E00 7800 Vd,Vn,Vm (vector) -INST1(trn1, "trn1", 0, 0, IF_DV_3A, 0x0E002800) +INST1(trn1, "trn1", 0, IF_DV_3A, 0x0E002800) // trn1 Vd,Vn,Vm DV_3A 0Q001110XX0mmmmm 001010nnnnnddddd 0E00 2800 Vd,Vn,Vm (vector) -INST1(trn2, "trn2", 0, 0, IF_DV_3A, 0x0E006800) +INST1(trn2, "trn2", 0, IF_DV_3A, 0x0E006800) // trn2 Vd,Vn,Vm DV_3A 0Q001110XX0mmmmm 011010nnnnnddddd 0E00 6800 Vd,Vn,Vm (vector) -INST1(xtn, "xtn", 0, 0, IF_DV_2M, 0x0E212800) +INST1(xtn, "xtn", 0, IF_DV_2M, 0x0E212800) // xtn Vd,Vn DV_2M 00101110XX110000 001110nnnnnddddd 0E21 2800 Vd,Vn (vector) -INST1(xtn2, "xtn2", 0, 0, IF_DV_2M, 0x4E212800) +INST1(xtn2, "xtn2", 0, IF_DV_2M, 0x4E212800) // xtn2 Vd,Vn DV_2M 01101110XX110000 001110nnnnnddddd 4E21 2800 Vd,Vn (vector) -INST1(fnmul, "fnmul", 0, 0, IF_DV_3D, 0x1E208800) +INST1(fnmul, "fnmul", 0, IF_DV_3D, 0x1E208800) // fnmul Vd,Vn,Vm DV_3D 000111100X1mmmmm 100010nnnnnddddd 1E20 8800 Vd,Vn,Vm (scalar) -INST1(fmadd, "fmadd", 0, 0, IF_DV_4A, 0x1F000000) +INST1(fmadd, "fmadd", 0, IF_DV_4A, 0x1F000000) // fmadd Vd,Va,Vn,Vm DV_4A 000111110X0mmmmm 0aaaaannnnnddddd 1F00 0000 Vd Vn Vm Va (scalar) -INST1(fmsub, "fmsub", 0, 0, IF_DV_4A, 0x1F008000) +INST1(fmsub, "fmsub", 0, IF_DV_4A, 0x1F008000) // fmsub Vd,Va,Vn,Vm DV_4A 000111110X0mmmmm 1aaaaannnnnddddd 1F00 8000 Vd Vn Vm Va (scalar) -INST1(fnmadd, "fnmadd", 0, 0, IF_DV_4A, 0x1F200000) +INST1(fnmadd, "fnmadd", 0, IF_DV_4A, 0x1F200000) // fnmadd Vd,Va,Vn,Vm DV_4A 000111110X1mmmmm 0aaaaannnnnddddd 1F20 0000 Vd Vn Vm Va (scalar) -INST1(fnmsub, "fnmsub", 0, 0, IF_DV_4A, 0x1F208000) +INST1(fnmsub, "fnmsub", 0, IF_DV_4A, 0x1F208000) // fnmsub Vd,Va,Vn,Vm DV_4A 000111110X1mmmmm 1aaaaannnnnddddd 1F20 8000 Vd Vn Vm Va (scalar) -INST1(fcvt, "fcvt", 0, 0, IF_DV_2J, 0x1E224000) +INST1(fcvt, "fcvt", 0, IF_DV_2J, 0x1E224000) // fcvt Vd,Vn DV_2J 00011110SS10001D D10000nnnnnddddd 1E22 4000 Vd,Vn -INST1(pmul, "pmul", 0, 0, IF_DV_3A, 0x2E209C00) +INST1(pmul, "pmul", 0, IF_DV_3A, 0x2E209C00) // pmul Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 100111nnnnnddddd 2E20 9C00 Vd,Vn,Vm (vector) -INST1(saba, "saba", 0, 0, IF_DV_3A, 0x0E207C00) +INST1(saba, "saba", 0, IF_DV_3A, 0x0E207C00) // saba Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 011111nnnnnddddd 0E20 7C00 Vd,Vn,Vm (vector) -INST1(sabd, "sabd", 0, 0, IF_DV_3A, 0x0E207400) +INST1(sabd, "sabd", 0, IF_DV_3A, 0x0E207400) // sabd Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 011101nnnnnddddd 0E20 7400 Vd,Vn,Vm (vector) -INST1(smax, "smax", 0, 0, IF_DV_3A, 0x0E206400) +INST1(smax, "smax", 0, IF_DV_3A, 0x0E206400) // smax Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 011001nnnnnddddd 0E20 6400 Vd,Vn,Vm (vector) -INST1(smaxp, "smaxp", 0, 0, IF_DV_3A, 0x0E20A400) +INST1(smaxp, "smaxp", 0, IF_DV_3A, 0x0E20A400) // smaxp Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 101001nnnnnddddd 0E20 A400 Vd,Vn,Vm (vector) -INST1(smin, "smin", 0, 0, IF_DV_3A, 0x0E206C00) +INST1(smin, "smin", 0, IF_DV_3A, 0x0E206C00) // smax Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 011011nnnnnddddd 0E20 6C00 Vd,Vn,Vm (vector) -INST1(sminp, "sminp", 0, 0, IF_DV_3A, 0x0E20AC00) +INST1(sminp, "sminp", 0, IF_DV_3A, 0x0E20AC00) // smax Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 101011nnnnnddddd 0E20 AC00 Vd,Vn,Vm (vector) -INST1(uaba, "uaba", 0, 0, IF_DV_3A, 0x2E207C00) +INST1(uaba, "uaba", 0, IF_DV_3A, 0x2E207C00) // uaba Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 011111nnnnnddddd 2E20 7C00 Vd,Vn,Vm (vector) -INST1(uabd, "uabd", 0, 0, IF_DV_3A, 0x2E207400) +INST1(uabd, "uabd", 0, IF_DV_3A, 0x2E207400) // uabd Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 011101nnnnnddddd 2E20 7400 Vd,Vn,Vm (vector) -INST1(umax, "umax", 0, 0, IF_DV_3A, 0x2E206400) +INST1(umax, "umax", 0, IF_DV_3A, 0x2E206400) // umax Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 011001nnnnnddddd 2E20 6400 Vd,Vn,Vm (vector) -INST1(umaxp, "umaxp", 0, 0, IF_DV_3A, 0x2E20A400) +INST1(umaxp, "umaxp", 0, IF_DV_3A, 0x2E20A400) // umaxp Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 101001nnnnnddddd 2E20 A400 Vd,Vn,Vm (vector) -INST1(umin, "umin", 0, 0, IF_DV_3A, 0x2E206C00) +INST1(umin, "umin", 0, IF_DV_3A, 0x2E206C00) // umin Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 011011nnnnnddddd 2E20 6C00 Vd,Vn,Vm (vector) -INST1(uminp, "uminp", 0, 0, IF_DV_3A, 0x2E20AC00) +INST1(uminp, "uminp", 0, IF_DV_3A, 0x2E20AC00) // umin Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 101011nnnnnddddd 2E20 AC00 Vd,Vn,Vm (vector) -INST1(fcvtl, "fcvtl", 0, 0, IF_DV_2G, 0x0E217800) - // fcvtl Vd,Vn DV_2G 000011100X100001 011110nnnnnddddd 0E21 7800 Vd,Vn (scalar) +INST1(fcvtl, "fcvtl", 0, IF_DV_2A, 0x0E217800) + // fcvtl Vd,Vn DV_2A 000011100X100001 011110nnnnnddddd 0E21 7800 Vd,Vn (vector) -INST1(fcvtl2, "fcvtl2", 0, 0, IF_DV_2G, 0x4E217800) - // fcvtl2 Vd,Vn DV_2G 040011100X100001 011110nnnnnddddd 4E21 7800 Vd,Vn (scalar) +INST1(fcvtl2, "fcvtl2", 0, IF_DV_2A, 0x4E217800) + // fcvtl2 Vd,Vn DV_2A 040011100X100001 011110nnnnnddddd 4E21 7800 Vd,Vn (vector) -INST1(fcvtn, "fcvtn", 0, 0, IF_DV_2G, 0x0E216800) - // fcvtn Vd,Vn DV_2G 000011100X100001 011010nnnnnddddd 0E21 6800 Vd,Vn (scalar) +INST1(fcvtn, "fcvtn", 0, IF_DV_2A, 0x0E216800) + // fcvtn Vd,Vn DV_2A 000011100X100001 011010nnnnnddddd 0E21 6800 Vd,Vn (vector) -INST1(fcvtn2, "fcvtn2", 0, 0, IF_DV_2G, 0x4E216800) - // fcvtn2 Vd,Vn DV_2G 040011100X100001 011010nnnnnddddd 4E21 6800 Vd,Vn (scalar) +INST1(fcvtn2, "fcvtn2", 0, IF_DV_2A, 0x4E216800) + // fcvtn2 Vd,Vn DV_2A 040011100X100001 011010nnnnnddddd 4E21 6800 Vd,Vn (vector) -INST1(frecpx, "frecpx", 0, 0, IF_DV_2G, 0x5EA1F800) - // C7.2.139 FRECPX +INST1(frecpx, "frecpx", 0, IF_DV_2G, 0x5EA1F800) // frecpx Vd,Vn DV_2G 010111101X100001 111110nnnnnddddd 5EA1 F800 Vd,Vn (scalar) -INST1(addhn, "addhn", 0, 0, IF_DV_3H, 0x0E204000) - // C7.2.3 ADDHN, ADDHN2 +INST1(addhn, "addhn", 0, IF_DV_3H, 0x0E204000) // addhn Vd,Vn,Vm DV_3H 00001110XX1mmmmm 010000nnnnnddddd 0E20 4000 Vd,Vn,Vm (vector) -INST1(addhn2, "addhn2", 0, 0, IF_DV_3H, 0x4E204000) - // C7.2.3 ADDHN, ADDHN2 +INST1(addhn2, "addhn2", 0, IF_DV_3H, 0x4E204000) // addhn2 Vd,Vn,Vm DV_3H 01001110XX1mmmmm 010000nnnnnddddd 4E20 4000 Vd,Vn,Vm (vector) -INST1(pmull, "pmull", 0, 0, IF_DV_3H, 0x0E20E000) - // C7.2.208 PMULL, PMULL2 +INST1(pmull, "pmull", 0, IF_DV_3H, 0x0E20E000) // pmull Vd,Vn,Vm DV_3H 00001110XX1mmmmm 111000nnnnnddddd 0E20 E000 Vd,Vn,Vm (vector) -INST1(pmull2, "pmull2", 0, 0, IF_DV_3H, 0x4E20E000) - // C7.2.208 PMULL, PMULL2 +INST1(pmull2, "pmull2", 0, IF_DV_3H, 0x4E20E000) // pmull2 Vd,Vn,Vm DV_3H 01001110XX1mmmmm 111000nnnnnddddd 4E20 E000 Vd,Vn,Vm (vector) -INST1(raddhn, "raddhn", 0, 0, IF_DV_3H, 0x2E204000) - // C7.2.209 RADDHN, RADDHN2 +INST1(raddhn, "raddhn", 0, IF_DV_3H, 0x2E204000) // raddhn Vd,Vn,Vm DV_3H 00101110XX1mmmmm 010000nnnnnddddd 2E20 4000 Vd,Vn,Vm (vector) -INST1(raddhn2, "raddhn2",0, 0, IF_DV_3H, 0x6E204000) - // C7.2.209 RADDHN, RADDHN2 +INST1(raddhn2, "raddhn2", 0, IF_DV_3H, 0x6E204000) // raddhn2 Vd,Vn,Vm DV_3H 01101110XX1mmmmm 010000nnnnnddddd 6E20 4000 Vd,Vn,Vm (vector) -INST1(rsubhn, "rsubhn", 0, 0, IF_DV_3H, 0x2E206000) - // C7.2.216 RSUBHN, RSUBHN2 +INST1(rsubhn, "rsubhn", 0, IF_DV_3H, 0x2E206000) // rsubhn Vd,Vn,Vm DV_3H 00101110XX1mmmmm 011000nnnnnddddd 2E20 6000 Vd,Vn,Vm (vector) -INST1(rsubhn2, "rsubhn2",0, 0, IF_DV_3H, 0x6E206000) - // C7.2.216 RSUBHN, RSUBHN2 +INST1(rsubhn2, "rsubhn2", 0, IF_DV_3H, 0x6E206000) // rsubhn2 Vd,Vn,Vm DV_3H 01101110XX1mmmmm 011000nnnnnddddd 6E20 6000 Vd,Vn,Vm (vector) -INST1(sabal, "sabal", 0, 0, IF_DV_3H, 0x0E205000) - // C7.2.218 SABAL, SABAL2 +INST1(sabal, "sabal", 0, IF_DV_3H, 0x0E205000) // sabal Vd,Vn,Vm DV_3H 00001110XX1mmmmm 010100nnnnnddddd 0E20 5000 Vd,Vn,Vm (vector) -INST1(sabal2, "sabal2", 0, 0, IF_DV_3H, 0x4E205000) - // C7.2.218 SABAL, SABAL2 +INST1(sabal2, "sabal2", 0, IF_DV_3H, 0x4E205000) // sabal2 Vd,Vn,Vm DV_3H 01001110XX1mmmmm 010100nnnnnddddd 4E20 5000 Vd,Vn,Vm (vector) -INST1(sabdl, "sabdl", 0, 0, IF_DV_3H, 0x0E207000) - // C7.2.220 SABDL, SABDL2 +INST1(sabdl, "sabdl", 0, IF_DV_3H, 0x0E207000) // sabdl Vd,Vn,Vm DV_3H 00001110XX1mmmmm 011100nnnnnddddd 0E20 7000 Vd,Vn,Vm (vector) -INST1(sabdl2, "sabdl2", 0, 0, IF_DV_3H, 0x4E207000) - // C7.2.220 SABDL, SABDL2 +INST1(sabdl2, "sabdl2", 0, IF_DV_3H, 0x4E207000) // sabdl2 Vd,Vn,Vm DV_3H 01001110XX1mmmmm 011100nnnnnddddd 4E20 7000 Vd,Vn,Vm (vector) -INST1(sadalp, "sadalp", 0, 0, IF_DV_2T, 0x0E206800) - // C7.2.221 SADALP +INST1(sadalp, "sadalp", 0, IF_DV_2T, 0x0E206800) // sadalp Vd,Vn DV_2T 0Q001110XX100000 011010nnnnnddddd 0E20 6800 Vd,Vn (vector) -INST1(saddl, "saddl", 0, 0, IF_DV_3H, 0x0E200000) - // C7.2.222 SADDL, SADDL2 +INST1(saddl, "saddl", 0, IF_DV_3H, 0x0E200000) // saddl Vd,Vn,Vm DV_3H 00001110XX1mmmmm 000000nnnnnddddd 0E20 0000 Vd,Vn,Vm (vector) -INST1(saddl2, "saddl2", 0, 0, IF_DV_3H, 0x4E200000) - // C7.2.222 SADDL, SADDL2 +INST1(saddl2, "saddl2", 0, IF_DV_3H, 0x4E200000) // saddl2 Vd,Vn,Vm DV_3H 01001110XX1mmmmm 000000nnnnnddddd 4E20 0000 Vd,Vn,Vm (vector) -INST1(saddlp, "saddlp", 0, 0, IF_DV_2T, 0x0E202800) - // C7.2.223 SADDLP +INST1(saddlp, "saddlp", 0, IF_DV_2T, 0x0E202800) // saddlp Vd,Vn DV_2T 0Q001110XX100000 001010nnnnnddddd 0E20 2800 Vd,Vn (vector) -INST1(saddw, "saddw", 0, 0, IF_DV_3H, 0x0E201000) - // C7.2.225 SADDW, SADDW2 +INST1(saddw, "saddw", 0, IF_DV_3H, 0x0E201000) // saddw Vd,Vn,Vm DV_3H 00001110XX1mmmmm 000100nnnnnddddd 0E20 1000 Vd,Vn,Vm (vector) -INST1(saddw2, "saddw2", 0, 0, IF_DV_3H, 0x4E201000) - // C7.2.225 SADDW, SADDW2 +INST1(saddw2, "saddw2", 0, IF_DV_3H, 0x4E201000) // saddw2 Vd,Vn,Vm DV_3H 01001110XX1mmmmm 000100nnnnnddddd 4E20 1000 Vd,Vn,Vm (vector) -INST1(shadd, "shadd", 0, 0, IF_DV_3A, 0x0E200400) - // C7.2.246 SHADD +INST1(shadd, "shadd", 0, IF_DV_3A, 0x0E200400) // shadd Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 000001nnnnnddddd 0E20 0400 Vd,Vn,Vm (vector) -INST1(shsub, "shsub", 0, 0, IF_DV_3A, 0x0E202400) - // C7.2.250 SHSUB +INST1(shsub, "shsub", 0, IF_DV_3A, 0x0E202400) // shsub Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 001001nnnnnddddd 0E20 2400 Vd,Vn,Vm (vector) -INST1(srhadd, "srhadd", 0, 0, IF_DV_3A, 0x0E201400) - // C7.2.302 SRHADD +INST1(srhadd, "srhadd", 0, IF_DV_3A, 0x0E201400) // srhadd Vd,Vn,Vm DV_3A 0Q001110XX1mmmmm 000101nnnnnddddd 0E20 1400 Vd,Vn,Vm (vector) -INST1(ssubl, "ssubl", 0, 0, IF_DV_3H, 0x0E202000) - // C7.2.311 SSUBL, SSUBL2 +INST1(ssubl, "ssubl", 0, IF_DV_3H, 0x0E202000) // ssubl Vd,Vn,Vm DV_3H 00001110XX1mmmmm 001000nnnnnddddd 0E20 2000 Vd,Vn,Vm (vector) -INST1(ssubl2, "ssubl2", 0, 0, IF_DV_3H, 0x4E202000) - // C7.2.311 SSUBL, SSUBL2 +INST1(ssubl2, "ssubl2", 0, IF_DV_3H, 0x4E202000) // ssubl2 Vd,Vn,Vm DV_3H 01001110XX1mmmmm 001000nnnnnddddd 4E20 2000 Vd,Vn,Vm (vector) -INST1(ssubw, "ssubw", 0, 0, IF_DV_3H, 0x0E203000) - // C7.2.312 SSUBW, SSUBW2 +INST1(ssubw, "ssubw", 0, IF_DV_3H, 0x0E203000) // ssubw Vd,Vn,Vm DV_3H 00001110XX1mmmmm 001100nnnnnddddd 0E20 3000 Vd,Vn,Vm (vector) -INST1(ssubw2, "ssubw2", 0, 0, IF_DV_3H, 0x4E203000) - // C7.2.312 SSUBW, SSUBW2 +INST1(ssubw2, "ssubw2", 0, IF_DV_3H, 0x4E203000) // ssubw2 Vd,Vn,Vm DV_3H 01001110XX1mmmmm 001100nnnnnddddd 4E20 3000 Vd,Vn,Vm (vector) -INST1(subhn, "subhn", 0, 0, IF_DV_3H, 0x0E206000) - // C7.2.327 SUBHN, SUBHN2 +INST1(subhn, "subhn", 0, IF_DV_3H, 0x0E206000) // subhn Vd,Vn,Vm DV_3H 00001110XX1mmmmm 011000nnnnnddddd 0E20 6000 Vd,Vn,Vm (vector) -INST1(subhn2, "subhn2",0, 0, IF_DV_3H, 0x4E206000) - // C7.2.327 SUBHN, SUBHN2 +INST1(subhn2, "subhn2", 0, IF_DV_3H, 0x4E206000) // subhn2 Vd,Vn,Vm DV_3H 01001110XX1mmmmm 011000nnnnnddddd 4E20 6000 Vd,Vn,Vm (vector) -INST1(uabal, "uabal", 0, 0, IF_DV_3H, 0x2E205000) - // C7.2.335 UABAL, UABAL2 +INST1(uabal, "uabal", 0, IF_DV_3H, 0x2E205000) // uabal Vd,Vn,Vm DV_3H 00101110XX1mmmmm 010100nnnnnddddd 2E20 5000 Vd,Vn,Vm (vector) -INST1(uabal2, "uabal2", 0, 0, IF_DV_3H, 0x6E205000) - // C7.2.335 UABAL, UABAL2 +INST1(uabal2, "uabal2", 0, IF_DV_3H, 0x6E205000) // uabal2 Vd,Vn,Vm DV_3H 01101110XX1mmmmm 010100nnnnnddddd 6E20 5000 Vd,Vn,Vm (vector) -INST1(uabdl, "uabdl", 0, 0, IF_DV_3H, 0x2E207000) - // C7.2.337 UABDL, UABDL2 +INST1(uabdl, "uabdl", 0, IF_DV_3H, 0x2E207000) // uabdl Vd,Vn,Vm DV_3H 00101110XX1mmmmm 011100nnnnnddddd 2E20 7000 Vd,Vn,Vm (vector) -INST1(uabdl2, "uabdl2", 0, 0, IF_DV_3H, 0x6E207000) - // C7.2.337 UABDL, UABDL2 +INST1(uabdl2, "uabdl2", 0, IF_DV_3H, 0x6E207000) // uabdl2 Vd,Vn,Vm DV_3H 01101110XX1mmmmm 011100nnnnnddddd 6E20 7000 Vd,Vn,Vm (vector) -INST1(uadalp, "uadalp", 0, 0, IF_DV_2T, 0x2E206800) - // C7.2.338 UADALP +INST1(uadalp, "uadalp", 0, IF_DV_2T, 0x2E206800) // uadalp Vd,Vn DV_2T 0Q101110XX100000 011010nnnnnddddd 2E20 6800 Vd,Vn (vector) -INST1(uaddl, "uaddl", 0, 0, IF_DV_3H, 0x2E200000) - // C7.2.339 UADDL, UADDL2 +INST1(uaddl, "uaddl", 0, IF_DV_3H, 0x2E200000) // uaddl Vd,Vn,Vm DV_3H 00101110XX1mmmmm 000000nnnnnddddd 2E20 0000 Vd,Vn,Vm (vector) -INST1(uaddl2, "uaddl2", 0, 0, IF_DV_3H, 0x6E200000) - // C7.2.339 UADDL, UADDL2 +INST1(uaddl2, "uaddl2", 0, IF_DV_3H, 0x6E200000) // uaddl2 Vd,Vn,Vm DV_3H 01101110XX1mmmmm 000000nnnnnddddd 6E20 0000 Vd,Vn,Vm (vector) -INST1(uaddlp, "uaddlp", 0, 0, IF_DV_2T, 0x2E202800) - // C7.2.340 UADDLP +INST1(uaddlp, "uaddlp", 0, IF_DV_2T, 0x2E202800) // uaddlp Vd,Vn DV_2T 0Q101110XX100000 001010nnnnnddddd 2E20 2800 Vd,Vn (vector) -INST1(uaddw, "uaddw", 0, 0, IF_DV_3H, 0x2E201000) - // C7.2.342 UADDW, UADDW2 +INST1(uaddw, "uaddw", 0, IF_DV_3H, 0x2E201000) // uaddw Vd,Vn,Vm DV_3H 00101110XX1mmmmm 000100nnnnnddddd 2E20 1000 Vd,Vn,Vm (vector) -INST1(uaddw2, "uaddw2", 0, 0, IF_DV_3H, 0x6E201000) - // C7.2.342 UADDW, UADDW2 +INST1(uaddw2, "uaddw2", 0, IF_DV_3H, 0x6E201000) // uaddw2 Vd,Vn,Vm DV_3H 01101110XX1mmmmm 000100nnnnnddddd 6E20 1000 Vd,Vn,Vm (vector) -INST1(uhadd, "uhadd", 0, 0, IF_DV_3A, 0x2E200400) - // C7.2.349 UHADD +INST1(uhadd, "uhadd", 0, IF_DV_3A, 0x2E200400) // uhadd Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 000001nnnnnddddd 2E20 0400 Vd,Vn,Vm (vector) -INST1(uhsub, "uhsub", 0, 0, IF_DV_3A, 0x2E202400) - // C7.2.350 UHSUB +INST1(uhsub, "uhsub", 0, IF_DV_3A, 0x2E202400) // uhsub Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 001001nnnnnddddd 2E20 2400 Vd,Vn,Vm (vector) -INST1(urhadd, "urhadd", 0, 0, IF_DV_3A, 0x2E201400) - // C7.2.373 URHADD +INST1(urhadd, "urhadd", 0, IF_DV_3A, 0x2E201400) // urhadd Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 000101nnnnnddddd 2E20 1400 Vd,Vn,Vm (vector) -INST1(usubl, "usubl", 0, 0, IF_DV_3H, 0x2E202000) - // C7.2.383 USUBL, USUBL2 +INST1(usubl, "usubl", 0, IF_DV_3H, 0x2E202000) // usubl Vd,Vn,Vm DV_3H 00101110XX1mmmmm 001000nnnnnddddd 2E20 2000 Vd,Vn,Vm (vector) -INST1(usubl2, "usubl2", 0, 0, IF_DV_3H, 0x6E202000) - // C7.2.383 USUBL, USUBL2 +INST1(usubl2, "usubl2", 0, IF_DV_3H, 0x6E202000) // usubl2 Vd,Vn,Vm DV_3H 01101110XX1mmmmm 001000nnnnnddddd 6E20 2000 Vd,Vn,Vm (vector) -INST1(usubw, "usubw", 0, 0, IF_DV_3H, 0x2E203000) - // C7.2.384 USUBW, USUBW2 +INST1(usubw, "usubw", 0, IF_DV_3H, 0x2E203000) // usubw Vd,Vn,Vm DV_3H 00101110XX1mmmmm 001100nnnnnddddd 2E20 3000 Vd,Vn,Vm (vector) -INST1(usubw2, "usubw2", 0, 0, IF_DV_3H, 0x6E203000) - // C7.2.384 USUBW, USUBW2 +INST1(usubw2, "usubw2", 0, IF_DV_3H, 0x6E203000) // usubw2 Vd,Vn,Vm DV_3H 01101110XX1mmmmm 001100nnnnnddddd 6E20 3000 Vd,Vn,Vm (vector) -INST1(shll, "shll", 0, 0, IF_DV_2M, 0x2F00A400) +INST1(shll, "shll", 0, IF_DV_2M, 0x2F00A400) // shll Vd,Vn,imm DV_2M 0Q101110XX100001 001110nnnnnddddd 2E21 3800 Vd,Vn, {8/16/32} -INST1(shll2, "shll2", 0, 0, IF_DV_2M, 0x6F00A400) +INST1(shll2, "shll2", 0, IF_DV_2M, 0x6F00A400) // shll Vd,Vn,imm DV_2M 0Q101110XX100001 001110nnnnnddddd 2E21 3800 Vd,Vn, {8/16/32} -INST1(sshll, "sshll", 0, 0, IF_DV_2O, 0x0F00A400) - // sshll Vd,Vn,imm DV_2O 000011110iiiiiii 101001nnnnnddddd 0F00 A400 Vd,Vn imm (shift - vector) +INST1(sshll, "sshll", 0, IF_DV_2O, 0x0F00A400) + // sshll Vd,Vn,imm DV_2O 000011110iiiiiii 101001nnnnnddddd 0F00 A400 Vd,Vn imm (left shift - vector) + +INST1(sshll2, "sshll2", 0, IF_DV_2O, 0x4F00A400) + // sshll2 Vd,Vn,imm DV_2O 010011110iiiiiii 101001nnnnnddddd 4F00 A400 Vd,Vn imm (left shift - vector) + +INST1(ushll, "ushll", 0, IF_DV_2O, 0x2F00A400) + // ushll Vd,Vn,imm DV_2O 001011110iiiiiii 101001nnnnnddddd 2F00 A400 Vd,Vn imm (left shift - vector) + +INST1(ushll2, "ushll2", 0, IF_DV_2O, 0x6F00A400) + // ushll2 Vd,Vn,imm DV_2O 011011110iiiiiii 101001nnnnnddddd 6F00 A400 Vd,Vn imm (left shift - vector) + +INST1(shrn, "shrn", RSH, IF_DV_2O, 0x0F008400) + // shrn Vd,Vn,imm DV_2O 000011110iiiiiii 100001nnnnnddddd 0F00 8400 Vd,Vn imm (right shift - vector) + +INST1(shrn2, "shrn2", RSH, IF_DV_2O, 0x4F008400) + // shrn2 Vd,Vn,imm DV_2O 010011110iiiiiii 100001nnnnnddddd 4F00 8400 Vd,Vn imm (right shift - vector) + +INST1(rshrn, "rshrn", RSH, IF_DV_2O, 0x0F008C00) + // rshrn Vd,Vn,imm DV_2O 000011110iiiiiii 100011nnnnnddddd 0F00 8C00 Vd,Vn imm (right shift - vector) -INST1(sshll2, "sshll2", 0, 0, IF_DV_2O, 0x4F00A400) - // sshll2 Vd,Vn,imm DV_2O 010011110iiiiiii 101001nnnnnddddd 4F00 A400 Vd,Vn imm (shift - vector) +INST1(rshrn2, "rshrn2", RSH, IF_DV_2O, 0x4F008C00) + // rshrn2 Vd,Vn,imm DV_2O 010011110iiiiiii 100011nnnnnddddd 4F00 8C00 Vd,Vn imm (right shift - vector) -INST1(ushll, "ushll", 0, 0, IF_DV_2O, 0x2F00A400) - // ushll Vd,Vn,imm DV_2O 001011110iiiiiii 101001nnnnnddddd 2F00 A400 Vd,Vn imm (shift - vector) +INST1(sqrshrn2, "sqrshrn2", RSH, IF_DV_2O, 0x0F009C00) + // sqrshrn2 Vd,Vn,imm DV_2O 0Q0011110iiiiiii 100111nnnnnddddd 0F00 9C00 Vd Vn imm (right shift - vector) -INST1(ushll2, "ushll2", 0, 0, IF_DV_2O, 0x6F00A400) - // ushll2 Vd,Vn,imm DV_2O 011011110iiiiiii 101001nnnnnddddd 6F00 A400 Vd,Vn imm (shift - vector) +INST1(sqrshrun2, "sqrshrun2", RSH, IF_DV_2O, 0x2F008C00) + // sqrshrun2 Vd,Vn,imm DV_2O 0Q1011110iiiiiii 100011nnnnnddddd 2F00 8C00 Vd Vn imm (right shift - vector) -INST1(shrn, "shrn", 0, 0, IF_DV_2O, 0x0F008400) - // shrn Vd,Vn,imm DV_2O 000011110iiiiiii 100001nnnnnddddd 0F00 8400 Vd,Vn imm (shift - vector) +INST1(sqshrn2, "sqshrn2", RSH, IF_DV_2O, 0x0F009400) + // sqshrn2 Vd,Vn,imm DV_2O 0Q0011110iiiiiii 100101nnnnnddddd 0F00 9400 Vd Vn imm (right shift - vector) -INST1(shrn2, "shrn2", 0, 0, IF_DV_2O, 0x4F008400) - // shrn2 Vd,Vn,imm DV_2O 010011110iiiiiii 100001nnnnnddddd 4F00 8400 Vd,Vn imm (shift - vector) +INST1(sqshrun2, "sqshrun2", RSH, IF_DV_2O, 0x2F008400) + // sqshrun2 Vd,Vn,imm DV_2O 0Q1011110iiiiiii 100001nnnnnddddd 2F00 8400 Vd Vn imm (right shift - vector) -INST1(rshrn, "rshrn", 0, 0, IF_DV_2O, 0x0F008C00) - // rshrn Vd,Vn,imm DV_2O 000011110iiiiiii 100011nnnnnddddd 0F00 8C00 Vd,Vn imm (shift - vector) +INST1(uqrshrn2, "uqrshrn2", RSH, IF_DV_2O, 0x2F009C00) + // uqrshrn2 Vd,Vn,imm DV_2O 0Q1011110iiiiiii 100111nnnnnddddd 2F00 9C00 Vd Vn imm (right shift - vector) -INST1(rshrn2, "rshrn2", 0, 0, IF_DV_2O, 0x4F008C00) - // rshrn2 Vd,Vn,imm DV_2O 010011110iiiiiii 100011nnnnnddddd 4F00 8C00 Vd,Vn imm (shift - vector) +INST1(uqshrn2, "uqshrn2", RSH, IF_DV_2O, 0x2F009400) + // uqshrn2 Vd,Vn,imm DV_2O 0Q1011110iiiiiii 100101nnnnnddddd 2F00 9400 Vd Vn imm (right shift - vector) -INST1(sxtl, "sxtl", 0, 0, IF_DV_2O, 0x0F00A400) - // sxtl Vd,Vn DV_2O 000011110iiiiiii 101001nnnnnddddd 0F00 A400 Vd,Vn (shift - vector) +INST1(sxtl, "sxtl", 0, IF_DV_2O, 0x0F00A400) + // sxtl Vd,Vn DV_2O 000011110iiiiiii 101001nnnnnddddd 0F00 A400 Vd,Vn (left shift - vector) -INST1(sxtl2, "sxtl2", 0, 0, IF_DV_2O, 0x4F00A400) - // sxtl2 Vd,Vn DV_2O 010011110iiiiiii 101001nnnnnddddd 4F00 A400 Vd,Vn (shift - vector) +INST1(sxtl2, "sxtl2", 0, IF_DV_2O, 0x4F00A400) + // sxtl2 Vd,Vn DV_2O 010011110iiiiiii 101001nnnnnddddd 4F00 A400 Vd,Vn (left shift - vector) -INST1(uxtl, "uxtl", 0, 0, IF_DV_2O, 0x2F00A400) - // uxtl Vd,Vn DV_2O 001011110iiiiiii 101001nnnnnddddd 2F00 A400 Vd,Vn (shift - vector) +INST1(uxtl, "uxtl", 0, IF_DV_2O, 0x2F00A400) + // uxtl Vd,Vn DV_2O 001011110iiiiiii 101001nnnnnddddd 2F00 A400 Vd,Vn (left shift - vector) -INST1(uxtl2, "uxtl2", 0, 0, IF_DV_2O, 0x6F00A400) - // uxtl2 Vd,Vn DV_2O 011011110iiiiiii 101001nnnnnddddd 6F00 A400 Vd,Vn (shift - vector) +INST1(uxtl2, "uxtl2", 0, IF_DV_2O, 0x6F00A400) + // uxtl2 Vd,Vn DV_2O 011011110iiiiiii 101001nnnnnddddd 6F00 A400 Vd,Vn (left shift - vector) -INST1(tbl, "tbl", 0, 0, IF_DV_3C, 0x0E000000) +INST1(tbl, "tbl", 0, IF_DV_3C, 0x0E000000) // tbl Vd,{Vn},Vm DV_3C 0Q001110000mmmmm 000000nnnnnddddd 0E00 0000 Vd,Vn,Vm (vector) -INST1(tbl_2regs, "tbl", 0, 0, IF_DV_3C, 0x0E002000) +INST1(tbl_2regs, "tbl", 0, IF_DV_3C, 0x0E002000) // tbl Vd,{Vn,Vn+1},Vm DV_3C 0Q001110000mmmmm 001000nnnnnddddd 0E00 2000 Vd,Vn,Vm (vector) -INST1(tbl_3regs, "tbl", 0, 0, IF_DV_3C, 0x0E004000) +INST1(tbl_3regs, "tbl", 0, IF_DV_3C, 0x0E004000) // tbl Vd,{Vn,Vn+1,Vn+2},Vm DV_3C 0Q001110000mmmmm 010000nnnnnddddd 0E00 4000 Vd,Vn,Vm (vector) -INST1(tbl_4regs, "tbl", 0, 0, IF_DV_3C, 0x0E006000) +INST1(tbl_4regs, "tbl", 0, IF_DV_3C, 0x0E006000) // tbl Vd,{Vn,Vn+1,Vn+2,Vn+3},Vm DV_3C 0Q001110000mmmmm 011000nnnnnddddd 0E00 6000 Vd,Vn,Vm (vector) -INST1(tbx, "tbx", 0, 0, IF_DV_3C, 0x0E001000) +INST1(tbx, "tbx", 0, IF_DV_3C, 0x0E001000) // tbx Vd,{Vn},Vm DV_3C 0Q001110000mmmmm 000100nnnnnddddd 0E00 1000 Vd,Vn,Vm (vector) -INST1(tbx_2regs, "tbx", 0, 0, IF_DV_3C, 0x0E003000) +INST1(tbx_2regs, "tbx", 0, IF_DV_3C, 0x0E003000) // tbx Vd,{Vn,Vn+1},Vm DV_3C 0Q001110000mmmmm 001100nnnnnddddd 0E00 3000 Vd,Vn,Vm (vector) -INST1(tbx_3regs, "tbx", 0, 0, IF_DV_3C, 0x0E005000) +INST1(tbx_3regs, "tbx", 0, IF_DV_3C, 0x0E005000) // tbx Vd,{Vn,Vn+1,Vn+2},Vm DV_3C 0Q001110000mmmmm 010100nnnnnddddd 0E00 5000 Vd,Vn,Vm (vector) -INST1(tbx_4regs, "tbx", 0, 0, IF_DV_3C, 0x0E007000) +INST1(tbx_4regs, "tbx", 0, IF_DV_3C, 0x0E007000) // tbx Vd,{Vn,Vn+1,Vn+2,Vn+3},Vm DV_3C 0Q001110000mmmmm 011100nnnnnddddd 0E00 7000 Vd,Vn,Vm (vector) // clang-format on From 6e30997a8b22710166942e21b94fd2f219eb5b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Fri, 22 May 2020 00:49:14 +0200 Subject: [PATCH 326/420] Stop emitting weird intermediate folder artifacts/tests/artifacts (#36833) The logic in dir.common.props for relativizing test directories doesn't work well for the generated XUnit wrapper csproj files as these are generated under artifacts\tests. Relativizing this directory against src\coreclr\tests\src ended up with a weird sequence that ended up duplicating the tests/artifacts folder level. I have fixed this by explicitly passing the root directory for relativization for the XUnit wrapper projects. Thanks Tomas Fixes: #1655 --- src/coreclr/tests/dir.common.props | 2 +- src/coreclr/tests/src/runtest.proj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/tests/dir.common.props b/src/coreclr/tests/dir.common.props index 97f640014d0c5..d31d607d7e9f0 100644 --- a/src/coreclr/tests/dir.common.props +++ b/src/coreclr/tests/dir.common.props @@ -12,7 +12,7 @@ $(TargetOS).$(TargetArchitecture).$(Configuration) - $(MSBuildThisFileDirectory)src + $(MSBuildThisFileDirectory)src $([MSBuild]::MakeRelative($(TestSrcDir), $(MSBuildProjectDirectory)))\$(MSBuildProjectName)\ - diff --git a/eng/Subsets.props b/eng/Subsets.props index 3aec271bc0c15..f7c472357e68c 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -13,7 +13,7 @@ ./build.sh corehost installer.managed - This builds the CoreHost and also the Managed installer portion (e.g. Microsoft.DotNet.PlatformAbstractions) + This builds the CoreHost and also the Managed installer portion (e.g. Microsoft.NET.HostModel) projects. A space ' ' or '+' are the delimiters between multiple subsets to build. ./build.sh -test installer.tests @@ -104,7 +104,7 @@ - + diff --git a/eng/Versions.props b/eng/Versions.props index 52dc93a876b92..d6acbf9f473e3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -65,8 +65,7 @@ 5.0.0-preview.4.20202.18 5.0.0-preview.4.20202.18 5.0.0-preview.4.20202.18 - 2.1.0 - 3.0.0 + 3.1.0 5.0.0-preview.4.20202.18 5.0.0-preview.4.20202.18 diff --git a/src/coreclr/src/System.Private.CoreLib/Tools/GenUnicodeProp/GenUnicodeProp.csproj b/src/coreclr/src/System.Private.CoreLib/Tools/GenUnicodeProp/GenUnicodeProp.csproj index a3fde0fd8eab2..73e115381ce75 100644 --- a/src/coreclr/src/System.Private.CoreLib/Tools/GenUnicodeProp/GenUnicodeProp.csproj +++ b/src/coreclr/src/System.Private.CoreLib/Tools/GenUnicodeProp/GenUnicodeProp.csproj @@ -43,7 +43,6 @@ - diff --git a/src/installer/Microsoft.DotNet.CoreSetup.sln b/src/installer/Microsoft.DotNet.CoreSetup.sln index e3b39fe6aff62..9e432a1616caa 100644 --- a/src/installer/Microsoft.DotNet.CoreSetup.sln +++ b/src/installer/Microsoft.DotNet.CoreSetup.sln @@ -9,8 +9,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution NuGet.Config = NuGet.Config EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.PlatformAbstractions", "managed\Microsoft.DotNet.PlatformAbstractions\Microsoft.DotNet.PlatformAbstractions.csproj", "{04D84DC8-A509-43FE-B846-16B770D9E3AA}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostActivation.Tests", "test\HostActivation.Tests\HostActivation.Tests.csproj", "{23F4AB97-D15C-4C51-A641-DF5C5D5EF70F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtils", "test\TestUtils\TestUtils.csproj", "{D6676666-D14D-4DFA-88FB-76E3E823E2E1}" @@ -41,22 +39,6 @@ Global RelWithDebInfo|x64 = RelWithDebInfo|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.Debug|x64.ActiveCfg = Debug|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.Debug|x64.Build.0 = Debug|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.MinSizeRel|Any CPU.ActiveCfg = Release|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.MinSizeRel|Any CPU.Build.0 = Release|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.MinSizeRel|x64.ActiveCfg = Release|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.MinSizeRel|x64.Build.0 = Release|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.Release|Any CPU.Build.0 = Release|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.Release|x64.ActiveCfg = Release|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.Release|x64.Build.0 = Release|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU - {04D84DC8-A509-43FE-B846-16B770D9E3AA}.RelWithDebInfo|x64.Build.0 = Release|Any CPU {23F4AB97-D15C-4C51-A641-DF5C5D5EF70F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {23F4AB97-D15C-4C51-A641-DF5C5D5EF70F}.Debug|Any CPU.Build.0 = Debug|Any CPU {23F4AB97-D15C-4C51-A641-DF5C5D5EF70F}.Debug|x64.ActiveCfg = Debug|Any CPU diff --git a/src/installer/corehost/cli/hostmisc/pal.h b/src/installer/corehost/cli/hostmisc/pal.h index 743687546ad07..1e1f4cf5f5c4f 100644 --- a/src/installer/corehost/cli/hostmisc/pal.h +++ b/src/installer/corehost/cli/hostmisc/pal.h @@ -249,7 +249,6 @@ namespace pal inline void err_flush() { std::fflush(stderr); } inline void out_flush() { std::fflush(stdout); } - // Based upon https://github.com/dotnet/core-setup/blob/master/src/Microsoft.DotNet.PlatformAbstractions/Native/PlatformApis.cs string_t get_current_os_rid_platform(); inline string_t get_current_os_fallback_rid() { diff --git a/src/installer/managed/CommonManaged.props b/src/installer/managed/CommonManaged.props index 5195cc2c4dd56..c96859a92e4a5 100644 --- a/src/installer/managed/CommonManaged.props +++ b/src/installer/managed/CommonManaged.props @@ -16,15 +16,6 @@ true $(NoWarn);CS1591 - - @@ -34,20 +25,6 @@ true - - true - - - - git - git://github.com/dotnet/core-setup - - - - - - - (TValue value, IEqualityComparer comparer) - { - var hashCode = value != null ? comparer.GetHashCode(value) : 0; - Add(hashCode); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static HashCodeCombiner Start() - { - return new HashCodeCombiner(0x1505L); - } - } -} \ No newline at end of file diff --git a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Microsoft.DotNet.PlatformAbstractions.csproj b/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Microsoft.DotNet.PlatformAbstractions.csproj deleted file mode 100644 index 93d5362c72e23..0000000000000 --- a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Microsoft.DotNet.PlatformAbstractions.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - - Abstractions for making code that uses file system and environment testable. - net45;netstandard1.3;netstandard2.0 - netstandard1.3;netstandard2.0 - true - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Native/NativeMethods.Darwin.cs b/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Native/NativeMethods.Darwin.cs deleted file mode 100644 index 0e0b7c0c576d6..0000000000000 --- a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Native/NativeMethods.Darwin.cs +++ /dev/null @@ -1,56 +0,0 @@ -// 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. - -using System; -using System.Runtime.InteropServices; - -namespace Microsoft.DotNet.PlatformAbstractions.Native -{ - internal static partial class NativeMethods - { - public static class Darwin - { - private const int CTL_KERN = 1; - private const int KERN_OSRELEASE = 2; - - public unsafe static string GetKernelRelease() - { - const uint BUFFER_LENGTH = 32; - - var name = stackalloc int[2]; - name[0] = CTL_KERN; - name[1] = KERN_OSRELEASE; - - var buf = stackalloc byte[(int)BUFFER_LENGTH]; - var len = stackalloc uint[1]; - *len = BUFFER_LENGTH; - - try - { - // If the buffer isn't big enough, it seems sysctl still returns 0 and just sets len to the - // necessary buffer size. This appears to be contrary to the man page, but it's easy to detect - // by simply checking len against the buffer length. - if (sysctl(name, 2, buf, len, IntPtr.Zero, 0) == 0 && *len < BUFFER_LENGTH) - { - return Marshal.PtrToStringAnsi((IntPtr)buf, (int)*len); - } - } - catch (Exception ex) - { - throw new PlatformNotSupportedException("Error reading Darwin Kernel Version", ex); - } - throw new PlatformNotSupportedException("Unknown error reading Darwin Kernel Version"); - } - - [DllImport("libc")] - private unsafe static extern int sysctl( - int* name, - uint namelen, - byte* oldp, - uint* oldlenp, - IntPtr newp, - uint newlen); - } - } -} diff --git a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Native/NativeMethods.Unix.cs b/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Native/NativeMethods.Unix.cs deleted file mode 100644 index c1976308260f1..0000000000000 --- a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Native/NativeMethods.Unix.cs +++ /dev/null @@ -1,40 +0,0 @@ -// 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. - -#if NET45 - -using System; -using System.Runtime.InteropServices; - -namespace Microsoft.DotNet.PlatformAbstractions.Native -{ - internal static partial class NativeMethods - { - public static class Unix - { - public unsafe static string GetUname() - { - // Utsname shouldn't be larger than 2K - var buf = stackalloc byte[2048]; - - try - { - if (uname((IntPtr)buf) == 0) - { - return Marshal.PtrToStringAnsi((IntPtr)buf); - } - } - catch (Exception ex) - { - throw new PlatformNotSupportedException("Error reading Unix name", ex); - } - throw new PlatformNotSupportedException("Unknown error reading Unix name"); - } - - [DllImport("libc")] - private static extern int uname(IntPtr utsname); - } - } -} -#endif \ No newline at end of file diff --git a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Native/NativeMethods.Windows.cs b/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Native/NativeMethods.Windows.cs deleted file mode 100644 index 58c31603a0e1f..0000000000000 --- a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Native/NativeMethods.Windows.cs +++ /dev/null @@ -1,44 +0,0 @@ -// 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. - -using System.Runtime.InteropServices; - -namespace Microsoft.DotNet.PlatformAbstractions.Native -{ - internal static partial class NativeMethods - { - public static class Windows - { - [StructLayout(LayoutKind.Sequential)] - internal struct RTL_OSVERSIONINFOEX - { - internal uint dwOSVersionInfoSize; - internal uint dwMajorVersion; - internal uint dwMinorVersion; - internal uint dwBuildNumber; - internal uint dwPlatformId; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] - internal string szCSDVersion; - } - - // This call avoids the shimming Windows does to report old versions - [DllImport("ntdll")] - private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation); - - internal static string RtlGetVersion() - { - RTL_OSVERSIONINFOEX osvi = new RTL_OSVERSIONINFOEX(); - osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi); - if (RtlGetVersion(out osvi) == 0) - { - return $"{osvi.dwMajorVersion}.{osvi.dwMinorVersion}.{osvi.dwBuildNumber}"; - } - else - { - return null; - } - } - } - } -} diff --git a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Native/PlatformApis.cs b/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Native/PlatformApis.cs deleted file mode 100644 index 1a344034304e7..0000000000000 --- a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Native/PlatformApis.cs +++ /dev/null @@ -1,236 +0,0 @@ -// 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. - -using System; -using System.IO; -using System.Runtime.InteropServices; - -namespace Microsoft.DotNet.PlatformAbstractions.Native -{ - internal static class PlatformApis - { - private class DistroInfo - { - public string Id; - public string VersionId; - } - - private static readonly Lazy _platform = new Lazy(DetermineOSPlatform); - private static readonly Lazy _distroInfo = new Lazy(LoadDistroInfo); - - public static string GetOSName() - { - switch (GetOSPlatform()) - { - case Platform.Windows: - return "Windows"; - case Platform.Linux: - return GetDistroId() ?? "Linux"; - case Platform.Darwin: - return "Mac OS X"; - case Platform.FreeBSD: - return "FreeBSD"; - default: - return "Unknown"; - } - } - - public static string GetOSVersion() - { - switch (GetOSPlatform()) - { - case Platform.Windows: - return NativeMethods.Windows.RtlGetVersion() ?? string.Empty; - case Platform.Linux: - return GetDistroVersionId() ?? string.Empty; - case Platform.Darwin: - return GetDarwinVersion() ?? string.Empty; - case Platform.FreeBSD: - return GetFreeBSDVersion() ?? string.Empty; - default: - return string.Empty; - } - } - - private static string GetDarwinVersion() - { - Version version; - var kernelRelease = NativeMethods.Darwin.GetKernelRelease(); - if (!Version.TryParse(kernelRelease, out version) || version.Major < 5) - { - // 10.0 covers all versions prior to Darwin 5 - // Similarly, if the version is not a valid version number, but we have still detected that it is Darwin, we just assume - // it is OS X 10.0 - return "10.0"; - } - else - { - // Mac OS X 10.1 mapped to Darwin 5.x, and the mapping continues that way - // So just subtract 4 from the Darwin version. - // https://en.wikipedia.org/wiki/Darwin_%28operating_system%29 - return $"10.{version.Major - 4}"; - } - } - - private static string GetFreeBSDVersion() - { - // This is same as sysctl kern.version - // FreeBSD 11.0-RELEASE-p1 FreeBSD 11.0-RELEASE-p1 #0 r306420: Thu Sep 29 01:43:23 UTC 2016 root@releng2.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC - // What we want is major release as minor releases should be compatible. - String version = RuntimeInformation.OSDescription; - try - { - // second token up to first dot - return RuntimeInformation.OSDescription.Split()[1].Split('.')[0]; - } - catch - { - } - return string.Empty; - } - - public static Platform GetOSPlatform() - { - return _platform.Value; - } - - private static string GetDistroId() - { - return _distroInfo.Value?.Id; - } - - private static string GetDistroVersionId() - { - return _distroInfo.Value?.VersionId; - } - - private static DistroInfo LoadDistroInfo() - { - DistroInfo result = null; - - // Sample os-release file: - // NAME="Ubuntu" - // VERSION = "14.04.3 LTS, Trusty Tahr" - // ID = ubuntu - // ID_LIKE = debian - // PRETTY_NAME = "Ubuntu 14.04.3 LTS" - // VERSION_ID = "14.04" - // HOME_URL = "http://www.ubuntu.com/" - // SUPPORT_URL = "http://help.ubuntu.com/" - // BUG_REPORT_URL = "http://bugs.launchpad.net/ubuntu/" - // We use ID and VERSION_ID - - if (File.Exists("/etc/os-release")) - { - var lines = File.ReadAllLines("/etc/os-release"); - result = new DistroInfo(); - foreach (var line in lines) - { - if (line.StartsWith("ID=", StringComparison.Ordinal)) - { - result.Id = line.Substring(3).Trim('"', '\''); - } - else if (line.StartsWith("VERSION_ID=", StringComparison.Ordinal)) - { - result.VersionId = line.Substring(11).Trim('"', '\''); - } - } - } - - if (result != null) - { - result = NormalizeDistroInfo(result); - } - - return result; - } - - // For some distros, we don't want to use the full version from VERSION_ID. One example is - // Red Hat Enterprise Linux, which includes a minor version in their VERSION_ID but minor - // versions are backwards compatable. - // - // In this case, we'll normalized RIDs like 'rhel.7.2' and 'rhel.7.3' to a generic - // 'rhel.7'. This brings RHEL in line with other distros like CentOS or Debian which - // don't put minor version numbers in their VERSION_ID fields because all minor versions - // are backwards compatible. - private static DistroInfo NormalizeDistroInfo(DistroInfo distroInfo) - { - // Handle if VersionId is null by just setting the index to -1. - int lastVersionNumberSeparatorIndex = distroInfo.VersionId?.IndexOf('.') ?? -1; - - if (lastVersionNumberSeparatorIndex != -1 && distroInfo.Id == "alpine") - { - // For Alpine, the version reported has three components, so we need to find the second version separator - lastVersionNumberSeparatorIndex = distroInfo.VersionId.IndexOf('.', lastVersionNumberSeparatorIndex + 1); - } - - if (lastVersionNumberSeparatorIndex != -1 && (distroInfo.Id == "rhel" || distroInfo.Id == "alpine")) - { - distroInfo.VersionId = distroInfo.VersionId.Substring(0, lastVersionNumberSeparatorIndex); - } - - return distroInfo; - } - - // I could probably have just done one method signature and put the #if inside the body but the implementations - // are just completely different so I wanted to make that clear by putting the whole thing inside the #if. -#if NET45 - private static Platform DetermineOSPlatform() - { - var platform = (int)Environment.OSVersion.Platform; - var isWindows = (platform != 4) && (platform != 6) && (platform != 128); - - if (isWindows) - { - return Platform.Windows; - } - else - { - try - { - var uname = NativeMethods.Unix.GetUname(); - if (string.Equals(uname, "Darwin", StringComparison.OrdinalIgnoreCase)) - { - return Platform.Darwin; - } - if (string.Equals(uname, "Linux", StringComparison.OrdinalIgnoreCase)) - { - return Platform.Linux; - } - if (string.Equals(uname, "FreeBSD", StringComparison.OrdinalIgnoreCase)) - { - return Platform.FreeBSD; - } - } - catch - { - } - return Platform.Unknown; - } - } -#else - private static Platform DetermineOSPlatform() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return Platform.Windows; - } - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - return Platform.Linux; - } - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - return Platform.Darwin; - } - if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD"))) - { - return Platform.FreeBSD; - } - - return Platform.Unknown; - } -#endif - } -} diff --git a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Platform.cs b/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Platform.cs deleted file mode 100644 index a8d7477ec55c2..0000000000000 --- a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Platform.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright(c) .NET Foundation and contributors.All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.DotNet.PlatformAbstractions -{ - public enum Platform - { - Unknown = 0, - Windows = 1, - Linux = 2, - Darwin = 3, - FreeBSD = 4 - } -} diff --git a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Properties/Properties.cs b/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Properties/Properties.cs deleted file mode 100644 index ffc81f49b41fe..0000000000000 --- a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/Properties/Properties.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -[assembly: AssemblyMetadataAttribute("Serviceable", "True")] diff --git a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/RuntimeEnvironment.cs b/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/RuntimeEnvironment.cs deleted file mode 100644 index ffece180eb960..0000000000000 --- a/src/installer/managed/Microsoft.DotNet.PlatformAbstractions/RuntimeEnvironment.cs +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright(c) .NET Foundation and contributors.All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Runtime.InteropServices; -using Microsoft.DotNet.PlatformAbstractions.Native; - -namespace Microsoft.DotNet.PlatformAbstractions -{ - public static class RuntimeEnvironment - { - private static readonly string OverrideEnvironmentVariableName = "DOTNET_RUNTIME_ID"; - - public static Platform OperatingSystemPlatform { get; } = PlatformApis.GetOSPlatform(); - - public static string OperatingSystemVersion { get; } = PlatformApis.GetOSVersion(); - - public static string OperatingSystem { get; } = PlatformApis.GetOSName(); - - public static string RuntimeArchitecture { get; } = GetArch(); - - private static string GetArch() - { -#if NET45 - return Environment.Is64BitProcess ? "x64" : "x86"; -#else - return RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant(); -#endif - } - - public static string GetRuntimeIdentifier() - { - return - Environment.GetEnvironmentVariable(OverrideEnvironmentVariableName) ?? - (GetRIDOS() + GetRIDVersion() + GetRIDArch()); - } - - private static string GetRIDArch() - { - return $"-{RuntimeArchitecture}"; - } - - private static string GetRIDVersion() - { - // Windows RIDs do not separate OS name and version by "." due to legacy - // Others do, that's why we have the "." prefix on them below - switch (OperatingSystemPlatform) - { - case Platform.Windows: - return GetWindowsProductVersion(); - case Platform.Linux: - if (string.IsNullOrEmpty(OperatingSystemVersion)) - { - return string.Empty; - } - - return $".{OperatingSystemVersion}"; - case Platform.Darwin: - return $".{OperatingSystemVersion}"; - case Platform.FreeBSD: - return $".{OperatingSystemVersion}"; - default: - return string.Empty; // Unknown Platform? Unknown Version! - } - } - - private static string GetWindowsProductVersion() - { - var ver = Version.Parse(OperatingSystemVersion); - if (ver.Major == 6) - { - if (ver.Minor == 1) - { - return "7"; - } - else if (ver.Minor == 2) - { - return "8"; - } - else if (ver.Minor == 3) - { - return "81"; - } - } - else if (ver.Major >= 10) - { - // Return the major version for use in RID computation without applying any cap. - return ver.Major.ToString(); - } - return string.Empty; // Unknown version - } - - private static string GetRIDOS() - { - switch (OperatingSystemPlatform) - { - case Platform.Windows: - return "win"; - case Platform.Linux: - return OperatingSystem.ToLowerInvariant(); - case Platform.Darwin: - return "osx"; - case Platform.FreeBSD: - return "freebsd"; - default: - return "unknown"; - } - } - } -} diff --git a/src/installer/test/HostActivation.Tests/HostActivation.Tests.csproj b/src/installer/test/HostActivation.Tests/HostActivation.Tests.csproj index 892ad3cafb63f..95b8cfd9a9f6e 100644 --- a/src/installer/test/HostActivation.Tests/HostActivation.Tests.csproj +++ b/src/installer/test/HostActivation.Tests/HostActivation.Tests.csproj @@ -17,8 +17,7 @@ - - + diff --git a/src/installer/test/HostActivation.Tests/HostVersionCompatibility.cs b/src/installer/test/HostActivation.Tests/HostVersionCompatibility.cs index 67a4f70b9c9b7..afb0862fecde9 100644 --- a/src/installer/test/HostActivation.Tests/HostVersionCompatibility.cs +++ b/src/installer/test/HostActivation.Tests/HostVersionCompatibility.cs @@ -3,9 +3,9 @@ // See the LICENSE file in the project root for more information. using Microsoft.DotNet.Cli.Build.Framework; -using Microsoft.DotNet.PlatformAbstractions; using System; using System.IO; +using System.Runtime.InteropServices; using Xunit; namespace Microsoft.DotNet.CoreSetup.Test.HostActivation @@ -137,13 +137,11 @@ private void Old_Host_Is_Forward_Compatible_With_Latest_Runtime(TestProjectFixtu private static bool IsRidSupported() { - Platform platform = RuntimeEnvironment.OperatingSystemPlatform; - // Some current Linux RIDs are not supported in 2.0\2.1; just test for Ubuntu 16. return ( - platform == Platform.Windows || - platform == Platform.Darwin || - (platform == Platform.Linux && RuntimeEnvironment.GetRuntimeIdentifier() == "ubuntu.16.04-x64") + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || + RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || + (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.RuntimeIdentifier == "ubuntu.16.04-x64") ); } diff --git a/src/installer/test/TestUtils/TestUtils.csproj b/src/installer/test/TestUtils/TestUtils.csproj index 5419bc266a1fb..35cb3e19e9d77 100644 --- a/src/installer/test/TestUtils/TestUtils.csproj +++ b/src/installer/test/TestUtils/TestUtils.csproj @@ -13,7 +13,6 @@ - diff --git a/src/libraries/Common/tests/TestUtilities.Unicode/TestUtilities.Unicode.csproj b/src/libraries/Common/tests/TestUtilities.Unicode/TestUtilities.Unicode.csproj index a3eaba2cfc48d..5f241043489c3 100644 --- a/src/libraries/Common/tests/TestUtilities.Unicode/TestUtilities.Unicode.csproj +++ b/src/libraries/Common/tests/TestUtilities.Unicode/TestUtilities.Unicode.csproj @@ -47,7 +47,6 @@ - diff --git a/src/mono/netcore/gen-xunit-runner/Program.cs b/src/mono/netcore/gen-xunit-runner/Program.cs index a73bbecdfd528..1bd127cef1f11 100644 --- a/src/mono/netcore/gen-xunit-runner/Program.cs +++ b/src/mono/netcore/gen-xunit-runner/Program.cs @@ -283,7 +283,6 @@ static int Main (string[] args) args = args.Where (s => s != String.Empty).Concat (extra_args).ToArray (); // Despite a lot of effort, couldn't get dotnet to load these assemblies from the sdk dir, so copy them to our binary dir -// File.Copy ($"{sdkdir}/Microsoft.DotNet.PlatformAbstractions.dll", AppContext.BaseDirectory, true); File.Copy ($"{sdkdir}/TestUtilities.dll", AppContext.BaseDirectory, true); File.Copy ($"{sdkdir}/Microsoft.DotNet.XUnitExtensions.dll", AppContext.BaseDirectory, true); From 1c66ad1b71bb84a16b71bb5efcef1fa999c1c8bc Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 21 May 2020 20:50:35 -0700 Subject: [PATCH 332/420] Porting more of the SIMD intrinsics to be implemented as HWIntrinsics (#36579) * Porting Ceiling and Floor to use SimdAsHWIntrinsic * Porting SquareRoot to use SimdAsHWIntrinsic * Porting ConditionalSelect to use SimdAsHWIntrinsic * Porting get_AllBitsSet, get_Count, and get_Zero to use SimdAsHWIntrinsic * Porting op_Explicit to use SimdAsHWIntrinsic * Changing Vector2/3/4 and Vector.Equals to forward to operator == * Removing SIMDIntrinsicAbs * Removing SIMDIntrinsicMax and SIMDIntrinsicMin * Removing SIMDIntrinsicCeil and SIMDIntrinsicFloor * Porting op_Equality and op_Inequality to use SimdAsHWIntrinsic * Removing SIMDIntrinsicSqrt * Removing SIMDIntrinsicSelect * Removing SIMDIntrinsicBitwiseAndNot and SIMDIntrinsicBitwiseXor * Removing SIMDIntrinsicGreaterThanOrEqual and SIMDIntrinsicLessThanOrEqual * Removing SIMDIntrinsicGreaterThan and SIMDIntrinsicLessThan * Removing SIMDIntrinsicInstEquals * Removing SIMDIntrinsicOpEquality and SIMDIntrinsicOpInEquality * Porting this.Equals to use SimdAsHWIntrinsic * Don't handle IEquatable`1.Equals via SimdAsHWIntrinsic * Applying formatting patch * Account for op2 being able to precede op1 in the LIR order * Ensure SimdAsHWIntrinsic with 0 args are properly handled * Fixup the arm64 LowerHWIntrinsicCmpOp implementation to use LowerNodeCC * Fixing an assert in the NotSupported HWIntrinsic tests --- src/coreclr/src/jit/codegen.h | 1 - src/coreclr/src/jit/codegenarm64.cpp | 167 +--- src/coreclr/src/jit/compiler.h | 53 +- src/coreclr/src/jit/gentree.cpp | 13 +- src/coreclr/src/jit/gentree.h | 60 +- src/coreclr/src/jit/hwintrinsic.cpp | 15 +- src/coreclr/src/jit/hwintrinsiclistarm64.h | 6 + src/coreclr/src/jit/hwintrinsiclistxarch.h | 8 +- src/coreclr/src/jit/lower.h | 1 + src/coreclr/src/jit/lowerarmarch.cpp | 135 ++- src/coreclr/src/jit/lowerxarch.cpp | 267 +++++- src/coreclr/src/jit/lsraarm64.cpp | 26 - src/coreclr/src/jit/lsrabuild.cpp | 3 +- src/coreclr/src/jit/lsraxarch.cpp | 79 +- src/coreclr/src/jit/namedintrinsiclist.h | 6 +- src/coreclr/src/jit/simd.cpp | 796 +----------------- src/coreclr/src/jit/simdashwintrinsic.cpp | 215 ++++- .../src/jit/simdashwintrinsiclistarm64.h | 131 ++- .../src/jit/simdashwintrinsiclistxarch.h | 178 ++-- src/coreclr/src/jit/simdcodegenxarch.cpp | 435 +--------- src/coreclr/src/jit/simdintrinsiclist.h | 26 - src/coreclr/src/jit/vartype.h | 32 + .../src/System/Numerics/Vector.cs | 268 +++--- .../src/System/Numerics/Vector.tt | 120 ++- .../src/System/Numerics/Vector2.cs | 4 +- .../src/System/Numerics/Vector2_Intrinsics.cs | 5 +- .../src/System/Numerics/Vector3.cs | 4 +- .../src/System/Numerics/Vector3_Intrinsics.cs | 14 +- .../src/System/Numerics/Vector4.cs | 4 +- .../src/System/Numerics/Vector4_Intrinsics.cs | 10 +- .../src/System/Numerics/Vector_Operations.cs | 8 +- 31 files changed, 1114 insertions(+), 1976 deletions(-) diff --git a/src/coreclr/src/jit/codegen.h b/src/coreclr/src/jit/codegen.h index 4262e561fe780..2d6167fb8916b 100644 --- a/src/coreclr/src/jit/codegen.h +++ b/src/coreclr/src/jit/codegen.h @@ -978,7 +978,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void genSIMDIntrinsicInit(GenTreeSIMD* simdNode); void genSIMDIntrinsicInitN(GenTreeSIMD* simdNode); void genSIMDIntrinsicUnOp(GenTreeSIMD* simdNode); - void genSIMDIntrinsicUnOpWithImm(GenTreeSIMD* simdNode); void genSIMDIntrinsicBinOp(GenTreeSIMD* simdNode); void genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode); void genSIMDIntrinsicDotProduct(GenTreeSIMD* simdNode); diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index 2392eb88a22d1..79fd8fb6b6b4c 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -3821,15 +3821,11 @@ void CodeGen::genSIMDIntrinsic(GenTreeSIMD* simdNode) genSIMDIntrinsicInitN(simdNode); break; - case SIMDIntrinsicSqrt: - case SIMDIntrinsicAbs: case SIMDIntrinsicCast: case SIMDIntrinsicConvertToSingle: case SIMDIntrinsicConvertToInt32: case SIMDIntrinsicConvertToDouble: case SIMDIntrinsicConvertToInt64: - case SIMDIntrinsicCeil: - case SIMDIntrinsicFloor: genSIMDIntrinsicUnOp(simdNode); break; @@ -3847,24 +3843,11 @@ void CodeGen::genSIMDIntrinsic(GenTreeSIMD* simdNode) case SIMDIntrinsicMul: case SIMDIntrinsicDiv: case SIMDIntrinsicBitwiseAnd: - case SIMDIntrinsicBitwiseAndNot: case SIMDIntrinsicBitwiseOr: - case SIMDIntrinsicBitwiseXor: - case SIMDIntrinsicMin: - case SIMDIntrinsicMax: case SIMDIntrinsicEqual: - case SIMDIntrinsicLessThan: - case SIMDIntrinsicGreaterThan: - case SIMDIntrinsicLessThanOrEqual: - case SIMDIntrinsicGreaterThanOrEqual: genSIMDIntrinsicBinOp(simdNode); break; - case SIMDIntrinsicOpEquality: - case SIMDIntrinsicOpInEquality: - genSIMDIntrinsicRelOp(simdNode); - break; - case SIMDIntrinsicDotProduct: genSIMDIntrinsicDotProduct(simdNode); break; @@ -3888,10 +3871,6 @@ void CodeGen::genSIMDIntrinsic(GenTreeSIMD* simdNode) genSIMDIntrinsicUpperRestore(simdNode); break; - case SIMDIntrinsicSelect: - NYI("SIMDIntrinsicSelect lowered during import to (a & sel) | (b & ~sel)"); - break; - default: noway_assert(!"Unimplemented SIMD intrinsic."); unreached(); @@ -3949,24 +3928,15 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type { switch (intrinsicId) { - case SIMDIntrinsicAbs: - result = INS_fabs; - break; case SIMDIntrinsicAdd: result = INS_fadd; break; case SIMDIntrinsicBitwiseAnd: result = INS_and; break; - case SIMDIntrinsicBitwiseAndNot: - result = INS_bic; - break; case SIMDIntrinsicBitwiseOr: result = INS_orr; break; - case SIMDIntrinsicBitwiseXor: - result = INS_eor; - break; case SIMDIntrinsicCast: result = INS_mov; break; @@ -3980,24 +3950,6 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type case SIMDIntrinsicEqual: result = INS_fcmeq; break; - case SIMDIntrinsicGreaterThan: - result = INS_fcmgt; - break; - case SIMDIntrinsicGreaterThanOrEqual: - result = INS_fcmge; - break; - case SIMDIntrinsicLessThan: - result = INS_fcmlt; - break; - case SIMDIntrinsicLessThanOrEqual: - result = INS_fcmle; - break; - case SIMDIntrinsicMax: - result = INS_fmax; - break; - case SIMDIntrinsicMin: - result = INS_fmin; - break; case SIMDIntrinsicMul: result = INS_fmul; break; @@ -4006,12 +3958,6 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type // Return lower bytes instruction here result = INS_fcvtn; break; - case SIMDIntrinsicSelect: - result = INS_bsl; - break; - case SIMDIntrinsicSqrt: - result = INS_fsqrt; - break; case SIMDIntrinsicSub: result = INS_fsub; break; @@ -4021,12 +3967,6 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type case SIMDIntrinsicWidenHi: result = INS_fcvtl2; break; - case SIMDIntrinsicCeil: - result = INS_frintp; - break; - case SIMDIntrinsicFloor: - result = INS_frintm; - break; default: assert(!"Unsupported SIMD intrinsic"); unreached(); @@ -4038,25 +3978,15 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type switch (intrinsicId) { - case SIMDIntrinsicAbs: - assert(!isUnsigned); - result = INS_abs; - break; case SIMDIntrinsicAdd: result = INS_add; break; case SIMDIntrinsicBitwiseAnd: result = INS_and; break; - case SIMDIntrinsicBitwiseAndNot: - result = INS_bic; - break; case SIMDIntrinsicBitwiseOr: result = INS_orr; break; - case SIMDIntrinsicBitwiseXor: - result = INS_eor; - break; case SIMDIntrinsicCast: result = INS_mov; break; @@ -4067,26 +3997,6 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type case SIMDIntrinsicEqual: result = INS_cmeq; break; - case SIMDIntrinsicGreaterThan: - result = isUnsigned ? INS_cmhi : INS_cmgt; - break; - case SIMDIntrinsicGreaterThanOrEqual: - result = isUnsigned ? INS_cmhs : INS_cmge; - break; - case SIMDIntrinsicLessThan: - assert(!isUnsigned); - result = INS_cmlt; - break; - case SIMDIntrinsicLessThanOrEqual: - assert(!isUnsigned); - result = INS_cmle; - break; - case SIMDIntrinsicMax: - result = isUnsigned ? INS_umax : INS_smax; - break; - case SIMDIntrinsicMin: - result = isUnsigned ? INS_umin : INS_smin; - break; case SIMDIntrinsicMul: result = INS_mul; break; @@ -4095,9 +4005,6 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type // Return lower bytes instruction here result = INS_xtn; break; - case SIMDIntrinsicSelect: - result = INS_bsl; - break; case SIMDIntrinsicSub: result = INS_sub; break; @@ -4256,13 +4163,11 @@ void CodeGen::genSIMDIntrinsicInitN(GenTreeSIMD* simdNode) // void CodeGen::genSIMDIntrinsicUnOp(GenTreeSIMD* simdNode) { - assert(simdNode->gtSIMDIntrinsicID == SIMDIntrinsicSqrt || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicCast || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicAbs || + assert(simdNode->gtSIMDIntrinsicID == SIMDIntrinsicCast || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicConvertToSingle || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicConvertToInt32 || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicConvertToDouble || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicConvertToInt64 || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicCeil || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicFloor); + simdNode->gtSIMDIntrinsicID == SIMDIntrinsicConvertToInt64); GenTree* op1 = simdNode->gtGetOp1(); var_types baseType = simdNode->gtSIMDBaseType; @@ -4407,14 +4312,7 @@ void CodeGen::genSIMDIntrinsicBinOp(GenTreeSIMD* simdNode) assert(simdNode->gtSIMDIntrinsicID == SIMDIntrinsicAdd || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicSub || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicMul || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicDiv || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicBitwiseAnd || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicBitwiseAndNot || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicBitwiseOr || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicBitwiseXor || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicMin || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicMax || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicEqual || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicLessThan || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicGreaterThan || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicLessThanOrEqual || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicGreaterThanOrEqual); + simdNode->gtSIMDIntrinsicID == SIMDIntrinsicBitwiseOr || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicEqual); GenTree* op1 = simdNode->gtGetOp1(); GenTree* op2 = simdNode->gtGetOp2(); @@ -4442,65 +4340,6 @@ void CodeGen::genSIMDIntrinsicBinOp(GenTreeSIMD* simdNode) genProduceReg(simdNode); } -//-------------------------------------------------------------------------------- -// genSIMDIntrinsicRelOp: Generate code for a SIMD Intrinsic relational operater -// == and != -// -// Arguments: -// simdNode - The GT_SIMD node -// -// Return Value: -// None. -// -void CodeGen::genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode) -{ - assert(simdNode->gtSIMDIntrinsicID == SIMDIntrinsicOpEquality || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicOpInEquality); - - GenTree* op1 = simdNode->gtGetOp1(); - GenTree* op2 = simdNode->gtGetOp2(); - var_types baseType = simdNode->gtSIMDBaseType; - regNumber targetReg = simdNode->GetRegNum(); - var_types targetType = simdNode->TypeGet(); - - genConsumeOperands(simdNode); - regNumber op1Reg = op1->GetRegNum(); - regNumber op2Reg = op2->GetRegNum(); - regNumber otherReg = op2Reg; - - instruction ins = getOpForSIMDIntrinsic(SIMDIntrinsicEqual, baseType); - emitAttr attr = (simdNode->gtSIMDSize > 8) ? EA_16BYTE : EA_8BYTE; - insOpts opt = genGetSimdInsOpt(attr, baseType); - - // TODO-ARM64-CQ Contain integer constants where possible - - regNumber tmpFloatReg = simdNode->GetSingleTempReg(RBM_ALLFLOAT); - - GetEmitter()->emitIns_R_R_R(ins, attr, tmpFloatReg, op1Reg, op2Reg, opt); - - if ((simdNode->gtFlags & GTF_SIMD12_OP) != 0) - { - // For 12Byte vectors we must set upper bits to get correct comparison - // We do not assume upper bits are zero. - instGen_Set_Reg_To_Imm(EA_4BYTE, targetReg, -1); - GetEmitter()->emitIns_R_R_I(INS_ins, EA_4BYTE, tmpFloatReg, targetReg, 3); - } - - GetEmitter()->emitIns_R_R(INS_uminv, attr, tmpFloatReg, tmpFloatReg, - (simdNode->gtSIMDSize > 8) ? INS_OPTS_16B : INS_OPTS_8B); - - GetEmitter()->emitIns_R_R_I(INS_mov, EA_1BYTE, targetReg, tmpFloatReg, 0); - - if (simdNode->gtSIMDIntrinsicID == SIMDIntrinsicOpInEquality) - { - GetEmitter()->emitIns_R_R_I(INS_eor, EA_4BYTE, targetReg, targetReg, 0x1); - } - - GetEmitter()->emitIns_R_R_I(INS_and, EA_4BYTE, targetReg, targetReg, 0x1); - - genProduceReg(simdNode); -} - //-------------------------------------------------------------------------------- // genSIMDIntrinsicDotProduct: Generate code for SIMD Intrinsic Dot Product. // diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 5a2dfcfbfb598..1fd8d8d547568 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -2621,6 +2621,16 @@ class Compiler var_types baseType, unsigned size); + GenTreeHWIntrinsic* gtNewSimdAsHWIntrinsicNode(var_types type, + NamedIntrinsic hwIntrinsicID, + var_types baseType, + unsigned size) + { + GenTreeHWIntrinsic* node = gtNewSimdHWIntrinsicNode(type, hwIntrinsicID, baseType, size); + node->gtFlags |= GTF_SIMDASHW_OP; + return node; + } + GenTreeHWIntrinsic* gtNewSimdAsHWIntrinsicNode( var_types type, GenTree* op1, NamedIntrinsic hwIntrinsicID, var_types baseType, unsigned size) { @@ -7970,9 +7980,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX static bool isRelOpSIMDIntrinsic(SIMDIntrinsicID intrinsicId) { - return (intrinsicId == SIMDIntrinsicEqual || intrinsicId == SIMDIntrinsicLessThan || - intrinsicId == SIMDIntrinsicLessThanOrEqual || intrinsicId == SIMDIntrinsicGreaterThan || - intrinsicId == SIMDIntrinsicGreaterThanOrEqual); + return (intrinsicId == SIMDIntrinsicEqual); } // Returns base type of a TYP_SIMD local. @@ -8076,22 +8084,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // Create a GT_SIMD tree for a Get property of SIMD vector with a fixed index. GenTreeSIMD* impSIMDGetFixed(var_types simdType, var_types baseType, unsigned simdSize, int index); - // Creates a GT_SIMD tree for Select operation - GenTree* impSIMDSelect(CORINFO_CLASS_HANDLE typeHnd, - var_types baseType, - unsigned simdVectorSize, - GenTree* op1, - GenTree* op2, - GenTree* op3); - - // Creates a GT_SIMD tree for Min/Max operation - GenTree* impSIMDMinMax(SIMDIntrinsicID intrinsicId, - CORINFO_CLASS_HANDLE typeHnd, - var_types baseType, - unsigned simdVectorSize, - GenTree* op1, - GenTree* op2); - // Transforms operands and returns the SIMD intrinsic to be applied on // transformed operands to obtain given relop result. SIMDIntrinsicID impSIMDRelOp(SIMDIntrinsicID relOpIntrinsicId, @@ -8101,9 +8093,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX GenTree** op1, GenTree** op2); - // Creates a GT_SIMD tree for Abs intrinsic. - GenTree* impSIMDAbs(CORINFO_CLASS_HANDLE typeHnd, var_types baseType, unsigned simdVectorSize, GenTree* op1); - #if defined(TARGET_XARCH) // Transforms operands and returns the SIMD intrinsic to be applied on @@ -8113,26 +8102,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX GenTree** op1, GenTree** op2); - // Transforms operands and returns the SIMD intrinsic to be applied on - // transformed operands to obtain > comparison result. - SIMDIntrinsicID impSIMDLongRelOpGreaterThan(CORINFO_CLASS_HANDLE typeHnd, - unsigned simdVectorSize, - GenTree** op1, - GenTree** op2); - - // Transforms operands and returns the SIMD intrinsic to be applied on - // transformed operands to obtain >= comparison result. - SIMDIntrinsicID impSIMDLongRelOpGreaterThanOrEqual(CORINFO_CLASS_HANDLE typeHnd, - unsigned simdVectorSize, - GenTree** op1, - GenTree** op2); - - // Transforms operands and returns the SIMD intrinsic to be applied on - // transformed operands to obtain >= comparison result in case of int32 - // and small int base type vectors. - SIMDIntrinsicID impSIMDIntegralRelOpGreaterThanOrEqual( - CORINFO_CLASS_HANDLE typeHnd, unsigned simdVectorSize, var_types baseType, GenTree** op1, GenTree** op2); - #endif // defined(TARGET_XARCH) void setLclRelatedToSIMDIntrinsic(GenTree* tree); diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index ece2e7c753fe3..191c87322b4ec 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -16520,13 +16520,7 @@ bool GenTree::isContained() const { // We have to cast away const-ness since AsOp() method is non-const. const GenTree* childNode = AsOp()->gtGetOp1(); - assert((isMarkedContained == false) || childNode->IsSIMDEqualityOrInequality()); - } - - // these either produce a result in register or set flags reg. - else if (IsSIMDEqualityOrInequality()) - { - assert(!isMarkedContained); + assert(isMarkedContained == false); } // if it's contained it can't be unused. @@ -18451,13 +18445,8 @@ bool GenTree::isCommutativeSIMDIntrinsic() case SIMDIntrinsicAdd: case SIMDIntrinsicBitwiseAnd: case SIMDIntrinsicBitwiseOr: - case SIMDIntrinsicBitwiseXor: case SIMDIntrinsicEqual: - case SIMDIntrinsicMax: - case SIMDIntrinsicMin: case SIMDIntrinsicMul: - case SIMDIntrinsicOpEquality: - case SIMDIntrinsicOpInEquality: return true; default: return false; diff --git a/src/coreclr/src/jit/gentree.h b/src/coreclr/src/jit/gentree.h index 62abda039dbe6..c43227bd66311 100644 --- a/src/coreclr/src/jit/gentree.h +++ b/src/coreclr/src/jit/gentree.h @@ -1650,8 +1650,6 @@ struct GenTree inline bool IsBoxedValue(); - inline bool IsSIMDEqualityOrInequality() const; - static bool OperIsList(genTreeOps gtOper) { return gtOper == GT_LIST; @@ -6799,7 +6797,50 @@ inline bool GenTree::IsIntegralConstVector(ssize_t constVal) assert(gtGetOp2IfPresent() == nullptr); return true; } -#endif +#endif // FEATURE_SIMD + +#ifdef FEATURE_HW_INTRINSICS + if (gtOper == GT_HWINTRINSIC) + { + GenTreeHWIntrinsic* node = AsHWIntrinsic(); + + if (!varTypeIsIntegral(node->gtSIMDBaseType)) + { + // Can't be an integral constant + return false; + } + + GenTree* op1 = gtGetOp1(); + GenTree* op2 = gtGetOp2(); + + NamedIntrinsic intrinsicId = node->gtHWIntrinsicId; + + if (op1 == nullptr) + { + assert(op2 == nullptr); + + if (constVal == 0) + { +#if defined(TARGET_XARCH) + return (intrinsicId == NI_Vector128_get_Zero) || (intrinsicId == NI_Vector256_get_Zero); +#elif defined(TARGET_ARM64) + return (intrinsicId == NI_Vector64_get_Zero) || (intrinsicId == NI_Vector128_get_Zero); +#endif // !TARGET_XARCH && !TARGET_ARM64 + } + } + else if ((op2 == nullptr) && !op1->OperIsList()) + { + if (op1->IsIntegralConst(constVal)) + { +#if defined(TARGET_XARCH) + return (intrinsicId == NI_Vector128_Create) || (intrinsicId == NI_Vector256_Create); +#elif defined(TARGET_ARM64) + return (intrinsicId == NI_Vector64_Create) || (intrinsicId == NI_Vector128_Create); +#endif // !TARGET_XARCH && !TARGET_ARM64 + } + } + } +#endif // FEATURE_HW_INTRINSICS return false; } @@ -6829,19 +6870,6 @@ inline bool GenTree::IsBoxedValue() return (gtOper == GT_BOX) && (gtFlags & GTF_BOX_VALUE); } -inline bool GenTree::IsSIMDEqualityOrInequality() const -{ -#ifdef FEATURE_SIMD - if (gtOper == GT_SIMD) - { - SIMDIntrinsicID id = AsSIMD()->gtSIMDIntrinsicID; - return (id == SIMDIntrinsicOpEquality) || (id == SIMDIntrinsicOpInEquality); - } -#endif - - return false; -} - inline GenTree* GenTree::MoveNext() { assert(OperIsAnyList()); diff --git a/src/coreclr/src/jit/hwintrinsic.cpp b/src/coreclr/src/jit/hwintrinsic.cpp index 15c623ceca151..cd197c7f27844 100644 --- a/src/coreclr/src/jit/hwintrinsic.cpp +++ b/src/coreclr/src/jit/hwintrinsic.cpp @@ -482,11 +482,14 @@ bool HWIntrinsicInfo::isImmOp(NamedIntrinsic id, const GenTree* op) GenTree* Compiler::getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass, bool expectAddr) { GenTree* arg = nullptr; - if (argType == TYP_STRUCT) + if (varTypeIsStruct(argType)) { - unsigned int argSizeBytes; - var_types base = getBaseTypeAndSizeOfSIMDType(argClass, &argSizeBytes); - argType = getSIMDTypeForSize(argSizeBytes); + if (!varTypeIsSIMD(argType)) + { + unsigned int argSizeBytes; + var_types base = getBaseTypeAndSizeOfSIMDType(argClass, &argSizeBytes); + argType = getSIMDTypeForSize(argSizeBytes); + } assert(varTypeIsSIMD(argType)); arg = impSIMDPopStack(argType, expectAddr); assert(varTypeIsSIMD(arg->TypeGet())); @@ -605,9 +608,9 @@ static bool isSupportedBaseType(NamedIntrinsic intrinsic, var_types baseType) #ifdef TARGET_XARCH assert((intrinsic >= NI_Vector128_As && intrinsic <= NI_Vector128_AsUInt64) || - (intrinsic >= NI_Vector128_get_AllBitsSet && intrinsic <= NI_Vector128_ToVector256Unsafe) || + (intrinsic >= NI_Vector128_get_AllBitsSet && intrinsic <= NI_Vector128_WithElement) || (intrinsic >= NI_Vector256_As && intrinsic <= NI_Vector256_AsUInt64) || - (intrinsic >= NI_Vector256_get_AllBitsSet && intrinsic <= NI_Vector256_ToScalar)); + (intrinsic >= NI_Vector256_get_AllBitsSet && intrinsic <= NI_Vector256_WithElement)); #else assert((intrinsic >= NI_Vector64_AsByte && intrinsic <= NI_Vector64_AsUInt32) || (intrinsic >= NI_Vector64_get_AllBitsSet && intrinsic <= NI_Vector64_ToVector128Unsafe) || diff --git a/src/coreclr/src/jit/hwintrinsiclistarm64.h b/src/coreclr/src/jit/hwintrinsiclistarm64.h index 5407ba7670ef9..5084324f84924 100644 --- a/src/coreclr/src/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/src/jit/hwintrinsiclistarm64.h @@ -29,6 +29,8 @@ HARDWARE_INTRINSIC(Vector64, get_AllBitsSet, HARDWARE_INTRINSIC(Vector64, get_Count, 8, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector64, get_Zero, 8, 0, {INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector64, GetElement, 8, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_NoJmpTableIMM|HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector64, op_Equality, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector64, op_Inequality, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector64, ToScalar, 8, 1, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector64, ToVector128, 8, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector64, ToVector128Unsafe, 8, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) @@ -56,6 +58,8 @@ HARDWARE_INTRINSIC(Vector128, get_Count, 1 HARDWARE_INTRINSIC(Vector128, get_Zero, 16, 0, {INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector128, GetElement, 16, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_NoJmpTableIMM|HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector128, GetLower, 16, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector128, op_Equality, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector128, op_Inequality, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, ToScalar, 16, 1, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** @@ -93,6 +97,7 @@ HARDWARE_INTRINSIC(AdvSimd, AddWideningUpper, 1 HARDWARE_INTRINSIC(AdvSimd, And, -1, 2, {INS_and, INS_and, INS_and, INS_and, INS_and, INS_and, INS_and, INS_and, INS_and, INS_and}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AdvSimd, BitwiseClear, -1, 2, {INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, BitwiseSelect, -1, 3, {INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, Ceiling, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frintp, INS_frintp}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, CompareEqual, -1, 2, {INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_invalid, INS_invalid, INS_fcmeq, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AdvSimd, CompareGreaterThan, -1, 2, {INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_invalid, INS_invalid, INS_fcmgt, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, CompareGreaterThanOrEqual, -1, 2, {INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_invalid, INS_invalid, INS_fcmge, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) @@ -109,6 +114,7 @@ HARDWARE_INTRINSIC(AdvSimd, ExtractAndNarrowHigh, 1 HARDWARE_INTRINSIC(AdvSimd, ExtractAndNarrowLow, 8, 1, {INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, ExtractVector64, 8, 3, {INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_invalid, INS_invalid, INS_ext, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AdvSimd, ExtractVector128, 16, 3, {INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, Floor, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frintm, INS_frintm}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, FusedAddHalving, -1, 2, {INS_shadd, INS_uhadd, INS_shadd, INS_uhadd, INS_shadd, INS_uhadd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AdvSimd, FusedAddRoundedHalving, -1, 2, {INS_srhadd, INS_urhadd, INS_srhadd, INS_urhadd, INS_srhadd, INS_urhadd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AdvSimd, FusedMultiplyAdd, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmla, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) diff --git a/src/coreclr/src/jit/hwintrinsiclistxarch.h b/src/coreclr/src/jit/hwintrinsiclistxarch.h index c041364c966bf..c6017fb12c44c 100644 --- a/src/coreclr/src/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/src/jit/hwintrinsiclistxarch.h @@ -50,10 +50,12 @@ HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, HARDWARE_INTRINSIC(Vector128, get_Count, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector128, get_Zero, 16, 0, {INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector128, GetElement, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, WithElement, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, op_Equality, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector128, op_Inequality, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, ToScalar, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movss, INS_movsdsse2}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector128, ToVector256, 16, 1, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movups, INS_movupd}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector128, ToVector256Unsafe, 16, 1, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movups, INS_movupd}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(Vector128, WithElement, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags @@ -80,9 +82,11 @@ HARDWARE_INTRINSIC(Vector256, get_Zero, HARDWARE_INTRINSIC(Vector256, Create, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector256, CreateScalarUnsafe, 32, 1, {INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_mov_i2xmm, INS_movss, INS_movsdsse2}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(Vector256, GetElement, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector256, WithElement, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector256, GetLower, 32, 1, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movups, INS_movupd}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(Vector256, op_Equality, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector256, op_Inequality, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector256, ToScalar, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movss, INS_movsdsse2}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(Vector256, WithElement, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags diff --git a/src/coreclr/src/jit/lower.h b/src/coreclr/src/jit/lower.h index f45e9973fa18d..91d5561d52fc8 100644 --- a/src/coreclr/src/jit/lower.h +++ b/src/coreclr/src/jit/lower.h @@ -318,6 +318,7 @@ class Lowering final : public Phase #ifdef FEATURE_HW_INTRINSICS void LowerHWIntrinsic(GenTreeHWIntrinsic* node); void LowerHWIntrinsicCC(GenTreeHWIntrinsic* node, NamedIntrinsic newIntrinsicId, GenCondition condition); + void LowerHWIntrinsicCmpOp(GenTreeHWIntrinsic* node, genTreeOps cmpOp); void LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node); void LowerFusedMultiplyAdd(GenTreeHWIntrinsic* node); diff --git a/src/coreclr/src/jit/lowerarmarch.cpp b/src/coreclr/src/jit/lowerarmarch.cpp index a6050c9baa48b..c47cb7ee4e9ff 100644 --- a/src/coreclr/src/jit/lowerarmarch.cpp +++ b/src/coreclr/src/jit/lowerarmarch.cpp @@ -553,6 +553,20 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) return; } + case NI_Vector64_op_Equality: + case NI_Vector128_op_Equality: + { + LowerHWIntrinsicCmpOp(node, GT_EQ); + return; + } + + case NI_Vector64_op_Inequality: + case NI_Vector128_op_Inequality: + { + LowerHWIntrinsicCmpOp(node, GT_NE); + return; + } + default: break; } @@ -625,6 +639,122 @@ bool Lowering::IsValidConstForMovImm(GenTreeHWIntrinsic* node) return false; } +//---------------------------------------------------------------------------------------------- +// Lowering::LowerHWIntrinsicCmpOp: Lowers a Vector128 or Vector256 comparison intrinsic +// +// Arguments: +// node - The hardware intrinsic node. +// cmpOp - The comparison operation, currently must be GT_EQ or GT_NE +// +void Lowering::LowerHWIntrinsicCmpOp(GenTreeHWIntrinsic* node, genTreeOps cmpOp) +{ + NamedIntrinsic intrinsicId = node->gtHWIntrinsicId; + var_types baseType = node->gtSIMDBaseType; + unsigned simdSize = node->gtSIMDSize; + var_types simdType = Compiler::getSIMDTypeForSize(simdSize); + + assert((intrinsicId == NI_Vector64_op_Equality) || (intrinsicId == NI_Vector64_op_Inequality) || + (intrinsicId == NI_Vector128_op_Equality) || (intrinsicId == NI_Vector128_op_Inequality)); + + assert(varTypeIsSIMD(simdType)); + assert(varTypeIsArithmetic(baseType)); + assert(simdSize != 0); + assert(node->gtType == TYP_BOOL); + assert((cmpOp == GT_EQ) || (cmpOp == GT_NE)); + + // We have the following (with the appropriate simd size and where the intrinsic could be op_Inequality): + // /--* op2 simd + // /--* op1 simd + // node = * HWINTRINSIC simd T op_Equality + + GenTree* op1 = node->gtGetOp1(); + GenTree* op2 = node->gtGetOp2(); + + NamedIntrinsic cmpIntrinsic; + + switch (baseType) + { + case TYP_BYTE: + case TYP_UBYTE: + case TYP_SHORT: + case TYP_USHORT: + case TYP_INT: + case TYP_UINT: + case TYP_FLOAT: + { + cmpIntrinsic = NI_AdvSimd_CompareEqual; + break; + } + + case TYP_LONG: + case TYP_ULONG: + case TYP_DOUBLE: + { + cmpIntrinsic = NI_AdvSimd_Arm64_CompareEqual; + break; + } + + default: + { + unreached(); + } + } + + GenTree* cmp = comp->gtNewSimdHWIntrinsicNode(simdType, op1, op2, cmpIntrinsic, baseType, simdSize); + BlockRange().InsertBefore(node, cmp); + LowerNode(cmp); + + if ((baseType == TYP_FLOAT) && (simdSize == 12)) + { + // For TYP_SIMD12 we need to clear the upper bits and can't assume their value + + GenTree* idxCns = comp->gtNewIconNode(3, TYP_INT); + BlockRange().InsertAfter(cmp, idxCns); + + GenTree* insCns = comp->gtNewIconNode(cmpOp == GT_EQ ? -1 : 0, TYP_INT); + BlockRange().InsertAfter(idxCns, insCns); + + GenTree* tmp = + comp->gtNewSimdAsHWIntrinsicNode(simdType, cmp, idxCns, insCns, NI_AdvSimd_Insert, TYP_INT, simdSize); + BlockRange().InsertAfter(insCns, tmp); + LowerNode(tmp); + + cmp = tmp; + } + + GenTree* msk = comp->gtNewSimdHWIntrinsicNode(simdType, cmp, NI_AdvSimd_Arm64_MinAcross, TYP_UBYTE, simdSize); + BlockRange().InsertAfter(cmp, msk); + LowerNode(msk); + + GenTree* zroCns = comp->gtNewIconNode(0, TYP_INT); + BlockRange().InsertAfter(msk, zroCns); + + GenTree* val = comp->gtNewSimdAsHWIntrinsicNode(TYP_UBYTE, msk, zroCns, NI_AdvSimd_Extract, TYP_UBYTE, simdSize); + BlockRange().InsertAfter(zroCns, val); + LowerNode(val); + + zroCns = comp->gtNewIconNode(0, TYP_INT); + BlockRange().InsertAfter(val, zroCns); + + node->ChangeOper(cmpOp); + + node->gtType = TYP_INT; + node->gtOp1 = val; + node->gtOp2 = zroCns; + + // The CompareEqual will set (condition is true) or clear (condition is false) all bits of the respective element + // The MinAcross then ensures we get either all bits set (all conditions are true) or clear (any condition is false) + // So, we need to invert the condition from the operation since we compare against zero + + GenCondition cmpCnd = (cmpOp == GT_EQ) ? GenCondition::NE : GenCondition::EQ; + GenTree* cc = LowerNodeCC(node, cmpCnd); + + node->gtType = TYP_VOID; + node->ClearUnusedValue(); + + LowerNode(node); +} + //---------------------------------------------------------------------------------------------- // Lowering::LowerHWIntrinsicCreate: Lowers a Vector64 or Vector128 Create call // @@ -1191,11 +1321,6 @@ void Lowering::ContainCheckSIMD(GenTreeSIMD* simdNode) CheckImmedAndMakeContained(simdNode, simdNode->gtGetOp2()); break; - case SIMDIntrinsicOpEquality: - case SIMDIntrinsicOpInEquality: - // TODO-ARM64-CQ Support containing 0 - break; - case SIMDIntrinsicGetItem: { // This implements get_Item method. The sources are: diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index 3cb0c50afba5f..db5617b4f1430 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -743,14 +743,6 @@ void Lowering::LowerSIMD(GenTreeSIMD* simdNode) // the addr of SIMD vector with the given index. simdNode->gtOp1->gtFlags |= GTF_IND_REQ_ADDR_IN_REG; } - else if (simdNode->IsSIMDEqualityOrInequality()) - { - LowerNodeCC(simdNode, - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicOpEquality ? GenCondition::EQ : GenCondition::NE); - - simdNode->gtType = TYP_VOID; - simdNode->ClearUnusedValue(); - } #endif ContainCheckSIMD(simdNode); } @@ -947,6 +939,20 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) return; } + case NI_Vector128_op_Equality: + case NI_Vector256_op_Equality: + { + LowerHWIntrinsicCmpOp(node, GT_EQ); + return; + } + + case NI_Vector128_op_Inequality: + case NI_Vector256_op_Inequality: + { + LowerHWIntrinsicCmpOp(node, GT_NE); + return; + } + case NI_SSE2_Insert: case NI_SSE41_Insert: case NI_SSE41_X64_Insert: @@ -1155,6 +1161,238 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) ContainCheckHWIntrinsic(node); } +//---------------------------------------------------------------------------------------------- +// Lowering::LowerHWIntrinsicCmpOp: Lowers a Vector128 or Vector256 comparison intrinsic +// +// Arguments: +// node - The hardware intrinsic node. +// cmpOp - The comparison operation, currently must be GT_EQ or GT_NE +// +void Lowering::LowerHWIntrinsicCmpOp(GenTreeHWIntrinsic* node, genTreeOps cmpOp) +{ + NamedIntrinsic intrinsicId = node->gtHWIntrinsicId; + var_types baseType = node->gtSIMDBaseType; + unsigned simdSize = node->gtSIMDSize; + var_types simdType = Compiler::getSIMDTypeForSize(simdSize); + + assert((intrinsicId == NI_Vector128_op_Equality) || (intrinsicId == NI_Vector128_op_Inequality) || + (intrinsicId == NI_Vector256_op_Equality) || (intrinsicId == NI_Vector256_op_Inequality)); + + assert(varTypeIsSIMD(simdType)); + assert(varTypeIsArithmetic(baseType)); + assert(simdSize != 0); + assert(node->gtType == TYP_BOOL); + assert((cmpOp == GT_EQ) || (cmpOp == GT_NE)); + + // We have the following (with the appropriate simd size and where the intrinsic could be op_Inequality): + // /--* op2 simd + // /--* op1 simd + // node = * HWINTRINSIC simd T op_Equality + + GenTree* op1 = node->gtGetOp1(); + GenTree* op2 = node->gtGetOp2(); + + GenCondition cmpCnd = (cmpOp == GT_EQ) ? GenCondition::EQ : GenCondition::NE; + + if (op2->IsIntegralConstVector(0) && comp->compOpportunisticallyDependsOn(InstructionSet_SSE41)) + { + // On SSE4.1 or higher we can optimize comparisons against zero to + // just use PTEST. We can't support it for floating-point, however, + // as it has both +0.0 and -0.0 where +0.0 == -0.0 + + node->gtOp1 = op1; + BlockRange().Remove(op2); + + LIR::Use op1Use(BlockRange(), &node->gtOp1, node); + ReplaceWithLclVar(op1Use); + op1 = node->gtOp1; + + op2 = comp->gtClone(op1); + BlockRange().InsertAfter(op1, op2); + node->gtOp2 = op2; + + if (simdSize == 32) + { + node->gtHWIntrinsicId = NI_AVX_TestZ; + LowerHWIntrinsicCC(node, NI_AVX_PTEST, cmpCnd); + } + else + { + node->gtHWIntrinsicId = NI_SSE41_TestZ; + LowerHWIntrinsicCC(node, NI_SSE41_PTEST, cmpCnd); + } + + return; + } + + NamedIntrinsic cmpIntrinsic; + var_types cmpType; + NamedIntrinsic mskIntrinsic; + var_types mskType; + int mskConstant; + + switch (baseType) + { + case TYP_BYTE: + case TYP_UBYTE: + case TYP_SHORT: + case TYP_USHORT: + case TYP_INT: + case TYP_UINT: + { + cmpType = baseType; + mskType = TYP_UBYTE; + + if (simdSize == 32) + { + cmpIntrinsic = NI_AVX2_CompareEqual; + mskIntrinsic = NI_AVX2_MoveMask; + mskConstant = -1; + } + else + { + assert(simdSize == 16); + + cmpIntrinsic = NI_SSE2_CompareEqual; + mskIntrinsic = NI_SSE2_MoveMask; + mskConstant = 0xFFFF; + } + break; + } + + case TYP_LONG: + case TYP_ULONG: + { + mskType = TYP_UBYTE; + + if (simdSize == 32) + { + cmpIntrinsic = NI_AVX2_CompareEqual; + cmpType = baseType; + mskIntrinsic = NI_AVX2_MoveMask; + mskConstant = -1; + } + else + { + assert(simdSize == 16); + + if (comp->compOpportunisticallyDependsOn(InstructionSet_SSE41)) + { + cmpIntrinsic = NI_SSE41_CompareEqual; + cmpType = baseType; + } + else + { + cmpIntrinsic = NI_SSE2_CompareEqual; + cmpType = TYP_UINT; + } + + mskIntrinsic = NI_SSE2_MoveMask; + mskConstant = 0xFFFF; + } + break; + } + + case TYP_FLOAT: + { + cmpType = baseType; + mskType = baseType; + + if (simdSize == 32) + { + cmpIntrinsic = NI_AVX_CompareEqual; + mskIntrinsic = NI_AVX_MoveMask; + mskConstant = 0xFF; + } + else + { + cmpIntrinsic = NI_SSE_CompareEqual; + mskIntrinsic = NI_SSE_MoveMask; + + if (simdSize == 16) + { + mskConstant = 0xF; + } + else if (simdSize == 12) + { + mskConstant = 0x7; + } + else + { + assert(simdSize == 8); + mskConstant = 0x3; + } + } + break; + } + + case TYP_DOUBLE: + { + cmpType = baseType; + mskType = baseType; + + if (simdSize == 32) + { + cmpIntrinsic = NI_AVX_CompareEqual; + mskIntrinsic = NI_AVX_MoveMask; + mskConstant = 0xF; + } + else + { + assert(simdSize == 16); + + cmpIntrinsic = NI_SSE2_CompareEqual; + mskIntrinsic = NI_SSE2_MoveMask; + mskConstant = 0x3; + } + break; + } + + default: + { + unreached(); + } + } + + GenTree* cmp = comp->gtNewSimdHWIntrinsicNode(simdType, op1, op2, cmpIntrinsic, cmpType, simdSize); + BlockRange().InsertBefore(node, cmp); + LowerNode(cmp); + + GenTree* msk = comp->gtNewSimdHWIntrinsicNode(TYP_INT, cmp, mskIntrinsic, mskType, simdSize); + BlockRange().InsertAfter(cmp, msk); + LowerNode(msk); + + GenTree* mskCns = comp->gtNewIconNode(mskConstant, TYP_INT); + BlockRange().InsertAfter(msk, mskCns); + + if ((baseType == TYP_FLOAT) && (simdSize < 16)) + { + // For TYP_SIMD8 and TYP_SIMD12 we need to clear the upper bits and can't assume their value + + GenTree* tmp = comp->gtNewOperNode(GT_AND, TYP_INT, msk, mskCns); + BlockRange().InsertAfter(mskCns, tmp); + LowerNode(msk); + + msk = tmp; + + mskCns = comp->gtNewIconNode(mskConstant, TYP_INT); + BlockRange().InsertAfter(msk, mskCns); + } + + node->ChangeOper(cmpOp); + + node->gtType = TYP_INT; + node->gtOp1 = msk; + node->gtOp2 = mskCns; + + GenTree* cc = LowerNodeCC(node, cmpCnd); + + node->gtType = TYP_VOID; + node->ClearUnusedValue(); + + LowerNode(node); +} + //---------------------------------------------------------------------------------------------- // Lowering::LowerHWIntrinsicCreate: Lowers a Vector128 or Vector256 Create call // @@ -3701,19 +3939,6 @@ void Lowering::ContainCheckSIMD(GenTreeSIMD* simdNode) CheckImmedAndMakeContained(simdNode, simdNode->gtGetOp2()); break; - case SIMDIntrinsicOpEquality: - case SIMDIntrinsicOpInEquality: - // On SSE4/AVX, we can generate optimal code for (in)equality - // against zero using ptest. We can safely do this optimization - // for integral vectors but not for floating-point for the reason - // that we have +0.0 and -0.0 and +0.0 == -0.0 - op2 = simdNode->gtGetOp2(); - if ((comp->getSIMDSupportLevel() >= SIMD_SSE4_Supported) && op2->IsIntegralConstVector(0)) - { - MakeSrcContained(simdNode, op2); - } - break; - case SIMDIntrinsicGetItem: { // This implements get_Item method. The sources are: diff --git a/src/coreclr/src/jit/lsraarm64.cpp b/src/coreclr/src/jit/lsraarm64.cpp index 60084a8e65f3e..2c93dd860ffbb 100644 --- a/src/coreclr/src/jit/lsraarm64.cpp +++ b/src/coreclr/src/jit/lsraarm64.cpp @@ -812,16 +812,12 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) { case SIMDIntrinsicInit: case SIMDIntrinsicCast: - case SIMDIntrinsicSqrt: - case SIMDIntrinsicAbs: case SIMDIntrinsicConvertToSingle: case SIMDIntrinsicConvertToInt32: case SIMDIntrinsicConvertToDouble: case SIMDIntrinsicConvertToInt64: case SIMDIntrinsicWidenLo: case SIMDIntrinsicWidenHi: - case SIMDIntrinsicCeil: - case SIMDIntrinsicFloor: // No special handling required. break; @@ -868,16 +864,8 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) case SIMDIntrinsicMul: case SIMDIntrinsicDiv: case SIMDIntrinsicBitwiseAnd: - case SIMDIntrinsicBitwiseAndNot: case SIMDIntrinsicBitwiseOr: - case SIMDIntrinsicBitwiseXor: - case SIMDIntrinsicMin: - case SIMDIntrinsicMax: case SIMDIntrinsicEqual: - case SIMDIntrinsicLessThan: - case SIMDIntrinsicGreaterThan: - case SIMDIntrinsicLessThanOrEqual: - case SIMDIntrinsicGreaterThanOrEqual: // No special handling required. break; @@ -926,23 +914,10 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) // We have an array and an index, which may be contained. break; - case SIMDIntrinsicOpEquality: - case SIMDIntrinsicOpInEquality: - buildInternalFloatRegisterDefForNode(simdTree); - break; - case SIMDIntrinsicDotProduct: buildInternalFloatRegisterDefForNode(simdTree); break; - case SIMDIntrinsicSelect: - // TODO-ARM64-CQ Allow lowering to see SIMDIntrinsicSelect so we can generate BSL VC, VA, VB - // bsl target register must be VC. Reserve a temp in case we need to shuffle things. - // This will require a different approach, as GenTreeSIMD has only two operands. - assert(!"SIMDIntrinsicSelect not yet supported"); - buildInternalFloatRegisterDefForNode(simdTree); - break; - case SIMDIntrinsicInitArrayX: case SIMDIntrinsicInitFixed: case SIMDIntrinsicCopyToArray: @@ -956,7 +931,6 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) case SIMDIntrinsicGetY: case SIMDIntrinsicGetZ: case SIMDIntrinsicGetW: - case SIMDIntrinsicInstEquals: case SIMDIntrinsicHWAccel: case SIMDIntrinsicWiden: case SIMDIntrinsicInvalid: diff --git a/src/coreclr/src/jit/lsrabuild.cpp b/src/coreclr/src/jit/lsrabuild.cpp index 44462d7a91ada..c1a5e0b586b40 100644 --- a/src/coreclr/src/jit/lsrabuild.cpp +++ b/src/coreclr/src/jit/lsrabuild.cpp @@ -1507,8 +1507,7 @@ int LinearScan::ComputeOperandDstCount(GenTree* operand) // Stores and void-typed operands may be encountered when processing call nodes, which contain // pointers to argument setup stores. assert(operand->OperIsStore() || operand->OperIsBlkOp() || operand->OperIsPutArgStk() || - operand->OperIsCompare() || operand->OperIs(GT_CMP) || operand->IsSIMDEqualityOrInequality() || - operand->TypeGet() == TYP_VOID); + operand->OperIsCompare() || operand->OperIs(GT_CMP) || operand->TypeGet() == TYP_VOID); return 0; } } diff --git a/src/coreclr/src/jit/lsraxarch.cpp b/src/coreclr/src/jit/lsraxarch.cpp index 1bc0f36bfb26d..1239ca23c7bbe 100644 --- a/src/coreclr/src/jit/lsraxarch.cpp +++ b/src/coreclr/src/jit/lsraxarch.cpp @@ -1862,21 +1862,17 @@ int LinearScan::BuildIntrinsic(GenTree* tree) // int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) { - // Only SIMDIntrinsicInit can be contained. Other than that, - // only SIMDIntrinsicOpEquality and SIMDIntrinsicOpInEquality can have 0 dstCount. - int dstCount = simdTree->IsValue() ? 1 : 0; + // All intrinsics have a dstCount of 1 + assert(simdTree->IsValue()); + bool buildUses = true; regMaskTP dstCandidates = RBM_NONE; if (simdTree->isContained()) { + // Only SIMDIntrinsicInit can be contained assert(simdTree->gtSIMDIntrinsicID == SIMDIntrinsicInit); } - else if (dstCount != 1) - { - assert((simdTree->gtSIMDIntrinsicID == SIMDIntrinsicOpEquality) || - (simdTree->gtSIMDIntrinsicID == SIMDIntrinsicOpInEquality)); - } SetContainsAVXFlags(simdTree->gtSIMDSize); GenTree* op1 = simdTree->gtGetOp1(); GenTree* op2 = simdTree->gtGetOp2(); @@ -1956,35 +1952,11 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) noway_assert(varTypeIsFloating(simdTree->gtSIMDBaseType)); break; - case SIMDIntrinsicAbs: - // float/double vectors: This gets implemented as bitwise-And operation - // with a mask and hence should never see here. - // - // Must be a Vector or Vector Vector - assert(simdTree->gtSIMDBaseType == TYP_INT || simdTree->gtSIMDBaseType == TYP_SHORT || - simdTree->gtSIMDBaseType == TYP_BYTE); - assert(compiler->getSIMDSupportLevel() >= SIMD_SSE4_Supported); - break; - - case SIMDIntrinsicSqrt: - // SSE2 has no instruction support for sqrt on integer vectors. - noway_assert(varTypeIsFloating(simdTree->gtSIMDBaseType)); - break; - - case SIMDIntrinsicCeil: - case SIMDIntrinsicFloor: - assert(compiler->getSIMDSupportLevel() >= SIMD_SSE4_Supported); - break; - case SIMDIntrinsicAdd: case SIMDIntrinsicSub: case SIMDIntrinsicMul: case SIMDIntrinsicBitwiseAnd: - case SIMDIntrinsicBitwiseAndNot: case SIMDIntrinsicBitwiseOr: - case SIMDIntrinsicBitwiseXor: - case SIMDIntrinsicMin: - case SIMDIntrinsicMax: // SSE2 32-bit integer multiplication requires two temp regs if (simdTree->gtSIMDIntrinsicID == SIMDIntrinsicMul && simdTree->gtSIMDBaseType == TYP_INT && compiler->getSIMDSupportLevel() == SIMD_SSE2_Supported) @@ -1997,40 +1969,6 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) case SIMDIntrinsicEqual: break; - // SSE2 doesn't support < and <= directly on int vectors. - // Instead we need to use > and >= with swapped operands. - case SIMDIntrinsicLessThan: - case SIMDIntrinsicLessThanOrEqual: - noway_assert(!varTypeIsIntegral(simdTree->gtSIMDBaseType)); - break; - - // SIMDIntrinsicEqual is supported only on non-floating point base type vectors. - // SSE2 cmpps/pd doesn't support > and >= directly on float/double vectors. - // Instead we need to use < and <= with swapped operands. - case SIMDIntrinsicGreaterThan: - noway_assert(!varTypeIsFloating(simdTree->gtSIMDBaseType)); - break; - - case SIMDIntrinsicOpEquality: - case SIMDIntrinsicOpInEquality: - if (simdTree->gtGetOp2()->isContained()) - { - // If the second operand is contained then ContainCheckSIMD has determined - // that PTEST can be used. We only need a single source register and no - // internal registers. - } - else - { - // Can't use PTEST so we need 2 source registers, 1 internal SIMD register - // (to hold the result of PCMPEQD or other similar SIMD compare instruction) - // and one internal INT register (to hold the result of PMOVMSKB). - buildInternalIntRegisterDefForNode(simdTree); - buildInternalFloatRegisterDefForNode(simdTree); - } - // These SIMD nodes only set the condition flags. - dstCount = 0; - break; - case SIMDIntrinsicDotProduct: // Float/Double vectors: // For SSE, or AVX with 32-byte vectors, we also need an internal register @@ -2258,14 +2196,7 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) srcCount = BuildRMWUses(simdTree); } buildInternalRegisterUses(); - if (dstCount == 1) - { - BuildDef(simdTree, dstCandidates); - } - else - { - assert(dstCount == 0); - } + BuildDef(simdTree, dstCandidates); return srcCount; } #endif // FEATURE_SIMD diff --git a/src/coreclr/src/jit/namedintrinsiclist.h b/src/coreclr/src/jit/namedintrinsiclist.h index 457d434898c9b..c9a87d782a62c 100644 --- a/src/coreclr/src/jit/namedintrinsiclist.h +++ b/src/coreclr/src/jit/namedintrinsiclist.h @@ -44,10 +44,12 @@ enum NamedIntrinsic : unsigned short NI_SIMD_AS_HWINTRINSIC_START, #if defined(TARGET_XARCH) -#define SIMD_AS_HWINTRINSIC(classId, name, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) NI_##classId##_##name, +#define SIMD_AS_HWINTRINSIC(classId, id, name, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) \ + NI_##classId##_##id, #include "simdashwintrinsiclistxarch.h" #elif defined(TARGET_ARM64) -#define SIMD_AS_HWINTRINSIC(classId, name, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) NI_##classId##_##name, +#define SIMD_AS_HWINTRINSIC(classId, id, name, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) \ + NI_##classId##_##id, #include "simdashwintrinsiclistarm64.h" #endif // !defined(TARGET_XARCH) && !defined(TARGET_ARM64) NI_SIMD_AS_HWINTRINSIC_END, diff --git a/src/coreclr/src/jit/simd.cpp b/src/coreclr/src/jit/simd.cpp index bfd8c04f76789..3bd38ef537199 100644 --- a/src/coreclr/src/jit/simd.cpp +++ b/src/coreclr/src/jit/simd.cpp @@ -1075,19 +1075,9 @@ const SIMDIntrinsicInfo* Compiler::getSIMDIntrinsicInfo(CORINFO_CLASS_HANDLE* in case SIMDIntrinsicSub: case SIMDIntrinsicMul: case SIMDIntrinsicDiv: - case SIMDIntrinsicSqrt: - case SIMDIntrinsicMin: - case SIMDIntrinsicMax: - case SIMDIntrinsicAbs: case SIMDIntrinsicEqual: - case SIMDIntrinsicLessThan: - case SIMDIntrinsicLessThanOrEqual: - case SIMDIntrinsicGreaterThan: - case SIMDIntrinsicGreaterThanOrEqual: case SIMDIntrinsicBitwiseAnd: - case SIMDIntrinsicBitwiseAndNot: case SIMDIntrinsicBitwiseOr: - case SIMDIntrinsicBitwiseXor: case SIMDIntrinsicDotProduct: case SIMDIntrinsicCast: case SIMDIntrinsicConvertToSingle: @@ -1268,218 +1258,6 @@ SIMDIntrinsicID Compiler::impSIMDLongRelOpEqual(CORINFO_CLASS_HANDLE typeHnd, SIMDIntrinsicShuffleSSE2, TYP_INT, size); return SIMDIntrinsicBitwiseAnd; } - -// impSIMDLongRelOpGreaterThan: transforms operands and returns the SIMD intrinsic to be applied on -// transformed operands to obtain > comparison result. -// -// Arguments: -// typeHnd - type handle of SIMD vector -// size - SIMD vector size -// pOp1 - in-out parameter; first operand -// pOp2 - in-out parameter; second operand -// -// Return Value: -// Modifies in-out params pOp1, pOp2 and returns intrinsic ID to be applied to modified operands -// -SIMDIntrinsicID Compiler::impSIMDLongRelOpGreaterThan(CORINFO_CLASS_HANDLE typeHnd, - unsigned size, - GenTree** pOp1, - GenTree** pOp2) -{ - var_types simdType = (*pOp1)->TypeGet(); - assert(varTypeIsSIMD(simdType) && ((*pOp2)->TypeGet() == simdType)); - - // GreaterThan(v1, v2) where v1 and v2 are vector long. - // Let us consider the case of single long element comparison. - // say L1 = (x1, y1) and L2 = (x2, y2) where x1, y1, x2, and y2 are 32-bit integers that comprise the longs L1 and - // L2. - // - // GreaterThan(L1, L2) can be expressed in terms of > relationship between 32-bit integers that comprise L1 and L2 - // as - // = (x1, y1) > (x2, y2) - // = (x1 > x2) || [(x1 == x2) && (y1 > y2)] - eq (1) - // - // t = (v1 > v2) 32-bit signed comparison - // u = (v1 == v2) 32-bit sized element equality - // v = (v1 > v2) 32-bit unsigned comparison - // - // z = shuffle(t, (3, 3, 1, 1)) - This corresponds to (x1 > x2) in eq(1) above - // t1 = Shuffle(v, (2, 2, 0, 0)) - This corresponds to (y1 > y2) in eq(1) above - // u1 = Shuffle(u, (3, 3, 1, 1)) - This corresponds to (x1 == x2) in eq(1) above - // w = And(t1, u1) - This corresponds to [(x1 == x2) && (y1 > y2)] in eq(1) above - // Result = BitwiseOr(z, w) - - // Since op1 and op2 gets used multiple times, make sure side effects are computed. - GenTree* dupOp1 = nullptr; - GenTree* dupOp2 = nullptr; - GenTree* dupDupOp1 = nullptr; - GenTree* dupDupOp2 = nullptr; - - if (((*pOp1)->gtFlags & GTF_SIDE_EFFECT) != 0) - { - dupOp1 = fgInsertCommaFormTemp(pOp1, typeHnd); - dupDupOp1 = gtNewLclvNode(dupOp1->AsLclVarCommon()->GetLclNum(), simdType); - } - else - { - dupOp1 = gtCloneExpr(*pOp1); - dupDupOp1 = gtCloneExpr(*pOp1); - } - - if (((*pOp2)->gtFlags & GTF_SIDE_EFFECT) != 0) - { - dupOp2 = fgInsertCommaFormTemp(pOp2, typeHnd); - dupDupOp2 = gtNewLclvNode(dupOp2->AsLclVarCommon()->GetLclNum(), simdType); - } - else - { - dupOp2 = gtCloneExpr(*pOp2); - dupDupOp2 = gtCloneExpr(*pOp2); - } - - assert(dupDupOp1 != nullptr && dupDupOp2 != nullptr); - assert(dupOp1 != nullptr && dupOp2 != nullptr); - assert(*pOp1 != nullptr && *pOp2 != nullptr); - - // v1GreaterThanv2Signed - signed 32-bit comparison - GenTree* v1GreaterThanv2Signed = gtNewSIMDNode(simdType, *pOp1, *pOp2, SIMDIntrinsicGreaterThan, TYP_INT, size); - - // v1Equalsv2 - 32-bit equality - GenTree* v1Equalsv2 = gtNewSIMDNode(simdType, dupOp1, dupOp2, SIMDIntrinsicEqual, TYP_INT, size); - - // v1GreaterThanv2Unsigned - unsigned 32-bit comparison - var_types tempBaseType = TYP_UINT; - SIMDIntrinsicID sid = impSIMDRelOp(SIMDIntrinsicGreaterThan, typeHnd, size, &tempBaseType, &dupDupOp1, &dupDupOp2); - GenTree* v1GreaterThanv2Unsigned = gtNewSIMDNode(simdType, dupDupOp1, dupDupOp2, sid, tempBaseType, size); - - GenTree* z = gtNewSIMDNode(simdType, v1GreaterThanv2Signed, gtNewIconNode(SHUFFLE_WWYY, TYP_INT), - SIMDIntrinsicShuffleSSE2, TYP_FLOAT, size); - GenTree* t1 = gtNewSIMDNode(simdType, v1GreaterThanv2Unsigned, gtNewIconNode(SHUFFLE_ZZXX, TYP_INT), - SIMDIntrinsicShuffleSSE2, TYP_FLOAT, size); - GenTree* u1 = gtNewSIMDNode(simdType, v1Equalsv2, gtNewIconNode(SHUFFLE_WWYY, TYP_INT), SIMDIntrinsicShuffleSSE2, - TYP_FLOAT, size); - GenTree* w = gtNewSIMDNode(simdType, u1, t1, SIMDIntrinsicBitwiseAnd, TYP_INT, size); - - *pOp1 = z; - *pOp2 = w; - return SIMDIntrinsicBitwiseOr; -} - -// impSIMDLongRelOpGreaterThanOrEqual: transforms operands and returns the SIMD intrinsic to be applied on -// transformed operands to obtain >= comparison result. -// -// Arguments: -// typeHnd - type handle of SIMD vector -// size - SIMD vector size -// pOp1 - in-out parameter; first operand -// pOp2 - in-out parameter; second operand -// -// Return Value: -// Modifies in-out params pOp1, pOp2 and returns intrinsic ID to be applied to modified operands -// -SIMDIntrinsicID Compiler::impSIMDLongRelOpGreaterThanOrEqual(CORINFO_CLASS_HANDLE typeHnd, - unsigned size, - GenTree** pOp1, - GenTree** pOp2) -{ - var_types simdType = (*pOp1)->TypeGet(); - assert(varTypeIsSIMD(simdType) && ((*pOp2)->TypeGet() == simdType)); - - // expand this to (a == b) | (a > b) - GenTree* dupOp1 = nullptr; - GenTree* dupOp2 = nullptr; - - if (((*pOp1)->gtFlags & GTF_SIDE_EFFECT) != 0) - { - dupOp1 = fgInsertCommaFormTemp(pOp1, typeHnd); - } - else - { - dupOp1 = gtCloneExpr(*pOp1); - } - - if (((*pOp2)->gtFlags & GTF_SIDE_EFFECT) != 0) - { - dupOp2 = fgInsertCommaFormTemp(pOp2, typeHnd); - } - else - { - dupOp2 = gtCloneExpr(*pOp2); - } - - assert(dupOp1 != nullptr && dupOp2 != nullptr); - assert(*pOp1 != nullptr && *pOp2 != nullptr); - - // (a==b) - SIMDIntrinsicID id = impSIMDLongRelOpEqual(typeHnd, size, pOp1, pOp2); - *pOp1 = gtNewSIMDNode(simdType, *pOp1, *pOp2, id, TYP_LONG, size); - - // (a > b) - id = impSIMDLongRelOpGreaterThan(typeHnd, size, &dupOp1, &dupOp2); - *pOp2 = gtNewSIMDNode(simdType, dupOp1, dupOp2, id, TYP_LONG, size); - - return SIMDIntrinsicBitwiseOr; -} - -// impSIMDInt32OrSmallIntRelOpGreaterThanOrEqual: transforms operands and returns the SIMD intrinsic to be applied on -// transformed operands to obtain >= comparison result in case of integer base type vectors -// -// Arguments: -// typeHnd - type handle of SIMD vector -// size - SIMD vector size -// baseType - base type of SIMD vector -// pOp1 - in-out parameter; first operand -// pOp2 - in-out parameter; second operand -// -// Return Value: -// Modifies in-out params pOp1, pOp2 and returns intrinsic ID to be applied to modified operands -// -SIMDIntrinsicID Compiler::impSIMDIntegralRelOpGreaterThanOrEqual( - CORINFO_CLASS_HANDLE typeHnd, unsigned size, var_types baseType, GenTree** pOp1, GenTree** pOp2) -{ - var_types simdType = (*pOp1)->TypeGet(); - assert(varTypeIsSIMD(simdType) && ((*pOp2)->TypeGet() == simdType)); - - // This routine should be used only for integer base type vectors - assert(varTypeIsIntegral(baseType)); - if ((getSIMDSupportLevel() == SIMD_SSE2_Supported) && ((baseType == TYP_LONG) || baseType == TYP_UBYTE)) - { - return impSIMDLongRelOpGreaterThanOrEqual(typeHnd, size, pOp1, pOp2); - } - - // expand this to (a == b) | (a > b) - GenTree* dupOp1 = nullptr; - GenTree* dupOp2 = nullptr; - - if (((*pOp1)->gtFlags & GTF_SIDE_EFFECT) != 0) - { - dupOp1 = fgInsertCommaFormTemp(pOp1, typeHnd); - } - else - { - dupOp1 = gtCloneExpr(*pOp1); - } - - if (((*pOp2)->gtFlags & GTF_SIDE_EFFECT) != 0) - { - dupOp2 = fgInsertCommaFormTemp(pOp2, typeHnd); - } - else - { - dupOp2 = gtCloneExpr(*pOp2); - } - - assert(dupOp1 != nullptr && dupOp2 != nullptr); - assert(*pOp1 != nullptr && *pOp2 != nullptr); - - // (a==b) - *pOp1 = gtNewSIMDNode(simdType, *pOp1, *pOp2, SIMDIntrinsicEqual, baseType, size); - - // (a > b) - *pOp2 = gtNewSIMDNode(simdType, dupOp1, dupOp2, SIMDIntrinsicGreaterThan, baseType, size); - - return SIMDIntrinsicBitwiseOr; -} #endif // TARGET_XARCH // Transforms operands and returns the SIMD intrinsic to be applied on @@ -1514,32 +1292,9 @@ SIMDIntrinsicID Compiler::impSIMDRelOp(SIMDIntrinsicID relOpIntrinsicId, if (varTypeIsFloating(baseType)) { - // SSE2/AVX doesn't support > and >= on vector float/double. - // Therefore, we need to use < and <= with swapped operands - if (relOpIntrinsicId == SIMDIntrinsicGreaterThan || relOpIntrinsicId == SIMDIntrinsicGreaterThanOrEqual) - { - GenTree* tmp = *pOp1; - *pOp1 = *pOp2; - *pOp2 = tmp; - - intrinsicID = - (relOpIntrinsicId == SIMDIntrinsicGreaterThan) ? SIMDIntrinsicLessThan : SIMDIntrinsicLessThanOrEqual; - } } else if (varTypeIsIntegral(baseType)) { - // SSE/AVX doesn't support < and <= on integer base type vectors. - // Therefore, we need to use > and >= with swapped operands. - if (intrinsicID == SIMDIntrinsicLessThan || intrinsicID == SIMDIntrinsicLessThanOrEqual) - { - GenTree* tmp = *pOp1; - *pOp1 = *pOp2; - *pOp2 = tmp; - - intrinsicID = (relOpIntrinsicId == SIMDIntrinsicLessThan) ? SIMDIntrinsicGreaterThan - : SIMDIntrinsicGreaterThanOrEqual; - } - if ((getSIMDSupportLevel() == SIMD_SSE2_Supported) && baseType == TYP_LONG) { // There is no direct SSE2 support for comparing TYP_LONG vectors. @@ -1548,28 +1303,13 @@ SIMDIntrinsicID Compiler::impSIMDRelOp(SIMDIntrinsicID relOpIntrinsicId, { intrinsicID = impSIMDLongRelOpEqual(typeHnd, size, pOp1, pOp2); } - else if (intrinsicID == SIMDIntrinsicGreaterThan) - { - intrinsicID = impSIMDLongRelOpGreaterThan(typeHnd, size, pOp1, pOp2); - } - else if (intrinsicID == SIMDIntrinsicGreaterThanOrEqual) - { - intrinsicID = impSIMDLongRelOpGreaterThanOrEqual(typeHnd, size, pOp1, pOp2); - } else { unreached(); } } // SSE2 and AVX direct support for signed comparison of int32, int16 and int8 types - else if (!varTypeIsUnsigned(baseType)) - { - if (intrinsicID == SIMDIntrinsicGreaterThanOrEqual) - { - intrinsicID = impSIMDIntegralRelOpGreaterThanOrEqual(typeHnd, size, baseType, pOp1, pOp2); - } - } - else // unsigned + else if (varTypeIsUnsigned(baseType)) { // Vector, Vector, Vector and Vector: // SSE2 supports > for signed comparison. Therefore, to use it for @@ -1644,21 +1384,7 @@ SIMDIntrinsicID Compiler::impSIMDRelOp(SIMDIntrinsicID relOpIntrinsicId, return impSIMDRelOp(intrinsicID, typeHnd, size, inOutBaseType, pOp1, pOp2); } } -#elif defined(TARGET_ARM64) - // TODO-ARM64-CQ handle comparisons against zero - - // TARGET_ARM64 doesn't support < and <= on register register comparisons - // Therefore, we need to use > and >= with swapped operands. - if (intrinsicID == SIMDIntrinsicLessThan || intrinsicID == SIMDIntrinsicLessThanOrEqual) - { - GenTree* tmp = *pOp1; - *pOp1 = *pOp2; - *pOp2 = tmp; - - intrinsicID = - (intrinsicID == SIMDIntrinsicLessThan) ? SIMDIntrinsicGreaterThan : SIMDIntrinsicGreaterThanOrEqual; - } -#else // !TARGET_XARCH +#elif !defined(TARGET_ARM64) assert(!"impSIMDRelOp() unimplemented on target arch"); unreached(); #endif // !TARGET_XARCH @@ -1666,411 +1392,6 @@ SIMDIntrinsicID Compiler::impSIMDRelOp(SIMDIntrinsicID relOpIntrinsicId, return intrinsicID; } -//------------------------------------------------------------------------- -// impSIMDAbs: creates GT_SIMD node to compute Abs value of a given vector. -// -// Arguments: -// typeHnd - type handle of SIMD vector -// baseType - base type of vector -// size - vector size in bytes -// op1 - operand of Abs intrinsic -// -GenTree* Compiler::impSIMDAbs(CORINFO_CLASS_HANDLE typeHnd, var_types baseType, unsigned size, GenTree* op1) -{ - assert(varTypeIsSIMD(op1)); - - var_types simdType = op1->TypeGet(); - GenTree* retVal = nullptr; - -#ifdef TARGET_XARCH - // When there is no direct support, Abs(v) could be computed - // on integer vectors as follows: - // BitVector = v < vector.Zero - // result = ConditionalSelect(BitVector, vector.Zero - v, v) - - bool useConditionalSelect = false; - if (getSIMDSupportLevel() == SIMD_SSE2_Supported) - { - // SSE2 doesn't support abs on signed integer type vectors. - if (baseType == TYP_LONG || baseType == TYP_INT || baseType == TYP_SHORT || baseType == TYP_BYTE) - { - useConditionalSelect = true; - } - } - else - { - assert(getSIMDSupportLevel() >= SIMD_SSE4_Supported); - if (baseType == TYP_LONG) - { - // SSE4/AVX2 don't support abs on long type vector. - useConditionalSelect = true; - } - } - - if (useConditionalSelect) - { - // This works only on integer vectors not on float/double vectors. - assert(varTypeIsIntegral(baseType)); - - GenTree* op1Assign; - unsigned op1LclNum; - - if (op1->OperGet() == GT_LCL_VAR) - { - op1LclNum = op1->AsLclVarCommon()->GetLclNum(); - op1Assign = nullptr; - } - else - { - op1LclNum = lvaGrabTemp(true DEBUGARG("SIMD Abs op1")); - lvaSetStruct(op1LclNum, typeHnd, false); - op1Assign = gtNewTempAssign(op1LclNum, op1); - op1 = gtNewLclvNode(op1LclNum, op1->TypeGet()); - } - - // Assign Vector.Zero to a temp since it is needed more than once - GenTree* vecZero = gtNewSIMDVectorZero(simdType, baseType, size); - unsigned vecZeroLclNum = lvaGrabTemp(true DEBUGARG("SIMD Abs VecZero")); - lvaSetStruct(vecZeroLclNum, typeHnd, false); - GenTree* vecZeroAssign = gtNewTempAssign(vecZeroLclNum, vecZero); - - // Construct BitVector = v < vector.Zero - GenTree* bitVecOp1 = op1; - GenTree* bitVecOp2 = gtNewLclvNode(vecZeroLclNum, vecZero->TypeGet()); - var_types relOpBaseType = baseType; - SIMDIntrinsicID relOpIntrinsic = - impSIMDRelOp(SIMDIntrinsicLessThan, typeHnd, size, &relOpBaseType, &bitVecOp1, &bitVecOp2); - GenTree* bitVec = gtNewSIMDNode(simdType, bitVecOp1, bitVecOp2, relOpIntrinsic, relOpBaseType, size); - unsigned bitVecLclNum = lvaGrabTemp(true DEBUGARG("SIMD Abs bitVec")); - lvaSetStruct(bitVecLclNum, typeHnd, false); - GenTree* bitVecAssign = gtNewTempAssign(bitVecLclNum, bitVec); - bitVec = gtNewLclvNode(bitVecLclNum, bitVec->TypeGet()); - - // Construct condSelectOp1 = vector.Zero - v - GenTree* subOp1 = gtNewLclvNode(vecZeroLclNum, vecZero->TypeGet()); - GenTree* subOp2 = gtNewLclvNode(op1LclNum, op1->TypeGet()); - GenTree* negVec = gtNewSIMDNode(simdType, subOp1, subOp2, SIMDIntrinsicSub, baseType, size); - - // Construct ConditionalSelect(bitVec, vector.Zero - v, v) - GenTree* vec = gtNewLclvNode(op1LclNum, op1->TypeGet()); - retVal = impSIMDSelect(typeHnd, baseType, size, bitVec, negVec, vec); - - // Prepend bitVec assignment to retVal. - // retVal = (tmp2 = v < tmp1), CondSelect(tmp2, tmp1 - v, v) - retVal = gtNewOperNode(GT_COMMA, simdType, bitVecAssign, retVal); - - // Prepend vecZero assignment to retVal. - // retVal = (tmp1 = vector.Zero), (tmp2 = v < tmp1), CondSelect(tmp2, tmp1 - v, v) - retVal = gtNewOperNode(GT_COMMA, simdType, vecZeroAssign, retVal); - - // If op1 was assigned to a temp, prepend that to retVal. - if (op1Assign != nullptr) - { - // retVal = (v=op1), (tmp1 = vector.Zero), (tmp2 = v < tmp1), CondSelect(tmp2, tmp1 - v, v) - retVal = gtNewOperNode(GT_COMMA, simdType, op1Assign, retVal); - } - } - else if (varTypeIsFloating(baseType)) - { - // Abs(vf) = vf & new SIMDVector(0x7fffffff); - // Abs(vd) = vf & new SIMDVector(0x7fffffffffffffff); - GenTree* bitMask = nullptr; - if (baseType == TYP_FLOAT) - { - float f; - static_assert_no_msg(sizeof(float) == sizeof(int)); - *((int*)&f) = 0x7fffffff; - bitMask = gtNewDconNode(f); - } - else if (baseType == TYP_DOUBLE) - { - double d; - static_assert_no_msg(sizeof(double) == sizeof(__int64)); - *((__int64*)&d) = 0x7fffffffffffffffLL; - bitMask = gtNewDconNode(d); - } - - assert(bitMask != nullptr); - bitMask->gtType = baseType; - GenTree* bitMaskVector = gtNewSIMDNode(simdType, bitMask, SIMDIntrinsicInit, baseType, size); - retVal = gtNewSIMDNode(simdType, op1, bitMaskVector, SIMDIntrinsicBitwiseAnd, baseType, size); - } - else if (baseType == TYP_USHORT || baseType == TYP_UBYTE || baseType == TYP_UINT || baseType == TYP_ULONG) - { - // Abs is a no-op on unsigned integer type vectors - retVal = op1; - } - else - { - assert(getSIMDSupportLevel() >= SIMD_SSE4_Supported); - assert(baseType != TYP_LONG); - - retVal = gtNewSIMDNode(simdType, op1, SIMDIntrinsicAbs, baseType, size); - } -#elif defined(TARGET_ARM64) - if (varTypeIsUnsigned(baseType)) - { - // Abs is a no-op on unsigned integer type vectors - retVal = op1; - } - else - { - retVal = gtNewSIMDNode(simdType, op1, SIMDIntrinsicAbs, baseType, size); - } -#else // !defined(TARGET_XARCH)_ && !defined(TARGET_ARM64) - assert(!"Abs intrinsic on non-xarch target not implemented"); -#endif // !TARGET_XARCH - - return retVal; -} - -// Creates a GT_SIMD tree for Select operation -// -// Arguments: -// typeHnd - type handle of SIMD vector -// baseType - base type of SIMD vector -// size - SIMD vector size -// op1 - first operand = Condition vector vc -// op2 - second operand = va -// op3 - third operand = vb -// -// Return Value: -// Returns GT_SIMD tree that computes Select(vc, va, vb) -// -GenTree* Compiler::impSIMDSelect( - CORINFO_CLASS_HANDLE typeHnd, var_types baseType, unsigned size, GenTree* op1, GenTree* op2, GenTree* op3) -{ - assert(varTypeIsSIMD(op1)); - var_types simdType = op1->TypeGet(); - assert(op2->TypeGet() == simdType); - assert(op3->TypeGet() == simdType); - - // TODO-ARM64-CQ Support generating select instruction for SIMD - - // Select(BitVector vc, va, vb) = (va & vc) | (vb & !vc) - // Select(op1, op2, op3) = (op2 & op1) | (op3 & !op1) - // = SIMDIntrinsicBitwiseOr(SIMDIntrinsicBitwiseAnd(op2, op1), - // SIMDIntrinsicBitwiseAndNot(op3, op1)) - // - // If Op1 has side effect, create an assignment to a temp - GenTree* tmp = op1; - GenTree* asg = nullptr; - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - unsigned lclNum = lvaGrabTemp(true DEBUGARG("SIMD Select")); - lvaSetStruct(lclNum, typeHnd, false); - tmp = gtNewLclvNode(lclNum, op1->TypeGet()); - asg = gtNewTempAssign(lclNum, op1); - } - - GenTree* andExpr = gtNewSIMDNode(simdType, op2, tmp, SIMDIntrinsicBitwiseAnd, baseType, size); - GenTree* dupOp1 = gtCloneExpr(tmp); - assert(dupOp1 != nullptr); -#ifdef TARGET_ARM64 - // ARM64 implements SIMDIntrinsicBitwiseAndNot as Left & ~Right - GenTree* andNotExpr = gtNewSIMDNode(simdType, op3, dupOp1, SIMDIntrinsicBitwiseAndNot, baseType, size); -#else - // XARCH implements SIMDIntrinsicBitwiseAndNot as ~Left & Right - GenTree* andNotExpr = gtNewSIMDNode(simdType, dupOp1, op3, SIMDIntrinsicBitwiseAndNot, baseType, size); -#endif - GenTree* simdTree = gtNewSIMDNode(simdType, andExpr, andNotExpr, SIMDIntrinsicBitwiseOr, baseType, size); - - // If asg not null, create a GT_COMMA tree. - if (asg != nullptr) - { - simdTree = gtNewOperNode(GT_COMMA, simdTree->TypeGet(), asg, simdTree); - } - - return simdTree; -} - -// Creates a GT_SIMD tree for Min/Max operation -// -// Arguments: -// IntrinsicId - SIMD intrinsic Id, either Min or Max -// typeHnd - type handle of SIMD vector -// baseType - base type of SIMD vector -// size - SIMD vector size -// op1 - first operand = va -// op2 - second operand = vb -// -// Return Value: -// Returns GT_SIMD tree that computes Max(va, vb) -// -GenTree* Compiler::impSIMDMinMax(SIMDIntrinsicID intrinsicId, - CORINFO_CLASS_HANDLE typeHnd, - var_types baseType, - unsigned size, - GenTree* op1, - GenTree* op2) -{ - assert(intrinsicId == SIMDIntrinsicMin || intrinsicId == SIMDIntrinsicMax); - assert(varTypeIsSIMD(op1)); - var_types simdType = op1->TypeGet(); - assert(op2->TypeGet() == simdType); - -#if defined(TARGET_XARCH) || defined(TARGET_ARM64) - GenTree* simdTree = nullptr; - -#ifdef TARGET_XARCH - // SSE2 has direct support for float/double/signed word/unsigned byte. - // SSE4.1 has direct support for int32/uint32/signed byte/unsigned word. - // For other integer types we compute min/max as follows - // - // int32/uint32 (SSE2) - // int64/uint64 (SSE2&SSE4): - // compResult = (op1 < op2) in case of Min - // (op1 > op2) in case of Max - // Min/Max(op1, op2) = Select(compResult, op1, op2) - // - // unsigned word (SSE2): - // op1 = op1 - 2^15 ; to make it fit within a signed word - // op2 = op2 - 2^15 ; to make it fit within a signed word - // result = SSE2 signed word Min/Max(op1, op2) - // result = result + 2^15 ; readjust it back - // - // signed byte (SSE2): - // op1 = op1 + 2^7 ; to make it unsigned - // op1 = op1 + 2^7 ; to make it unsigned - // result = SSE2 unsigned byte Min/Max(op1, op2) - // result = result - 2^15 ; readjust it back - - if (varTypeIsFloating(baseType) || baseType == TYP_SHORT || baseType == TYP_UBYTE || - (getSIMDSupportLevel() >= SIMD_SSE4_Supported && - (baseType == TYP_BYTE || baseType == TYP_INT || baseType == TYP_UINT || baseType == TYP_USHORT))) - { - // SSE2 or SSE4.1 has direct support - simdTree = gtNewSIMDNode(simdType, op1, op2, intrinsicId, baseType, size); - } - else if (baseType == TYP_USHORT || baseType == TYP_BYTE) - { - assert(getSIMDSupportLevel() == SIMD_SSE2_Supported); - int constVal; - SIMDIntrinsicID operIntrinsic; - SIMDIntrinsicID adjustIntrinsic; - var_types minMaxOperBaseType; - if (baseType == TYP_USHORT) - { - constVal = 0x80008000; - operIntrinsic = SIMDIntrinsicSub; - adjustIntrinsic = SIMDIntrinsicAdd; - minMaxOperBaseType = TYP_SHORT; - } - else - { - assert(baseType == TYP_BYTE); - constVal = 0x80808080; - operIntrinsic = SIMDIntrinsicAdd; - adjustIntrinsic = SIMDIntrinsicSub; - minMaxOperBaseType = TYP_UBYTE; - } - - GenTree* initVal = gtNewIconNode(constVal); - GenTree* constVector = gtNewSIMDNode(simdType, initVal, nullptr, SIMDIntrinsicInit, TYP_INT, size); - - // Assign constVector to a temp, since we intend to use it more than once - // TODO-CQ: We have quite a few such constant vectors constructed during - // the importation of SIMD intrinsics. Make sure that we have a single - // temp per distinct constant per method. - GenTree* tmp = fgInsertCommaFormTemp(&constVector, typeHnd); - - // op1 = op1 - constVector - // op2 = op2 - constVector - op1 = gtNewSIMDNode(simdType, op1, constVector, operIntrinsic, baseType, size); - op2 = gtNewSIMDNode(simdType, op2, tmp, operIntrinsic, baseType, size); - - // compute min/max of op1 and op2 considering them as if minMaxOperBaseType - simdTree = gtNewSIMDNode(simdType, op1, op2, intrinsicId, minMaxOperBaseType, size); - - // re-adjust the value by adding or subtracting constVector - tmp = gtNewLclvNode(tmp->AsLclVarCommon()->GetLclNum(), tmp->TypeGet()); - simdTree = gtNewSIMDNode(simdType, simdTree, tmp, adjustIntrinsic, baseType, size); - } -#elif defined(TARGET_ARM64) - // Arm64 has direct support for all types except int64/uint64 - // For which we compute min/max as follows - // - // int64/uint64 - // compResult = (op1 < op2) in case of Min - // (op1 > op2) in case of Max - // Min/Max(op1, op2) = Select(compResult, op1, op2) - if (baseType != TYP_ULONG && baseType != TYP_LONG) - { - simdTree = gtNewSIMDNode(simdType, op1, op2, intrinsicId, baseType, size); - } -#endif - else - { - GenTree* dupOp1 = nullptr; - GenTree* dupOp2 = nullptr; - GenTree* op1Assign = nullptr; - GenTree* op2Assign = nullptr; - unsigned op1LclNum; - unsigned op2LclNum; - - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - op1LclNum = lvaGrabTemp(true DEBUGARG("SIMD Min/Max")); - lvaSetStruct(op1LclNum, typeHnd, false); - dupOp1 = gtNewLclvNode(op1LclNum, op1->TypeGet()); - op1Assign = gtNewTempAssign(op1LclNum, op1); - op1 = gtNewLclvNode(op1LclNum, op1->TypeGet()); - } - else - { - dupOp1 = gtCloneExpr(op1); - } - - if ((op2->gtFlags & GTF_SIDE_EFFECT) != 0) - { - op2LclNum = lvaGrabTemp(true DEBUGARG("SIMD Min/Max")); - lvaSetStruct(op2LclNum, typeHnd, false); - dupOp2 = gtNewLclvNode(op2LclNum, op2->TypeGet()); - op2Assign = gtNewTempAssign(op2LclNum, op2); - op2 = gtNewLclvNode(op2LclNum, op2->TypeGet()); - } - else - { - dupOp2 = gtCloneExpr(op2); - } - - SIMDIntrinsicID relOpIntrinsic = - (intrinsicId == SIMDIntrinsicMin) ? SIMDIntrinsicLessThan : SIMDIntrinsicGreaterThan; - var_types relOpBaseType = baseType; - - // compResult = op1 relOp op2 - // simdTree = Select(compResult, op1, op2); - assert(dupOp1 != nullptr); - assert(dupOp2 != nullptr); - relOpIntrinsic = impSIMDRelOp(relOpIntrinsic, typeHnd, size, &relOpBaseType, &dupOp1, &dupOp2); - GenTree* compResult = gtNewSIMDNode(simdType, dupOp1, dupOp2, relOpIntrinsic, relOpBaseType, size); - unsigned compResultLclNum = lvaGrabTemp(true DEBUGARG("SIMD Min/Max")); - lvaSetStruct(compResultLclNum, typeHnd, false); - GenTree* compResultAssign = gtNewTempAssign(compResultLclNum, compResult); - compResult = gtNewLclvNode(compResultLclNum, compResult->TypeGet()); - simdTree = impSIMDSelect(typeHnd, baseType, size, compResult, op1, op2); - simdTree = gtNewOperNode(GT_COMMA, simdTree->TypeGet(), compResultAssign, simdTree); - - // Now create comma trees if we have created assignments of op1/op2 to temps - if (op2Assign != nullptr) - { - simdTree = gtNewOperNode(GT_COMMA, simdTree->TypeGet(), op2Assign, simdTree); - } - - if (op1Assign != nullptr) - { - simdTree = gtNewOperNode(GT_COMMA, simdTree->TypeGet(), op1Assign, simdTree); - } - } - - assert(simdTree != nullptr); - return simdTree; -#else // !(defined(TARGET_XARCH) || defined(TARGET_ARM64)) - assert(!"impSIMDMinMax() unimplemented on target arch"); - unreached(); -#endif // !(defined(TARGET_XARCH) || defined(TARGET_ARM64)) -} - //------------------------------------------------------------------------ // getOp1ForConstructor: Get the op1 for a constructor call. // @@ -2906,44 +2227,7 @@ GenTree* Compiler::impSIMDIntrinsic(OPCODE opcode, } break; - case SIMDIntrinsicOpEquality: - case SIMDIntrinsicInstEquals: - { - op2 = impSIMDPopStack(simdType); - op1 = impSIMDPopStack(simdType, instMethod); - - assert(op1->TypeGet() == simdType); - assert(op2->TypeGet() == simdType); - - simdTree = gtNewSIMDNode(genActualType(callType), op1, op2, SIMDIntrinsicOpEquality, baseType, size); - if (simdType == TYP_SIMD12) - { - simdTree->gtFlags |= GTF_SIMD12_OP; - } - retVal = simdTree; - } - break; - - case SIMDIntrinsicOpInEquality: - { - // op1 is the first operand - // op2 is the second operand - op2 = impSIMDPopStack(simdType); - op1 = impSIMDPopStack(simdType, instMethod); - simdTree = gtNewSIMDNode(genActualType(callType), op1, op2, SIMDIntrinsicOpInEquality, baseType, size); - if (simdType == TYP_SIMD12) - { - simdTree->gtFlags |= GTF_SIMD12_OP; - } - retVal = simdTree; - } - break; - case SIMDIntrinsicEqual: - case SIMDIntrinsicLessThan: - case SIMDIntrinsicLessThanOrEqual: - case SIMDIntrinsicGreaterThan: - case SIMDIntrinsicGreaterThanOrEqual: { op2 = impSIMDPopStack(simdType); op1 = impSIMDPopStack(simdType, instMethod); @@ -2959,9 +2243,7 @@ GenTree* Compiler::impSIMDIntrinsic(OPCODE opcode, case SIMDIntrinsicMul: case SIMDIntrinsicDiv: case SIMDIntrinsicBitwiseAnd: - case SIMDIntrinsicBitwiseAndNot: case SIMDIntrinsicBitwiseOr: - case SIMDIntrinsicBitwiseXor: { #if defined(DEBUG) // check for the cases where we don't support intrinsics. @@ -3010,48 +2292,11 @@ GenTree* Compiler::impSIMDIntrinsic(OPCODE opcode, op2 = impSIMDPopStack(simdType); op1 = impSIMDPopStack(simdType, instMethod); -#ifdef TARGET_XARCH - if (simdIntrinsicID == SIMDIntrinsicBitwiseAndNot) - { - // XARCH implements SIMDIntrinsicBitwiseAndNot as ~op1 & op2, while the - // software implementation does op1 & ~op2, so we need to swap the operands - - GenTree* tmp = op2; - op2 = op1; - op1 = tmp; - } -#endif // TARGET_XARCH - simdTree = gtNewSIMDNode(simdType, op1, op2, simdIntrinsicID, baseType, size); retVal = simdTree; } break; - case SIMDIntrinsicSelect: - { - // op3 is a SIMD variable that is the second source - // op2 is a SIMD variable that is the first source - // op1 is a SIMD variable which is the bit mask. - op3 = impSIMDPopStack(simdType); - op2 = impSIMDPopStack(simdType); - op1 = impSIMDPopStack(simdType); - - retVal = impSIMDSelect(clsHnd, baseType, size, op1, op2, op3); - } - break; - - case SIMDIntrinsicMin: - case SIMDIntrinsicMax: - { - // op1 is the first operand; if instance method, op1 is "this" arg - // op2 is the second operand - op2 = impSIMDPopStack(simdType); - op1 = impSIMDPopStack(simdType, instMethod); - - retVal = impSIMDMinMax(simdIntrinsicID, clsHnd, baseType, size, op1, op2); - } - break; - case SIMDIntrinsicGetItem: { // op1 is a SIMD variable that is "this" arg @@ -3118,43 +2363,6 @@ GenTree* Compiler::impSIMDIntrinsic(OPCODE opcode, } break; - case SIMDIntrinsicSqrt: - { -#if (defined(TARGET_XARCH) || defined(TARGET_ARM64)) && defined(DEBUG) - // SSE/AVX/ARM64 doesn't support sqrt on integer type vectors and hence - // should never be seen as an intrinsic here. See SIMDIntrinsicList.h - // for supported base types for this intrinsic. - if (!varTypeIsFloating(baseType)) - { - assert(!"Sqrt not supported on integer vectors\n"); - return nullptr; - } -#endif // (defined(TARGET_XARCH) || defined(TARGET_ARM64)) && defined(DEBUG) - - op1 = impSIMDPopStack(simdType); - - retVal = gtNewSIMDNode(genActualType(callType), op1, nullptr, simdIntrinsicID, baseType, size); - } - break; - - case SIMDIntrinsicCeil: - case SIMDIntrinsicFloor: -#if defined(TARGET_XARCH) - // Rounding instructions are only available from SSE4.1. - if (getSIMDSupportLevel() < SIMD_SSE4_Supported) - { - return nullptr; - } -#endif // defined(TARGET_XARCH) - op1 = impSIMDPopStack(simdType); - retVal = gtNewSIMDNode(genActualType(callType), op1, simdIntrinsicID, baseType, size); - break; - - case SIMDIntrinsicAbs: - op1 = impSIMDPopStack(simdType); - retVal = impSIMDAbs(clsHnd, baseType, size, op1); - break; - case SIMDIntrinsicGetW: retVal = impSIMDGetFixed(simdType, baseType, size, 3); break; diff --git a/src/coreclr/src/jit/simdashwintrinsic.cpp b/src/coreclr/src/jit/simdashwintrinsic.cpp index 1463ed30ca407..a4f07b0c2dc81 100644 --- a/src/coreclr/src/jit/simdashwintrinsic.cpp +++ b/src/coreclr/src/jit/simdashwintrinsic.cpp @@ -10,12 +10,12 @@ static const SimdAsHWIntrinsicInfo simdAsHWIntrinsicInfoArray[] = { // clang-format off #if defined(TARGET_XARCH) -#define SIMD_AS_HWINTRINSIC(classId, name, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) \ - {NI_##classId##_##name, #name, SimdAsHWIntrinsicClassId::classId, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, static_cast(flag)}, +#define SIMD_AS_HWINTRINSIC(classId, id, name, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) \ + {NI_##classId##_##id, name, SimdAsHWIntrinsicClassId::classId, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, static_cast(flag)}, #include "simdashwintrinsiclistxarch.h" #elif defined(TARGET_ARM64) -#define SIMD_AS_HWINTRINSIC(classId, name, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) \ - {NI_##classId##_##name, #name, SimdAsHWIntrinsicClassId::classId, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, static_cast(flag)}, +#define SIMD_AS_HWINTRINSIC(classId, id, name, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) \ + {NI_##classId##_##id, name, SimdAsHWIntrinsicClassId::classId, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, static_cast(flag)}, #include "simdashwintrinsiclistarm64.h" #else #error Unsupported platform @@ -65,6 +65,15 @@ NamedIntrinsic SimdAsHWIntrinsicInfo::lookupId(CORINFO_SIG_INFO* sig, return NI_Illegal; } + unsigned numArgs = sig->numArgs; + bool isInstanceMethod = false; + + if (sig->hasThis()) + { + numArgs++; + isInstanceMethod = true; + } + for (int i = 0; i < (NI_SIMD_AS_HWINTRINSIC_END - NI_SIMD_AS_HWINTRINSIC_START - 1); i++) { const SimdAsHWIntrinsicInfo& intrinsicInfo = simdAsHWIntrinsicInfoArray[i]; @@ -74,12 +83,12 @@ NamedIntrinsic SimdAsHWIntrinsicInfo::lookupId(CORINFO_SIG_INFO* sig, continue; } - if (sig->numArgs != static_cast(intrinsicInfo.numArgs)) + if (numArgs != static_cast(intrinsicInfo.numArgs)) { continue; } - if (sig->hasThis() != SimdAsHWIntrinsicInfo::IsInstanceMethod(intrinsicInfo.id)) + if (isInstanceMethod != SimdAsHWIntrinsicInfo::IsInstanceMethod(intrinsicInfo.id)) { continue; } @@ -170,30 +179,38 @@ GenTree* Compiler::impSimdAsHWIntrinsic(NamedIntrinsic intrinsic, return nullptr; } - var_types retType = JITtype2varType(sig->retType); - var_types baseType = TYP_UNKNOWN; - var_types simdType = TYP_UNKNOWN; - unsigned simdSize = 0; + CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE; + var_types retType = JITtype2varType(sig->retType); + var_types baseType = TYP_UNKNOWN; + var_types simdType = TYP_UNKNOWN; + unsigned simdSize = 0; + unsigned numArgs = sig->numArgs; + bool isInstanceMethod = false; // We want to resolve and populate the handle cache for this type even // if it isn't the basis for anything carried on the node. baseType = getBaseTypeAndSizeOfSIMDType(clsHnd, &simdSize); - assert(simdSize != 0); - - CORINFO_CLASS_HANDLE argClass; if (retType == TYP_STRUCT) { baseType = getBaseTypeAndSizeOfSIMDType(sig->retTypeSigClass, &simdSize); retType = getSIMDTypeForSize(simdSize); } - else + else if (numArgs != 0) { argClass = info.compCompHnd->getArgClass(sig, sig->args); baseType = getBaseTypeAndSizeOfSIMDType(argClass, &simdSize); } - if ((clsHnd == m_simdHandleCache->SIMDVectorHandle) && (sig->numArgs != 0)) + if (sig->hasThis()) + { + assert(SimdAsHWIntrinsicInfo::IsInstanceMethod(intrinsic)); + numArgs++; + + isInstanceMethod = true; + argClass = clsHnd; + } + else if ((clsHnd == m_simdHandleCache->SIMDVectorHandle) && (numArgs != 0)) { // We need to fixup the clsHnd in the case we are an intrinsic on Vector // The first argument will be the appropriate Vector handle to use @@ -206,15 +223,16 @@ GenTree* Compiler::impSimdAsHWIntrinsic(NamedIntrinsic intrinsic, baseType = getBaseTypeAndSizeOfSIMDType(clsHnd, &simdSize); } - simdType = getSIMDTypeForSize(simdSize); - assert(varTypeIsSIMD(simdType)); - - if (!varTypeIsArithmetic(baseType)) + if (!varTypeIsArithmetic(baseType) || (simdSize == 0)) { - // We only support intrinsics on the 10 primitive arithmetic types + // We get here for a devirtualization of IEquatable`1.Equals + // or if the user tries to use Vector with an unsupported type return nullptr; } + simdType = getSIMDTypeForSize(simdSize); + assert(varTypeIsSIMD(simdType)); + NamedIntrinsic hwIntrinsic = SimdAsHWIntrinsicInfo::lookupHWIntrinsic(intrinsic, baseType); if ((hwIntrinsic == NI_Illegal) || !varTypeIsSIMD(simdType)) @@ -250,14 +268,19 @@ GenTree* Compiler::impSimdAsHWIntrinsic(NamedIntrinsic intrinsic, GenTree* op1 = nullptr; GenTree* op2 = nullptr; - bool isInstanceMethod = SimdAsHWIntrinsicInfo::IsInstanceMethod(intrinsic); - - switch (sig->numArgs) + switch (numArgs) { + case 0: + { + assert(!SimdAsHWIntrinsicInfo::NeedsOperandsSwapped(intrinsic)); + return gtNewSimdAsHWIntrinsicNode(retType, hwIntrinsic, baseType, simdSize); + } + case 1: { - argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); - op1 = getArgForHWIntrinsic(argType, argClass, isInstanceMethod); + argType = isInstanceMethod ? simdType + : JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); + op1 = getArgForHWIntrinsic(argType, argClass, isInstanceMethod); assert(!SimdAsHWIntrinsicInfo::NeedsOperandsSwapped(intrinsic)); return gtNewSimdAsHWIntrinsicNode(retType, op1, hwIntrinsic, baseType, simdSize); @@ -265,12 +288,13 @@ GenTree* Compiler::impSimdAsHWIntrinsic(NamedIntrinsic intrinsic, case 2: { - CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(argList); + CORINFO_ARG_LIST_HANDLE arg2 = isInstanceMethod ? argList : info.compCompHnd->getArgNext(argList); argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass))); op2 = getArgForHWIntrinsic(argType, argClass); - argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); - op1 = getArgForHWIntrinsic(argType, argClass, isInstanceMethod); + argType = isInstanceMethod ? simdType + : JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); + op1 = getArgForHWIntrinsic(argType, argClass, isInstanceMethod); if (SimdAsHWIntrinsicInfo::NeedsOperandsSwapped(intrinsic)) { @@ -311,18 +335,31 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic, assert(retType != TYP_UNKNOWN); assert(varTypeIsArithmetic(baseType)); assert(simdSize != 0); - assert(varTypeIsSIMD(getSIMDTypeForSize(simdSize))); assert(SimdAsHWIntrinsicInfo::lookupHWIntrinsic(intrinsic, baseType) == intrinsic); - CORINFO_ARG_LIST_HANDLE argList = sig->args; - var_types argType = TYP_UNKNOWN; - CORINFO_CLASS_HANDLE argClass; + var_types simdType = getSIMDTypeForSize(simdSize); + assert(varTypeIsSIMD(simdType)); + + CORINFO_ARG_LIST_HANDLE argList = sig->args; + var_types argType = TYP_UNKNOWN; + CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE; GenTree* op1 = nullptr; GenTree* op2 = nullptr; + GenTree* op3 = nullptr; SimdAsHWIntrinsicClassId classId = SimdAsHWIntrinsicInfo::lookupClassId(intrinsic); - bool isInstanceMethod = SimdAsHWIntrinsicInfo::IsInstanceMethod(intrinsic); + unsigned numArgs = sig->numArgs; + bool isInstanceMethod = false; + + if (sig->hasThis()) + { + assert(SimdAsHWIntrinsicInfo::IsInstanceMethod(intrinsic)); + numArgs++; + + isInstanceMethod = true; + argClass = clsHnd; + } #if defined(TARGET_XARCH) bool isVectorT256 = (SimdAsHWIntrinsicInfo::lookupClassId(intrinsic) == SimdAsHWIntrinsicClassId::VectorT256); @@ -342,12 +379,64 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic, assert(!isVectorT256 || compIsaSupportedDebugOnly(InstructionSet_AVX2)); #endif - switch (sig->numArgs) + switch (numArgs) { + case 0: + { + switch (intrinsic) + { +#if defined(TARGET_XARCH) + case NI_VectorT128_get_Count: + case NI_VectorT256_get_Count: + { + GenTreeIntCon* countNode = gtNewIconNode(getSIMDVectorLength(simdSize, baseType), TYP_INT); + countNode->gtFlags |= GTF_ICON_SIMD_COUNT; + return countNode; + } +#elif defined(TARGET_ARM64) + case NI_VectorT128_get_Count: + { + GenTreeIntCon* countNode = gtNewIconNode(getSIMDVectorLength(simdSize, baseType), TYP_INT); + countNode->gtFlags |= GTF_ICON_SIMD_COUNT; + return countNode; + } +#else +#error Unsupported platform +#endif // !TARGET_XARCH && !TARGET_ARM64 + + default: + { + // Some platforms warn about unhandled switch cases + // We handle it more generally via the assert and nullptr return below. + break; + } + } + } + case 1: { - argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); - op1 = getArgForHWIntrinsic(argType, argClass, isInstanceMethod); + bool isOpExplicit = (intrinsic == NI_VectorT128_op_Explicit); + +#if defined(TARGET_XARCH) + isOpExplicit |= (intrinsic == NI_VectorT256_op_Explicit); +#endif + + if (isOpExplicit) + { + // We fold away the cast here, as it only exists to satisfy the + // type system. It is safe to do this here since the op1 type + // and the signature return type are both the same TYP_SIMD. + + op1 = impSIMDPopStack(retType, /* expectAddr: */ false, sig->retTypeClass); + SetOpLclRelatedToSIMDIntrinsic(op1); + assert(op1->gtType == getSIMDTypeForSize(getSIMDTypeSizeInBytes(sig->retTypeSigClass))); + + return op1; + } + + argType = isInstanceMethod ? simdType + : JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); + op1 = getArgForHWIntrinsic(argType, argClass, isInstanceMethod); assert(!SimdAsHWIntrinsicInfo::NeedsOperandsSwapped(intrinsic)); @@ -447,12 +536,13 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic, case 2: { - CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(argList); + CORINFO_ARG_LIST_HANDLE arg2 = isInstanceMethod ? argList : info.compCompHnd->getArgNext(argList); argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass))); op2 = getArgForHWIntrinsic(argType, argClass); - argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); - op1 = getArgForHWIntrinsic(argType, argClass, isInstanceMethod); + argType = isInstanceMethod ? simdType + : JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); + op1 = getArgForHWIntrinsic(argType, argClass, isInstanceMethod); assert(!SimdAsHWIntrinsicInfo::NeedsOperandsSwapped(intrinsic)); @@ -681,7 +771,7 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic, } #else #error Unsupported platform -#endif // TARGET_XARCH +#endif // !TARGET_XARCH && !TARGET_ARM64 default: { @@ -692,6 +782,49 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic, } break; } + + case 3: + { + CORINFO_ARG_LIST_HANDLE arg2 = isInstanceMethod ? argList : info.compCompHnd->getArgNext(argList); + CORINFO_ARG_LIST_HANDLE arg3 = info.compCompHnd->getArgNext(arg2); + + argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg3, &argClass))); + op3 = getArgForHWIntrinsic(argType, argClass); + + argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass))); + op2 = getArgForHWIntrinsic(argType, argClass); + + argType = isInstanceMethod ? simdType + : JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); + op1 = getArgForHWIntrinsic(argType, argClass, isInstanceMethod); + + assert(!SimdAsHWIntrinsicInfo::NeedsOperandsSwapped(intrinsic)); + + switch (intrinsic) + { +#if defined(TARGET_XARCH) + case NI_VectorT128_ConditionalSelect: + case NI_VectorT256_ConditionalSelect: + { + return impSimdAsHWIntrinsicCndSel(clsHnd, retType, baseType, simdSize, op1, op2, op3); + } +#elif defined(TARGET_ARM64) + case NI_VectorT128_ConditionalSelect: + { + return impSimdAsHWIntrinsicCndSel(clsHnd, retType, baseType, simdSize, op1, op2, op3); + } +#else +#error Unsupported platform +#endif // !TARGET_XARCH && !TARGET_ARM64 + + default: + { + // Some platforms warn about unhandled switch cases + // We handle it more generally via the assert and nullptr return below. + break; + } + } + } } assert(!"Unexpected SimdAsHWIntrinsic"); @@ -723,7 +856,7 @@ GenTree* Compiler::impSimdAsHWIntrinsicCndSel(CORINFO_CLASS_HANDLE clsHnd, { assert(featureSIMD); assert(retType != TYP_UNKNOWN); - assert(varTypeIsIntegral(baseType)); + assert(varTypeIsArithmetic(baseType)); assert(simdSize != 0); assert(varTypeIsSIMD(getSIMDTypeForSize(simdSize))); assert(op1 != nullptr); diff --git a/src/coreclr/src/jit/simdashwintrinsiclistarm64.h b/src/coreclr/src/jit/simdashwintrinsiclistarm64.h index cfd47939cf3dc..9621486e69657 100644 --- a/src/coreclr/src/jit/simdashwintrinsiclistarm64.h +++ b/src/coreclr/src/jit/simdashwintrinsiclistarm64.h @@ -6,12 +6,24 @@ #ifndef SIMD_AS_HWINTRINSIC #error Define SIMD_AS_HWINTRINSIC before including this file #endif + +#if defined(SIMD_AS_HWINTRINSIC_ID) || defined(SIMD_AS_HWINTRINSIC_NM) +#error SIMD_AS_HWINTRINSIC_ID and SIMD_AS_HWINTRINSIC_NM should not be defined before including this file +#endif /*****************************************************************************/ // clang-format off #ifdef FEATURE_HW_INTRINSICS +// Defines a SimdAsHWIntrinsic where the name is implicitly taken from the id +#define SIMD_AS_HWINTRINSIC_ID(classId, id, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) \ + SIMD_AS_HWINTRINSIC(classId, id, #id, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) + +// Defines a SimdAsHWIntrinsic where the name is explicit +#define SIMD_AS_HWINTRINSIC_NM(classId, id, name, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) \ + SIMD_AS_HWINTRINSIC(classId, id, name, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) + /* Note * Each intrinsic has a unique Intrinsic ID with type of `enum NamedIntrinsic` * Each intrinsic has a `NumArg` for number of parameters @@ -22,65 +34,94 @@ */ // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* -// ISA Function name NumArg Instructions Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA ID Name NumArg Instructions Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* // Vector2 Intrinsics -SIMD_AS_HWINTRINSIC(Vector2, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector2, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector2, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector2, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Add, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector2, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Arm64_Divide, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector2, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector2, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Subtract, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_NM(Vector2, EqualsInstance, "Equals", 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector64_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod) +SIMD_AS_HWINTRINSIC_ID(Vector2, get_Zero, 0, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector64_get_Zero, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Add, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Arm64_Divide, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, op_Equality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector64_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, op_Inequality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector64_op_Inequality, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Subtract, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, SquareRoot, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Arm64_Sqrt, NI_Illegal}, SimdAsHWIntrinsicFlag::None) // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* -// ISA Function name NumArg Instructions Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA ID Name NumArg Instructions Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* // Vector3 Intrinsics -SIMD_AS_HWINTRINSIC(Vector3, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector3, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector3, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector3, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Add, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector3, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Arm64_Divide, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector3, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector3, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Subtract, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_NM(Vector3, EqualsInstance, "Equals", 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod) +SIMD_AS_HWINTRINSIC_ID(Vector3, get_Zero, 0, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_get_Zero, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Add, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Arm64_Divide, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, op_Equality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, op_Inequality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Inequality, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Subtract, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, SquareRoot, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Arm64_Sqrt, NI_Illegal}, SimdAsHWIntrinsicFlag::None) // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* -// ISA Function name NumArg Instructions Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA ID Name NumArg Instructions Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* // Vector4 Intrinsics -SIMD_AS_HWINTRINSIC(Vector4, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector4, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector4, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector4, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Add, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector4, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Arm64_Divide, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector4, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector4, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Subtract, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_NM(Vector4, EqualsInstance, "Equals", 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod) +SIMD_AS_HWINTRINSIC_ID(Vector4, get_Zero, 0, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_get_Zero, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Add, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Arm64_Divide, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, op_Equality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, op_Inequality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Inequality, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Subtract, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, SquareRoot, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Arm64_Sqrt, NI_Illegal}, SimdAsHWIntrinsicFlag::None) // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* -// ISA Function name NumArg Instructions Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA ID Name NumArg Instructions Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* // Vector Intrinsics -SIMD_AS_HWINTRINSIC(VectorT128, Abs, 1, {NI_AdvSimd_Abs, NI_VectorT128_Abs, NI_AdvSimd_Abs, NI_VectorT128_Abs, NI_AdvSimd_Abs, NI_VectorT128_Abs, NI_AdvSimd_Arm64_Abs, NI_VectorT128_Abs, NI_AdvSimd_Abs, NI_AdvSimd_Arm64_Abs}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, AndNot, 2, {NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, Equals, 2, {NI_AdvSimd_CompareEqual, NI_AdvSimd_CompareEqual, NI_AdvSimd_CompareEqual, NI_AdvSimd_CompareEqual, NI_AdvSimd_CompareEqual, NI_AdvSimd_CompareEqual, NI_AdvSimd_Arm64_CompareEqual, NI_AdvSimd_Arm64_CompareEqual, NI_AdvSimd_CompareEqual, NI_AdvSimd_Arm64_CompareEqual}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, GreaterThan, 2, {NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_Arm64_CompareGreaterThan, NI_AdvSimd_Arm64_CompareGreaterThan, NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_Arm64_CompareGreaterThan}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, GreaterThanOrEqual, 2, {NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_Arm64_CompareGreaterThanOrEqual, NI_AdvSimd_Arm64_CompareGreaterThanOrEqual, NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_Arm64_CompareGreaterThanOrEqual}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, LessThan, 2, {NI_AdvSimd_CompareLessThan, NI_AdvSimd_CompareLessThan, NI_AdvSimd_CompareLessThan, NI_AdvSimd_CompareLessThan, NI_AdvSimd_CompareLessThan, NI_AdvSimd_CompareLessThan, NI_AdvSimd_Arm64_CompareLessThan, NI_AdvSimd_Arm64_CompareLessThan, NI_AdvSimd_CompareLessThan, NI_AdvSimd_Arm64_CompareLessThan}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, LessThanOrEqual, 2, {NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_Arm64_CompareLessThanOrEqual, NI_AdvSimd_Arm64_CompareLessThanOrEqual, NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_Arm64_CompareLessThanOrEqual}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, Max, 2, {NI_AdvSimd_Max, NI_AdvSimd_Max, NI_AdvSimd_Max, NI_AdvSimd_Max, NI_AdvSimd_Max, NI_AdvSimd_Max, NI_VectorT128_Max, NI_VectorT128_Max, NI_AdvSimd_Max, NI_AdvSimd_Arm64_Max}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, Min, 2, {NI_AdvSimd_Min, NI_AdvSimd_Min, NI_AdvSimd_Min, NI_AdvSimd_Min, NI_AdvSimd_Min, NI_AdvSimd_Min, NI_VectorT128_Min, NI_VectorT128_Min, NI_AdvSimd_Min, NI_AdvSimd_Arm64_Min}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_Addition, 2, {NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Arm64_Add}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_BitwiseAnd, 2, {NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_BitwiseOr, 2, {NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Arm64_Divide, NI_AdvSimd_Arm64_Divide}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_ExclusiveOr, 2, {NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_Multiply, 2, {NI_AdvSimd_Multiply, NI_AdvSimd_Multiply, NI_AdvSimd_Multiply, NI_AdvSimd_Multiply, NI_AdvSimd_Multiply, NI_AdvSimd_Multiply, NI_Illegal, NI_Illegal, NI_AdvSimd_Multiply, NI_AdvSimd_Arm64_Multiply}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_Subtraction, 2, {NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Arm64_Subtract}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, Abs, 1, {NI_AdvSimd_Abs, NI_VectorT128_Abs, NI_AdvSimd_Abs, NI_VectorT128_Abs, NI_AdvSimd_Abs, NI_VectorT128_Abs, NI_AdvSimd_Arm64_Abs, NI_VectorT128_Abs, NI_AdvSimd_Abs, NI_AdvSimd_Arm64_Abs}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, AndNot, 2, {NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear, NI_AdvSimd_BitwiseClear}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, Ceiling, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Ceiling, NI_AdvSimd_Ceiling}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, ConditionalSelect, 3, {NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, Equals, 2, {NI_AdvSimd_CompareEqual, NI_AdvSimd_CompareEqual, NI_AdvSimd_CompareEqual, NI_AdvSimd_CompareEqual, NI_AdvSimd_CompareEqual, NI_AdvSimd_CompareEqual, NI_AdvSimd_Arm64_CompareEqual, NI_AdvSimd_Arm64_CompareEqual, NI_AdvSimd_CompareEqual, NI_AdvSimd_Arm64_CompareEqual}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_NM(VectorT128, EqualsInstance, "Equals", 2, {NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality}, SimdAsHWIntrinsicFlag::InstanceMethod) +SIMD_AS_HWINTRINSIC_ID(VectorT128, Floor, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Floor, NI_AdvSimd_Floor}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, get_AllBitsSet, 0, {NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, get_Count, 0, {NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, get_Zero, 0, {NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, GreaterThan, 2, {NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_Arm64_CompareGreaterThan, NI_AdvSimd_Arm64_CompareGreaterThan, NI_AdvSimd_CompareGreaterThan, NI_AdvSimd_Arm64_CompareGreaterThan}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, GreaterThanOrEqual, 2, {NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_Arm64_CompareGreaterThanOrEqual, NI_AdvSimd_Arm64_CompareGreaterThanOrEqual, NI_AdvSimd_CompareGreaterThanOrEqual, NI_AdvSimd_Arm64_CompareGreaterThanOrEqual}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, LessThan, 2, {NI_AdvSimd_CompareLessThan, NI_AdvSimd_CompareLessThan, NI_AdvSimd_CompareLessThan, NI_AdvSimd_CompareLessThan, NI_AdvSimd_CompareLessThan, NI_AdvSimd_CompareLessThan, NI_AdvSimd_Arm64_CompareLessThan, NI_AdvSimd_Arm64_CompareLessThan, NI_AdvSimd_CompareLessThan, NI_AdvSimd_Arm64_CompareLessThan}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, LessThanOrEqual, 2, {NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_Arm64_CompareLessThanOrEqual, NI_AdvSimd_Arm64_CompareLessThanOrEqual, NI_AdvSimd_CompareLessThanOrEqual, NI_AdvSimd_Arm64_CompareLessThanOrEqual}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, Max, 2, {NI_AdvSimd_Max, NI_AdvSimd_Max, NI_AdvSimd_Max, NI_AdvSimd_Max, NI_AdvSimd_Max, NI_AdvSimd_Max, NI_VectorT128_Max, NI_VectorT128_Max, NI_AdvSimd_Max, NI_AdvSimd_Arm64_Max}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, Min, 2, {NI_AdvSimd_Min, NI_AdvSimd_Min, NI_AdvSimd_Min, NI_AdvSimd_Min, NI_AdvSimd_Min, NI_AdvSimd_Min, NI_VectorT128_Min, NI_VectorT128_Min, NI_AdvSimd_Min, NI_AdvSimd_Arm64_Min}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Addition, 2, {NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Add, NI_AdvSimd_Arm64_Add}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_BitwiseAnd, 2, {NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And, NI_AdvSimd_And}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_BitwiseOr, 2, {NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or, NI_AdvSimd_Or}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Arm64_Divide, NI_AdvSimd_Arm64_Divide}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Equality, 2, {NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_ExclusiveOr, 2, {NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor, NI_AdvSimd_Xor}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Explicit, 1, {NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Inequality, 2, {NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Multiply, 2, {NI_AdvSimd_Multiply, NI_AdvSimd_Multiply, NI_AdvSimd_Multiply, NI_AdvSimd_Multiply, NI_AdvSimd_Multiply, NI_AdvSimd_Multiply, NI_Illegal, NI_Illegal, NI_AdvSimd_Multiply, NI_AdvSimd_Arm64_Multiply}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Subtraction, 2, {NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Subtract, NI_AdvSimd_Arm64_Subtract}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, SquareRoot, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AdvSimd_Arm64_Sqrt, NI_AdvSimd_Arm64_Sqrt}, SimdAsHWIntrinsicFlag::None) + +#undef SIMD_AS_HWINTRINSIC_NM +#undef SIMD_AS_HWINTRINSIC_ID #endif // FEATURE_HW_INTRINSICS diff --git a/src/coreclr/src/jit/simdashwintrinsiclistxarch.h b/src/coreclr/src/jit/simdashwintrinsiclistxarch.h index 8f2ac6264041c..d13153db4aad7 100644 --- a/src/coreclr/src/jit/simdashwintrinsiclistxarch.h +++ b/src/coreclr/src/jit/simdashwintrinsiclistxarch.h @@ -6,12 +6,24 @@ #ifndef SIMD_AS_HWINTRINSIC #error Define SIMD_AS_HWINTRINSIC before including this file #endif + +#if defined(SIMD_AS_HWINTRINSIC_ID) || defined(SIMD_AS_HWINTRINSIC_NM) +#error SIMD_AS_HWINTRINSIC_ID and SIMD_AS_HWINTRINSIC_NM should not be defined before including this file +#endif /*****************************************************************************/ // clang-format off #ifdef FEATURE_HW_INTRINSICS +// Defines a SimdAsHWIntrinsic where the name is implicitly taken from the id +#define SIMD_AS_HWINTRINSIC_ID(classId, id, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) \ + SIMD_AS_HWINTRINSIC(classId, id, #id, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) + +// Defines a SimdAsHWIntrinsic where the name is explicit +#define SIMD_AS_HWINTRINSIC_NM(classId, id, name, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) \ + SIMD_AS_HWINTRINSIC(classId, id, name, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, flag) + /* Note * Each intrinsic has a unique Intrinsic ID with type of `enum NamedIntrinsic` * Each intrinsic has a `NumArg` for number of parameters @@ -22,87 +34,127 @@ */ // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* -// ISA Function name NumArg Instructions Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA ID Name NumArg Instructions Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* // Vector2 Intrinsics -SIMD_AS_HWINTRINSIC(Vector2, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector2, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector2, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector2, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Add, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector2, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Division, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector2, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector2, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Subtract, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_NM(Vector2, EqualsInstance, "Equals", 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod) +SIMD_AS_HWINTRINSIC_ID(Vector2, get_Zero, 0, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_get_Zero, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Add, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector2_op_Division, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, op_Equality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, op_Inequality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Inequality, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Subtract, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector2, SquareRoot, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Sqrt, NI_Illegal}, SimdAsHWIntrinsicFlag::None) // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* -// ISA Function name NumArg Instructions Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA ID Name NumArg Instructions Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* // Vector3 Intrinsics -SIMD_AS_HWINTRINSIC(Vector3, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector3, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector3, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector3, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Add, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector3, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Division, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector3, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector3, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Subtract, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_NM(Vector3, EqualsInstance, "Equals", 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod) +SIMD_AS_HWINTRINSIC_ID(Vector3, get_Zero, 0, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_get_Zero, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Add, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector3_op_Division, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, op_Equality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, op_Inequality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Inequality, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Subtract, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector3, SquareRoot, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Sqrt, NI_Illegal}, SimdAsHWIntrinsicFlag::None) // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* -// ISA Function name NumArg Instructions Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA ID Name NumArg Instructions Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* // Vector4 Intrinsics -SIMD_AS_HWINTRINSIC(Vector4, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector4_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector4, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector4, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector4, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Add, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector4, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Divide, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector4, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(Vector4, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Subtract, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, Abs, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector4_Abs, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_NM(Vector4, EqualsInstance, "Equals", 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::InstanceMethod) +SIMD_AS_HWINTRINSIC_ID(Vector4, get_Zero, 0, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_get_Zero, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, Max, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Max, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, Min, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Min, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, op_Addition, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Add, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Divide, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, op_Equality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Equality, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, op_Inequality, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Vector128_op_Inequality, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Multiply, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, op_Subtraction, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Subtract, NI_Illegal}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(Vector4, SquareRoot, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Sqrt, NI_Illegal}, SimdAsHWIntrinsicFlag::None) // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* -// ISA Function name NumArg Instructions Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA ID Name NumArg Instructions Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* // Vector Intrinsics -SIMD_AS_HWINTRINSIC(VectorT128, Abs, 1, {NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, AndNot, 2, {NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE_AndNot, NI_SSE2_AndNot}, SimdAsHWIntrinsicFlag::NeedsOperandsSwapped) -SIMD_AS_HWINTRINSIC(VectorT128, Equals, 2, {NI_SSE2_CompareEqual, NI_SSE2_CompareEqual, NI_SSE2_CompareEqual, NI_SSE2_CompareEqual, NI_SSE2_CompareEqual, NI_SSE2_CompareEqual, NI_VectorT128_Equals, NI_VectorT128_Equals, NI_SSE_CompareEqual, NI_SSE2_CompareEqual}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, GreaterThan, 2, {NI_SSE2_CompareGreaterThan, NI_VectorT128_GreaterThan, NI_SSE2_CompareGreaterThan, NI_VectorT128_GreaterThan, NI_SSE2_CompareGreaterThan, NI_VectorT128_GreaterThan, NI_VectorT128_GreaterThan, NI_VectorT128_GreaterThan, NI_SSE_CompareGreaterThan, NI_SSE2_CompareGreaterThan}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, GreaterThanOrEqual, 2, {NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_SSE_CompareGreaterThanOrEqual, NI_SSE2_CompareGreaterThanOrEqual}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, LessThan, 2, {NI_SSE2_CompareLessThan, NI_VectorT128_LessThan, NI_SSE2_CompareLessThan, NI_VectorT128_LessThan, NI_SSE2_CompareLessThan, NI_VectorT128_LessThan, NI_VectorT128_LessThan, NI_VectorT128_LessThan, NI_SSE_CompareLessThan, NI_SSE2_CompareLessThan}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, LessThanOrEqual, 2, {NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_SSE_CompareLessThanOrEqual, NI_SSE2_CompareLessThanOrEqual}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, Max, 2, {NI_VectorT128_Max, NI_SSE2_Max, NI_SSE2_Max, NI_VectorT128_Max, NI_VectorT128_Max, NI_VectorT128_Max, NI_VectorT128_Max, NI_VectorT128_Max, NI_SSE_Max, NI_SSE2_Max}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, Min, 2, {NI_VectorT128_Min, NI_SSE2_Min, NI_SSE2_Min, NI_VectorT128_Min, NI_VectorT128_Min, NI_VectorT128_Min, NI_VectorT128_Min, NI_VectorT128_Min, NI_SSE_Min, NI_SSE2_Min}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_Addition, 2, {NI_SSE2_Add, NI_SSE2_Add, NI_SSE2_Add, NI_SSE2_Add, NI_SSE2_Add, NI_SSE2_Add, NI_SSE2_Add, NI_SSE2_Add, NI_SSE_Add, NI_SSE2_Add}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_BitwiseAnd, 2, {NI_SSE2_And, NI_SSE2_And, NI_SSE2_And, NI_SSE2_And, NI_SSE2_And, NI_SSE2_And, NI_SSE2_And, NI_SSE2_And, NI_SSE_And, NI_SSE2_And}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_BitwiseOr, 2, {NI_SSE2_Or, NI_SSE2_Or, NI_SSE2_Or, NI_SSE2_Or, NI_SSE2_Or, NI_SSE2_Or, NI_SSE2_Or, NI_SSE2_Or, NI_SSE_Or, NI_SSE2_Or}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Divide, NI_SSE2_Divide}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_ExclusiveOr, 2, {NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE_Xor, NI_SSE2_Xor}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_SSE2_MultiplyLow, NI_Illegal, NI_VectorT128_op_Multiply, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Multiply, NI_SSE2_Multiply}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT128, op_Subtraction, 2, {NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE_Subtract, NI_SSE2_Subtract}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, Abs, 1, {NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs, NI_VectorT128_Abs}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, AndNot, 2, {NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE2_AndNot, NI_SSE_AndNot, NI_SSE2_AndNot}, SimdAsHWIntrinsicFlag::NeedsOperandsSwapped) +SIMD_AS_HWINTRINSIC_ID(VectorT128, Ceiling, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE41_Ceiling, NI_SSE41_Ceiling}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, ConditionalSelect, 3, {NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect, NI_VectorT128_ConditionalSelect}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, Equals, 2, {NI_SSE2_CompareEqual, NI_SSE2_CompareEqual, NI_SSE2_CompareEqual, NI_SSE2_CompareEqual, NI_SSE2_CompareEqual, NI_SSE2_CompareEqual, NI_VectorT128_Equals, NI_VectorT128_Equals, NI_SSE_CompareEqual, NI_SSE2_CompareEqual}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_NM(VectorT128, EqualsInstance, "Equals", 2, {NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality}, SimdAsHWIntrinsicFlag::InstanceMethod) +SIMD_AS_HWINTRINSIC_ID(VectorT128, Floor, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE41_Floor, NI_SSE41_Floor}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, get_AllBitsSet, 0, {NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet, NI_Vector128_get_AllBitsSet}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, get_Count, 0, {NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, get_Zero, 0, {NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero, NI_Vector128_get_Zero}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, GreaterThan, 2, {NI_SSE2_CompareGreaterThan, NI_VectorT128_GreaterThan, NI_SSE2_CompareGreaterThan, NI_VectorT128_GreaterThan, NI_SSE2_CompareGreaterThan, NI_VectorT128_GreaterThan, NI_VectorT128_GreaterThan, NI_VectorT128_GreaterThan, NI_SSE_CompareGreaterThan, NI_SSE2_CompareGreaterThan}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, GreaterThanOrEqual, 2, {NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_VectorT128_GreaterThanOrEqual, NI_SSE_CompareGreaterThanOrEqual, NI_SSE2_CompareGreaterThanOrEqual}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, LessThan, 2, {NI_SSE2_CompareLessThan, NI_VectorT128_LessThan, NI_SSE2_CompareLessThan, NI_VectorT128_LessThan, NI_SSE2_CompareLessThan, NI_VectorT128_LessThan, NI_VectorT128_LessThan, NI_VectorT128_LessThan, NI_SSE_CompareLessThan, NI_SSE2_CompareLessThan}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, LessThanOrEqual, 2, {NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_VectorT128_LessThanOrEqual, NI_SSE_CompareLessThanOrEqual, NI_SSE2_CompareLessThanOrEqual}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, Max, 2, {NI_VectorT128_Max, NI_SSE2_Max, NI_SSE2_Max, NI_VectorT128_Max, NI_VectorT128_Max, NI_VectorT128_Max, NI_VectorT128_Max, NI_VectorT128_Max, NI_SSE_Max, NI_SSE2_Max}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, Min, 2, {NI_VectorT128_Min, NI_SSE2_Min, NI_SSE2_Min, NI_VectorT128_Min, NI_VectorT128_Min, NI_VectorT128_Min, NI_VectorT128_Min, NI_VectorT128_Min, NI_SSE_Min, NI_SSE2_Min}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Addition, 2, {NI_SSE2_Add, NI_SSE2_Add, NI_SSE2_Add, NI_SSE2_Add, NI_SSE2_Add, NI_SSE2_Add, NI_SSE2_Add, NI_SSE2_Add, NI_SSE_Add, NI_SSE2_Add}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_BitwiseAnd, 2, {NI_SSE2_And, NI_SSE2_And, NI_SSE2_And, NI_SSE2_And, NI_SSE2_And, NI_SSE2_And, NI_SSE2_And, NI_SSE2_And, NI_SSE_And, NI_SSE2_And}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_BitwiseOr, 2, {NI_SSE2_Or, NI_SSE2_Or, NI_SSE2_Or, NI_SSE2_Or, NI_SSE2_Or, NI_SSE2_Or, NI_SSE2_Or, NI_SSE2_Or, NI_SSE_Or, NI_SSE2_Or}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Divide, NI_SSE2_Divide}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Equality, 2, {NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality, NI_Vector128_op_Equality}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_ExclusiveOr, 2, {NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE2_Xor, NI_SSE_Xor, NI_SSE2_Xor}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Explicit, 1, {NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit, NI_VectorT128_op_Explicit}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Inequality, 2, {NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality, NI_Vector128_op_Inequality}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_SSE2_MultiplyLow, NI_Illegal, NI_VectorT128_op_Multiply, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Multiply, NI_SSE2_Multiply}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, op_Subtraction, 2, {NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE2_Subtract, NI_SSE_Subtract, NI_SSE2_Subtract}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT128, SquareRoot, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_SSE_Sqrt, NI_SSE2_Sqrt}, SimdAsHWIntrinsicFlag::None) // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* -// ISA Function name NumArg Instructions Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA ID Name NumArg Instructions Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************* // Vector Intrinsics -SIMD_AS_HWINTRINSIC(VectorT256, Abs, 1, {NI_AVX2_Abs, NI_VectorT256_Abs, NI_AVX2_Abs, NI_VectorT256_Abs, NI_AVX2_Abs, NI_VectorT256_Abs, NI_VectorT256_Abs, NI_VectorT256_Abs, NI_VectorT256_Abs, NI_VectorT256_Abs}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, AndNot, 2, {NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX_AndNot, NI_AVX_AndNot}, SimdAsHWIntrinsicFlag::NeedsOperandsSwapped) -SIMD_AS_HWINTRINSIC(VectorT256, Equals, 2, {NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX_CompareEqual, NI_AVX_CompareEqual}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, GreaterThan, 2, {NI_AVX2_CompareGreaterThan, NI_VectorT256_GreaterThan, NI_AVX2_CompareGreaterThan, NI_VectorT256_GreaterThan, NI_AVX2_CompareGreaterThan, NI_VectorT256_GreaterThan, NI_AVX2_CompareGreaterThan, NI_VectorT256_GreaterThan, NI_AVX_CompareGreaterThan, NI_AVX_CompareGreaterThan}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, GreaterThanOrEqual, 2, {NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_AVX_CompareGreaterThanOrEqual, NI_AVX_CompareGreaterThanOrEqual}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, LessThan, 2, {NI_AVX2_CompareLessThan, NI_VectorT256_LessThan, NI_AVX2_CompareLessThan, NI_VectorT256_LessThan, NI_AVX2_CompareLessThan, NI_VectorT256_LessThan, NI_AVX2_CompareLessThan, NI_VectorT256_LessThan, NI_AVX_CompareLessThan, NI_AVX_CompareLessThan}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, LessThanOrEqual, 2, {NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_AVX_CompareLessThanOrEqual, NI_AVX_CompareLessThanOrEqual}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, Max, 2, {NI_AVX2_Max, NI_AVX2_Max, NI_AVX2_Max, NI_AVX2_Max, NI_AVX2_Max, NI_AVX2_Max, NI_VectorT256_Max, NI_VectorT256_Max, NI_AVX_Max, NI_AVX_Max}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, Min, 2, {NI_AVX2_Min, NI_AVX2_Min, NI_AVX2_Min, NI_AVX2_Min, NI_AVX2_Min, NI_AVX2_Min, NI_VectorT256_Min, NI_VectorT256_Min, NI_AVX_Min, NI_AVX_Min}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, op_Addition, 2, {NI_AVX2_Add, NI_AVX2_Add, NI_AVX2_Add, NI_AVX2_Add, NI_AVX2_Add, NI_AVX2_Add, NI_AVX2_Add, NI_AVX2_Add, NI_AVX_Add, NI_AVX_Add}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, op_BitwiseAnd, 2, {NI_AVX2_And, NI_AVX2_And, NI_AVX2_And, NI_AVX2_And, NI_AVX2_And, NI_AVX2_And, NI_AVX2_And, NI_AVX2_And, NI_AVX_And, NI_AVX_And}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, op_BitwiseOr, 2, {NI_AVX2_Or, NI_AVX2_Or, NI_AVX2_Or, NI_AVX2_Or, NI_AVX2_Or, NI_AVX2_Or, NI_AVX2_Or, NI_AVX2_Or, NI_AVX_Or, NI_AVX_Or}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AVX_Divide, NI_AVX_Divide}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, op_ExclusiveOr, 2, {NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX_Xor, NI_AVX_Xor}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_AVX2_MultiplyLow, NI_Illegal, NI_AVX2_MultiplyLow, NI_Illegal, NI_Illegal, NI_Illegal, NI_AVX_Multiply, NI_AVX_Multiply}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC(VectorT256, op_Subtraction, 2, {NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX_Subtract, NI_AVX_Subtract}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, Abs, 1, {NI_AVX2_Abs, NI_VectorT256_Abs, NI_AVX2_Abs, NI_VectorT256_Abs, NI_AVX2_Abs, NI_VectorT256_Abs, NI_VectorT256_Abs, NI_VectorT256_Abs, NI_VectorT256_Abs, NI_VectorT256_Abs}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, AndNot, 2, {NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX2_AndNot, NI_AVX_AndNot, NI_AVX_AndNot}, SimdAsHWIntrinsicFlag::NeedsOperandsSwapped) +SIMD_AS_HWINTRINSIC_ID(VectorT256, Ceiling, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AVX_Ceiling, NI_AVX_Ceiling}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, ConditionalSelect, 3, {NI_VectorT256_ConditionalSelect, NI_VectorT256_ConditionalSelect, NI_VectorT256_ConditionalSelect, NI_VectorT256_ConditionalSelect, NI_VectorT256_ConditionalSelect, NI_VectorT256_ConditionalSelect, NI_VectorT256_ConditionalSelect, NI_VectorT256_ConditionalSelect, NI_VectorT256_ConditionalSelect, NI_VectorT256_ConditionalSelect}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, Equals, 2, {NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX2_CompareEqual, NI_AVX_CompareEqual, NI_AVX_CompareEqual}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_NM(VectorT256, EqualsInstance, "Equals", 2, {NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality}, SimdAsHWIntrinsicFlag::InstanceMethod) +SIMD_AS_HWINTRINSIC_ID(VectorT256, Floor, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AVX_Floor, NI_AVX_Floor}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, get_AllBitsSet, 0, {NI_Vector256_get_AllBitsSet, NI_Vector256_get_AllBitsSet, NI_Vector256_get_AllBitsSet, NI_Vector256_get_AllBitsSet, NI_Vector256_get_AllBitsSet, NI_Vector256_get_AllBitsSet, NI_Vector256_get_AllBitsSet, NI_Vector256_get_AllBitsSet, NI_Vector256_get_AllBitsSet, NI_Vector256_get_AllBitsSet}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, get_Count, 0, {NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, get_Zero, 0, {NI_Vector256_get_Zero, NI_Vector256_get_Zero, NI_Vector256_get_Zero, NI_Vector256_get_Zero, NI_Vector256_get_Zero, NI_Vector256_get_Zero, NI_Vector256_get_Zero, NI_Vector256_get_Zero, NI_Vector256_get_Zero, NI_Vector256_get_Zero}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, GreaterThan, 2, {NI_AVX2_CompareGreaterThan, NI_VectorT256_GreaterThan, NI_AVX2_CompareGreaterThan, NI_VectorT256_GreaterThan, NI_AVX2_CompareGreaterThan, NI_VectorT256_GreaterThan, NI_AVX2_CompareGreaterThan, NI_VectorT256_GreaterThan, NI_AVX_CompareGreaterThan, NI_AVX_CompareGreaterThan}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, GreaterThanOrEqual, 2, {NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_VectorT256_GreaterThanOrEqual, NI_AVX_CompareGreaterThanOrEqual, NI_AVX_CompareGreaterThanOrEqual}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, LessThan, 2, {NI_AVX2_CompareLessThan, NI_VectorT256_LessThan, NI_AVX2_CompareLessThan, NI_VectorT256_LessThan, NI_AVX2_CompareLessThan, NI_VectorT256_LessThan, NI_AVX2_CompareLessThan, NI_VectorT256_LessThan, NI_AVX_CompareLessThan, NI_AVX_CompareLessThan}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, LessThanOrEqual, 2, {NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_VectorT256_LessThanOrEqual, NI_AVX_CompareLessThanOrEqual, NI_AVX_CompareLessThanOrEqual}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, Max, 2, {NI_AVX2_Max, NI_AVX2_Max, NI_AVX2_Max, NI_AVX2_Max, NI_AVX2_Max, NI_AVX2_Max, NI_VectorT256_Max, NI_VectorT256_Max, NI_AVX_Max, NI_AVX_Max}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, Min, 2, {NI_AVX2_Min, NI_AVX2_Min, NI_AVX2_Min, NI_AVX2_Min, NI_AVX2_Min, NI_AVX2_Min, NI_VectorT256_Min, NI_VectorT256_Min, NI_AVX_Min, NI_AVX_Min}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, op_Addition, 2, {NI_AVX2_Add, NI_AVX2_Add, NI_AVX2_Add, NI_AVX2_Add, NI_AVX2_Add, NI_AVX2_Add, NI_AVX2_Add, NI_AVX2_Add, NI_AVX_Add, NI_AVX_Add}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, op_BitwiseAnd, 2, {NI_AVX2_And, NI_AVX2_And, NI_AVX2_And, NI_AVX2_And, NI_AVX2_And, NI_AVX2_And, NI_AVX2_And, NI_AVX2_And, NI_AVX_And, NI_AVX_And}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, op_BitwiseOr, 2, {NI_AVX2_Or, NI_AVX2_Or, NI_AVX2_Or, NI_AVX2_Or, NI_AVX2_Or, NI_AVX2_Or, NI_AVX2_Or, NI_AVX2_Or, NI_AVX_Or, NI_AVX_Or}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, op_Division, 2, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AVX_Divide, NI_AVX_Divide}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, op_Equality, 2, {NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality, NI_Vector256_op_Equality}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, op_ExclusiveOr, 2, {NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX2_Xor, NI_AVX_Xor, NI_AVX_Xor}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, op_Explicit, 1, {NI_VectorT256_op_Explicit, NI_VectorT256_op_Explicit, NI_VectorT256_op_Explicit, NI_VectorT256_op_Explicit, NI_VectorT256_op_Explicit, NI_VectorT256_op_Explicit, NI_VectorT256_op_Explicit, NI_VectorT256_op_Explicit, NI_VectorT256_op_Explicit, NI_VectorT256_op_Explicit}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, op_Inequality, 2, {NI_Vector256_op_Inequality, NI_Vector256_op_Inequality, NI_Vector256_op_Inequality, NI_Vector256_op_Inequality, NI_Vector256_op_Inequality, NI_Vector256_op_Inequality, NI_Vector256_op_Inequality, NI_Vector256_op_Inequality, NI_Vector256_op_Inequality, NI_Vector256_op_Inequality}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, op_Multiply, 2, {NI_Illegal, NI_Illegal, NI_AVX2_MultiplyLow, NI_Illegal, NI_AVX2_MultiplyLow, NI_Illegal, NI_Illegal, NI_Illegal, NI_AVX_Multiply, NI_AVX_Multiply}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, op_Subtraction, 2, {NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX2_Subtract, NI_AVX_Subtract, NI_AVX_Subtract}, SimdAsHWIntrinsicFlag::None) +SIMD_AS_HWINTRINSIC_ID(VectorT256, SquareRoot, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_AVX_Sqrt, NI_AVX_Sqrt}, SimdAsHWIntrinsicFlag::None) + +#undef SIMD_AS_HWINTRINSIC_NM +#undef SIMD_AS_HWINTRINSIC_ID #endif // FEATURE_HW_INTRINSICS diff --git a/src/coreclr/src/jit/simdcodegenxarch.cpp b/src/coreclr/src/jit/simdcodegenxarch.cpp index b777d1da4eeed..e6aa4db08fe54 100644 --- a/src/coreclr/src/jit/simdcodegenxarch.cpp +++ b/src/coreclr/src/jit/simdcodegenxarch.cpp @@ -130,21 +130,6 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type } break; - case SIMDIntrinsicSqrt: - if (baseType == TYP_FLOAT) - { - result = INS_sqrtps; - } - else if (baseType == TYP_DOUBLE) - { - result = INS_sqrtpd; - } - else - { - unreached(); - } - break; - case SIMDIntrinsicAdd: if (baseType == TYP_FLOAT) { @@ -233,108 +218,6 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type } break; - case SIMDIntrinsicMin: - if (baseType == TYP_FLOAT) - { - result = INS_minps; - } - else if (baseType == TYP_DOUBLE) - { - result = INS_minpd; - } - else if (baseType == TYP_UBYTE) - { - result = INS_pminub; - } - else if (baseType == TYP_SHORT) - { - result = INS_pminsw; - } - else if (compiler->getSIMDSupportLevel() >= SIMD_SSE4_Supported) - { - if (baseType == TYP_BYTE) - { - result = INS_pminsb; - } - else if (baseType == TYP_USHORT) - { - result = INS_pminuw; - } - else if (baseType == TYP_INT) - { - result = INS_pminsd; - } - else if (baseType == TYP_UINT) - { - result = INS_pminud; - } - } - else - { - unreached(); - } - break; - - case SIMDIntrinsicMax: - if (baseType == TYP_FLOAT) - { - result = INS_maxps; - } - else if (baseType == TYP_DOUBLE) - { - result = INS_maxpd; - } - else if (baseType == TYP_UBYTE) - { - result = INS_pmaxub; - } - else if (baseType == TYP_SHORT) - { - result = INS_pmaxsw; - } - else if (compiler->getSIMDSupportLevel() >= SIMD_SSE4_Supported) - { - if (baseType == TYP_BYTE) - { - result = INS_pmaxsb; - } - else if (baseType == TYP_USHORT) - { - result = INS_pmaxuw; - } - else if (baseType == TYP_INT) - { - result = INS_pmaxsd; - } - else if (baseType == TYP_UINT) - { - result = INS_pmaxud; - } - } - else - { - unreached(); - } - break; - - case SIMDIntrinsicAbs: - if (compiler->getSIMDSupportLevel() >= SIMD_SSE4_Supported) - { - if (baseType == TYP_INT) - { - result = INS_pabsd; - } - else if (baseType == TYP_SHORT) - { - result = INS_pabsw; - } - else if (baseType == TYP_BYTE) - { - result = INS_pabsb; - } - } - break; - case SIMDIntrinsicEqual: if (baseType == TYP_FLOAT) { @@ -367,65 +250,6 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type } break; - case SIMDIntrinsicLessThan: - // Packed integers use > with swapped operands - assert(baseType != TYP_INT); - - if (baseType == TYP_FLOAT) - { - result = INS_cmpps; - assert(ival != nullptr); - *ival = 1; - } - else if (baseType == TYP_DOUBLE) - { - result = INS_cmppd; - assert(ival != nullptr); - *ival = 1; - } - break; - - case SIMDIntrinsicLessThanOrEqual: - // Packed integers use (a==b) || ( b > a) in place of a <= b. - assert(baseType != TYP_INT); - - if (baseType == TYP_FLOAT) - { - result = INS_cmpps; - assert(ival != nullptr); - *ival = 2; - } - else if (baseType == TYP_DOUBLE) - { - result = INS_cmppd; - assert(ival != nullptr); - *ival = 2; - } - break; - - case SIMDIntrinsicGreaterThan: - // Packed float/double use < with swapped operands - assert(!varTypeIsFloating(baseType)); - - // SSE2 supports only signed > - if (baseType == TYP_INT) - { - result = INS_pcmpgtd; - } - else if (baseType == TYP_SHORT) - { - result = INS_pcmpgtw; - } - else if (baseType == TYP_BYTE) - { - result = INS_pcmpgtb; - } - else if ((baseType == TYP_LONG) && (compiler->getSIMDSupportLevel() >= SIMD_SSE4_Supported)) - { - result = INS_pcmpgtq; - } - break; - case SIMDIntrinsicBitwiseAnd: if (baseType == TYP_FLOAT) { @@ -441,25 +265,6 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type } break; - case SIMDIntrinsicBitwiseAndNot: - if (baseType == TYP_FLOAT) - { - result = INS_andnps; - } - else if (baseType == TYP_DOUBLE) - { - result = INS_andnpd; - } - else if (baseType == TYP_INT) - { - result = INS_pandn; - } - else if (varTypeIsIntegral(baseType)) - { - result = INS_pandn; - } - break; - case SIMDIntrinsicBitwiseOr: if (baseType == TYP_FLOAT) { @@ -475,21 +280,6 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type } break; - case SIMDIntrinsicBitwiseXor: - if (baseType == TYP_FLOAT) - { - result = INS_xorps; - } - else if (baseType == TYP_DOUBLE) - { - result = INS_xorpd; - } - else if (varTypeIsIntegral(baseType)) - { - result = INS_pxor; - } - break; - case SIMDIntrinsicCast: result = INS_movaps; break; @@ -645,26 +435,6 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type result = INS_insertps; break; - case SIMDIntrinsicCeil: - case SIMDIntrinsicFloor: - if (compiler->getSIMDSupportLevel() >= SIMD_SSE4_Supported) - { - if (baseType == TYP_FLOAT) - { - result = INS_roundps; - } - else - { - assert(baseType == TYP_DOUBLE); - result = INS_roundpd; - } - - assert(ival != nullptr); - *ival = (intrinsicId == SIMDIntrinsicCeil) ? ROUNDPS_TOWARD_POSITIVE_INFINITY_IMM - : ROUNDPS_TOWARD_NEGATIVE_INFINITY_IMM; - } - break; - default: assert(!"Unsupported SIMD intrinsic"); unreached(); @@ -760,10 +530,10 @@ void CodeGen::genSIMDScalarMove( void CodeGen::genSIMDZero(var_types targetType, var_types baseType, regNumber targetReg) { - // We just use `INS_xorps` instead of `getOpForSIMDIntrinsic(SIMDIntrinsicBitwiseXor, baseType)` - // since `genSIMDZero` is used for both `System.Numerics.Vectors` and HardwareIntrinsics. Modern - // CPUs handle this specially in the renamer and it never hits the execution pipeline, additionally - // `INS_xorps` is always available (when using either the legacy or VEX encoding). + // We just use `INS_xorps` since `genSIMDZero` is used for both `System.Numerics.Vectors` and + // HardwareIntrinsics. Modern CPUs handle this specially in the renamer and it never hits the + // execution pipeline, additionally `INS_xorps` is always available (when using either the + // legacy or VEX encoding). inst_RV_RV(INS_xorps, targetReg, targetReg, targetType, emitActualTypeSize(targetType)); } @@ -1062,8 +832,7 @@ void CodeGen::genSIMDIntrinsicInitN(GenTreeSIMD* simdNode) // void CodeGen::genSIMDIntrinsicUnOp(GenTreeSIMD* simdNode) { - assert(simdNode->gtSIMDIntrinsicID == SIMDIntrinsicSqrt || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicCast || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicAbs); + assert(simdNode->gtSIMDIntrinsicID == SIMDIntrinsicCast); GenTree* op1 = simdNode->gtGetOp1(); var_types baseType = simdNode->gtSIMDBaseType; @@ -1080,32 +849,6 @@ void CodeGen::genSIMDIntrinsicUnOp(GenTreeSIMD* simdNode) genProduceReg(simdNode); } -//---------------------------------------------------------------------------------- -// genSIMDIntrinsicUnOpWithImm: Generate code for SIMD Intrinsic unary operations with an imm8, such as Ceil. -// -// Arguments: -// simdNode - The GT_SIMD node -// -// Return Value: -// None. -// -void CodeGen::genSIMDIntrinsicUnOpWithImm(GenTreeSIMD* simdNode) -{ - assert(simdNode->gtSIMDIntrinsicID == SIMDIntrinsicCeil || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicFloor); - - GenTree* op1 = simdNode->gtGetOp1(); - var_types baseType = simdNode->gtSIMDBaseType; - regNumber targetReg = simdNode->GetRegNum(); - assert(targetReg != REG_NA); - var_types targetType = simdNode->TypeGet(); - - regNumber op1Reg = genConsumeReg(op1); - unsigned ival; - instruction ins = getOpForSIMDIntrinsic(simdNode->gtSIMDIntrinsicID, baseType, &ival); - assert((ival >= 0) && (ival <= 255)); - GetEmitter()->emitIns_R_R_I(ins, emitActualTypeSize(targetType), targetReg, op1Reg, (int8_t)ival); -} - //---------------------------------------------------------------------------------- // genSIMDIntrinsic32BitConvert: Generate code for 32-bit SIMD Convert (int/uint <-> float) // @@ -1627,7 +1370,26 @@ void CodeGen::genSIMDIntrinsicWiden(GenTreeSIMD* simdNode) genSIMDZero(simdType, baseType, tmpReg); if (!varTypeIsUnsigned(baseType)) { - instruction compareIns = getOpForSIMDIntrinsic(SIMDIntrinsicGreaterThan, baseType); + instruction compareIns = INS_invalid; + + if (baseType == TYP_INT) + { + compareIns = INS_pcmpgtd; + } + else if (baseType == TYP_SHORT) + { + compareIns = INS_pcmpgtw; + } + else if (baseType == TYP_BYTE) + { + compareIns = INS_pcmpgtb; + } + else if ((baseType == TYP_LONG) && (compiler->getSIMDSupportLevel() >= SIMD_SSE4_Supported)) + { + compareIns = INS_pcmpgtq; + } + + assert(compareIns != INS_invalid); inst_RV_RV(compareIns, tmpReg, targetReg, simdType, emitSize); } inst_RV_RV(widenIns, targetReg, tmpReg, simdType); @@ -1797,10 +1559,7 @@ void CodeGen::genSIMDIntrinsicBinOp(GenTreeSIMD* simdNode) assert(simdNode->gtSIMDIntrinsicID == SIMDIntrinsicAdd || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicSub || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicMul || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicDiv || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicBitwiseAnd || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicBitwiseAndNot || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicBitwiseOr || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicBitwiseXor || simdNode->gtSIMDIntrinsicID == SIMDIntrinsicMin || - simdNode->gtSIMDIntrinsicID == SIMDIntrinsicMax); + simdNode->gtSIMDIntrinsicID == SIMDIntrinsicBitwiseOr); GenTree* op1 = simdNode->gtGetOp1(); GenTree* op2 = simdNode->gtGetOp2(); @@ -1997,7 +1756,6 @@ void CodeGen::genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode) switch (simdNode->gtSIMDIntrinsicID) { case SIMDIntrinsicEqual: - case SIMDIntrinsicGreaterThan: { assert(targetReg != REG_NA); @@ -2010,12 +1768,6 @@ void CodeGen::genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode) } #endif - // Greater-than: Floating point vectors use "<" with swapped operands - if (simdNode->gtSIMDIntrinsicID == SIMDIntrinsicGreaterThan) - { - assert(!varTypeIsFloating(baseType)); - } - unsigned ival = 0; instruction ins = getOpForSIMDIntrinsic(simdNode->gtSIMDIntrinsicID, baseType, &ival); @@ -2047,124 +1799,6 @@ void CodeGen::genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode) } break; - case SIMDIntrinsicLessThan: - case SIMDIntrinsicLessThanOrEqual: - { - assert(targetReg != REG_NA); - - // Int vectors use ">" and ">=" with swapped operands - assert(varTypeIsFloating(baseType)); - - // Get the instruction opcode for compare operation - unsigned ival; - instruction ins = getOpForSIMDIntrinsic(simdNode->gtSIMDIntrinsicID, baseType, &ival); - - // targetReg = op1reg RelOp op2reg - // Thefore, we can optimize if op1Reg == targetReg - if (op1Reg != targetReg) - { - inst_RV_RV(ins_Copy(targetType), targetReg, op1Reg, targetType, emitActualTypeSize(targetType)); - } - - assert((ival >= 0) && (ival <= 255)); - GetEmitter()->emitIns_R_R_I(ins, emitActualTypeSize(targetType), targetReg, op2Reg, (int8_t)ival); - } - break; - - // (In)Equality that produces bool result instead of a bit vector - case SIMDIntrinsicOpEquality: - case SIMDIntrinsicOpInEquality: - { - // We're only setting condition flags, if a 0/1 value is desired then Lowering should have inserted a SETCC. - assert(targetReg == REG_NA); - - var_types simdType = op1->TypeGet(); - // TODO-1stClassStructs: Temporary to minimize asmDiffs - if (simdType == TYP_DOUBLE) - { - simdType = TYP_SIMD8; - } - - // Here we should consider TYP_SIMD12 operands as if they were TYP_SIMD16 - // since both the operands will be in XMM registers. - if (simdType == TYP_SIMD12) - { - simdType = TYP_SIMD16; - } - - // On SSE4/AVX, we can generate optimal code for (in)equality against zero using ptest. - if (op2->isContained()) - { - assert((compiler->getSIMDSupportLevel() >= SIMD_SSE4_Supported) && op2->IsIntegralConstVector(0)); - inst_RV_RV(INS_ptest, op1->GetRegNum(), op1->GetRegNum(), simdType, emitActualTypeSize(simdType)); - } - else - { - // We need one additional SIMD register to store the result of the SIMD compare. - regNumber tmpReg1 = simdNode->GetSingleTempReg(RBM_ALLFLOAT); - - // tmpReg1 = (op1Reg == op2Reg) - // Call this value of tmpReg1 as 'compResult' for further reference below. - regNumber otherReg = op2Reg; - if (tmpReg1 != op2Reg) - { - if (tmpReg1 != op1Reg) - { - inst_RV_RV(ins_Copy(simdType), tmpReg1, op1Reg, simdType, emitActualTypeSize(simdType)); - } - } - else - { - otherReg = op1Reg; - } - - // For all integer types we can use TYP_INT comparison. - unsigned ival = 0; - instruction ins = - getOpForSIMDIntrinsic(SIMDIntrinsicEqual, varTypeIsFloating(baseType) ? baseType : TYP_INT, &ival); - - if (varTypeIsFloating(baseType)) - { - assert((ival >= 0) && (ival <= 255)); - GetEmitter()->emitIns_R_R_I(ins, emitActualTypeSize(simdType), tmpReg1, otherReg, (int8_t)ival); - } - else - { - inst_RV_RV(ins, tmpReg1, otherReg, simdType, emitActualTypeSize(simdType)); - } - - regNumber intReg = simdNode->GetSingleTempReg(RBM_ALLINT); - inst_RV_RV(INS_pmovmskb, intReg, tmpReg1, simdType, emitActualTypeSize(simdType)); - // There's no pmovmskw/pmovmskd/pmovmskq but they're not needed anyway. Vector compare - // instructions produce "all ones"/"all zeroes" components and pmovmskb extracts a - // subset of each component's ones/zeroes. In the end we need to know if the result is - // "all ones" where the number of ones is given by the vector byte size, not by the - // vector component count. So, for AVX registers we need to compare to 0xFFFFFFFF and - // for SSE registers we need to compare to 0x0000FFFF. - // The SIMD12 case is handled specially, because we can't rely on the upper bytes being - // zero, so we must compare only the lower 3 floats (hence the byte mask of 0xFFF). - // Note that -1 is used instead of 0xFFFFFFFF, on x64 emit doesn't correctly recognize - // that 0xFFFFFFFF can be encoded in a single byte and emits the longer 3DFFFFFFFF - // encoding instead of 83F8FF. - ssize_t mask; - if ((simdNode->gtFlags & GTF_SIMD12_OP) != 0) - { - mask = 0x00000FFF; - GetEmitter()->emitIns_R_I(INS_and, EA_4BYTE, intReg, mask); - } - else if (emitActualTypeSize(simdType) == 32) - { - mask = -1; - } - else - { - mask = 0x0000FFFF; - } - GetEmitter()->emitIns_R_I(INS_cmp, EA_4BYTE, intReg, mask); - } - } - break; - default: noway_assert(!"Unimplemented SIMD relational operation."); unreached(); @@ -3224,9 +2858,7 @@ void CodeGen::genSIMDIntrinsic(GenTreeSIMD* simdNode) genSIMDIntrinsicInitN(simdNode); break; - case SIMDIntrinsicSqrt: case SIMDIntrinsicCast: - case SIMDIntrinsicAbs: genSIMDIntrinsicUnOp(simdNode); break; @@ -3254,21 +2886,11 @@ void CodeGen::genSIMDIntrinsic(GenTreeSIMD* simdNode) case SIMDIntrinsicMul: case SIMDIntrinsicDiv: case SIMDIntrinsicBitwiseAnd: - case SIMDIntrinsicBitwiseAndNot: case SIMDIntrinsicBitwiseOr: - case SIMDIntrinsicBitwiseXor: - case SIMDIntrinsicMin: - case SIMDIntrinsicMax: genSIMDIntrinsicBinOp(simdNode); break; - case SIMDIntrinsicOpEquality: - case SIMDIntrinsicOpInEquality: case SIMDIntrinsicEqual: - case SIMDIntrinsicLessThan: - case SIMDIntrinsicGreaterThan: - case SIMDIntrinsicLessThanOrEqual: - case SIMDIntrinsicGreaterThanOrEqual: genSIMDIntrinsicRelOp(simdNode); break; @@ -3298,11 +2920,6 @@ void CodeGen::genSIMDIntrinsic(GenTreeSIMD* simdNode) genSIMDIntrinsicUpperRestore(simdNode); break; - case SIMDIntrinsicCeil: - case SIMDIntrinsicFloor: - genSIMDIntrinsicUnOpWithImm(simdNode); - break; - default: noway_assert(!"Unimplemented SIMD intrinsic."); unreached(); diff --git a/src/coreclr/src/jit/simdintrinsiclist.h b/src/coreclr/src/jit/simdintrinsiclist.h index 7b535c0112dc8..813a937fd056b 100644 --- a/src/coreclr/src/jit/simdintrinsiclist.h +++ b/src/coreclr/src/jit/simdintrinsiclist.h @@ -76,13 +76,6 @@ SIMD_INTRINSIC("set_Y", true, SetY, SIMD_INTRINSIC("set_Z", true, SetZ, "setZ", TYP_VOID, 2, {TYP_BYREF, TYP_UNKNOWN, TYP_UNDEF}, {TYP_FLOAT, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF}) SIMD_INTRINSIC("set_W", true, SetW, "setW", TYP_VOID, 2, {TYP_BYREF, TYP_UNKNOWN, TYP_UNDEF}, {TYP_FLOAT, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF}) -// Object.Equals() -SIMD_INTRINSIC("Equals", true, InstEquals, "equals", TYP_BOOL, 2, {TYP_BYREF, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) - -// Operator == and != -SIMD_INTRINSIC("op_Equality", false, OpEquality, "==", TYP_BOOL, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) -SIMD_INTRINSIC("op_Inequality", false, OpInEquality, "!=", TYP_BOOL, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) - // Arithmetic Operations SIMD_INTRINSIC("op_Addition", false, Add, "+", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) SIMD_INTRINSIC("op_Subtraction", false, Sub, "-", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) @@ -96,28 +89,12 @@ SIMD_INTRINSIC("op_Multiply", false, Mul, SIMD_INTRINSIC("op_Division", false, Div, "/", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_FLOAT, TYP_DOUBLE, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF}) -// SquareRoot is recognized as an intrinsic only for float or double vectors -SIMD_INTRINSIC("SquareRoot", false, Sqrt, "sqrt", TYP_STRUCT, 1, {TYP_STRUCT, TYP_UNDEF, TYP_UNDEF}, {TYP_FLOAT, TYP_DOUBLE, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF}) - -SIMD_INTRINSIC("Ceiling", false, Ceil, "ceil", TYP_STRUCT, 1, {TYP_STRUCT, TYP_UNDEF, TYP_UNDEF}, {TYP_FLOAT, TYP_DOUBLE, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF}) -SIMD_INTRINSIC("Floor", false, Floor, "floor", TYP_STRUCT, 1, {TYP_STRUCT, TYP_UNDEF, TYP_UNDEF}, {TYP_FLOAT, TYP_DOUBLE, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF}) - -SIMD_INTRINSIC("Min", false, Min, "min", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) -SIMD_INTRINSIC("Max", false, Max, "max", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) -SIMD_INTRINSIC("Abs", false, Abs, "abs", TYP_STRUCT, 1, {TYP_STRUCT, TYP_UNDEF, TYP_UNDEF }, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) - // Vector Relational operators SIMD_INTRINSIC("Equals", false, Equal, "eq", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) -SIMD_INTRINSIC("LessThan", false, LessThan, "lt", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) -SIMD_INTRINSIC("LessThanOrEqual", false, LessThanOrEqual, "le", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) -SIMD_INTRINSIC("GreaterThan", false, GreaterThan, "gt", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) -SIMD_INTRINSIC("GreaterThanOrEqual", false, GreaterThanOrEqual, "ge", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) // Bitwise operations SIMD_INTRINSIC("op_BitwiseAnd", false, BitwiseAnd, "&", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) -SIMD_INTRINSIC("AndNot", false, BitwiseAndNot, "&~", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) SIMD_INTRINSIC("op_BitwiseOr", false, BitwiseOr, "|", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) -SIMD_INTRINSIC("op_ExclusiveOr", false, BitwiseXor, "^", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) // Dot Product #if defined(TARGET_XARCH) @@ -128,9 +105,6 @@ SIMD_INTRINSIC("Dot", false, DotProduct, SIMD_INTRINSIC("Dot", false, DotProduct, "Dot", TYP_UNKNOWN, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_UNDEF, TYP_UNDEF}) #endif -// Select -SIMD_INTRINSIC("ConditionalSelect", false, Select, "Select", TYP_STRUCT, 3, {TYP_STRUCT, TYP_STRUCT, TYP_STRUCT}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) - // Cast SIMD_INTRINSIC("op_Explicit", false, Cast, "Cast", TYP_STRUCT, 1, {TYP_STRUCT, TYP_UNDEF, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_USHORT, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG}) diff --git a/src/coreclr/src/jit/vartype.h b/src/coreclr/src/jit/vartype.h index d69a75e5bfb54..e34ee7e5a8df8 100644 --- a/src/coreclr/src/jit/vartype.h +++ b/src/coreclr/src/jit/vartype.h @@ -113,6 +113,12 @@ inline bool varTypeIsUnsigned(T vt) return ((varTypeClassification[TypeGet(vt)] & (VTF_UNS)) != 0); } +template +inline bool varTypeIsSigned(T vt) +{ + return varTypeIsIntegralOrI(vt) && !varTypeIsUnsigned(vt); +} + // If "vt" is an unsigned integral type, returns the corresponding signed integral type, otherwise // return "vt". inline var_types varTypeUnsignedToSigned(var_types vt) @@ -140,6 +146,32 @@ inline var_types varTypeUnsignedToSigned(var_types vt) } } +// If "vt" is a signed integral type, returns the corresponding unsigned integral type, otherwise +// return "vt". +inline var_types varTypeSignedToUnsigned(var_types vt) +{ + if (varTypeIsSigned(vt)) + { + switch (vt) + { + case TYP_BYTE: + return TYP_UBYTE; + case TYP_SHORT: + return TYP_USHORT; + case TYP_INT: + return TYP_UINT; + case TYP_LONG: + return TYP_ULONG; + default: + unreached(); + } + } + else + { + return vt; + } +} + template inline bool varTypeIsFloating(T vt) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs index e27b5bf883d1c..4cfebe72cab69 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs @@ -84,12 +84,12 @@ public static Vector One } private static readonly Vector s_one = new Vector(GetOneValue()); - internal static Vector AllOnes + internal static Vector AllBitsSet { [Intrinsic] - get => s_allOnes; + get => s_allBitsSet; } - private static readonly Vector s_allOnes = new Vector(GetAllBitsSetValue()); + private static readonly Vector s_allBitsSet = new Vector(GetAllBitsSetValue()); #endregion Static Members #region Constructors @@ -478,11 +478,7 @@ public Vector(Span values) [MethodImpl(MethodImplOptions.AggressiveInlining)] public override readonly bool Equals(object? obj) { - if (!(obj is Vector)) - { - return false; - } - return Equals((Vector)obj); + return (obj is Vector other) && Equals(other); } /// @@ -493,130 +489,7 @@ public Vector(Span values) [Intrinsic] public readonly bool Equals(Vector other) { - if (Vector.IsHardwareAccelerated) - { - for (int g = 0; g < Count; g++) - { - if (!ScalarEquals(this[g], other[g])) - { - return false; - } - } - return true; - } - else - { - if (typeof(T) == typeof(byte)) - { - return - this.register.byte_0 == other.register.byte_0 - && this.register.byte_1 == other.register.byte_1 - && this.register.byte_2 == other.register.byte_2 - && this.register.byte_3 == other.register.byte_3 - && this.register.byte_4 == other.register.byte_4 - && this.register.byte_5 == other.register.byte_5 - && this.register.byte_6 == other.register.byte_6 - && this.register.byte_7 == other.register.byte_7 - && this.register.byte_8 == other.register.byte_8 - && this.register.byte_9 == other.register.byte_9 - && this.register.byte_10 == other.register.byte_10 - && this.register.byte_11 == other.register.byte_11 - && this.register.byte_12 == other.register.byte_12 - && this.register.byte_13 == other.register.byte_13 - && this.register.byte_14 == other.register.byte_14 - && this.register.byte_15 == other.register.byte_15; - } - else if (typeof(T) == typeof(sbyte)) - { - return - this.register.sbyte_0 == other.register.sbyte_0 - && this.register.sbyte_1 == other.register.sbyte_1 - && this.register.sbyte_2 == other.register.sbyte_2 - && this.register.sbyte_3 == other.register.sbyte_3 - && this.register.sbyte_4 == other.register.sbyte_4 - && this.register.sbyte_5 == other.register.sbyte_5 - && this.register.sbyte_6 == other.register.sbyte_6 - && this.register.sbyte_7 == other.register.sbyte_7 - && this.register.sbyte_8 == other.register.sbyte_8 - && this.register.sbyte_9 == other.register.sbyte_9 - && this.register.sbyte_10 == other.register.sbyte_10 - && this.register.sbyte_11 == other.register.sbyte_11 - && this.register.sbyte_12 == other.register.sbyte_12 - && this.register.sbyte_13 == other.register.sbyte_13 - && this.register.sbyte_14 == other.register.sbyte_14 - && this.register.sbyte_15 == other.register.sbyte_15; - } - else if (typeof(T) == typeof(ushort)) - { - return - this.register.uint16_0 == other.register.uint16_0 - && this.register.uint16_1 == other.register.uint16_1 - && this.register.uint16_2 == other.register.uint16_2 - && this.register.uint16_3 == other.register.uint16_3 - && this.register.uint16_4 == other.register.uint16_4 - && this.register.uint16_5 == other.register.uint16_5 - && this.register.uint16_6 == other.register.uint16_6 - && this.register.uint16_7 == other.register.uint16_7; - } - else if (typeof(T) == typeof(short)) - { - return - this.register.int16_0 == other.register.int16_0 - && this.register.int16_1 == other.register.int16_1 - && this.register.int16_2 == other.register.int16_2 - && this.register.int16_3 == other.register.int16_3 - && this.register.int16_4 == other.register.int16_4 - && this.register.int16_5 == other.register.int16_5 - && this.register.int16_6 == other.register.int16_6 - && this.register.int16_7 == other.register.int16_7; - } - else if (typeof(T) == typeof(uint)) - { - return - this.register.uint32_0 == other.register.uint32_0 - && this.register.uint32_1 == other.register.uint32_1 - && this.register.uint32_2 == other.register.uint32_2 - && this.register.uint32_3 == other.register.uint32_3; - } - else if (typeof(T) == typeof(int)) - { - return - this.register.int32_0 == other.register.int32_0 - && this.register.int32_1 == other.register.int32_1 - && this.register.int32_2 == other.register.int32_2 - && this.register.int32_3 == other.register.int32_3; - } - else if (typeof(T) == typeof(ulong)) - { - return - this.register.uint64_0 == other.register.uint64_0 - && this.register.uint64_1 == other.register.uint64_1; - } - else if (typeof(T) == typeof(long)) - { - return - this.register.int64_0 == other.register.int64_0 - && this.register.int64_1 == other.register.int64_1; - } - else if (typeof(T) == typeof(float)) - { - return - this.register.single_0 == other.register.single_0 - && this.register.single_1 == other.register.single_1 - && this.register.single_2 == other.register.single_2 - && this.register.single_3 == other.register.single_3; - } - else if (typeof(T) == typeof(double)) - { - return - this.register.double_0 == other.register.double_0 - && this.register.double_1 == other.register.double_1; - } - else - { - throw new NotSupportedException(SR.Arg_TypeNotSupported); - } - } + return this == other; } /// @@ -1722,7 +1595,7 @@ public Vector(Span values) /// The one's complement vector. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector operator ~(Vector value) => - s_allOnes ^ value; + AllBitsSet ^ value; #endregion Bitwise Operators #region Logical Operators @@ -1734,8 +1607,133 @@ public Vector(Span values) /// True if all elements are equal; False otherwise. [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Vector left, Vector right) => - left.Equals(right); + public static bool operator ==(Vector left, Vector right) + { + if (Vector.IsHardwareAccelerated) + { + for (int g = 0; g < Count; g++) + { + if (!ScalarEquals(left[g], right[g])) + { + return false; + } + } + return true; + } + else + { + if (typeof(T) == typeof(byte)) + { + return + left.register.byte_0 == right.register.byte_0 + && left.register.byte_1 == right.register.byte_1 + && left.register.byte_2 == right.register.byte_2 + && left.register.byte_3 == right.register.byte_3 + && left.register.byte_4 == right.register.byte_4 + && left.register.byte_5 == right.register.byte_5 + && left.register.byte_6 == right.register.byte_6 + && left.register.byte_7 == right.register.byte_7 + && left.register.byte_8 == right.register.byte_8 + && left.register.byte_9 == right.register.byte_9 + && left.register.byte_10 == right.register.byte_10 + && left.register.byte_11 == right.register.byte_11 + && left.register.byte_12 == right.register.byte_12 + && left.register.byte_13 == right.register.byte_13 + && left.register.byte_14 == right.register.byte_14 + && left.register.byte_15 == right.register.byte_15; + } + else if (typeof(T) == typeof(sbyte)) + { + return + left.register.sbyte_0 == right.register.sbyte_0 + && left.register.sbyte_1 == right.register.sbyte_1 + && left.register.sbyte_2 == right.register.sbyte_2 + && left.register.sbyte_3 == right.register.sbyte_3 + && left.register.sbyte_4 == right.register.sbyte_4 + && left.register.sbyte_5 == right.register.sbyte_5 + && left.register.sbyte_6 == right.register.sbyte_6 + && left.register.sbyte_7 == right.register.sbyte_7 + && left.register.sbyte_8 == right.register.sbyte_8 + && left.register.sbyte_9 == right.register.sbyte_9 + && left.register.sbyte_10 == right.register.sbyte_10 + && left.register.sbyte_11 == right.register.sbyte_11 + && left.register.sbyte_12 == right.register.sbyte_12 + && left.register.sbyte_13 == right.register.sbyte_13 + && left.register.sbyte_14 == right.register.sbyte_14 + && left.register.sbyte_15 == right.register.sbyte_15; + } + else if (typeof(T) == typeof(ushort)) + { + return + left.register.uint16_0 == right.register.uint16_0 + && left.register.uint16_1 == right.register.uint16_1 + && left.register.uint16_2 == right.register.uint16_2 + && left.register.uint16_3 == right.register.uint16_3 + && left.register.uint16_4 == right.register.uint16_4 + && left.register.uint16_5 == right.register.uint16_5 + && left.register.uint16_6 == right.register.uint16_6 + && left.register.uint16_7 == right.register.uint16_7; + } + else if (typeof(T) == typeof(short)) + { + return + left.register.int16_0 == right.register.int16_0 + && left.register.int16_1 == right.register.int16_1 + && left.register.int16_2 == right.register.int16_2 + && left.register.int16_3 == right.register.int16_3 + && left.register.int16_4 == right.register.int16_4 + && left.register.int16_5 == right.register.int16_5 + && left.register.int16_6 == right.register.int16_6 + && left.register.int16_7 == right.register.int16_7; + } + else if (typeof(T) == typeof(uint)) + { + return + left.register.uint32_0 == right.register.uint32_0 + && left.register.uint32_1 == right.register.uint32_1 + && left.register.uint32_2 == right.register.uint32_2 + && left.register.uint32_3 == right.register.uint32_3; + } + else if (typeof(T) == typeof(int)) + { + return + left.register.int32_0 == right.register.int32_0 + && left.register.int32_1 == right.register.int32_1 + && left.register.int32_2 == right.register.int32_2 + && left.register.int32_3 == right.register.int32_3; + } + else if (typeof(T) == typeof(ulong)) + { + return + left.register.uint64_0 == right.register.uint64_0 + && left.register.uint64_1 == right.register.uint64_1; + } + else if (typeof(T) == typeof(long)) + { + return + left.register.int64_0 == right.register.int64_0 + && left.register.int64_1 == right.register.int64_1; + } + else if (typeof(T) == typeof(float)) + { + return + left.register.single_0 == right.register.single_0 + && left.register.single_1 == right.register.single_1 + && left.register.single_2 == right.register.single_2 + && left.register.single_3 == right.register.single_3; + } + else if (typeof(T) == typeof(double)) + { + return + left.register.double_0 == right.register.double_0 + && left.register.double_1 == right.register.double_1; + } + else + { + throw new NotSupportedException(SR.Arg_TypeNotSupported); + } + } + } /// /// Returns a boolean indicating whether any single pair of elements in the given vectors are not equal. diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.tt b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.tt index 86bd98984a947..b556656e918c4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.tt +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.tt @@ -89,12 +89,12 @@ namespace System.Numerics } private static readonly Vector s_one = new Vector(GetOneValue()); - internal static Vector AllOnes + internal static Vector AllBitsSet { [Intrinsic] - get => s_allOnes; + get => s_allBitsSet; } - private static readonly Vector s_allOnes = new Vector(GetAllBitsSetValue()); + private static readonly Vector s_allBitsSet = new Vector(GetAllBitsSetValue()); #endregion Static Members #region Constructors @@ -322,11 +322,7 @@ namespace System.Numerics [MethodImpl(MethodImplOptions.AggressiveInlining)] public override readonly bool Equals(object? obj) { - if (!(obj is Vector)) - { - return false; - } - return Equals((Vector)obj); + return (obj is Vector other) && Equals(other); } /// @@ -337,56 +333,7 @@ namespace System.Numerics [Intrinsic] public readonly bool Equals(Vector other) { - if (Vector.IsHardwareAccelerated) - { - for (int g = 0; g < Count; g++) - { - if (!ScalarEquals(this[g], other[g])) - { - return false; - } - } - return true; - } - else - { -<# - foreach (Type type in supportedTypes) - { -#> - <#=GenerateIfStatementHeader(type)#> - { - return -<# - for (int g = 0; g < GetNumFields(type, totalSize); g++) - { -#> -<# - if (g == 0) - { -#> - this.<#=GetRegisterFieldName(type, g)#> == other.<#=GetRegisterFieldName(type, g)#> -<# - } - else - { -#> - && this.<#=GetRegisterFieldName(type, g)#> == other.<#=GetRegisterFieldName(type, g)#><#=(g == (GetNumFields(type, totalSize) -1)) ? ";" : ""#> -<# - } -#> -<# - } -#> - } -<# - } -#> - else - { - throw new NotSupportedException(SR.Arg_TypeNotSupported); - } - } + return this == other; } /// @@ -884,7 +831,7 @@ namespace System.Numerics /// The one's complement vector. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector operator ~(Vector value) => - s_allOnes ^ value; + AllBitsSet ^ value; #endregion Bitwise Operators #region Logical Operators @@ -896,8 +843,59 @@ namespace System.Numerics /// True if all elements are equal; False otherwise. [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Vector left, Vector right) => - left.Equals(right); + public static bool operator ==(Vector left, Vector right) + { + if (Vector.IsHardwareAccelerated) + { + for (int g = 0; g < Count; g++) + { + if (!ScalarEquals(left[g], right[g])) + { + return false; + } + } + return true; + } + else + { +<# + foreach (Type type in supportedTypes) + { +#> + <#=GenerateIfStatementHeader(type)#> + { + return +<# + for (int g = 0; g < GetNumFields(type, totalSize); g++) + { +#> +<# + if (g == 0) + { +#> + left.<#=GetRegisterFieldName(type, g)#> == right.<#=GetRegisterFieldName(type, g)#> +<# + } + else + { +#> + && left.<#=GetRegisterFieldName(type, g)#> == right.<#=GetRegisterFieldName(type, g)#><#=(g == (GetNumFields(type, totalSize) -1)) ? ";" : ""#> +<# + } +#> +<# + } +#> + } +<# + } +#> + else + { + throw new NotSupportedException(SR.Arg_TypeNotSupported); + } + } + } /// /// Returns a boolean indicating whether any single pair of elements in the given vectors are not equal. diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs index 38b572207d916..cee4a0e4ca66a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs @@ -65,9 +65,7 @@ public static Vector2 One [MethodImpl(MethodImplOptions.AggressiveInlining)] public override readonly bool Equals(object? obj) { - if (!(obj is Vector2)) - return false; - return Equals((Vector2)obj); + return (obj is Vector2 other) && Equals(other); } /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2_Intrinsics.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2_Intrinsics.cs index 27d3469bfb92c..b776c5d0a3cad 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2_Intrinsics.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2_Intrinsics.cs @@ -91,7 +91,7 @@ public Vector2(float x, float y) [Intrinsic] public readonly bool Equals(Vector2 other) { - return this.X == other.X && this.Y == other.Y; + return this == other; } #endregion Public Instance Methods @@ -275,7 +275,8 @@ public static Vector2 SquareRoot(Vector2 value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Vector2 left, Vector2 right) { - return left.Equals(right); + return left.X == right.X && + left.Y == right.Y; } /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs index af110ffcc56d5..1ca945caa5bf5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3.cs @@ -70,9 +70,7 @@ public static Vector3 One [MethodImpl(MethodImplOptions.AggressiveInlining)] public override readonly bool Equals(object? obj) { - if (!(obj is Vector3)) - return false; - return Equals((Vector3)obj); + return (obj is Vector3 other) && Equals(other); } /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3_Intrinsics.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3_Intrinsics.cs index df32e8331d70c..3ff9a8aa6525a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3_Intrinsics.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector3_Intrinsics.cs @@ -106,9 +106,7 @@ public Vector3(float x, float y, float z) [Intrinsic] public readonly bool Equals(Vector3 other) { - return X == other.X && - Y == other.Y && - Z == other.Z; + return this == other; } #endregion Public Instance Methods @@ -294,9 +292,9 @@ public static Vector3 SquareRoot(Vector3 value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Vector3 left, Vector3 right) { - return (left.X == right.X && - left.Y == right.Y && - left.Z == right.Z); + return left.X == right.X && + left.Y == right.Y && + left.Z == right.Z; } /// @@ -309,9 +307,7 @@ public static Vector3 SquareRoot(Vector3 value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(Vector3 left, Vector3 right) { - return (left.X != right.X || - left.Y != right.Y || - left.Z != right.Z); + return !(left == right); } #endregion Public Static Operators } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.cs index 45a9f42264b5e..c6dc6a8de8c4f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4.cs @@ -73,9 +73,7 @@ public static Vector4 One [MethodImpl(MethodImplOptions.AggressiveInlining)] public override readonly bool Equals(object? obj) { - if (!(obj is Vector4)) - return false; - return Equals((Vector4)obj); + return (obj is Vector4 other) && Equals(other); } /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4_Intrinsics.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4_Intrinsics.cs index 70d692457e1a5..4e95120c244c9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4_Intrinsics.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector4_Intrinsics.cs @@ -136,10 +136,7 @@ public Vector4(Vector3 value, float w) [Intrinsic] public readonly bool Equals(Vector4 other) { - return this.X == other.X - && this.Y == other.Y - && this.Z == other.Z - && this.W == other.W; + return this == other; } #endregion Public Instance Methods @@ -329,7 +326,10 @@ public static Vector4 SquareRoot(Vector4 value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Vector4 left, Vector4 right) { - return left.Equals(right); + return left.X == right.X + && left.Y == right.Y + && left.Z == right.Z + && left.W == right.W; } /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_Operations.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_Operations.cs index f16d1c4fc5777..4d97d1ad70caa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_Operations.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_Operations.cs @@ -230,7 +230,7 @@ public static Vector LessThan(Vector left, Vector right) public static bool LessThanAll(Vector left, Vector right) where T : struct { Vector cond = (Vector)Vector.LessThan(left, right); - return cond.Equals(Vector.AllOnes); + return cond.Equals(Vector.AllBitsSet); } /// @@ -328,7 +328,7 @@ public static Vector LessThanOrEqual(Vector left, Vector r public static bool LessThanOrEqualAll(Vector left, Vector right) where T : struct { Vector cond = (Vector)Vector.LessThanOrEqual(left, right); - return cond.Equals(Vector.AllOnes); + return cond.Equals(Vector.AllBitsSet); } /// @@ -427,7 +427,7 @@ public static Vector GreaterThan(Vector left, Vector right) public static bool GreaterThanAll(Vector left, Vector right) where T : struct { Vector cond = (Vector)Vector.GreaterThan(left, right); - return cond.Equals(Vector.AllOnes); + return cond.Equals(Vector.AllBitsSet); } /// @@ -526,7 +526,7 @@ public static Vector GreaterThanOrEqual(Vector left, Vector(Vector left, Vector right) where T : struct { Vector cond = (Vector)Vector.GreaterThanOrEqual(left, right); - return cond.Equals(Vector.AllOnes); + return cond.Equals(Vector.AllBitsSet); } /// From c44dc40b763b7c74012622a0a6120cd8ffa35ce4 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 22 May 2020 00:19:46 -0400 Subject: [PATCH 333/420] Use socketpair to implement Process.Start redirection (#34861) * Use socketpair to implement Process.Start redirection Today on Unix, we create an anonymous pipe via pipe/pipe2 to be used for stdin/stdout/stderr on processes created by Process.Start. We then wrap the resulting file descriptors with FileStreams to hand out via Process.StandardInput/Output/Error. This has a few issues, however. Any async operations on the resulting stream (or wrapping stream reader) will actually be async-over-sync, and that in turn means that a) any async read will end up blocking a thread pool thread until it's satisified, and b) the operation isn't cancelable. The implications of (b) are obvious, and the problem with (a) is that code which launches a bunch of processes and uses BeginOutput/ErrorReadLine or the like will end up blocking a bunch of thread pool threads. This change replaces the pipe/pipe2 calls with socketpair calls, and instead of wrapping the resulting file descriptors with FileStream, wraps them in Sockets and NetworkStreams. This gives us the full capabilities of the networking stack, which fully supports asynchronous and cancelable reads and writes. * Try to fix macOS failures with socketpair --- .../Native/Unix/System.Native/pal_process.c | 50 ++++++++++++----- .../src/System.Diagnostics.Process.csproj | 1 + .../src/System/Diagnostics/Process.Unix.cs | 12 ++-- .../tests/ProcessStreamReadTests.cs | 36 ++++++++++++ .../src/System/Net/Sockets/Socket.cs | 55 +++++++++++-------- 5 files changed, 112 insertions(+), 42 deletions(-) diff --git a/src/libraries/Native/Unix/System.Native/pal_process.c b/src/libraries/Native/Unix/System.Native/pal_process.c index 2824eb05073e3..4b640ceef6fcf 100644 --- a/src/libraries/Native/Unix/System.Native/pal_process.c +++ b/src/libraries/Native/Unix/System.Native/pal_process.c @@ -21,9 +21,8 @@ #if HAVE_CRT_EXTERNS_H #include #endif -#if HAVE_PIPE2 #include -#endif +#include #include #if HAVE_SCHED_SETAFFINITY || HAVE_SCHED_GETAFFINITY @@ -48,7 +47,7 @@ c_static_assert(PAL_PRIO_PROCESS == (int)PRIO_PROCESS); c_static_assert(PAL_PRIO_PGRP == (int)PRIO_PGRP); c_static_assert(PAL_PRIO_USER == (int)PRIO_USER); -#if !HAVE_PIPE2 +#ifndef SOCK_CLOEXEC static pthread_mutex_t ProcessCreateLock = PTHREAD_MUTEX_INITIALIZER; #endif @@ -183,6 +182,31 @@ static int SetGroups(uint32_t* userGroups, int32_t userGroupsLength, uint32_t* p return rv; } +static int32_t SocketPair(int32_t sv[2]) +{ + int32_t result; + + int type = SOCK_STREAM; +#ifdef SOCK_CLOEXEC + type |= SOCK_CLOEXEC; +#endif + + while ((result = socketpair(AF_UNIX, type, 0, sv)) < 0 && errno == EINTR); + +#ifndef SOCK_CLOEXEC + if (result == 0) + { + while ((result = fcntl(sv[READ_END_OF_PIPE], F_SETFD, FD_CLOEXEC)) < 0 && errno == EINTR); + if (result == 0) + { + while ((result = fcntl(sv[WRITE_END_OF_PIPE], F_SETFD, FD_CLOEXEC)) < 0 && errno == EINTR); + } + } +#endif + + return result; +} + int32_t SystemNative_ForkAndExecProcess(const char* filename, char* const argv[], char* const envp[], @@ -201,7 +225,7 @@ int32_t SystemNative_ForkAndExecProcess(const char* filename, int32_t* stderrFd) { #if HAVE_FORK -#if !HAVE_PIPE2 +#ifndef SOCK_CLOEXEC bool haveProcessCreateLock = false; #endif bool success = true; @@ -257,11 +281,11 @@ int32_t SystemNative_ForkAndExecProcess(const char* filename, goto done; } -#if !HAVE_PIPE2 - // We do not have pipe2(); take the lock to emulate it race free. - // If another process were to be launched between the pipe creation and the fcntl call to set CLOEXEC on it, that - // file descriptor will be inherited into the other child process, eventually causing a deadlock either in the loop - // below that waits for that pipe to be closed or in StreamReader.ReadToEnd() in the calling code. +#ifndef SOCK_CLOEXEC + // We do not have SOCK_CLOEXEC; take the lock to emulate it race free. + // If another process were to be launched between the socket creation and the fcntl call to set CLOEXEC on it, that + // file descriptor would be inherited into the other child process, eventually causing a deadlock either in the loop + // below that waits for that socket to be closed or in StreamReader.ReadToEnd() in the calling code. if (pthread_mutex_lock(&ProcessCreateLock) != 0) { // This check is pretty much just checking for trashed memory. @@ -273,9 +297,9 @@ int32_t SystemNative_ForkAndExecProcess(const char* filename, // Open pipes for any requests to redirect stdin/stdout/stderr and set the // close-on-exec flag to the pipe file descriptors. - if ((redirectStdin && SystemNative_Pipe(stdinFds, PAL_O_CLOEXEC) != 0) || - (redirectStdout && SystemNative_Pipe(stdoutFds, PAL_O_CLOEXEC) != 0) || - (redirectStderr && SystemNative_Pipe(stderrFds, PAL_O_CLOEXEC) != 0)) + if ((redirectStdin && SocketPair(stdinFds) != 0) || + (redirectStdout && SocketPair(stdoutFds) != 0) || + (redirectStderr && SocketPair(stderrFds) != 0)) { success = false; goto done; @@ -426,7 +450,7 @@ int32_t SystemNative_ForkAndExecProcess(const char* filename, *stderrFd = stderrFds[READ_END_OF_PIPE]; done:; -#if !HAVE_PIPE2 +#ifndef SOCK_CLOEXEC if (haveProcessCreateLock) { pthread_mutex_unlock(&ProcessCreateLock); diff --git a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj index ffe15beea64d1..33d388e4441a4 100644 --- a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj +++ b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj @@ -340,6 +340,7 @@ + diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs index 129963c07793c..29ec30ccdd885 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.IO; +using System.Net.Sockets; using System.Security; using System.Text; using System.Threading; @@ -761,16 +762,15 @@ internal static TimeSpan TicksToTimeSpan(double ticks) return TimeSpan.FromSeconds(ticks / (double)ticksPerSecond); } - /// Opens a stream around the specified file descriptor and with the specified access. - /// The file descriptor. + /// Opens a stream around the specified socket file descriptor and with the specified access. + /// The socket file descriptor. /// The access mode. /// The opened stream. - private static FileStream OpenStream(int fd, FileAccess access) + private static Stream OpenStream(int fd, FileAccess access) { Debug.Assert(fd >= 0); - return new FileStream( - new SafeFileHandle((IntPtr)fd, ownsHandle: true), - access, StreamBufferSize, isAsync: false); + var socket = new Socket(new SafeSocketHandle((IntPtr)fd, ownsHandle: true)); + return new NetworkStream(socket, access, ownsSocket: true); } /// Parses a command-line argument string into a list of arguments. diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessStreamReadTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessStreamReadTests.cs index 8fac2af7d9b85..0fb4160d7eacb 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessStreamReadTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessStreamReadTests.cs @@ -314,6 +314,42 @@ async private Task WaitPipeSignal(PipeStream pipe, int millisecond) } } + [PlatformSpecific(~TestPlatforms.Windows)] // currently on Windows these operations async-over-sync on Windows + [Fact] + public async Task ReadAsync_OutputStreams_Cancel_RespondsQuickly() + { + Process p = CreateProcessLong(); + try + { + p.StartInfo.RedirectStandardOutput = true; + p.StartInfo.RedirectStandardError = true; + Assert.True(p.Start()); + + using (var cts = new CancellationTokenSource()) + { + ValueTask vt = p.StandardOutput.ReadAsync(new char[1].AsMemory(), cts.Token); + await Task.Delay(1); + Assert.False(vt.IsCompleted); + cts.Cancel(); + await Assert.ThrowsAnyAsync(async () => await vt); + } + + using (var cts = new CancellationTokenSource()) + { + ValueTask vt = p.StandardError.ReadAsync(new char[1].AsMemory(), cts.Token); + await Task.Delay(1); + Assert.False(vt.IsCompleted); + cts.Cancel(); + await Assert.ThrowsAnyAsync(async () => await vt); + } + } + finally + { + p.Kill(); + p.Dispose(); + } + } + [Fact] public void TestSyncStreams() { diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index 6f548723ecfa3..e307dc4d6812b 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -188,36 +188,45 @@ private unsafe Socket(SafeSocketHandle handle, bool loadPropertiesFromHandle) { try { - // Local and Remote EP may be different sizes for something like UDS. + // Local and remote end points may be different sizes for protocols like Unix Domain Sockets. bufferLength = buffer.Length; - if (SocketPal.GetPeerName(handle, buffer, ref bufferLength) != SocketError.Success) + switch (SocketPal.GetPeerName(handle, buffer, ref bufferLength)) { - return; - } + case SocketError.Success: + switch (_addressFamily) + { + case AddressFamily.InterNetwork: + _remoteEndPoint = new IPEndPoint( + new IPAddress((long)SocketAddressPal.GetIPv4Address(buffer.Slice(0, bufferLength)) & 0x0FFFFFFFF), + SocketAddressPal.GetPort(buffer)); + break; + + case AddressFamily.InterNetworkV6: + Span address = stackalloc byte[IPAddressParserStatics.IPv6AddressBytes]; + SocketAddressPal.GetIPv6Address(buffer.Slice(0, bufferLength), address, out uint scope); + _remoteEndPoint = new IPEndPoint( + new IPAddress(address, scope), + SocketAddressPal.GetPort(buffer)); + break; + + case AddressFamily.Unix: + socketAddress = new Internals.SocketAddress(_addressFamily, buffer.Slice(0, bufferLength)); + _remoteEndPoint = new UnixDomainSocketEndPoint(IPEndPointExtensions.GetNetSocketAddress(socketAddress)); + break; + } - switch (_addressFamily) - { - case AddressFamily.InterNetwork: - _remoteEndPoint = new IPEndPoint( - new IPAddress((long)SocketAddressPal.GetIPv4Address(buffer.Slice(0, bufferLength)) & 0x0FFFFFFFF), - SocketAddressPal.GetPort(buffer)); - break; - - case AddressFamily.InterNetworkV6: - Span address = stackalloc byte[IPAddressParserStatics.IPv6AddressBytes]; - SocketAddressPal.GetIPv6Address(buffer.Slice(0, bufferLength), address, out uint scope); - _remoteEndPoint = new IPEndPoint( - new IPAddress(address, scope), - SocketAddressPal.GetPort(buffer)); + _isConnected = true; break; - case AddressFamily.Unix: - socketAddress = new Internals.SocketAddress(_addressFamily, buffer.Slice(0, bufferLength)); - _remoteEndPoint = new UnixDomainSocketEndPoint(IPEndPointExtensions.GetNetSocketAddress(socketAddress)); + case SocketError.InvalidArgument: + // On some OSes (e.g. macOS), EINVAL means the socket has been shut down. + // This can happen if, for example, socketpair was used and the parent + // process closed its copy of the child's socket. Since we don't know + // whether we're actually connected or not, err on the side of saying + // we're connected. + _isConnected = true; break; } - - _isConnected = true; } catch { } } From a593764e602af4853761ee1067f7628255950f24 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 21 May 2020 21:37:07 -0700 Subject: [PATCH 334/420] Extract shared functionality to a TryRemoveCastIfPresent method (#36837) --- src/coreclr/src/jit/lower.h | 29 +++++++++++++++++++++++++++++ src/coreclr/src/jit/lowerxarch.cpp | 29 ++--------------------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/coreclr/src/jit/lower.h b/src/coreclr/src/jit/lower.h index 91d5561d52fc8..0582cfe61e5d6 100644 --- a/src/coreclr/src/jit/lower.h +++ b/src/coreclr/src/jit/lower.h @@ -460,6 +460,35 @@ class Lowering final : public Phase } #endif // FEATURE_HW_INTRINSICS + //---------------------------------------------------------------------------------------------- + // TryRemoveCastIfPresent: Removes op it is a cast operation and the size of its input is at + // least the size of expectedType + // + // Arguments: + // expectedType - The expected type of the cast operation input if it is to be removed + // op - The tree to remove if it is a cast op whose input is at least the size of expectedType + // + // Returns: + // op if it was not a cast node or if its input is not at least the size of expected type; + // Otherwise, it returns the underlying operation that was being casted + GenTree* TryRemoveCastIfPresent(var_types expectedType, GenTree* op) + { + if (!op->OperIs(GT_CAST)) + { + return op; + } + + GenTree* castOp = op->AsCast()->CastOp(); + + if (genTypeSize(castOp->gtType) >= genTypeSize(expectedType)) + { + BlockRange().Remove(op); + return castOp; + } + + return op; + } + // Utility functions public: static bool IndirsAreEquivalent(GenTree* pTreeA, GenTree* pTreeB); diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index db5617b4f1430..b2c77ffb15569 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -960,25 +960,13 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) assert(HWIntrinsicInfo::lookupNumArgs(node) == 3); GenTreeArgList* argList = node->gtOp1->AsArgList(); - GenTree* op2 = argList->Rest()->Current(); - - if (!op2->OperIs(GT_CAST)) - { - break; - } // Insert takes either a 32-bit register or a memory operand. // In either case, only gtSIMDBaseType bits are read and so // widening or narrowing the operand may be unnecessary and it // can just be used directly. - GenTree* castOp = op2->AsCast()->CastOp(); - - if (genTypeSize(castOp->gtType) >= genTypeSize(node->gtSIMDBaseType)) - { - BlockRange().Remove(op2); - argList->Rest()->gtOp1 = castOp; - } + argList->Rest()->gtOp1 = TryRemoveCastIfPresent(node->gtSIMDBaseType, argList->Rest()->gtOp1); break; } @@ -986,25 +974,12 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node) { assert(HWIntrinsicInfo::lookupNumArgs(node) == 2); - GenTree* op2 = node->gtOp2; - - if (!op2->OperIs(GT_CAST)) - { - break; - } - // Crc32 takes either a bit register or a memory operand. // In either case, only gtType bits are read and so widening // or narrowing the operand may be unnecessary and it can // just be used directly. - GenTree* castOp = op2->AsCast()->CastOp(); - - if (genTypeSize(castOp->gtType) >= genTypeSize(node->gtType)) - { - BlockRange().Remove(op2); - node->gtOp2 = castOp; - } + node->gtOp2 = TryRemoveCastIfPresent(node->gtType, node->gtOp2); break; } From 144e5145453ac3885ac20bc1f1f2641523c6fcea Mon Sep 17 00:00:00 2001 From: Ivan Diaz Sanchez Date: Thu, 21 May 2020 22:43:08 -0700 Subject: [PATCH 335/420] Added CreateDelegate overloads to MethodInfo (#36680) * Added generic overloads for MethodInfo.CreateDelegate<>() * Added full support of CreateDelegate and the necessary tests. * Refactored to apply the new CreateDelegate overloads as necessary throughout runtime. * Reverted Linq.Expressions changes and fully qualified Delegate to System.Delegate --- .../System/Diagnostics/StackFrameHelper.cs | 2 +- .../Serialization/SerializationGuard.cs | 2 +- .../ComInterop/ComRuntimeHelpers.cs | 4 +- .../RuntimeBinder/RuntimeBinderExtensions.cs | 2 +- .../src/System/Data/SQLTypes/SqlXml.cs | 2 +- .../src/System/AppDomain.cs | 4 +- .../Environment.GetFolderPathCore.Unix.cs | 2 +- .../src/System/Reflection/MethodInfo.cs | 6 +++ .../Runtime/Serialization/ReflectionReader.cs | 4 +- .../tests/MethodInfoTests.cs | 48 +++++++++++++++++++ .../Runtime/Serialization/ObjectManager.cs | 4 +- .../Serialization/SerializationEventsCache.cs | 2 +- .../System.Runtime/ref/System.Runtime.cs | 2 + .../Security/Cryptography/XmlKeyHelper.cs | 4 +- .../Cryptography/CryptoConfigForwarder.cs | 2 +- .../CompiledRegexRunnerFactory.cs | 4 +- 16 files changed, 75 insertions(+), 19 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/StackFrameHelper.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/StackFrameHelper.cs index 20a0c57492d8a..41b1dd72e0102 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/StackFrameHelper.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/StackFrameHelper.cs @@ -131,7 +131,7 @@ internal void InitializeSourceInfo(int iSkip, bool fNeedFileInfo, Exception? exc object? target = Activator.CreateInstance(symbolsType); // Create an instance delegate for the GetSourceLineInfo method - GetSourceLineInfoDelegate getSourceLineInfo = (GetSourceLineInfoDelegate)symbolsMethodInfo.CreateDelegate(typeof(GetSourceLineInfoDelegate), target); + GetSourceLineInfoDelegate getSourceLineInfo = symbolsMethodInfo.CreateDelegate(target); // We could race with another thread. It doesn't matter if we win or lose, the losing instance will be GC'ed and all threads including this one will // use the winning instance diff --git a/src/libraries/Common/src/System/Runtime/Serialization/SerializationGuard.cs b/src/libraries/Common/src/System/Runtime/Serialization/SerializationGuard.cs index 3fa5f3f49c3c2..35614ed285774 100644 --- a/src/libraries/Common/src/System/Runtime/Serialization/SerializationGuard.cs +++ b/src/libraries/Common/src/System/Runtime/Serialization/SerializationGuard.cs @@ -26,7 +26,7 @@ internal static partial class SerializationGuard if (throwMethod != null) { - throwIfDeserializationInProgressDelegate = (ThrowIfDeserializationInProgressWithSwitchDel)throwMethod.CreateDelegate(typeof(ThrowIfDeserializationInProgressWithSwitchDel)); + throwIfDeserializationInProgressDelegate = throwMethod.CreateDelegate(); } return throwIfDeserializationInProgressDelegate; diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ComRuntimeHelpers.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ComRuntimeHelpers.cs index 9e9ade68ea2bf..11bfce9b08dcd 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ComRuntimeHelpers.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ComRuntimeHelpers.cs @@ -399,7 +399,7 @@ private static IUnknownReleaseDelegate Create_IUnknownRelease() method.Emit(OpCodes.Ret); - return (IUnknownReleaseDelegate)dm.CreateDelegate(typeof(IUnknownReleaseDelegate)); + return dm.CreateDelegate(); } internal static readonly IntPtr s_nullInterfaceId = GetNullInterfaceId(); @@ -539,7 +539,7 @@ private static IDispatchInvokeDelegate Create_IDispatchInvoke(bool returnResult) method.EmitCalli(OpCodes.Calli, CallingConvention.Winapi, typeof(int), invokeParamTypes); method.Emit(OpCodes.Ret); - return (IDispatchInvokeDelegate)dm.CreateDelegate(typeof(IDispatchInvokeDelegate)); + return dm.CreateDelegate(); } #endregion diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinderExtensions.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinderExtensions.cs index e08bc7d9b66f2..3cc1e52fb30b4 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinderExtensions.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/RuntimeBinderExtensions.cs @@ -262,7 +262,7 @@ private static bool IsTypeParameterEquivalentToTypeInst(this Type typeParam, Typ modifiers: null); if (apiMethod != null) { - Func apiDelegate = (Func)(apiMethod.CreateDelegate(typeof(Func))); + Func apiDelegate = apiMethod.CreateDelegate>(); try { bool result = apiDelegate(m1, m2); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SqlXml.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SqlXml.cs index 76db4a1017815..02baf8afcd2d6 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SqlXml.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SqlXml.cs @@ -123,7 +123,7 @@ internal static XmlReader CreateSqlXmlReader(Stream stream, bool closeInput = fa { Debug.Assert(CreateSqlReaderMethodInfo != null, "MethodInfo reference for XmlReader.CreateSqlReader should not be null."); - return (Func)CreateSqlReaderMethodInfo.CreateDelegate(typeof(Func)); + return CreateSqlReaderMethodInfo.CreateDelegate>(); } private static MethodInfo CreateSqlReaderMethodInfo diff --git a/src/libraries/System.Private.CoreLib/src/System/AppDomain.cs b/src/libraries/System.Private.CoreLib/src/System/AppDomain.cs index 7cd1e8e97a4e8..08f52df721fa6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/AppDomain.cs +++ b/src/libraries/System.Private.CoreLib/src/System/AppDomain.cs @@ -402,7 +402,7 @@ public void SetThreadPrincipal(IPrincipal principal) // Don't throw PNSE if null like for WindowsPrincipal as UnauthenticatedPrincipal should // be available on all platforms. Volatile.Write(ref s_getUnauthenticatedPrincipal, - (Func)mi.CreateDelegate(typeof(Func))); + mi.CreateDelegate>()); } principal = s_getUnauthenticatedPrincipal(); @@ -418,7 +418,7 @@ public void SetThreadPrincipal(IPrincipal principal) throw new PlatformNotSupportedException(SR.PlatformNotSupported_Principal); } Volatile.Write(ref s_getWindowsPrincipal, - (Func)mi.CreateDelegate(typeof(Func))); + mi.CreateDelegate>()); } principal = s_getWindowsPrincipal(); diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs index ad37bba3746e5..385b578890402 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs @@ -46,7 +46,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio { Type dirType = Type.GetType("System.IO.Directory, System.IO.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: true)!; MethodInfo mi = dirType.GetTypeInfo().GetDeclaredMethod("CreateDirectory")!; - return (Func)mi.CreateDelegate(typeof(Func)); + return mi.CreateDelegate>(); }); createDirectory(path); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.cs index 622ba56e44fe6..12412fe536eeb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.cs @@ -26,6 +26,12 @@ public abstract partial class MethodInfo : MethodBase public virtual Delegate CreateDelegate(Type delegateType) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); } public virtual Delegate CreateDelegate(Type delegateType, object? target) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); } + /// Creates a delegate of the given type 'T' from this method. + public T CreateDelegate() where T : Delegate => (T)CreateDelegate(typeof(T)); + + /// Creates a delegate of the given type 'T' with the specified target from this method. + public T CreateDelegate(object? target) where T : Delegate => (T)CreateDelegate(typeof(T), target); + public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ReflectionReader.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ReflectionReader.cs index d9d9277f33485..67f0afc57a017 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ReflectionReader.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ReflectionReader.cs @@ -502,8 +502,8 @@ private CollectionSetItemDelegate GetCollectionSetItemDelegate(CollectionData { Type keyType = collectionContract.ItemType.GenericTypeArguments[0]; Type valueType = collectionContract.ItemType.GenericTypeArguments[1]; - Func objectToKeyValuePairGetKey = (Func)s_objectToKeyValuePairGetKey.MakeGenericMethod(keyType, valueType).CreateDelegate(typeof(Func)); - Func objectToKeyValuePairGetValue = (Func)s_objectToKeyValuePairGetValue.MakeGenericMethod(keyType, valueType).CreateDelegate(typeof(Func)); + Func objectToKeyValuePairGetKey = s_objectToKeyValuePairGetKey.MakeGenericMethod(keyType, valueType).CreateDelegate>(); + Func objectToKeyValuePairGetValue = s_objectToKeyValuePairGetValue.MakeGenericMethod(keyType, valueType).CreateDelegate>(); if (collectionContract.Kind == CollectionKind.GenericDictionary) { diff --git a/src/libraries/System.Reflection/tests/MethodInfoTests.cs b/src/libraries/System.Reflection/tests/MethodInfoTests.cs index 9906b28601ffc..37e16ac8748cf 100644 --- a/src/libraries/System.Reflection/tests/MethodInfoTests.cs +++ b/src/libraries/System.Reflection/tests/MethodInfoTests.cs @@ -26,21 +26,41 @@ public void CreateDelegate_PublicMethod() object returnValue = ((Delegate_TC_Int)methodDelegate).DynamicInvoke(new object[] { baseClass }); Assert.Equal(baseClass.VirtualMethod(), returnValue); + Delegate genMethodDelegate = virtualMethodInfo.CreateDelegate(); + object genReturnValue = genMethodDelegate.DynamicInvoke(new object[] { baseClass }); + Assert.Equal(returnValue, genReturnValue); + methodDelegate = privateInstanceMethodInfo.CreateDelegate(typeof(Delegate_TC_Int)); returnValue = ((Delegate_TC_Int)methodDelegate).DynamicInvoke(new object[] { baseClass }); Assert.Equal(21, returnValue); + genMethodDelegate = privateInstanceMethodInfo.CreateDelegate(); + genReturnValue = genMethodDelegate.DynamicInvoke(new object[] { baseClass }); + Assert.Equal(returnValue, genReturnValue); + methodDelegate = virtualMethodInfo.CreateDelegate(typeof(Delegate_Void_Int), baseClass); returnValue = ((Delegate_Void_Int)methodDelegate).DynamicInvoke(null); Assert.Equal(baseClass.VirtualMethod(), returnValue); + genMethodDelegate = virtualMethodInfo.CreateDelegate(baseClass); + genReturnValue = genMethodDelegate.DynamicInvoke(null); + Assert.Equal(returnValue, genReturnValue); + methodDelegate = publicStaticMethodInfo.CreateDelegate(typeof(Delegate_Str_Str)); returnValue = ((Delegate_Str_Str)methodDelegate).DynamicInvoke(new object[] { "85" }); Assert.Equal("85", returnValue); + genMethodDelegate = publicStaticMethodInfo.CreateDelegate(); + genReturnValue = genMethodDelegate.DynamicInvoke(new object[] { "85" }); + Assert.Equal(returnValue, genReturnValue); + methodDelegate = publicStaticMethodInfo.CreateDelegate(typeof(Delegate_Void_Str), "93"); returnValue = ((Delegate_Void_Str)methodDelegate).DynamicInvoke(null); Assert.Equal("93", returnValue); + + genMethodDelegate = publicStaticMethodInfo.CreateDelegate("93"); + genReturnValue = genMethodDelegate.DynamicInvoke(null); + Assert.Equal(returnValue, genReturnValue); } [Fact] @@ -57,9 +77,17 @@ public void CreateDelegate_InheritedMethod() object returnValue = ((Delegate_TC_Int)methodDelegate).DynamicInvoke(new object[] { testSubClass }); Assert.Equal(testSubClass.VirtualMethod(), returnValue); + Delegate genMethodDelegate = virtualMethodInfo.CreateDelegate(); + object genReturnValue = genMethodDelegate.DynamicInvoke(new object[] { testSubClass }); + Assert.Equal(returnValue, genReturnValue); + methodDelegate = virtualMethodInfo.CreateDelegate(typeof(Delegate_Void_Int), testSubClass); returnValue = ((Delegate_Void_Int)methodDelegate).DynamicInvoke(); Assert.Equal(testSubClass.VirtualMethod(), returnValue); + + genMethodDelegate = virtualMethodInfo.CreateDelegate(testSubClass); + genReturnValue = genMethodDelegate.DynamicInvoke(); + Assert.Equal(returnValue, genReturnValue); } [Fact] @@ -78,17 +106,33 @@ public void CreateDelegate_GenericMethod() object returnValue = ((Delegate_GC_T_T)methodDelegate).DynamicInvoke(new object[] { genericClass, "TestGeneric" }); Assert.Equal(genericClass.GenericMethod1("TestGeneric"), returnValue); + Delegate genMethodDelegate = miMethod1String.CreateDelegate>(); + object genReturnValue = genMethodDelegate.DynamicInvoke(new object[] { genericClass, "TestGeneric" }); + Assert.Equal(returnValue, genReturnValue); + methodDelegate = miMethod1String.CreateDelegate(typeof(Delegate_T_T), genericClass); returnValue = ((Delegate_T_T)methodDelegate).DynamicInvoke(new object[] { "TestGeneric" }); Assert.Equal(genericClass.GenericMethod1("TestGeneric"), returnValue); + genMethodDelegate = miMethod1String.CreateDelegate>(genericClass); + genReturnValue = genMethodDelegate.DynamicInvoke(new object[] { "TestGeneric" }); + Assert.Equal(returnValue, genReturnValue); + methodDelegate = miMethod2IntGeneric.CreateDelegate(typeof(Delegate_T_T)); returnValue = ((Delegate_T_T)methodDelegate).DynamicInvoke(new object[] { 58 }); Assert.Equal(58, returnValue); + genMethodDelegate = miMethod2IntGeneric.CreateDelegate>(); + genReturnValue = genMethodDelegate.DynamicInvoke(new object[] { 58 }); + Assert.Equal(returnValue, genReturnValue); + methodDelegate = miMethod2StringGeneric.CreateDelegate(typeof(Delegate_Void_T), "firstArg"); returnValue = ((Delegate_Void_T)methodDelegate).DynamicInvoke(); Assert.Equal("firstArg", returnValue); + + genMethodDelegate = miMethod2StringGeneric.CreateDelegate>("firstArg"); + genReturnValue = genMethodDelegate.DynamicInvoke(); + Assert.Equal(returnValue, genReturnValue); } [Fact] @@ -100,6 +144,10 @@ public void CreateDelegate_ValueTypeParameters() Delegate methodDelegate = miPublicStructMethod.CreateDelegate(typeof(Delegate_DateTime_Str)); object returnValue = ((Delegate_DateTime_Str)methodDelegate).DynamicInvoke(new object[] { testClass, null }); Assert.Equal(testClass.PublicStructMethod(new DateTime()), returnValue); + + Delegate genMethodDelegate = miPublicStructMethod.CreateDelegate(); + object genReturnValue = genMethodDelegate.DynamicInvoke(new object[] { testClass, null }); + Assert.Equal(returnValue, genReturnValue); } [Theory] diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/ObjectManager.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/ObjectManager.cs index 845a0686ad232..8570965d0272c 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/ObjectManager.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/ObjectManager.cs @@ -1614,9 +1614,9 @@ internal TypeLoadExceptionHolder(string? typeName) internal static class SerializationInfoExtensions { private static readonly Action s_updateValue = - (Action)typeof(SerializationInfo) + typeof(SerializationInfo) .GetMethod("UpdateValue", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)! - .CreateDelegate(typeof(Action)); + .CreateDelegate>(); public static void UpdateValue(this SerializationInfo si, string name, object value, Type type) => s_updateValue(si, name, value, type); diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/SerializationEventsCache.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/SerializationEventsCache.cs index bd194c39816dd..7eb55502786bb 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/SerializationEventsCache.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/SerializationEventsCache.cs @@ -82,7 +82,7 @@ private static void InvokeOnDelegate(object obj, StreamingContext context, List< { foreach (MethodInfo m in methods) { - SerializationEventHandler onDeserialized = (SerializationEventHandler)m.CreateDelegate(typeof(SerializationEventHandler), obj); + SerializationEventHandler onDeserialized = m.CreateDelegate(obj); handler = (SerializationEventHandler)Delegate.Combine(handler, onDeserialized); } } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 50ef98b9c7930..f84784e75b1d4 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -8124,6 +8124,8 @@ public abstract partial class MethodInfo : System.Reflection.MethodBase public abstract System.Reflection.ICustomAttributeProvider ReturnTypeCustomAttributes { get; } public virtual System.Delegate CreateDelegate(System.Type delegateType) { throw null; } public virtual System.Delegate CreateDelegate(System.Type delegateType, object? target) { throw null; } + public T CreateDelegate() where T : System.Delegate { throw null; } + public T CreateDelegate(object? target) where T : System.Delegate { throw null; } public override bool Equals(object? obj) { throw null; } public abstract System.Reflection.MethodInfo GetBaseDefinition(); public override System.Type[] GetGenericArguments() { throw null; } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/XmlKeyHelper.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/XmlKeyHelper.cs index 9012886b3ed08..a8d3460c1369b 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/XmlKeyHelper.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/XmlKeyHelper.cs @@ -267,12 +267,12 @@ private static class Functions { private static readonly Type s_xDocument = Type.GetType("System.Xml.Linq.XDocument, System.Private.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")!; private static readonly Func s_xDocumentCreate = - (Func)s_xDocument.GetMethod( + s_xDocument.GetMethod( "Parse", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(string) }, - null)!.CreateDelegate(typeof(Func)); + null)!.CreateDelegate>(); private static readonly PropertyInfo s_docRootProperty = s_xDocument.GetProperty("Root")!; private static readonly MethodInfo s_getElementsMethod = s_docRootProperty.PropertyType.GetMethod( "Elements", diff --git a/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/CryptoConfigForwarder.cs b/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/CryptoConfigForwarder.cs index c42440669f4b4..9e1055857753a 100644 --- a/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/CryptoConfigForwarder.cs +++ b/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/CryptoConfigForwarder.cs @@ -25,7 +25,7 @@ internal static class CryptoConfigForwarder throw new MissingMethodException(t.FullName, CreateFromNameMethodName); } - return (Func)createFromName.CreateDelegate(typeof(Func)); + return createFromName.CreateDelegate>(); } internal static object? CreateFromName(string name) => s_createFromName(name); diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/CompiledRegexRunnerFactory.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/CompiledRegexRunnerFactory.cs index 2d2d930e97548..e025fdf69f080 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/CompiledRegexRunnerFactory.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/CompiledRegexRunnerFactory.cs @@ -25,8 +25,8 @@ public CompiledRegexRunnerFactory(DynamicMethod goMethod, DynamicMethod findFirs protected internal override RegexRunner CreateInstance() => new CompiledRegexRunner( - _go ??= (Action)_goMethod.CreateDelegate(typeof(Action)), - _findFirstChar ??= (Func)_findFirstCharMethod.CreateDelegate(typeof(Func)), + _go ??= _goMethod.CreateDelegate>(), + _findFirstChar ??= _findFirstCharMethod.CreateDelegate>(), _trackcount); } } From eabb02503e5d1f8082f098b10d6d59329f076a31 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Fri, 22 May 2020 11:21:28 +0300 Subject: [PATCH 336/420] [mono] Fix MonoRunner.java - assets were not copied correctly (#36824) --- .../netcore/sample/Android/Program.csproj | 2 +- .../AndroidAppBuilder/ApkBuilder.cs | 15 ++--- .../Templates/MonoRunner.java | 60 +++++++++++-------- 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/src/mono/netcore/sample/Android/Program.csproj b/src/mono/netcore/sample/Android/Program.csproj index cb8ff0a7489a6..6f452e61dfede 100644 --- a/src/mono/netcore/sample/Android/Program.csproj +++ b/src/mono/netcore/sample/Android/Program.csproj @@ -60,7 +60,7 @@ - + diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs index 409cbb5224c21..511483a4bcb4d 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs @@ -80,6 +80,7 @@ public class ApkBuilder Directory.CreateDirectory(OutputDir); Directory.CreateDirectory(Path.Combine(OutputDir, "bin")); Directory.CreateDirectory(Path.Combine(OutputDir, "obj")); + Directory.CreateDirectory(Path.Combine(OutputDir, "assets-tozip")); Directory.CreateDirectory(Path.Combine(OutputDir, "assets")); var extensionsToIgnore = new List { ".so", ".a", ".gz" }; @@ -89,17 +90,13 @@ public class ApkBuilder extensionsToIgnore.Add(".dbg"); } - // Copy AppDir to OutputDir/assets (ignore native files) - Utils.DirectoryCopy(sourceDir, Path.Combine(OutputDir, "assets"), file => + // Copy AppDir to OutputDir/assets-tozip (ignore native files) + // these files then will be zipped and copied to apk/assets/assets.zip + Utils.DirectoryCopy(sourceDir, Path.Combine(OutputDir, "assets-tozip"), file => { string fileName = Path.GetFileName(file); string extension = Path.GetExtension(file); - if (file.Any(s => s >= 128)) - { - // non-ascii files/folders are not allowed - return false; - } if (extensionsToIgnore.Contains(extension)) { // ignore native files, those go to lib/%abi% @@ -124,6 +121,10 @@ public class ApkBuilder string keytool = "keytool"; string javac = "javac"; string cmake = "cmake"; + string zip = "zip"; + + Utils.RunProcess(zip, workingDir: Path.Combine(OutputDir, "assets-tozip"), args: "-r ../assets/assets.zip ."); + Directory.Delete(Path.Combine(OutputDir, "assets-tozip"), true); if (!File.Exists(androidJar)) throw new ArgumentException($"API level={BuildApiLevel} is not downloaded in Android SDK"); diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/MonoRunner.java b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/MonoRunner.java index 2323f83d46914..6cbf3147a0a91 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/MonoRunner.java +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/MonoRunner.java @@ -13,8 +13,8 @@ import android.util.Log; import android.view.View; import android.app.Activity; -import android.os.Bundle; import android.os.Environment; +import android.net.Uri; import java.io.File; import java.io.FileNotFoundException; @@ -22,6 +22,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.BufferedInputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; public class MonoRunner extends Instrumentation { @@ -43,13 +46,14 @@ public void onStart() { MonoRunner.inst = this; Context context = getContext(); - AssetManager am = context.getAssets(); String filesDir = context.getFilesDir().getAbsolutePath(); String cacheDir = context.getCacheDir().getAbsolutePath(); String docsDir = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath(); - copyAssetDir(am, "", filesDir); + // unzip libs and test files to filesDir + unzipAssets(context, filesDir, "assets.zip"); + Log.i("DOTNET", "initRuntime"); int retcode = initRuntime(filesDir, cacheDir, docsDir); runOnMainSync(new Runnable() { public void run() { @@ -62,34 +66,38 @@ public void run() { }); } - static void copyAssetDir(AssetManager am, String path, String outpath) { + static void unzipAssets(Context context, String toPath, String zipName) { + AssetManager assetManager = context.getAssets(); try { - String[] res = am.list(path); - for (int i = 0; i < res.length; ++i) { - String fromFile = res[i]; - String toFile = outpath + "/" + res[i]; - try { - InputStream fromStream = am.open(fromFile); - Log.w("DOTNET", "\tCOPYING " + fromFile + " to " + toFile); - copy(fromStream, new FileOutputStream(toFile)); - } catch (FileNotFoundException e) { - new File(toFile).mkdirs(); - copyAssetDir(am, fromFile, toFile); + InputStream inputStream = assetManager.open(zipName); + ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(inputStream)); + ZipEntry zipEntry; + byte[] buffer = new byte[4096]; + while ((zipEntry = zipInputStream.getNextEntry()) != null) { + String fileOrDirectory = zipEntry.getName(); + Uri.Builder builder = new Uri.Builder(); + builder.scheme("file"); + builder.appendPath(toPath); + builder.appendPath(fileOrDirectory); + String fullToPath = builder.build().getPath(); + if (zipEntry.isDirectory()) { + File directory = new File(fullToPath); + directory.mkdirs(); continue; } + Log.i("DOTNET", "Extracting asset to " + fullToPath); + int count = 0; + FileOutputStream fileOutputStream = new FileOutputStream(fullToPath); + while ((count = zipInputStream.read(buffer)) != -1) { + fileOutputStream.write(buffer, 0, count); + } + fileOutputStream.close(); + zipInputStream.closeEntry(); } + zipInputStream.close(); + } catch (IOException e) { + Log.e("DOTNET", e.getLocalizedMessage()); } - catch (Exception e) { - Log.w("DOTNET", "EXCEPTION", e); - } - } - - static void copy(InputStream in, OutputStream out) throws IOException { - byte[] buff = new byte [1024]; - for (int len = in.read(buff); len != -1; len = in.read(buff)) - out.write(buff, 0, len); - in.close(); - out.close(); } native int initRuntime(String libsDir, String cacheDir, String docsDir); From 2614887d8b5bfa55af757bb25f71f9f899c11071 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Fri, 22 May 2020 09:16:40 -0400 Subject: [PATCH 337/420] Move where wasm binaries are generated (#36781) This change shifts producing wasm binaries to the native dir so that they'll come over to the installer on CI. --- eng/liveBuilds.targets | 6 +++++- .../pkg/projects/netcoreapp/src/netcoreapp.depproj | 2 +- src/mono/wasm/Makefile | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/eng/liveBuilds.targets b/eng/liveBuilds.targets index 0101292cdf18a..83f8c41353d29 100644 --- a/eng/liveBuilds.targets +++ b/eng/liveBuilds.targets @@ -175,7 +175,7 @@ $(LibrariesAllBinArtifactsPath)*.dll; $(LibrariesAllBinArtifactsPath)*.pdb" IsNative="" /> - + diff --git a/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj b/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj index 339c8a26e3065..863f359bf3700 100644 --- a/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj +++ b/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj @@ -105,7 +105,7 @@ - + diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile index 6dc4699c7e429..e652422d1aef3 100644 --- a/src/mono/wasm/Makefile +++ b/src/mono/wasm/Makefile @@ -44,7 +44,7 @@ emsdk_env.sh: | provision-wasm MONO_OBJ_DIR=$(OBJDIR)/mono/Browser.wasm.$(CONFIG) MONO_INCLUDE_DIR=$(MONO_BIN_DIR)/include/mono-2.0 -BUILDS_BIN_DIR=$(MONO_BIN_DIR)/wasm/runtimes +BUILDS_BIN_DIR=$(SYS_NATIVE_DIR)/wasm/runtimes BUILDS_OBJ_DIR=$(MONO_OBJ_DIR)/wasm/runtimes MONO_LIBS = \ $(MONO_BIN_DIR)/{libmono-ee-interp.a,libmonosgen-2.0.a,libmono-ilgen.a,libmono-icall-table.a} \ From 0a8363e2c08759d22ac9d9dd2db280e4ed307e57 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Fri, 22 May 2020 08:23:35 -0500 Subject: [PATCH 338/420] Strip the ILLinkTrim.xml file from System.Security assemblies (#36864) Contributes to #35199 --- src/libraries/System.Private.CoreLib/src/System/AppDomain.cs | 3 +++ .../src/{ILLinkTrim.xml => ILLinkTrim_LibraryBuild.xml} | 0 .../src/{ILLinkTrim.xml => ILLinkTrim_LibraryBuild.xml} | 0 3 files changed, 3 insertions(+) rename src/libraries/System.Security.Claims/src/{ILLinkTrim.xml => ILLinkTrim_LibraryBuild.xml} (100%) rename src/libraries/System.Security.Principal.Windows/src/{ILLinkTrim.xml => ILLinkTrim_LibraryBuild.xml} (100%) diff --git a/src/libraries/System.Private.CoreLib/src/System/AppDomain.cs b/src/libraries/System.Private.CoreLib/src/System/AppDomain.cs index 08f52df721fa6..19164e5ce634c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/AppDomain.cs +++ b/src/libraries/System.Private.CoreLib/src/System/AppDomain.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.IO; using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Runtime.Loader; using System.Runtime.Remoting; @@ -386,6 +387,8 @@ public void SetThreadPrincipal(IPrincipal principal) return oh?.Unwrap(); } + [PreserveDependency("GetDefaultInstance", "System.Security.Principal.GenericPrincipal", "System.Security.Claims")] + [PreserveDependency("GetDefaultInstance", "System.Security.Principal.WindowsPrincipal", "System.Security.Principal.Windows")] internal IPrincipal? GetThreadPrincipal() { IPrincipal? principal = _defaultPrincipal; diff --git a/src/libraries/System.Security.Claims/src/ILLinkTrim.xml b/src/libraries/System.Security.Claims/src/ILLinkTrim_LibraryBuild.xml similarity index 100% rename from src/libraries/System.Security.Claims/src/ILLinkTrim.xml rename to src/libraries/System.Security.Claims/src/ILLinkTrim_LibraryBuild.xml diff --git a/src/libraries/System.Security.Principal.Windows/src/ILLinkTrim.xml b/src/libraries/System.Security.Principal.Windows/src/ILLinkTrim_LibraryBuild.xml similarity index 100% rename from src/libraries/System.Security.Principal.Windows/src/ILLinkTrim.xml rename to src/libraries/System.Security.Principal.Windows/src/ILLinkTrim_LibraryBuild.xml From 4d9a45f19d3e2a61ba9745d67e17b60bfbab3874 Mon Sep 17 00:00:00 2001 From: Gleb Balykov Date: Fri, 22 May 2020 16:24:00 +0300 Subject: [PATCH 339/420] Consider armel arch (#36872) --- eng/liveBuilds.targets | 1 + .../projects/netcoreapp/src/localnetcoreapp.override.targets | 3 +++ 2 files changed, 4 insertions(+) diff --git a/eng/liveBuilds.targets b/eng/liveBuilds.targets index 83f8c41353d29..38755cc50ae19 100644 --- a/eng/liveBuilds.targets +++ b/eng/liveBuilds.targets @@ -76,6 +76,7 @@ x64 x86 x64 + x64 diff --git a/src/installer/pkg/projects/netcoreapp/src/localnetcoreapp.override.targets b/src/installer/pkg/projects/netcoreapp/src/localnetcoreapp.override.targets index 52f64d3386d39..831a758a0326f 100644 --- a/src/installer/pkg/projects/netcoreapp/src/localnetcoreapp.override.targets +++ b/src/installer/pkg/projects/netcoreapp/src/localnetcoreapp.override.targets @@ -15,6 +15,9 @@ <_crossHostArch>x64 + + <_crossHostArch>x64 + <_crossHostArch>x64 From 5118b4aaf8a3ece106fb8cb7069d3787ebd22bdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Honza=20Rame=C5=A1?= Date: Fri, 22 May 2020 15:24:56 +0200 Subject: [PATCH 340/420] Fix a summary typo in ConsoleLoggerOptions.cs (#36870) --- .../src/ConsoleLoggerOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs index c2b9f5e73d3ef..a2fb5967231b6 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerOptions.cs @@ -40,7 +40,7 @@ public ConsoleLoggerFormat Format } /// - /// Gets or sets value indicating the minimum level of messaged that would get written to Console.Error. + /// Gets or sets value indicating the minimum level of messages that would get written to Console.Error. /// public LogLevel LogToStandardErrorThreshold { get; set; } = LogLevel.None; From 2e748bf01147585d773779f38a9d2c51d5e2a0a5 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Fri, 22 May 2020 15:25:16 +0200 Subject: [PATCH 341/420] Remove x86 OSX code (#36874) This removes x86 OSX code that was never used for .NET Core. --- .../src/pal/src/exception/machexception.cpp | 125 ------------------ 1 file changed, 125 deletions(-) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index 4acafddbce74e..01130e80978cf 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -357,17 +357,11 @@ PAL_ERROR CorUnix::CPalThread::DisableMachExceptions() return palError; } -#if !defined(HOST_AMD64) -extern "C" -void PAL_DispatchException(PCONTEXT pContext, PEXCEPTION_RECORD pExRecord, MachExceptionInfo *pMachExceptionInfo) -#else // defined(HOST_AMD64) - // Since HijackFaultingThread pushed the context, exception record and info on the stack, we need to adjust the // signature of PAL_DispatchException such that the corresponding arguments are considered to be on the stack // per GCC64 calling convention rules. Hence, the first 6 dummy arguments (corresponding to RDI, RSI, RDX,RCX, R8, R9). extern "C" void PAL_DispatchException(DWORD64 dwRDI, DWORD64 dwRSI, DWORD64 dwRDX, DWORD64 dwRCX, DWORD64 dwR8, DWORD64 dwR9, PCONTEXT pContext, PEXCEPTION_RECORD pExRecord, MachExceptionInfo *pMachExceptionInfo) -#endif // !defined(HOST_AMD64) { CPalThread *pThread = InternalGetCurrentThread(); @@ -414,10 +408,8 @@ void PAL_DispatchException(DWORD64 dwRDI, DWORD64 dwRSI, DWORD64 dwRDX, DWORD64 } } -#if defined(HOST_X86) || defined(HOST_AMD64) extern "C" void PAL_DispatchExceptionWrapper(); extern "C" int PAL_DispatchExceptionReturnOffset; -#endif // HOST_X86 || HOST_AMD64 /*++ Function : @@ -477,7 +469,6 @@ BuildExceptionRecord( { switch (exceptionInfo.Subcodes[0]) { -#if defined(HOST_X86) || defined(HOST_AMD64) case EXC_I386_DIV: exceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO; break; @@ -490,9 +481,6 @@ BuildExceptionRecord( case EXC_I386_BOUND: exceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED; break; -#else -#error Trap code to exception mapping not defined for this architecture -#endif default: exceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; break; @@ -501,16 +489,11 @@ BuildExceptionRecord( break; case EXC_SOFTWARE: -#if defined(HOST_X86) || defined(HOST_AMD64) exceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; break; -#else -#error Trap code to exception mapping not defined for this architecture -#endif // Trace, breakpoint, etc. Details in subcode field. case EXC_BREAKPOINT: -#if defined(HOST_X86) || defined(HOST_AMD64) if (exceptionInfo.Subcodes[0] == EXC_I386_SGL) { exceptionCode = EXCEPTION_SINGLE_STEP; @@ -519,9 +502,6 @@ BuildExceptionRecord( { exceptionCode = EXCEPTION_BREAKPOINT; } -#else -#error Trap code to exception mapping not defined for this architecture -#endif else { WARN("unexpected subcode %d for EXC_BREAKPOINT", exceptionInfo.Subcodes[0]); @@ -615,17 +595,12 @@ HijackFaultingThread( // Fill in the exception record from the exception info BuildExceptionRecord(exceptionInfo, &exceptionRecord); -#ifdef HOST_X86 - threadContext.ContextFlags = CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS; -#else threadContext.ContextFlags = CONTEXT_FLOATING_POINT; -#endif CONTEXT_GetThreadContextFromThreadState(x86_FLOAT_STATE, (thread_state_t)&exceptionInfo.FloatState, &threadContext); threadContext.ContextFlags |= CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS; CONTEXT_GetThreadContextFromThreadState(x86_THREAD_STATE, (thread_state_t)&exceptionInfo.ThreadState, &threadContext); -#if defined(CORECLR) && (defined(HOST_X86) || defined(HOST_AMD64)) // For CoreCLR we look more deeply at access violations to determine whether they're the result of a stack // overflow. If so we'll terminate the process immediately (the current default policy of the CoreCLR EE). // Otherwise we'll either A/V ourselves trying to set up the SEH exception record and context on the @@ -671,7 +646,6 @@ HijackFaultingThread( // corrupted). Our managed jits always generate code which does this as does MSVC. GCC, however, // does not do this by default. We have to explicitly provide the -fstack-check compiler option // to enable the behavior. -#if (defined(HOST_X86) || defined(HOST_AMD64)) && defined(__APPLE__) // Assume that AV isn't an SO to begin with. bool fIsStackOverflow = false; @@ -680,11 +654,7 @@ HijackFaultingThread( // Calculate the page base addresses for the fault and the faulting thread's SP. int cbPage = getpagesize(); char *pFaultPage = (char*)(exceptionRecord.ExceptionInformation[1] & ~(cbPage - 1)); -#ifdef HOST_X86 - char *pStackTopPage = (char*)(threadContext.Esp & ~(cbPage - 1)); -#elif defined(HOST_AMD64) char *pStackTopPage = (char*)(threadContext.Rsp & ~(cbPage - 1)); -#endif if (pFaultPage == pStackTopPage || pFaultPage == (pStackTopPage - cbPage)) { @@ -699,24 +669,14 @@ HijackFaultingThread( vm_size_t vm_size; vm_region_flavor_t vm_flavor; mach_msg_type_number_t infoCnt; -#ifdef HOST_64BIT vm_region_basic_info_data_64_t info; infoCnt = VM_REGION_BASIC_INFO_COUNT_64; vm_flavor = VM_REGION_BASIC_INFO_64; -#else - vm_region_basic_info_data_t info; - infoCnt = VM_REGION_BASIC_INFO_COUNT; - vm_flavor = VM_REGION_BASIC_INFO; -#endif mach_port_t object_name; vm_address = (vm_address_t)(pFaultPage + cbPage); -#ifdef HOST_64BIT machret = vm_region_64( -#else - machret = vm_region( -#endif mach_task_self(), &vm_address, &vm_size, @@ -724,11 +684,7 @@ HijackFaultingThread( (vm_region_info_t)&info, &infoCnt, &object_name); -#ifdef HOST_X86 - CHECK_MACH("vm_region", machret); -#elif defined(HOST_AMD64) CHECK_MACH("vm_region_64", machret); -#endif // If vm_region updated the address we gave it then that address was not part of a region at all // (and so this cannot be an SO). Otherwise check that the ESP lies in the region returned. @@ -738,7 +694,6 @@ HijackFaultingThread( fIsStackOverflow = true; } -#if defined(HOST_AMD64) if (!fIsStackOverflow) { // Check if we can read pointer sizeD bytes below the target thread's stack pointer. @@ -755,79 +710,8 @@ HijackFaultingThread( fIsStackOverflow = true; } } -#endif // HOST_AMD64 - } -#else // (HOST_X86 || HOST_AMD64) && __APPLE__ -#error Platform not supported for correct stack overflow handling -#endif // (HOST_X86 || HOST_AMD64) && __APPLE__ -#endif // CORECLR && HOST_X86 - -#if defined(HOST_X86) - NONPAL_ASSERTE(exceptionInfo.ThreadState.tsh.flavor == x86_THREAD_STATE32); - - // Make a copy of the thread state because the one in exceptionInfo needs to be preserved to restore - // the state if the exception is forwarded. - x86_thread_state32_t ts32 = exceptionInfo.ThreadState.uts.ts32; - - // If we're in single step mode, disable it since we're going to call PAL_DispatchException - if (exceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP) - { - ts32.eflags &= ~EFL_TF; } - exceptionRecord.ExceptionFlags = EXCEPTION_IS_SIGNAL; - exceptionRecord.ExceptionRecord = NULL; - exceptionRecord.ExceptionAddress = (void *)ts32.eip; - - void **FramePointer = (void **)ts32.esp; - - *--FramePointer = (void *)ts32.eip; - - // Construct a stack frame for a pretend activation of the function - // PAL_DispatchExceptionWrapper that serves only to make the stack - // correctly unwindable by the system exception unwinder. - // PAL_DispatchExceptionWrapper has an ebp frame, its local variables - // are the context and exception record, and it has just "called" - // PAL_DispatchException. - *--FramePointer = (void *)ts32.ebp; - ts32.ebp = (unsigned)FramePointer; - - // Put the context on the stack - FramePointer = (void **)((ULONG_PTR)FramePointer - sizeof(CONTEXT)); - // Make sure it's aligned - CONTEXT has 8-byte alignment - FramePointer = (void **)((ULONG_PTR)FramePointer - ((ULONG_PTR)FramePointer % 8)); - CONTEXT *pContext = (CONTEXT *)FramePointer; - *pContext = threadContext; - - // Put the exception record on the stack - FramePointer = (void **)((ULONG_PTR)FramePointer - sizeof(EXCEPTION_RECORD)); - EXCEPTION_RECORD *pExceptionRecord = (EXCEPTION_RECORD *)FramePointer; - *pExceptionRecord = exceptionRecord; - - FramePointer = (void **)((ULONG_PTR)FramePointer - sizeof(MachExceptionInfo)); - MachExceptionInfo *pMachExceptionInfo = (MachExceptionInfo *)FramePointer; - *pMachExceptionInfo = exceptionInfo; - - // Push arguments to PAL_DispatchException - FramePointer = (void **)((ULONG_PTR)FramePointer - 3 * sizeof(void *)); - - // Make sure it's aligned - ABI requires 16-byte alignment - FramePointer = (void **)((ULONG_PTR)FramePointer - ((ULONG_PTR)FramePointer % 16)); - FramePointer[0] = pContext; - FramePointer[1] = pExceptionRecord; - FramePointer[2] = pMachExceptionInfo; - - // Place the return address to right after the fake call in PAL_DispatchExceptionWrapper - FramePointer[-1] = (void *)((ULONG_PTR)PAL_DispatchExceptionWrapper + PAL_DispatchExceptionReturnOffset); - - // Make the instruction register point to DispatchException - ts32.eip = (unsigned)PAL_DispatchException; - ts32.esp = (unsigned)&FramePointer[-1]; // skip return address - - // Now set the thread state for the faulting thread so that PAL_DispatchException executes next - machret = thread_set_state(thread, x86_THREAD_STATE32, (thread_state_t)&ts32, x86_THREAD_STATE32_COUNT); - CHECK_MACH("thread_set_state(thread)", machret); -#elif defined(HOST_AMD64) NONPAL_ASSERTE(exceptionInfo.ThreadState.tsh.flavor == x86_THREAD_STATE64); // Make a copy of the thread state because the one in exceptionInfo needs to be preserved to restore @@ -919,9 +803,6 @@ HijackFaultingThread( // Now set the thread state for the faulting thread so that PAL_DispatchException executes next machret = thread_set_state(thread, x86_THREAD_STATE64, (thread_state_t)&ts64, x86_THREAD_STATE64_COUNT); CHECK_MACH("thread_set_state(thread)", machret); -#else -#error HijackFaultingThread not defined for this architecture -#endif } /*++ @@ -1234,13 +1115,7 @@ void MachExceptionInfo::RestoreState(mach_port_t thread) { if (Subcodes[0] == EXC_I386_BPT) { -#ifdef HOST_X86 - ThreadState.uts.ts32.eip--; -#elif defined(HOST_AMD64) ThreadState.uts.ts64.__rip--; -#else -#error Platform not supported -#endif } } kern_return_t machret = thread_set_state(thread, x86_THREAD_STATE, (thread_state_t)&ThreadState, x86_THREAD_STATE_COUNT); From 00685a7bbe78089c6a53fc8928dee084028bb219 Mon Sep 17 00:00:00 2001 From: Eric StJohn Date: Fri, 22 May 2020 06:48:15 -0700 Subject: [PATCH 342/420] Ensure Image.Save can handle non readable / seekable Streams (#36805) * Ensure Image.Save can handle non readable / seekable Streams * Address feedback * Fix Image.Save on Unix for write only non-seekable stream * Remove test which uses bogus handle value --- .../Drawing/GdiPlusStreamHelper.Unix.cs | 4 +- .../src/System/Drawing/Image.Unix.cs | 4 +- .../src/System/Drawing/Image.Windows.cs | 2 +- .../System/Drawing/Imaging/Metafile.Unix.cs | 8 ++-- .../tests/BitmapTests.cs | 47 ++++++++++++++++--- .../System.Drawing.Common/tests/IconTests.cs | 22 --------- 6 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/GdiPlusStreamHelper.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/GdiPlusStreamHelper.Unix.cs index 23494a11bef72..abe50711c9fd6 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/GdiPlusStreamHelper.Unix.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/GdiPlusStreamHelper.Unix.cs @@ -43,10 +43,10 @@ internal sealed partial class GdiPlusStreamHelper { private Stream _stream; - public unsafe GdiPlusStreamHelper(Stream stream, bool seekToOrigin) + public unsafe GdiPlusStreamHelper(Stream stream, bool seekToOrigin, bool makeSeekable = true) { // Seeking required - if (!stream.CanSeek) + if (makeSeekable && !stream.CanSeek) { var memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Unix.cs index ab88eaf44305f..7398b5e2c98bb 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Unix.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Unix.cs @@ -74,7 +74,7 @@ private protected static IntPtr InitializeFromStream(Stream stream) // We use a custom API for this, because there's no easy way // to get the Stream down to libgdiplus. So, we wrap the stream // with a set of delegates. - GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, true); + GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, seekToOrigin: true); int st = Gdip.GdipLoadImageFromDelegate_linux(sh.GetHeaderDelegate, sh.GetBytesDelegate, sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, out IntPtr imagePtr); @@ -247,7 +247,7 @@ public void Save(Stream stream, ImageCodecInfo encoder, EncoderParameters? encod try { - GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, false); + GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, seekToOrigin: false, makeSeekable: false); st = Gdip.GdipSaveImageToDelegate_linux(nativeImage, sh.GetBytesDelegate, sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, ref guid, nativeEncoderParams); diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Windows.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Windows.cs index 4747b9c9ca436..da4dd3eac2fc6 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Windows.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Image.Windows.cs @@ -243,7 +243,7 @@ public void Save(Stream stream, ImageCodecInfo encoder, EncoderParameters? encod { Gdip.CheckStatus(Gdip.GdipSaveImageToStream( new HandleRef(this, nativeImage), - new GPStream(stream), + new GPStream(stream, makeSeekable: false), ref g, new HandleRef(encoderParams, encoderParamsMemory))); } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.Unix.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.Unix.cs index d101b970b63f8..596a2e097fbf9 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.Unix.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Imaging/Metafile.Unix.cs @@ -54,7 +54,7 @@ public Metafile(Stream stream) // With libgdiplus we use a custom API for this, because there's no easy way // to get the Stream down to libgdiplus. So, we wrap the stream with a set of delegates. - GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, false); + GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, seekToOrigin: false); int status = Gdip.GdipCreateMetafileFromDelegate_linux(sh.GetHeaderDelegate, sh.GetBytesDelegate, sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, out nativeImage); @@ -101,7 +101,7 @@ public Metafile(IntPtr hmetafile, WmfPlaceableFileHeader wmfHeader) // With libgdiplus we use a custom API for this, because there's no easy way // to get the Stream down to libgdiplus. So, we wrap the stream with a set of delegates. - GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, false); + GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, seekToOrigin: false); int status = Gdip.GdipRecordMetafileFromDelegateI_linux(sh.GetHeaderDelegate, sh.GetBytesDelegate, sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, referenceHdc, type, ref frameRect, frameUnit, description, out nativeImage); @@ -120,7 +120,7 @@ public Metafile(IntPtr hmetafile, WmfPlaceableFileHeader wmfHeader) // With libgdiplus we use a custom API for this, because there's no easy way // to get the Stream down to libgdiplus. So, we wrap the stream with a set of delegates. - GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, false); + GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, seekToOrigin: false); int status = Gdip.GdipRecordMetafileFromDelegate_linux(sh.GetHeaderDelegate, sh.GetBytesDelegate, sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, referenceHdc, type, ref frameRect, frameUnit, description, out nativeImage); @@ -189,7 +189,7 @@ public static MetafileHeader GetMetafileHeader(Stream stream) { // With libgdiplus we use a custom API for this, because there's no easy way // to get the Stream down to libgdiplus. So, we wrap the stream with a set of delegates. - GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, false); + GdiPlusStreamHelper sh = new GdiPlusStreamHelper(stream, seekToOrigin: false); int status = Gdip.GdipGetMetafileHeaderFromDelegate_linux(sh.GetHeaderDelegate, sh.GetBytesDelegate, sh.PutBytesDelegate, sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate, header); diff --git a/src/libraries/System.Drawing.Common/tests/BitmapTests.cs b/src/libraries/System.Drawing.Common/tests/BitmapTests.cs index 997b2069ad995..9c5ca385b9f99 100644 --- a/src/libraries/System.Drawing.Common/tests/BitmapTests.cs +++ b/src/libraries/System.Drawing.Common/tests/BitmapTests.cs @@ -1741,7 +1741,7 @@ public void FromNonSeekableStream() using (FileStream stream = new FileStream(path, FileMode.Open)) { - using (Bitmap bitmap = new Bitmap(new NonSeekableStream(stream))) + using (Bitmap bitmap = new Bitmap(new TestStream(stream, canSeek: false))) { Assert.Equal(100, bitmap.Height); Assert.Equal(100, bitmap.Width); @@ -1750,22 +1750,55 @@ public void FromNonSeekableStream() } } - private class NonSeekableStream : Stream + [ConditionalTheory(Helpers.IsDrawingSupported)] + [InlineData(true, false)] + [InlineData(false, false)] + [InlineData(false, true)] + public void SaveToRestrictiveStream(bool canRead, bool canSeek) + { + using (Stream backingStream = new MemoryStream()) + using (Stream restrictiveStream = new TestStream(backingStream, canRead, canSeek)) + { + using (Bitmap bitmap = new Bitmap(100, 100)) + { + bitmap.Save(restrictiveStream, ImageFormat.Png); + } + + backingStream.Position = 0; + + using (Bitmap bitmap = new Bitmap(backingStream)) + { + Assert.Equal(100, bitmap.Height); + Assert.Equal(100, bitmap.Width); + Assert.Equal(ImageFormat.Png, bitmap.RawFormat); + } + } + } + + private class TestStream : Stream { private Stream _stream; + private bool _canRead; + private bool _canSeek; - public NonSeekableStream(Stream stream) + public TestStream(Stream stream, bool canRead = true, bool canSeek = true) { _stream = stream; + _canRead = canRead; + _canSeek = canSeek; } - public override bool CanRead => _stream.CanRead; - public override bool CanSeek => false; + public override bool CanRead => _canRead && _stream.CanRead; + public override bool CanSeek => _canSeek && _stream.CanSeek; public override bool CanWrite => _stream.CanWrite; public override long Length => _stream.Length; - public override long Position { get => _stream.Position; set => throw new InvalidOperationException(); } + public override long Position + { + get => _stream.Position; + set => _stream.Position = _canSeek ? value : throw new NotSupportedException(); + } public override void Flush() => _stream.Flush(); - public override int Read(byte[] buffer, int offset, int count) => _stream.Read(buffer, offset, count); + public override int Read(byte[] buffer, int offset, int count) => _canRead ? _stream.Read(buffer, offset, count) : throw new NotSupportedException(); public override long Seek(long offset, SeekOrigin origin) => _stream.Seek(offset, origin); public override void SetLength(long value) => _stream.SetLength(value); public override void Write(byte[] buffer, int offset, int count) => _stream.Write(buffer, offset, count); diff --git a/src/libraries/System.Drawing.Common/tests/IconTests.cs b/src/libraries/System.Drawing.Common/tests/IconTests.cs index 440fd59f2be77..25b8c5b9631e6 100644 --- a/src/libraries/System.Drawing.Common/tests/IconTests.cs +++ b/src/libraries/System.Drawing.Common/tests/IconTests.cs @@ -266,28 +266,6 @@ public void Ctor_NullIcon_ThrowsArgumentNullException() AssertExtensions.Throws("original", null, () => new Icon((Icon)null, new Size(32, 32))); } - // libgdiplus causes a segfault when given an invalid Icon handle. - [PlatformSpecific(TestPlatforms.Windows)] - [ConditionalFact(Helpers.IsDrawingSupported)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/34591", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)] - public void Ctor_InvalidHandle_Success() - { - using (Icon icon = Icon.FromHandle((IntPtr)1)) - using (var stream = new MemoryStream()) - { - Exception ex = Assert.ThrowsAny(() => icon.Save(stream)); - Assert.True(ex is COMException || ex is ObjectDisposedException || ex is FileNotFoundException, $"{ex.GetType().ToString()} was thrown."); - - AssertExtensions.Throws(null, () => icon.ToBitmap()); - Assert.Equal(Size.Empty, icon.Size); - - using (var newIcon = new Icon(icon, 10, 10)) - { - Assert.Throws(() => newIcon.Handle); - } - } - } - [ConditionalFact(Helpers.IsDrawingSupported)] public void Ctor_Type_Resource() { From c240d1184e77748bf3e674fb30a70f1e9391f1ff Mon Sep 17 00:00:00 2001 From: Simon Nattress Date: Fri, 22 May 2020 09:43:28 -0700 Subject: [PATCH 343/420] Use linux-musl runtime on Alpine Helix workers (#36827) * Use linux-musl runtime on Alpine Helix workers * Add OS Subgroup to send-to-helix-step * Pass in osSubgroup Also, capitalize it in line with the rest of the repo * Use __TargetOS which understands linux_musl for rid generation I don't fully understand why we use `TargetOS` in `helixpublishwitharcade.proj` but set `__TargetOS` in the calling `send-to-helix-step.yml`. --- .../common/templates/runtimes/run-test-job.yml | 1 + .../common/templates/runtimes/send-to-helix-step.yml | 5 +++-- src/coreclr/tests/helixpublishwitharcade.proj | 12 +++++++----- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/eng/pipelines/common/templates/runtimes/run-test-job.yml b/eng/pipelines/common/templates/runtimes/run-test-job.yml index 760dad39c85d8..d93d842be6598 100644 --- a/eng/pipelines/common/templates/runtimes/run-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/run-test-job.yml @@ -281,6 +281,7 @@ jobs: buildConfig: $(buildConfigUpper) archType: ${{ parameters.archType }} osGroup: ${{ parameters.osGroup }} + osSubgroup: ${{ parameters.osSubgroup}} coreClrRepoRoot: $(coreClrRepoRoot) runtimeFlavorDisplayName: ${{ parameters.runtimeFlavorDisplayName }} diff --git a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml index ca58a7eff3165..3602929653dc3 100644 --- a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml +++ b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml @@ -3,6 +3,7 @@ parameters: condition: '' archType: '' osGroup: '' + osSubgroup: '' buildConfig: '' creator: '' publishTestResults: '' @@ -39,7 +40,7 @@ steps: condition: ${{ parameters.condition }} env: __BuildArch: ${{ parameters.archType }} - __TargetOS: ${{ parameters.osGroup }} + __TargetOS: ${{ parameters.osGroup }}${{ parameters.osSubgroup }} __BuildType: ${{ parameters.buildConfig }} _Creator: ${{ parameters.creator }} _PublishTestResults: ${{ parameters.publishTestResults }} @@ -81,7 +82,7 @@ steps: condition: ${{ parameters.condition }} env: __BuildArch: ${{ parameters.archType }} - __TargetOS: ${{ parameters.osGroup }} + __TargetOS: ${{ parameters.osGroup }}${{ parameters.osSubgroup }} __BuildType: ${{ parameters.buildConfig }} _Creator: ${{ parameters.creator }} _PublishTestResults: ${{ parameters.publishTestResults }} diff --git a/src/coreclr/tests/helixpublishwitharcade.proj b/src/coreclr/tests/helixpublishwitharcade.proj index c1d2de4f8b713..f75ae6c12cfe3 100644 --- a/src/coreclr/tests/helixpublishwitharcade.proj +++ b/src/coreclr/tests/helixpublishwitharcade.proj @@ -34,7 +34,8 @@ TimeoutPerTestCollectionInMinutes=$(_TimeoutPerTestCollectionInMinutes); TimeoutPerTestInMinutes=$(_TimeoutPerTestInMinutes); RuntimeVariant=$(_RuntimeVariant); - BundledNETCoreAppPackageVersion=$(BundledNETCoreAppPackageVersion) + BundledNETCoreAppPackageVersion=$(BundledNETCoreAppPackageVersion); + HelixRuntimeRid=$(HelixRuntimeRid) @@ -64,10 +65,11 @@ - - win-$(TargetArchitecture) - osx-$(TargetArchitecture) - linux-$(TargetArchitecture) + + win-$(TargetArchitecture) + osx-$(TargetArchitecture) + linux-$(TargetArchitecture) + linux-musl-$(TargetArchitecture) From 2d0e6b49f63732124615c16807446761d2917124 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Fri, 22 May 2020 10:07:21 -0700 Subject: [PATCH 344/420] Fix wasm build when runtime configuration and configuration are different (#36855) * Fix wasm build when runtime configuration and configuration are different * PR Feedback --- src/libraries/pretest.proj | 1 + src/libraries/src.proj | 9 --------- src/mono/wasm/wasm.proj | 17 ++++++----------- .../WasmAppBuilder/WasmAppBuilder.csproj | 4 ++++ 4 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj index 94141031b8b85..01ff1b776e79a 100644 --- a/src/libraries/pretest.proj +++ b/src/libraries/pretest.proj @@ -18,6 +18,7 @@ + - - - - - - diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index d83f1fcd4e160..4da46637398e5 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -1,10 +1,10 @@ - + $(NetCoreAppCurrent) + AssemblyFile="$([MSBuild]::NormalizePath('$(ArtifactsBinDir)', 'WasmAppBuilder', 'Debug', '$(NetCoreAppCurrent)', 'publish', 'WasmAppBuilder.dll'))"/> $(MonoObjDir)wasm/pinvoke-table.h @@ -28,14 +28,7 @@ - - - - - - + - + diff --git a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.csproj b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.csproj index 7913d15f6a944..ab82b35f70807 100644 --- a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.csproj +++ b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.csproj @@ -16,4 +16,8 @@ + + From a0e140d6a8f49d77ec0846003f0f9f60c8af132e Mon Sep 17 00:00:00 2001 From: Adeel Mujahid Date: Fri, 22 May 2020 20:37:33 +0300 Subject: [PATCH 345/420] Fix CoreCLR initialization on Illumos-based distros (#36808) --- src/coreclr/src/pal/src/map/virtual.cpp | 8 ++++- src/coreclr/src/pal/src/thread/thread.cpp | 41 ++++++++++++++++++++++- src/coreclr/src/vm/vars.hpp | 13 ++++++- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/pal/src/map/virtual.cpp b/src/coreclr/src/pal/src/map/virtual.cpp index d6a33c793143c..3d796d9efc17a 100644 --- a/src/coreclr/src/pal/src/map/virtual.cpp +++ b/src/coreclr/src/pal/src/map/virtual.cpp @@ -2276,6 +2276,12 @@ void *ExecutableMemoryAllocator::AllocateMemoryWithinRange(const void *beginAddr at which the allocator should start allocating memory from its reserved memory range. --*/ +#ifdef __sun +// The upper limit of the random() function on SunOS derived operating systems is not RAND_MAX, but 2^31-1. +#define OFFSET_RAND_MAX 0x7FFFFFFF +#else +#define OFFSET_RAND_MAX RAND_MAX +#endif int32_t ExecutableMemoryAllocator::GenerateRandomStartOffset() { int32_t pageCount; @@ -2284,7 +2290,7 @@ int32_t ExecutableMemoryAllocator::GenerateRandomStartOffset() // This code is similar to what coreclr runtime does on Windows. // It generates a random number of pages to skip between 0...MaxStartPageOffset. srandom(time(NULL)); - pageCount = (int32_t)(MaxStartPageOffset * (int64_t)random() / RAND_MAX); + pageCount = (int32_t)(MaxStartPageOffset * (int64_t)random() / OFFSET_RAND_MAX); return pageCount * GetVirtualPageSize(); } diff --git a/src/coreclr/src/pal/src/thread/thread.cpp b/src/coreclr/src/pal/src/thread/thread.cpp index 36a523e28d120..fa4a663801353 100644 --- a/src/coreclr/src/pal/src/thread/thread.cpp +++ b/src/coreclr/src/pal/src/thread/thread.cpp @@ -43,6 +43,15 @@ SET_DEFAULT_DEBUG_CHANNEL(THREAD); // some headers have code with asserts, so do #include #include #include +#elif defined(__sun) +#ifndef _KERNEL +#define _KERNEL +#define UNDEF_KERNEL +#endif +#include +#ifdef UNDEF_KERNEL +#undef _KERNEL +#endif #endif #include @@ -1441,7 +1450,11 @@ CorUnix::GetThreadTimesInternal( CPalThread *pThread; CPalThread *pTargetThread; IPalObject *pobjThread = NULL; +#ifdef __sun + int fd; +#else // __sun clockid_t cid; +#endif // __sun pThread = InternalGetCurrentThread(); @@ -1463,7 +1476,6 @@ CorUnix::GetThreadTimesInternal( #if HAVE_PTHREAD_GETCPUCLOCKID if (pthread_getcpuclockid(pTargetThread->GetPThreadSelf(), &cid) != 0) -#endif { ASSERT("Unable to get clock from thread\n", hThread); SetLastError(ERROR_INTERNAL_ERROR); @@ -1479,6 +1491,33 @@ CorUnix::GetThreadTimesInternal( pTargetThread->Unlock(pThread); goto SetTimesToZero; } +#elif defined(__sun) + timestruc_t ts; + int readResult; + char statusFilename[64]; + snprintf(statusFilename, sizeof(statusFilename), "/proc/%d/lwp/%d/lwpstatus", getpid(), pTargetThread->GetLwpId()); + fd = open(statusFilename, O_RDONLY); + if (fd == -1) + { + ASSERT("open(%s) failed; errno is %d (%s)\n", statusFilename, errno, strerror(errno)); + SetLastError(ERROR_INTERNAL_ERROR); + pTargetThread->Unlock(pThread); + goto SetTimesToZero; + } + + lwpstatus_t status; + do + { + readResult = read(fd, &status, sizeof(status)); + } + while ((readResult == -1) && (errno == EINTR)); + + close(fd); + + ts = status.pr_utime; +#else // HAVE_PTHREAD_GETCPUCLOCKID +#error "Don't know how to obtain user cpu time on this platform." +#endif // HAVE_PTHREAD_GETCPUCLOCKID pTargetThread->Unlock(pThread); diff --git a/src/coreclr/src/vm/vars.hpp b/src/coreclr/src/vm/vars.hpp index cd4080018f8e6..997c2157bcdae 100644 --- a/src/coreclr/src/vm/vars.hpp +++ b/src/coreclr/src/vm/vars.hpp @@ -690,12 +690,23 @@ struct ModuleIndex typedef DPTR(GSCookie) PTR_GSCookie; +#ifdef _MSC_VER +#define READONLY_ATTR +#else +#ifdef __APPLE__ +#define READONLY_ATTR_ARGS section("__TEXT,__const") +#else +#define READONLY_ATTR_ARGS section(".rodata") +#endif +#define READONLY_ATTR __attribute__((READONLY_ATTR_ARGS)) +#endif + #ifndef DACCESS_COMPILE // const is so that it gets placed in the .text section (which is read-only) // volatile is so that accesses to it do not get optimized away because of the const // -extern "C" RAW_KEYWORD(volatile) const GSCookie s_gsCookie; +extern "C" RAW_KEYWORD(volatile) READONLY_ATTR const GSCookie s_gsCookie; inline GSCookie * GetProcessGSCookiePtr() { return const_cast(&s_gsCookie); } From 1c18e8c038bbf2cca8297922519ebe05bb003f3c Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Fri, 22 May 2020 10:46:19 -0700 Subject: [PATCH 346/420] [Arm64] Polynomial Multiply Long Intrinsics (#36853) Implements PolynomialMultiplyWideningLower and PolynomialMultiplyWideningUpper --- .../src/jit/hwintrinsiccodegenarm64.cpp | 6 + src/coreclr/src/jit/hwintrinsiclistarm64.h | 4 + .../Arm/AdvSimd/AdvSimd_r.csproj | 4 + .../Arm/AdvSimd/AdvSimd_ro.csproj | 4 + ...mialMultiplyWideningLower.Vector64.Byte.cs | 530 +++++++++++++++++ ...ialMultiplyWideningLower.Vector64.SByte.cs | 530 +++++++++++++++++ ...ialMultiplyWideningUpper.Vector128.Byte.cs | 530 +++++++++++++++++ ...alMultiplyWideningUpper.Vector128.SByte.cs | 530 +++++++++++++++++ .../Arm/AdvSimd/Program.AdvSimd.cs | 4 + .../HardwareIntrinsics/Arm/Aes/Aes_r.csproj | 4 + .../HardwareIntrinsics/Arm/Aes/Aes_ro.csproj | 4 + ...ialMultiplyWideningLower.Vector64.Int64.cs | 537 ++++++++++++++++++ ...alMultiplyWideningLower.Vector64.UInt64.cs | 537 ++++++++++++++++++ ...alMultiplyWideningUpper.Vector128.Int64.cs | 537 ++++++++++++++++++ ...lMultiplyWideningUpper.Vector128.UInt64.cs | 537 ++++++++++++++++++ .../HardwareIntrinsics/Arm/Aes/Program.Aes.cs | 4 + .../Arm/Shared/GenerateTests.csx | 8 + .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 117 +++- .../HardwareIntrinsics/Arm/Shared/Helpers.tt | 85 ++- .../Arm/AdvSimd.PlatformNotSupported.cs | 28 + .../System/Runtime/Intrinsics/Arm/AdvSimd.cs | 28 + .../Arm/Aes.PlatformNotSupported.cs | 29 + .../src/System/Runtime/Intrinsics/Arm/Aes.cs | 28 + .../System.Runtime.Intrinsics.Experimental.cs | 57 +- 24 files changed, 4637 insertions(+), 45 deletions(-) create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningLower.Vector64.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningLower.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningUpper.Vector128.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningUpper.Vector128.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningLower.Vector64.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningLower.Vector64.UInt64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningUpper.Vector128.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningUpper.Vector128.UInt64.cs diff --git a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp index 7b16a566410b0..f722ea75d5c0a 100644 --- a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp @@ -360,6 +360,11 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) } break; + case NI_Aes_PolynomialMultiplyWideningLower: + ins = INS_pmull; + opt = INS_OPTS_1D; + break; + default: ins = HWIntrinsicInfo::lookupIns(intrin.id, intrin.baseType); break; @@ -397,6 +402,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Crc32_ComputeCrc32C: case NI_Crc32_Arm64_ComputeCrc32: case NI_Crc32_Arm64_ComputeCrc32C: + case NI_Aes_PolynomialMultiplyWideningLower: GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt); break; diff --git a/src/coreclr/src/jit/hwintrinsiclistarm64.h b/src/coreclr/src/jit/hwintrinsiclistarm64.h index 5084324f84924..a8011ab80b6fd 100644 --- a/src/coreclr/src/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/src/jit/hwintrinsiclistarm64.h @@ -153,6 +153,8 @@ HARDWARE_INTRINSIC(AdvSimd, Not, - HARDWARE_INTRINSIC(AdvSimd, Or, -1, 2, {INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AdvSimd, OrNot, -1, 2, {INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, PolynomialMultiply, -1, 2, {INS_pmul, INS_pmul, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, PolynomialMultiplyWideningLower, 8, 2, {INS_pmull, INS_pmull, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, PolynomialMultiplyWideningUpper, 16, 2, {INS_pmull2, INS_pmull2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AdvSimd, PopCount, -1, 1, {INS_cnt, INS_cnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, ReciprocalEstimate, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_urecpe, INS_invalid, INS_invalid, INS_frecpe, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, ReciprocalSquareRootEstimate, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ursqrte, INS_invalid, INS_invalid, INS_frsqrte, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) @@ -268,6 +270,8 @@ HARDWARE_INTRINSIC(Aes, Decrypt, 1 HARDWARE_INTRINSIC(Aes, Encrypt, 16, 2, {INS_invalid, INS_aese, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Aes, InverseMixColumns, 16, 1, {INS_invalid, INS_aesimc, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(Aes, MixColumns, 16, 1, {INS_invalid, INS_aesmc, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(Aes, PolynomialMultiplyWideningLower, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pmull, INS_pmull, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Aes, PolynomialMultiplyWideningUpper, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pmull2, INS_pmull2, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj index a1c2428103019..0a2139adeb4b6 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj @@ -742,6 +742,10 @@ + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj index c15b086b93c63..ed52c2b89031c 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj @@ -742,6 +742,10 @@ + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningLower.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningLower.Vector64.Byte.cs new file mode 100644 index 0000000000000..729db2ea0559d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningLower.Vector64.Byte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void PolynomialMultiplyWideningLower_Vector64_Byte() + { + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__PolynomialMultiplyWideningLower_Vector64_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, Byte[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Byte testClass) + { + var result = AdvSimd.PolynomialMultiplyWideningLower(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Byte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((Byte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static Byte[] _data2 = new Byte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.PolynomialMultiplyWideningLower( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.PolynomialMultiplyWideningLower), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.PolynomialMultiplyWideningLower), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.PolynomialMultiplyWideningLower( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((Byte*)(pClsVar1)), + AdvSimd.LoadVector64((Byte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.PolynomialMultiplyWideningLower(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.PolynomialMultiplyWideningLower(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Byte(); + var result = AdvSimd.PolynomialMultiplyWideningLower(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Byte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((Byte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.PolynomialMultiplyWideningLower(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((Byte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.PolynomialMultiplyWideningLower(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((Byte*)(&test._fld1)), + AdvSimd.LoadVector64((Byte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + Byte[] inArray2 = new Byte[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + Byte[] inArray2 = new Byte[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] left, Byte[] right, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.PolynomialMultiplyWidening(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.PolynomialMultiplyWideningLower)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningLower.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningLower.Vector64.SByte.cs new file mode 100644 index 0000000000000..995f417e47501 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningLower.Vector64.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void PolynomialMultiplyWideningLower_Vector64_SByte() + { + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__PolynomialMultiplyWideningLower_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_SByte testClass) + { + var result = AdvSimd.PolynomialMultiplyWideningLower(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.PolynomialMultiplyWideningLower( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.PolynomialMultiplyWideningLower), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.PolynomialMultiplyWideningLower), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.PolynomialMultiplyWideningLower( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((SByte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.PolynomialMultiplyWideningLower(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.PolynomialMultiplyWideningLower(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_SByte(); + var result = AdvSimd.PolynomialMultiplyWideningLower(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.PolynomialMultiplyWideningLower(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.PolynomialMultiplyWideningLower(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((SByte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.PolynomialMultiplyWidening(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.PolynomialMultiplyWideningLower)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningUpper.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningUpper.Vector128.Byte.cs new file mode 100644 index 0000000000000..dfd07f4ab3260 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningUpper.Vector128.Byte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void PolynomialMultiplyWideningUpper_Vector128_Byte() + { + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__PolynomialMultiplyWideningUpper_Vector128_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, Byte[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Byte testClass) + { + var result = AdvSimd.PolynomialMultiplyWideningUpper(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Byte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((Byte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static Byte[] _data2 = new Byte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.PolynomialMultiplyWideningUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.PolynomialMultiplyWideningUpper), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.PolynomialMultiplyWideningUpper), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.PolynomialMultiplyWideningUpper( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((Byte*)(pClsVar1)), + AdvSimd.LoadVector128((Byte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.PolynomialMultiplyWideningUpper(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.PolynomialMultiplyWideningUpper(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Byte(); + var result = AdvSimd.PolynomialMultiplyWideningUpper(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Byte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((Byte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.PolynomialMultiplyWideningUpper(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((Byte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.PolynomialMultiplyWideningUpper(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((Byte*)(&test._fld1)), + AdvSimd.LoadVector128((Byte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + Byte[] inArray2 = new Byte[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + Byte[] inArray2 = new Byte[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] left, Byte[] right, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.PolynomialMultiplyWideningUpper(left, right, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.PolynomialMultiplyWideningUpper)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningUpper.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningUpper.Vector128.SByte.cs new file mode 100644 index 0000000000000..32780778dbdd0 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/PolynomialMultiplyWideningUpper.Vector128.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void PolynomialMultiplyWideningUpper_Vector128_SByte() + { + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__PolynomialMultiplyWideningUpper_Vector128_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_SByte testClass) + { + var result = AdvSimd.PolynomialMultiplyWideningUpper(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_SByte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.PolynomialMultiplyWideningUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.PolynomialMultiplyWideningUpper), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.PolynomialMultiplyWideningUpper), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.PolynomialMultiplyWideningUpper( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((SByte*)(pClsVar1)), + AdvSimd.LoadVector128((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.PolynomialMultiplyWideningUpper(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.PolynomialMultiplyWideningUpper(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_SByte(); + var result = AdvSimd.PolynomialMultiplyWideningUpper(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_SByte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.PolynomialMultiplyWideningUpper(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.PolynomialMultiplyWideningUpper(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((SByte*)(&test._fld1)), + AdvSimd.LoadVector128((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.PolynomialMultiplyWideningUpper(left, right, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.PolynomialMultiplyWideningUpper)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs index f8c35610338ab..cc7f28a388fbc 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs @@ -746,6 +746,10 @@ static Program() ["PolynomialMultiply.Vector64.SByte"] = PolynomialMultiply_Vector64_SByte, ["PolynomialMultiply.Vector128.Byte"] = PolynomialMultiply_Vector128_Byte, ["PolynomialMultiply.Vector128.SByte"] = PolynomialMultiply_Vector128_SByte, + ["PolynomialMultiplyWideningLower.Vector64.Byte"] = PolynomialMultiplyWideningLower_Vector64_Byte, + ["PolynomialMultiplyWideningLower.Vector64.SByte"] = PolynomialMultiplyWideningLower_Vector64_SByte, + ["PolynomialMultiplyWideningUpper.Vector128.Byte"] = PolynomialMultiplyWideningUpper_Vector128_Byte, + ["PolynomialMultiplyWideningUpper.Vector128.SByte"] = PolynomialMultiplyWideningUpper_Vector128_SByte, ["PopCount.Vector64.Byte"] = PopCount_Vector64_Byte, ["PopCount.Vector64.SByte"] = PopCount_Vector64_SByte, ["PopCount.Vector128.Byte"] = PopCount_Vector128_Byte, diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/Aes_r.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/Aes_r.csproj index 0742b17dadfe6..ee55253dbbb23 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/Aes_r.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/Aes_r.csproj @@ -12,6 +12,10 @@ + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/Aes_ro.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/Aes_ro.csproj index e4b915cd4e3f7..509b345bdc5ca 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/Aes_ro.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/Aes_ro.csproj @@ -12,6 +12,10 @@ + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningLower.Vector64.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningLower.Vector64.Int64.cs new file mode 100644 index 0000000000000..3cba2406b3af3 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningLower.Vector64.Int64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void PolynomialMultiplyWideningLower_Vector64_Int64() + { + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__PolynomialMultiplyWideningLower_Vector64_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Int64 testClass) + { + var result = Aes.PolynomialMultiplyWideningLower(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Int64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = Aes.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Aes.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Aes.PolynomialMultiplyWideningLower( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Aes.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Aes).GetMethod(nameof(Aes.PolynomialMultiplyWideningLower), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Aes).GetMethod(nameof(Aes.PolynomialMultiplyWideningLower), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Aes.PolynomialMultiplyWideningLower( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = Aes.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((Int64*)(pClsVar1)), + AdvSimd.LoadVector64((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Aes.PolynomialMultiplyWideningLower(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = Aes.PolynomialMultiplyWideningLower(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Int64(); + var result = Aes.PolynomialMultiplyWideningLower(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_Int64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = Aes.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Aes.PolynomialMultiplyWideningLower(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = Aes.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Aes.PolynomialMultiplyWideningLower(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = Aes.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((Int64*)(&test._fld1)), + AdvSimd.LoadVector64((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.PolynomialMultiplyWideningLo64(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (Helpers.PolynomialMultiplyWideningHi64(left[0], right[0]) != result[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Aes)}.{nameof(Aes.PolynomialMultiplyWideningLower)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningLower.Vector64.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningLower.Vector64.UInt64.cs new file mode 100644 index 0000000000000..9941f644a2dc2 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningLower.Vector64.UInt64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void PolynomialMultiplyWideningLower_Vector64_UInt64() + { + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_UInt64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__PolynomialMultiplyWideningLower_Vector64_UInt64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_UInt64 testClass) + { + var result = Aes.PolynomialMultiplyWideningLower(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_UInt64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = Aes.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((UInt64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static UInt64[] _data2 = new UInt64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_UInt64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_UInt64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Aes.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Aes.PolynomialMultiplyWideningLower( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Aes.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Aes).GetMethod(nameof(Aes.PolynomialMultiplyWideningLower), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Aes).GetMethod(nameof(Aes.PolynomialMultiplyWideningLower), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Aes.PolynomialMultiplyWideningLower( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = Aes.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((UInt64*)(pClsVar1)), + AdvSimd.LoadVector64((UInt64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Aes.PolynomialMultiplyWideningLower(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray2Ptr)); + var result = Aes.PolynomialMultiplyWideningLower(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_UInt64(); + var result = Aes.PolynomialMultiplyWideningLower(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningLower_Vector64_UInt64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = Aes.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((UInt64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Aes.PolynomialMultiplyWideningLower(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = Aes.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((UInt64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Aes.PolynomialMultiplyWideningLower(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = Aes.PolynomialMultiplyWideningLower( + AdvSimd.LoadVector64((UInt64*)(&test._fld1)), + AdvSimd.LoadVector64((UInt64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.PolynomialMultiplyWideningLo64(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (Helpers.PolynomialMultiplyWideningHi64(left[0], right[0]) != result[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Aes)}.{nameof(Aes.PolynomialMultiplyWideningLower)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningUpper.Vector128.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningUpper.Vector128.Int64.cs new file mode 100644 index 0000000000000..72791aa51283d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningUpper.Vector128.Int64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void PolynomialMultiplyWideningUpper_Vector128_Int64() + { + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__PolynomialMultiplyWideningUpper_Vector128_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Int64 testClass) + { + var result = Aes.PolynomialMultiplyWideningUpper(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Int64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = Aes.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Aes.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Aes.PolynomialMultiplyWideningUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Aes.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Aes).GetMethod(nameof(Aes.PolynomialMultiplyWideningUpper), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Aes).GetMethod(nameof(Aes.PolynomialMultiplyWideningUpper), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Aes.PolynomialMultiplyWideningUpper( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = Aes.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((Int64*)(pClsVar1)), + AdvSimd.LoadVector128((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Aes.PolynomialMultiplyWideningUpper(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = Aes.PolynomialMultiplyWideningUpper(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Int64(); + var result = Aes.PolynomialMultiplyWideningUpper(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_Int64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = Aes.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Aes.PolynomialMultiplyWideningUpper(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = Aes.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Aes.PolynomialMultiplyWideningUpper(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = Aes.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((Int64*)(&test._fld1)), + AdvSimd.LoadVector128((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.PolynomialMultiplyWideningLo64(left[1], right[1]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (Helpers.PolynomialMultiplyWideningHi64(left[1], right[1]) != result[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Aes)}.{nameof(Aes.PolynomialMultiplyWideningUpper)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningUpper.Vector128.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningUpper.Vector128.UInt64.cs new file mode 100644 index 0000000000000..bb4064cfa115e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/PolynomialMultiplyWideningUpper.Vector128.UInt64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void PolynomialMultiplyWideningUpper_Vector128_UInt64() + { + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_UInt64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__PolynomialMultiplyWideningUpper_Vector128_UInt64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_UInt64 testClass) + { + var result = Aes.PolynomialMultiplyWideningUpper(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_UInt64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = Aes.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((UInt64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static UInt64[] _data2 = new UInt64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_UInt64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_UInt64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Aes.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Aes.PolynomialMultiplyWideningUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Aes.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Aes).GetMethod(nameof(Aes.PolynomialMultiplyWideningUpper), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Aes).GetMethod(nameof(Aes.PolynomialMultiplyWideningUpper), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Aes.PolynomialMultiplyWideningUpper( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = Aes.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((UInt64*)(pClsVar1)), + AdvSimd.LoadVector128((UInt64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Aes.PolynomialMultiplyWideningUpper(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = Aes.PolynomialMultiplyWideningUpper(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_UInt64(); + var result = Aes.PolynomialMultiplyWideningUpper(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__PolynomialMultiplyWideningUpper_Vector128_UInt64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = Aes.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((UInt64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Aes.PolynomialMultiplyWideningUpper(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = Aes.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((UInt64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Aes.PolynomialMultiplyWideningUpper(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = Aes.PolynomialMultiplyWideningUpper( + AdvSimd.LoadVector128((UInt64*)(&test._fld1)), + AdvSimd.LoadVector128((UInt64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.PolynomialMultiplyWideningLo64(left[1], right[1]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (Helpers.PolynomialMultiplyWideningHi64(left[1], right[1]) != result[1]) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Aes)}.{nameof(Aes.PolynomialMultiplyWideningUpper)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/Program.Aes.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/Program.Aes.cs index fd0188702e40f..96b49b50943e3 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/Program.Aes.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Aes/Program.Aes.cs @@ -16,6 +16,10 @@ static Program() ["Encrypt.Vector128.Byte"] = Encrypt_Vector128_Byte, ["InverseMixColumns.Vector128.Byte"] = InverseMixColumns_Vector128_Byte, ["MixColumns.Vector128.Byte"] = MixColumns_Vector128_Byte, + ["PolynomialMultiplyWideningLower.Vector64.Int64"] = PolynomialMultiplyWideningLower_Vector64_Int64, + ["PolynomialMultiplyWideningLower.Vector64.UInt64"] = PolynomialMultiplyWideningLower_Vector64_UInt64, + ["PolynomialMultiplyWideningUpper.Vector128.Int64"] = PolynomialMultiplyWideningUpper_Vector128_Int64, + ["PolynomialMultiplyWideningUpper.Vector128.UInt64"] = PolynomialMultiplyWideningUpper_Vector128_UInt64, }; } } diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx index c2f17ba406e11..4d1e1a79d56d4 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx @@ -838,6 +838,10 @@ private static readonly (string templateFileName, Dictionary tem ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWideningUpper(left, right, i) != result[i]"}), ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), @@ -1305,6 +1309,10 @@ private static readonly (string templateFileName, Dictionary tem ("AesBinOpTest.template", new Dictionary { ["TestName"] = "Encrypt_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "Encrypt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["KeySize"] = "16", ["Key"] = "{0xFF, 0xDD, 0xBB, 0x99, 0x77, 0x55, 0x33, 0x11, 0xEE, 0xCC, 0xAA, 0x88, 0x66, 0x44, 0x22, 0x00}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xCA, 0xCA, 0xF5, 0xC4, 0xCA, 0x93, 0xEA, 0xCA, 0x82, 0x28, 0xCA, 0xCA, 0xC1, 0xCA, 0xCA, 0x1B}"}), ("AesUnOpTest.template", new Dictionary { ["TestName"] = "InverseMixColumns_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "InverseMixColumns", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xA0, 0x0A, 0xE4, 0x4E, 0x28, 0x82, 0x6C, 0xC6, 0x55, 0x00, 0x77, 0x22, 0x11, 0x44, 0x33, 0x66}"}), ("AesUnOpTest.template", new Dictionary { ["TestName"] = "MixColumns_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "MixColumns", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xAB, 0x01, 0xEF, 0x45, 0x23, 0x89, 0x67, 0xCD, 0xDD, 0x88, 0xFF, 0xAA, 0x99, 0xCC, 0xBB, 0xEE}"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_Int64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[0], right[0]) != result[1]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_UInt64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[0], right[0]) != result[1]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_Int64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[1], right[1]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[1], right[1]) != result[1]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_UInt64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[1], right[1]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[1], right[1]) != result[1]"}) }; private static readonly (string templateFileName, Dictionary templateData)[] ArmBaseInputs = new [] diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 3b766823195b4..b22f7cd0f6078 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2983,34 +2983,109 @@ private static double Reduce(Func reduceOp, double[] op1 public static float MinNumberAcross(float[] op1) => Reduce(MinNumber, op1); - private static ulong PolynomialMult(sbyte op1, sbyte op2) + private struct poly128_t { - ulong result = 0; - ulong extendedOp2 = (ulong)op2; + public ulong lo; + public ulong hi; + + public static poly128_t operator ^(poly128_t op1, poly128_t op2) + { + op1.lo ^= op2.lo; + op1.hi ^= op2.hi; + + return op1; + } + + public static poly128_t operator <<(poly128_t val, int shiftAmount) + { + for (int i = 0; i < shiftAmount; i++) + { + val.hi <<= 1; + + if ((val.lo & 0x8000000000000000U) != 0) + { + val.hi |= 1; + } + + val.lo <<= 1; + } + + return val; + } + + public static implicit operator poly128_t(ulong lo) + { + poly128_t result = new poly128_t(); + result.lo = lo; + return result; + } + + public static explicit operator poly128_t(long lo) + { + poly128_t result = new poly128_t(); + result.lo = (ulong)lo; + return result; + } + } + + private static ushort PolynomialMult(byte op1, byte op2) + { + ushort result = default(ushort); + ushort extendedOp2 = (ushort)op2; + + for (int i = 0; i < 8 * sizeof(byte); i++) + { + if ((op1 & ((byte)1 << i)) != 0) + { + result = (ushort)(result ^ (extendedOp2 << i)); + } + } + + return result; + } + + private static short PolynomialMult(sbyte op1, sbyte op2) + { + short result = default(short); + short extendedOp2 = (short)op2; for (int i = 0; i < 8 * sizeof(sbyte); i++) { - if ((op1 & (1 << i)) != 0) + if ((op1 & ((sbyte)1 << i)) != 0) { - result ^= (extendedOp2 << i); + result = (short)(result ^ (extendedOp2 << i)); } } return result; } - public static sbyte PolynomialMultiply(sbyte op1, sbyte op2) => (sbyte)PolynomialMult(op1, op2); + private static poly128_t PolynomialMult(ulong op1, ulong op2) + { + poly128_t result = default(poly128_t); + poly128_t extendedOp2 = (poly128_t)op2; + + for (int i = 0; i < 8 * sizeof(ulong); i++) + { + if ((op1 & ((ulong)1 << i)) != 0) + { + result = (poly128_t)(result ^ (extendedOp2 << i)); + } + } + + return result; + } - private static ulong PolynomialMult(byte op1, byte op2) + private static poly128_t PolynomialMult(long op1, long op2) { - ulong result = 0; - ulong extendedOp2 = (ulong)op2; + poly128_t result = default(poly128_t); + poly128_t extendedOp2 = (poly128_t)op2; - for (int i = 0; i < 8 * sizeof(byte); i++) + for (int i = 0; i < 8 * sizeof(long); i++) { - if ((op1 & (1 << i)) != 0) + if ((op1 & ((long)1 << i)) != 0) { - result ^= (extendedOp2 << i); + result = (poly128_t)(result ^ (extendedOp2 << i)); } } @@ -3019,6 +3094,24 @@ private static ulong PolynomialMult(byte op1, byte op2) public static byte PolynomialMultiply(byte op1, byte op2) => (byte)PolynomialMult(op1, op2); + public static ushort PolynomialMultiplyWidening(byte op1, byte op2) => PolynomialMult(op1, op2); + + public static ushort PolynomialMultiplyWideningUpper(byte[] op1, byte[] op2, int i) => PolynomialMultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + + public static sbyte PolynomialMultiply(sbyte op1, sbyte op2) => (sbyte)PolynomialMult(op1, op2); + + public static short PolynomialMultiplyWidening(sbyte op1, sbyte op2) => PolynomialMult(op1, op2); + + public static short PolynomialMultiplyWideningUpper(sbyte[] op1, sbyte[] op2, int i) => PolynomialMultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); + + public static ulong PolynomialMultiplyWideningLo64(ulong op1, ulong op2) => PolynomialMult(op1, op2).lo; + + public static long PolynomialMultiplyWideningLo64(long op1, long op2) => (long)PolynomialMult(op1, op2).lo; + + public static ulong PolynomialMultiplyWideningHi64(ulong op1, ulong op2) => PolynomialMult(op1, op2).hi; + + public static long PolynomialMultiplyWideningHi64(long op1, long op2) => (long)PolynomialMult(op1, op2).hi; + public static bool ExtractAndNarrowHigh(int i, sbyte[] left, short[] right, sbyte[] result) diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt index a1086d6cef26d..8552ab7e435e8 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt @@ -680,31 +680,100 @@ namespace JIT.HardwareIntrinsics.Arm public static float MinNumberAcross(float[] op1) => Reduce(MinNumber, op1); + private struct poly128_t + { + public ulong lo; + public ulong hi; + + public static poly128_t operator ^(poly128_t op1, poly128_t op2) + { + op1.lo ^= op2.lo; + op1.hi ^= op2.hi; + + return op1; + } + + public static poly128_t operator <<(poly128_t val, int shiftAmount) + { + for (int i = 0; i < shiftAmount; i++) + { + val.hi <<= 1; + + if ((val.lo & 0x8000000000000000U) != 0) + { + val.hi |= 1; + } + + val.lo <<= 1; + } + + return val; + } + + public static implicit operator poly128_t(ulong lo) + { + poly128_t result = new poly128_t(); + result.lo = lo; + return result; + } + + public static explicit operator poly128_t(long lo) + { + poly128_t result = new poly128_t(); + result.lo = (ulong)lo; + return result; + } + } + <# - foreach (string typeName in new string[] { "sbyte", "byte" }) + foreach (var type in new[] { (name: "byte", wide: "ushort"), + (name: "sbyte", wide: "short"), + (name: "ulong", wide: "poly128_t"), + (name: "long", wide: "poly128_t") }) { #> - private static ulong PolynomialMult(<#= typeName #> op1, <#= typeName #> op2) + private static <#= type.wide #> PolynomialMult(<#= type.name #> op1, <#= type.name #> op2) { - ulong result = 0; - ulong extendedOp2 = (ulong)op2; + <#= type.wide #> result = default(<#= type.wide #>); + <#= type.wide #> extendedOp2 = (<#= type.wide #>)op2; - for (int i = 0; i < 8 * sizeof(<#= typeName #>); i++) + for (int i = 0; i < 8 * sizeof(<#= type.name #>); i++) { - if ((op1 & (1 << i)) != 0) + if ((op1 & ((<#= type.name #>)1 << i)) != 0) { - result ^= (extendedOp2 << i); + result = (<#= type.wide #>)(result ^ (extendedOp2 << i)); } } return result; } - public static <#= typeName #> PolynomialMultiply(<#= typeName #> op1, <#= typeName #> op2) => (<#= typeName #>)PolynomialMult(op1, op2); +<# + } + + foreach (var type in new[] { (name: "byte", wide: "ushort"), + (name: "sbyte", wide: "short") }) + { + +#> + public static <#= type.name #> PolynomialMultiply(<#= type.name #> op1, <#= type.name #> op2) => (<#= type.name #>)PolynomialMult(op1, op2); + + public static <#= type.wide #> PolynomialMultiplyWidening(<#= type.name #> op1, <#= type.name #> op2) => PolynomialMult(op1, op2); + + public static <#= type.wide #> PolynomialMultiplyWideningUpper(<#= type.name #>[] op1, <#= type.name #>[] op2, int i) => PolynomialMultiplyWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); <# } +#> + public static ulong PolynomialMultiplyWideningLo64(ulong op1, ulong op2) => PolynomialMult(op1, op2).lo; + public static long PolynomialMultiplyWideningLo64(long op1, long op2) => (long)PolynomialMult(op1, op2).lo; + + public static ulong PolynomialMultiplyWideningHi64(ulong op1, ulong op2) => PolynomialMult(op1, op2).hi; + + public static long PolynomialMultiplyWideningHi64(long op1, long op2) => (long)PolynomialMult(op1, op2).hi; + +<# foreach (var type in new[] { (small: "sbyte", wide: "short"), (small: "short", wide: "int"), (small: "int", wide: "long"), diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs index f5ffb5d6236da..ed581eb676ddd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs @@ -6994,6 +6994,34 @@ public new abstract class Arm64 : ArmBase.Arm64 /// public static Vector128 PolynomialMultiply(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + /// + /// poly16x8_t vmull_p8 (poly8x8_t a, poly8x8_t b) + /// A32: VMULL.P8 Qd, Dn, Dm + /// A64: PMULL Vd.16B, Vn.8B, Vm.8B + /// + public static Vector128 PolynomialMultiplyWideningLower(Vector64 left, Vector64 right) { throw new PlatformNotSupportedException(); } + + /// + /// poly16x8_t vmull_p8 (poly8x8_t a, poly8x8_t b) + /// A32: VMULL.P8 Qd, Dn, Dm + /// A64: PMULL Vd.16B, Vn.8B, Vm.8B + /// + public static Vector128 PolynomialMultiplyWideningLower(Vector64 left, Vector64 right) { throw new PlatformNotSupportedException(); } + + /// + /// poly16x8_t vmull_high_p8 (poly8x16_t a, poly8x16_t b) + /// A32: VMULL.P8 Qd, Dn+1, Dm+1 + /// A64: PMULL2 Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 PolynomialMultiplyWideningUpper(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// poly16x8_t vmull_high_p8 (poly8x16_t a, poly8x16_t b) + /// A32: VMULL.P8 Qd, Dn+1, Dm+1 + /// A64: PMULL2 Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 PolynomialMultiplyWideningUpper(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + /// /// uint8x8_t vcnt_u8 (uint8x8_t a) /// A32: VCNT.I8 Dd, Dm diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs index 33d80a65510c7..7f79a36693efa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs @@ -6996,6 +6996,34 @@ public new abstract class Arm64 : ArmBase.Arm64 /// public static Vector128 PolynomialMultiply(Vector128 left, Vector128 right) => PolynomialMultiply(left, right); + /// + /// poly16x8_t vmull_p8 (poly8x8_t a, poly8x8_t b) + /// A32: VMULL.P8 Qd, Dn, Dm + /// A64: PMULL Vd.16B, Vn.8B, Vm.8B + /// + public static Vector128 PolynomialMultiplyWideningLower(Vector64 left, Vector64 right) => PolynomialMultiplyWideningLower(left, right); + + /// + /// poly16x8_t vmull_p8 (poly8x8_t a, poly8x8_t b) + /// A32: VMULL.P8 Qd, Dn, Dm + /// A64: PMULL Vd.16B, Vn.8B, Vm.8B + /// + public static Vector128 PolynomialMultiplyWideningLower(Vector64 left, Vector64 right) => PolynomialMultiplyWideningLower(left, right); + + /// + /// poly16x8_t vmull_high_p8 (poly8x16_t a, poly8x16_t b) + /// A32: VMULL.P8 Qd, Dn+1, Dm+1 + /// A64: PMULL2 Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 PolynomialMultiplyWideningUpper(Vector128 left, Vector128 right) => PolynomialMultiplyWideningUpper(left, right); + + /// + /// poly16x8_t vmull_high_p8 (poly8x16_t a, poly8x16_t b) + /// A32: VMULL.P8 Qd, Dn+1, Dm+1 + /// A64: PMULL2 Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 PolynomialMultiplyWideningUpper(Vector128 left, Vector128 right) => PolynomialMultiplyWideningUpper(left, right); + /// /// uint8x8_t vcnt_u8 (uint8x8_t a) /// A32: VCNT.I8 Dd, Dm diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Aes.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Aes.PlatformNotSupported.cs index 8f62ae5fcbc94..de081c7e6e728 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Aes.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Aes.PlatformNotSupported.cs @@ -44,5 +44,34 @@ public abstract class Aes : ArmBase /// A64: AESMC V>.16B, Vn.16B /// public static Vector128 MixColumns(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// poly128_t vmull_p64 (poly64_t a, poly64_t b) + /// A32: VMULL.P8 Qd, Dn, Dm + /// A64: PMULL Vd.1Q, Vn.1D, Vm.1D + /// + public static Vector128 PolynomialMultiplyWideningLower(Vector64 left, Vector64 right) { throw new PlatformNotSupportedException(); } + + /// + /// poly128_t vmull_p64 (poly64_t a, poly64_t b) + /// A32: VMULL.P8 Qd, Dn, Dm + /// A64: PMULL Vd.1Q, Vn.1D, Vm.1D + /// + public static Vector128 PolynomialMultiplyWideningLower(Vector64 left, Vector64 right) { throw new PlatformNotSupportedException(); } + + /// + /// poly128_t vmull_high_p64 (poly64x2_t a, poly64x2_t b) + /// A32: VMULL.P8 Qd, Dn+1, Dm+1 + /// A64: PMULL2 Vd.1Q, Vn.2D, Vm.2D + /// + public static Vector128 PolynomialMultiplyWideningUpper(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// poly128_t vmull_high_p64 (poly64x2_t a, poly64x2_t b) + /// A32: VMULL.P8 Qd, Dn+1, Dm+1 + /// A64: PMULL2 Vd.1Q, Vn.2D, Vm.2D + /// + public static Vector128 PolynomialMultiplyWideningUpper(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Aes.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Aes.cs index fb0a1c63975c3..97253b888eedc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Aes.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Aes.cs @@ -44,5 +44,33 @@ public abstract class Aes : ArmBase /// A64: AESMC V>.16B, Vn.16B /// public static Vector128 MixColumns(Vector128 value) => MixColumns(value); + + /// + /// poly128_t vmull_p64 (poly64_t a, poly64_t b) + /// A32: VMULL.P8 Qd, Dn, Dm + /// A64: PMULL Vd.1Q, Vn.1D, Vm.1D + /// + public static Vector128 PolynomialMultiplyWideningLower(Vector64 left, Vector64 right) => PolynomialMultiplyWideningLower(left, right); + + /// + /// poly128_t vmull_p64 (poly64_t a, poly64_t b) + /// A32: VMULL.P8 Qd, Dn, Dm + /// A64: PMULL Vd.1Q, Vn.1D, Vm.1D + /// + public static Vector128 PolynomialMultiplyWideningLower(Vector64 left, Vector64 right) => PolynomialMultiplyWideningLower(left, right); + + /// + /// poly128_t vmull_high_p64 (poly64x2_t a, poly64x2_t b) + /// A32: VMULL.P8 Qd, Dn+1, Dm+1 + /// A64: PMULL2 Vd.1Q, Vn.2D, Vm.2D + /// + public static Vector128 PolynomialMultiplyWideningUpper(Vector128 left, Vector128 right) => PolynomialMultiplyWideningUpper(left, right); + + /// + /// poly128_t vmull_high_p64 (poly64x2_t a, poly64x2_t b) + /// A32: VMULL.P8 Qd, Dn+1, Dm+1 + /// A64: PMULL2 Vd.1Q, Vn.2D, Vm.2D + /// + public static Vector128 PolynomialMultiplyWideningUpper(Vector128 left, Vector128 right) => PolynomialMultiplyWideningUpper(left, right); } } diff --git a/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs b/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs index addbcf945c048..e903bf390fadc 100644 --- a/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs +++ b/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs @@ -341,41 +341,34 @@ public abstract partial class AdvSimd : System.Runtime.Intrinsics.Arm.ArmBase public static System.Runtime.Intrinsics.Vector64 CompareTest(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 DivideScalar(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 DivideScalar(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateSelectedScalarToVector128(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(byte value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(short value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(int value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(sbyte value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(float value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(ushort value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(uint value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector128 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateSelectedScalarToVector64(System.Runtime.Intrinsics.Vector64 value, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(byte value) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(short value) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(int value) { throw null; } @@ -383,6 +376,13 @@ public abstract partial class AdvSimd : System.Runtime.Intrinsics.Arm.ArmBase public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(float value) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(ushort value) { throw null; } public static System.Runtime.Intrinsics.Vector128 DuplicateToVector128(uint value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(byte value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(short value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(int value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(sbyte value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(float value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(ushort value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 DuplicateToVector64(uint value) { throw null; } public static byte Extract(System.Runtime.Intrinsics.Vector128 vector, byte index) { throw null; } public static double Extract(System.Runtime.Intrinsics.Vector128 vector, byte index) { throw null; } public static short Extract(System.Runtime.Intrinsics.Vector128 vector, byte index) { throw null; } @@ -732,6 +732,10 @@ public abstract partial class AdvSimd : System.Runtime.Intrinsics.Arm.ArmBase public static System.Runtime.Intrinsics.Vector128 PolynomialMultiply(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 PolynomialMultiply(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 PolynomialMultiply(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 PolynomialMultiplyWideningLower(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 PolynomialMultiplyWideningLower(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 PolynomialMultiplyWideningUpper(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 PolynomialMultiplyWideningUpper(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 PopCount(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector128 PopCount(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector64 PopCount(System.Runtime.Intrinsics.Vector64 value) { throw null; } @@ -1199,6 +1203,10 @@ public abstract partial class Aes : System.Runtime.Intrinsics.Arm.ArmBase public static System.Runtime.Intrinsics.Vector128 Encrypt(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 roundKey) { throw null; } public static System.Runtime.Intrinsics.Vector128 InverseMixColumns(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector128 MixColumns(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 PolynomialMultiplyWideningLower(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 PolynomialMultiplyWideningLower(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 PolynomialMultiplyWideningUpper(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 PolynomialMultiplyWideningUpper(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } } [System.CLSCompliantAttribute(false)] public abstract partial class ArmBase @@ -1209,7 +1217,6 @@ public abstract partial class ArmBase public static int LeadingZeroCount(uint value) { throw null; } public static int ReverseElementBits(int value) { throw null; } public static uint ReverseElementBits(uint value) { throw null; } - public abstract partial class Arm64 { internal Arm64() { } @@ -1218,7 +1225,7 @@ public abstract partial class Arm64 public static int LeadingSignCount(long value) { throw null; } public static int LeadingZeroCount(long value) { throw null; } public static int LeadingZeroCount(ulong value) { throw null; } - public static long ReverseElementBits(long value) { throw null; } + public static long ReverseElementBits(long value) { throw null; } public static ulong ReverseElementBits(ulong value) { throw null; } } } From abfdb542e8dfd72ab2715222edf527952e9fda10 Mon Sep 17 00:00:00 2001 From: buyaa-n Date: Fri, 22 May 2020 12:49:42 -0700 Subject: [PATCH 347/420] Add NotNullIfNotNull, MemberNotNull attributes to doc (#36856) --- docs/coding-guidelines/api-guidelines/nullability.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/coding-guidelines/api-guidelines/nullability.md b/docs/coding-guidelines/api-guidelines/nullability.md index 062189469fad1..997c2b38ac79f 100644 --- a/docs/coding-guidelines/api-guidelines/nullability.md +++ b/docs/coding-guidelines/api-guidelines/nullability.md @@ -95,6 +95,9 @@ The C# compiler respects a set of attributes that impact its flow analysis. We - **DO** annotate properties where a getter will never return `null` but a setter allows `null` as being non-nullable but also `[AllowNull]`. - **DO** annotate properties where a getter may return `null` but a setter throws for `null` as being nullable but also `[DisallowNull]`. - **DO** add `[NotNullWhen(true)]` to nullable arguments of `Try` methods that will definitively be non-`null` if the method returns `true`. For example, if `Int32.TryParse(string? s)` returns `true`, `s` is known to not be `null`, and so the method should be `public static bool TryParse([NotNullWhen(true)] string? s, out int result)`. +- **DO** add `[NotNullIfNotNull(string)]` if nullable ref argument will be non-`null` upon exit, when an other argument passed evaluated to non-`null`, pass that argument name as string. Example: `public void Exchange([NotNullIfNotNull("value")] ref object? location, object? value);`. +- **DO** add `[return: NotNullIfNotNull(string)]` if a method would not return `null` in case an argument passed evaluated to non-`null`, pass that argument name as string. Example: `[return: NotNullIfNotNull("name")] public string? FormatName(string? name);` +- **DO** add `[MemberNotNull(params string[])]` for a helper method which initializes member field(s), pass the field name. Example: `[MemberNotNull("_buffer")] private void InitializeBuffer()` ## Code Review Guidance From d81a2761b509162e0dbdb20d229aa4ab3f9e73eb Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Fri, 22 May 2020 13:33:59 -0700 Subject: [PATCH 348/420] [Arm64] Follow-up on renaming intrinsics to Narrowing for consistency with Widening (#36857) * Rename AddHighNarrow to AddHighNarrowing * Rename AddRoundedHighNarrow to AddRoundedHighNarrowing * Rename ExtractAndNarrowHigh to ExtractNarrowingUpper * Rename ExtractAndNarrowLow to ExtractNarrowingLower * Rename SubtractHighNarrow to SubtractHighNarrowing * Rename SubtractRoundedHighNarrow to SubtractRoundedHighNarrowing --- src/coreclr/src/jit/hwintrinsiclistarm64.h | 20 +- ...=> AddHighNarrowingLower.Vector64.Byte.cs} | 54 ++--- ...> AddHighNarrowingLower.Vector64.Int16.cs} | 54 ++--- ...> AddHighNarrowingLower.Vector64.Int32.cs} | 54 ++--- ...> AddHighNarrowingLower.Vector64.SByte.cs} | 54 ++--- ... AddHighNarrowingLower.Vector64.UInt16.cs} | 54 ++--- ... AddHighNarrowingLower.Vector64.UInt32.cs} | 54 ++--- ...> AddHighNarrowingUpper.Vector128.Byte.cs} | 54 ++--- ... AddHighNarrowingUpper.Vector128.Int16.cs} | 54 ++--- ... AddHighNarrowingUpper.Vector128.Int32.cs} | 54 ++--- ... AddHighNarrowingUpper.Vector128.SByte.cs} | 54 ++--- ...AddHighNarrowingUpper.Vector128.UInt16.cs} | 54 ++--- ...AddHighNarrowingUpper.Vector128.UInt32.cs} | 54 ++--- ...oundedHighNarrowingLower.Vector64.Byte.cs} | 54 ++--- ...undedHighNarrowingLower.Vector64.Int16.cs} | 54 ++--- ...undedHighNarrowingLower.Vector64.Int32.cs} | 54 ++--- ...undedHighNarrowingLower.Vector64.SByte.cs} | 54 ++--- ...ndedHighNarrowingLower.Vector64.UInt16.cs} | 54 ++--- ...ndedHighNarrowingLower.Vector64.UInt32.cs} | 54 ++--- ...undedHighNarrowingUpper.Vector128.Byte.cs} | 54 ++--- ...ndedHighNarrowingUpper.Vector128.Int16.cs} | 54 ++--- ...ndedHighNarrowingUpper.Vector128.Int32.cs} | 54 ++--- ...ndedHighNarrowingUpper.Vector128.SByte.cs} | 54 ++--- ...dedHighNarrowingUpper.Vector128.UInt16.cs} | 54 ++--- ...dedHighNarrowingUpper.Vector128.UInt32.cs} | 54 ++--- .../Arm/AdvSimd/AdvSimd_r.csproj | 120 +++++------ .../Arm/AdvSimd/AdvSimd_ro.csproj | 120 +++++------ ... ExtractNarrowingLower.Vector128.Int16.cs} | 54 ++--- ... ExtractNarrowingLower.Vector128.Int32.cs} | 54 ++--- ... ExtractNarrowingLower.Vector128.Int64.cs} | 54 ++--- ...ExtractNarrowingLower.Vector128.UInt16.cs} | 54 ++--- ...ExtractNarrowingLower.Vector128.UInt32.cs} | 54 ++--- ...ExtractNarrowingLower.Vector128.UInt64.cs} | 54 ++--- ... ExtractNarrowingUpper.Vector128.Int16.cs} | 67 +++---- ... ExtractNarrowingUpper.Vector128.Int32.cs} | 67 +++---- ... ExtractNarrowingUpper.Vector128.Int64.cs} | 67 +++---- ...ExtractNarrowingUpper.Vector128.UInt16.cs} | 67 +++---- ...ExtractNarrowingUpper.Vector128.UInt32.cs} | 67 +++---- ...ExtractNarrowingUpper.Vector128.UInt64.cs} | 67 +++---- .../Arm/AdvSimd/Program.AdvSimd.cs | 120 +++++------ ...btractHighNarrowingLower.Vector64.Byte.cs} | 54 ++--- ...tractHighNarrowingLower.Vector64.Int16.cs} | 54 ++--- ...tractHighNarrowingLower.Vector64.Int32.cs} | 54 ++--- ...tractHighNarrowingLower.Vector64.SByte.cs} | 54 ++--- ...ractHighNarrowingLower.Vector64.UInt16.cs} | 54 ++--- ...ractHighNarrowingLower.Vector64.UInt32.cs} | 54 ++--- ...tractHighNarrowingUpper.Vector128.Byte.cs} | 54 ++--- ...ractHighNarrowingUpper.Vector128.Int16.cs} | 54 ++--- ...ractHighNarrowingUpper.Vector128.Int32.cs} | 54 ++--- ...ractHighNarrowingUpper.Vector128.SByte.cs} | 54 ++--- ...actHighNarrowingUpper.Vector128.UInt16.cs} | 54 ++--- ...actHighNarrowingUpper.Vector128.UInt32.cs} | 54 ++--- ...oundedHighNarrowingLower.Vector64.Byte.cs} | 54 ++--- ...undedHighNarrowingLower.Vector64.Int16.cs} | 54 ++--- ...undedHighNarrowingLower.Vector64.Int32.cs} | 54 ++--- ...undedHighNarrowingLower.Vector64.SByte.cs} | 54 ++--- ...ndedHighNarrowingLower.Vector64.UInt16.cs} | 54 ++--- ...ndedHighNarrowingLower.Vector64.UInt32.cs} | 54 ++--- ...undedHighNarrowingUpper.Vector128.Byte.cs} | 54 ++--- ...ndedHighNarrowingUpper.Vector128.Int16.cs} | 54 ++--- ...ndedHighNarrowingUpper.Vector128.Int32.cs} | 54 ++--- ...ndedHighNarrowingUpper.Vector128.SByte.cs} | 54 ++--- ...dedHighNarrowingUpper.Vector128.UInt16.cs} | 54 ++--- ...dedHighNarrowingUpper.Vector128.UInt32.cs} | 54 ++--- .../Arm/Shared/GenerateTests.csx | 120 +++++------ .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 186 ++++++++---------- .../HardwareIntrinsics/Arm/Shared/Helpers.tt | 42 ++-- .../Arm/AdvSimd.PlatformNotSupported.cs | 120 +++++------ .../System/Runtime/Intrinsics/Arm/AdvSimd.cs | 120 +++++------ .../System.Runtime.Intrinsics.Experimental.cs | 120 +++++------ 70 files changed, 2159 insertions(+), 2247 deletions(-) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddHighNarrowLower.Vector64.Byte.cs => AddHighNarrowingLower.Vector64.Byte.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddHighNarrowLower.Vector64.Int16.cs => AddHighNarrowingLower.Vector64.Int16.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddHighNarrowLower.Vector64.Int32.cs => AddHighNarrowingLower.Vector64.Int32.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddHighNarrowLower.Vector64.SByte.cs => AddHighNarrowingLower.Vector64.SByte.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddHighNarrowLower.Vector64.UInt16.cs => AddHighNarrowingLower.Vector64.UInt16.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddHighNarrowLower.Vector64.UInt32.cs => AddHighNarrowingLower.Vector64.UInt32.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddHighNarrowUpper.Vector128.Byte.cs => AddHighNarrowingUpper.Vector128.Byte.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddHighNarrowUpper.Vector128.Int16.cs => AddHighNarrowingUpper.Vector128.Int16.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddHighNarrowUpper.Vector128.Int32.cs => AddHighNarrowingUpper.Vector128.Int32.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddHighNarrowUpper.Vector128.SByte.cs => AddHighNarrowingUpper.Vector128.SByte.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddHighNarrowUpper.Vector128.UInt16.cs => AddHighNarrowingUpper.Vector128.UInt16.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddHighNarrowUpper.Vector128.UInt32.cs => AddHighNarrowingUpper.Vector128.UInt32.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddRoundedHighNarrowLower.Vector64.Byte.cs => AddRoundedHighNarrowingLower.Vector64.Byte.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddRoundedHighNarrowLower.Vector64.Int16.cs => AddRoundedHighNarrowingLower.Vector64.Int16.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddRoundedHighNarrowLower.Vector64.Int32.cs => AddRoundedHighNarrowingLower.Vector64.Int32.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddRoundedHighNarrowLower.Vector64.SByte.cs => AddRoundedHighNarrowingLower.Vector64.SByte.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddRoundedHighNarrowLower.Vector64.UInt16.cs => AddRoundedHighNarrowingLower.Vector64.UInt16.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddRoundedHighNarrowLower.Vector64.UInt32.cs => AddRoundedHighNarrowingLower.Vector64.UInt32.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddRoundedHighNarrowUpper.Vector128.Byte.cs => AddRoundedHighNarrowingUpper.Vector128.Byte.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddRoundedHighNarrowUpper.Vector128.Int16.cs => AddRoundedHighNarrowingUpper.Vector128.Int16.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddRoundedHighNarrowUpper.Vector128.Int32.cs => AddRoundedHighNarrowingUpper.Vector128.Int32.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddRoundedHighNarrowUpper.Vector128.SByte.cs => AddRoundedHighNarrowingUpper.Vector128.SByte.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddRoundedHighNarrowUpper.Vector128.UInt16.cs => AddRoundedHighNarrowingUpper.Vector128.UInt16.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{AddRoundedHighNarrowUpper.Vector128.UInt32.cs => AddRoundedHighNarrowingUpper.Vector128.UInt32.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{ExtractAndNarrowLow.Vector128.Int16.cs => ExtractNarrowingLower.Vector128.Int16.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{ExtractAndNarrowLow.Vector128.Int32.cs => ExtractNarrowingLower.Vector128.Int32.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{ExtractAndNarrowLow.Vector128.Int64.cs => ExtractNarrowingLower.Vector128.Int64.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{ExtractAndNarrowLow.Vector128.UInt16.cs => ExtractNarrowingLower.Vector128.UInt16.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{ExtractAndNarrowLow.Vector128.UInt32.cs => ExtractNarrowingLower.Vector128.UInt32.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{ExtractAndNarrowLow.Vector128.UInt64.cs => ExtractNarrowingLower.Vector128.UInt64.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{ExtractAndNarrowHigh.Vector128.Int16.cs => ExtractNarrowingUpper.Vector128.Int16.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{ExtractAndNarrowHigh.Vector128.Int32.cs => ExtractNarrowingUpper.Vector128.Int32.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{ExtractAndNarrowHigh.Vector128.Int64.cs => ExtractNarrowingUpper.Vector128.Int64.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{ExtractAndNarrowHigh.Vector128.UInt16.cs => ExtractNarrowingUpper.Vector128.UInt16.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{ExtractAndNarrowHigh.Vector128.UInt32.cs => ExtractNarrowingUpper.Vector128.UInt32.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{ExtractAndNarrowHigh.Vector128.UInt64.cs => ExtractNarrowingUpper.Vector128.UInt64.cs} (90%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractHighNarrowLower.Vector64.Byte.cs => SubtractHighNarrowingLower.Vector64.Byte.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractHighNarrowLower.Vector64.Int16.cs => SubtractHighNarrowingLower.Vector64.Int16.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractHighNarrowLower.Vector64.Int32.cs => SubtractHighNarrowingLower.Vector64.Int32.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractHighNarrowLower.Vector64.SByte.cs => SubtractHighNarrowingLower.Vector64.SByte.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractHighNarrowLower.Vector64.UInt16.cs => SubtractHighNarrowingLower.Vector64.UInt16.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractHighNarrowLower.Vector64.UInt32.cs => SubtractHighNarrowingLower.Vector64.UInt32.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractHighNarrowUpper.Vector128.Byte.cs => SubtractHighNarrowingUpper.Vector128.Byte.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractHighNarrowUpper.Vector128.Int16.cs => SubtractHighNarrowingUpper.Vector128.Int16.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractHighNarrowUpper.Vector128.Int32.cs => SubtractHighNarrowingUpper.Vector128.Int32.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractHighNarrowUpper.Vector128.SByte.cs => SubtractHighNarrowingUpper.Vector128.SByte.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractHighNarrowUpper.Vector128.UInt16.cs => SubtractHighNarrowingUpper.Vector128.UInt16.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractHighNarrowUpper.Vector128.UInt32.cs => SubtractHighNarrowingUpper.Vector128.UInt32.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractRoundedHighNarrowLower.Vector64.Byte.cs => SubtractRoundedHighNarrowingLower.Vector64.Byte.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractRoundedHighNarrowLower.Vector64.Int16.cs => SubtractRoundedHighNarrowingLower.Vector64.Int16.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractRoundedHighNarrowLower.Vector64.Int32.cs => SubtractRoundedHighNarrowingLower.Vector64.Int32.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractRoundedHighNarrowLower.Vector64.SByte.cs => SubtractRoundedHighNarrowingLower.Vector64.SByte.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractRoundedHighNarrowLower.Vector64.UInt16.cs => SubtractRoundedHighNarrowingLower.Vector64.UInt16.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractRoundedHighNarrowLower.Vector64.UInt32.cs => SubtractRoundedHighNarrowingLower.Vector64.UInt32.cs} (91%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractRoundedHighNarrowUpper.Vector128.Byte.cs => SubtractRoundedHighNarrowingUpper.Vector128.Byte.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractRoundedHighNarrowUpper.Vector128.Int16.cs => SubtractRoundedHighNarrowingUpper.Vector128.Int16.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractRoundedHighNarrowUpper.Vector128.Int32.cs => SubtractRoundedHighNarrowingUpper.Vector128.Int32.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractRoundedHighNarrowUpper.Vector128.SByte.cs => SubtractRoundedHighNarrowingUpper.Vector128.SByte.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractRoundedHighNarrowUpper.Vector128.UInt16.cs => SubtractRoundedHighNarrowingUpper.Vector128.UInt16.cs} (92%) rename src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/{SubtractRoundedHighNarrowUpper.Vector128.UInt32.cs => SubtractRoundedHighNarrowingUpper.Vector128.UInt32.cs} (92%) diff --git a/src/coreclr/src/jit/hwintrinsiclistarm64.h b/src/coreclr/src/jit/hwintrinsiclistarm64.h index a8011ab80b6fd..dc6436de9a77d 100644 --- a/src/coreclr/src/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/src/jit/hwintrinsiclistarm64.h @@ -80,15 +80,15 @@ HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningLowerAndAdd, HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningUpper, 16, 2, {INS_sabdl2, INS_uabdl2, INS_sabdl2, INS_uabdl2, INS_sabdl2, INS_uabdl2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningUpperAndAdd, 16, 3, {INS_sabal2, INS_uabal2, INS_sabal2, INS_uabal2, INS_sabal2, INS_uabal2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) HARDWARE_INTRINSIC(AdvSimd, Add, -1, 2, {INS_add, INS_add, INS_add, INS_add, INS_add, INS_add, INS_add, INS_add, INS_fadd, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, AddHighNarrowLower, 8, 2, {INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, AddHighNarrowUpper, 16, 3, {INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, AddHighNarrowingLower, 8, 2, {INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, AddHighNarrowingUpper, 16, 3, {INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(AdvSimd, AddPairwise, 8, 2, {INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_invalid, INS_invalid, INS_faddp, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWidening, -1, 1, {INS_saddlp, INS_uaddlp, INS_saddlp, INS_uaddlp, INS_saddlp, INS_uaddlp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWideningAndAdd, -1, 2, {INS_sadalp, INS_uadalp, INS_sadalp, INS_uadalp, INS_sadalp, INS_uadalp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWideningAndAddScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sadalp, INS_uadalp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWideningScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_saddlp, INS_uaddlp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd, AddRoundedHighNarrowLower, 8, 2, {INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, AddRoundedHighNarrowUpper, 16, 3, {INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, AddRoundedHighNarrowingLower, 8, 2, {INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, AddRoundedHighNarrowingUpper, 16, 3, {INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(AdvSimd, AddSaturate, -1, 2, {INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AdvSimd, AddSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqadd, INS_uqadd, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_Commutative) HARDWARE_INTRINSIC(AdvSimd, AddScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_add, INS_add, INS_fadd, INS_fadd}, HW_Category_SIMDScalar, HW_Flag_Commutative) @@ -110,8 +110,8 @@ HARDWARE_INTRINSIC(AdvSimd, DuplicateSelectedScalarToVector128, - HARDWARE_INTRINSIC(AdvSimd, DuplicateToVector64, 8, 1, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AdvSimd, DuplicateToVector128, 16, 1, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AdvSimd, Extract, -1, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, ExtractAndNarrowHigh, 16, 2, {INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, ExtractAndNarrowLow, 8, 1, {INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ExtractNarrowingUpper, 16, 2, {INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ExtractNarrowingLower, 8, 1, {INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, ExtractVector64, 8, 3, {INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_invalid, INS_invalid, INS_ext, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AdvSimd, ExtractVector128, 16, 3, {INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AdvSimd, Floor, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frintm, INS_frintm}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) @@ -163,10 +163,10 @@ HARDWARE_INTRINSIC(AdvSimd, ReciprocalStep, - HARDWARE_INTRINSIC(AdvSimd, SqrtScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fsqrt, INS_fsqrt}, HW_Category_SIMDScalar, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, Store, -1, 2, {INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1}, HW_Category_MemoryStore, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) HARDWARE_INTRINSIC(AdvSimd, Subtract, -1, 2, {INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_fsub, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, SubtractHighNarrowLower, 8, 2, {INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, SubtractHighNarrowUpper, 16, 3, {INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, SubtractRoundedHighNarrowLower, 8, 2, {INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, SubtractRoundedHighNarrowUpper, 16, 3, {INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, SubtractHighNarrowingLower, 8, 2, {INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, SubtractHighNarrowingUpper, 16, 3, {INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, SubtractRoundedHighNarrowingLower, 8, 2, {INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, SubtractRoundedHighNarrowingUpper, 16, 3, {INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(AdvSimd, SubtractSaturate, -1, 2, {INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, SubtractSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqsub, INS_uqsub, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AdvSimd, SubtractScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sub, INS_sub, INS_fsub, INS_fsub}, HW_Category_SIMDScalar, HW_Flag_NoFlag) diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.Byte.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.Byte.cs index 3afd373050037..5468c6e2326db 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddHighNarrowLower_Vector64_Byte() + private static void AddHighNarrowingLower_Vector64_Byte() { - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddHighNarrowLower_Vector64_Byte() } } - public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte + public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Byte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Byte testClass) { - var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Byte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vec private DataTable _dataTable; - static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte() + static SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte() + public SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Byte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte(); - var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Byte(); + var result = AdvSimd.AddHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Byte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.Int16.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.Int16.cs index 5b7b69db8a75f..aef7a1a9f85ee 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddHighNarrowLower_Vector64_Int16() + private static void AddHighNarrowingLower_Vector64_Int16() { - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddHighNarrowLower_Vector64_Int16() } } - public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16 + public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int16 testClass) { - var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vec private DataTable _dataTable; - static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16() + static SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16() + public SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16(); - var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int16(); + var result = AdvSimd.AddHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.Int32.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.Int32.cs index dd832dd534564..c8bed51ae70bb 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddHighNarrowLower_Vector64_Int32() + private static void AddHighNarrowingLower_Vector64_Int32() { - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddHighNarrowLower_Vector64_Int32() } } - public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32 + public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int32 testClass) { - var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vec private DataTable _dataTable; - static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32() + static SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32() + public SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32(); - var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int32(); + var result = AdvSimd.AddHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_Int32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.SByte.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.SByte.cs index 89fe1b5029ecb..024712d6f9545 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddHighNarrowLower_Vector64_SByte() + private static void AddHighNarrowingLower_Vector64_SByte() { - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddHighNarrowLower_Vector64_SByte() } } - public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte + public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_SByte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_SByte testClass) { - var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_SByte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vec private DataTable _dataTable; - static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte() + static SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte() + public SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_SByte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte(); - var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_SByte(); + var result = AdvSimd.AddHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_SByte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.UInt16.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.UInt16.cs index b61ff798ed8cf..6d9318b1f6931 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddHighNarrowLower_Vector64_UInt16() + private static void AddHighNarrowingLower_Vector64_UInt16() { - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddHighNarrowLower_Vector64_UInt16() } } - public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16 + public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt16 testClass) { - var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vec private DataTable _dataTable; - static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16() + static SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16() + public SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16(); - var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt16(); + var result = AdvSimd.AddHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.UInt32.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.UInt32.cs index 9d3c0769354f9..bb587e95effa5 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowLower.Vector64.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingLower.Vector64.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddHighNarrowLower_Vector64_UInt32() + private static void AddHighNarrowingLower_Vector64_UInt32() { - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddHighNarrowLower_Vector64_UInt32() } } - public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32 + public sealed unsafe class SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt32 testClass) { - var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddHighNarrowLower_Vec private DataTable _dataTable; - static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32() + static SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32() + public SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddHighNarrowLower(op1, op2); + var result = AdvSimd.AddHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32(); - var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt32(); + var result = AdvSimd.AddHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__AddHighNarrowingLower_Vector64_UInt32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowLower( + var result = AdvSimd.AddHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.Byte.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.Byte.cs index 7a070b8a17920..400ff583a4a95 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddHighNarrowUpper_Vector128_Byte() + private static void AddHighNarrowingUpper_Vector128_Byte() { - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddHighNarrowUpper_Vector128_Byte() } } - public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte + public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Byte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Byte testClass) { - var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Byte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Ve private DataTable _dataTable; - static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte() + static SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte() + public SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Byte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)), AdvSimd.LoadVector128((UInt16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte(); - var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Byte(); + var result = AdvSimd.AddHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Byte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)), AdvSimd.LoadVector128((UInt16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.Int16.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.Int16.cs index a3897efe7c132..1ed95b9057f43 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddHighNarrowUpper_Vector128_Int16() + private static void AddHighNarrowingUpper_Vector128_Int16() { - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddHighNarrowUpper_Vector128_Int16() } } - public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16 + public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int16 testClass) { - var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Ve private DataTable _dataTable; - static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16() + static SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16() + public SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)), AdvSimd.LoadVector128((Int32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16(); - var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int16(); + var result = AdvSimd.AddHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)), AdvSimd.LoadVector128((Int32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.Int32.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.Int32.cs index 45740dbbcee63..ba16eab980ede 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddHighNarrowUpper_Vector128_Int32() + private static void AddHighNarrowingUpper_Vector128_Int32() { - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddHighNarrowUpper_Vector128_Int32() } } - public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32 + public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int32 testClass) { - var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Ve private DataTable _dataTable; - static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32() + static SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32() + public SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)), AdvSimd.LoadVector128((Int64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32(); - var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int32(); + var result = AdvSimd.AddHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_Int32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)), AdvSimd.LoadVector128((Int64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.SByte.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.SByte.cs index 23d291db07c17..93fcc6036ab16 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddHighNarrowUpper_Vector128_SByte() + private static void AddHighNarrowingUpper_Vector128_SByte() { - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddHighNarrowUpper_Vector128_SByte() } } - public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte + public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_SByte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_SByte testClass) { - var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_SByte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Ve private DataTable _dataTable; - static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte() + static SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte() + public SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_SByte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)), AdvSimd.LoadVector128((Int16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte(); - var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_SByte(); + var result = AdvSimd.AddHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_SByte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)), AdvSimd.LoadVector128((Int16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.UInt16.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.UInt16.cs index aab766401538c..2ab6d94fdcb95 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddHighNarrowUpper_Vector128_UInt16() + private static void AddHighNarrowingUpper_Vector128_UInt16() { - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddHighNarrowUpper_Vector128_UInt16() } } - public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16 + public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt16 testClass) { - var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Ve private DataTable _dataTable; - static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16() + static SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16() + public SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)), AdvSimd.LoadVector128((UInt32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16(); - var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt16(); + var result = AdvSimd.AddHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)), AdvSimd.LoadVector128((UInt32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.UInt32.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.UInt32.cs index dd881a90a4467..c09986aa72125 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowUpper.Vector128.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddHighNarrowingUpper.Vector128.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddHighNarrowUpper_Vector128_UInt32() + private static void AddHighNarrowingUpper_Vector128_UInt32() { - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddHighNarrowUpper_Vector128_UInt32() } } - public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32 + public sealed unsafe class SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt32 testClass) { - var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddHighNarrowUpper_Ve private DataTable _dataTable; - static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32() + static SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32() + public SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)), AdvSimd.LoadVector128((UInt64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32(); - var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt32(); + var result = AdvSimd.AddHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__AddHighNarrowingUpper_Vector128_UInt32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddHighNarrowUpper( + var result = AdvSimd.AddHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)), AdvSimd.LoadVector128((UInt64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.Byte.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.Byte.cs index b05d6361fbd20..1724511cd47f6 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddRoundedHighNarrowLower_Vector64_Byte() + private static void AddRoundedHighNarrowingLower_Vector64_Byte() { - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddRoundedHighNarrowLower_Vector64_Byte() } } - public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte + public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Byte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Byte testClass) { - var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Byte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLo private DataTable _dataTable; - static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte() + static SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte() + public SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Byte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte(); - var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Byte(); + var result = AdvSimd.AddRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Byte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.Int16.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.Int16.cs index 07985b071e27c..21fc2ac668e35 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddRoundedHighNarrowLower_Vector64_Int16() + private static void AddRoundedHighNarrowingLower_Vector64_Int16() { - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddRoundedHighNarrowLower_Vector64_Int16() } } - public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16 + public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int16 testClass) { - var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLo private DataTable _dataTable; - static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16() + static SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16() + public SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16(); - var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int16(); + var result = AdvSimd.AddRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.Int32.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.Int32.cs index 70291f629f7be..8812d14278392 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddRoundedHighNarrowLower_Vector64_Int32() + private static void AddRoundedHighNarrowingLower_Vector64_Int32() { - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddRoundedHighNarrowLower_Vector64_Int32() } } - public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32 + public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int32 testClass) { - var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLo private DataTable _dataTable; - static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32() + static SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32() + public SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32(); - var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int32(); + var result = AdvSimd.AddRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_Int32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.SByte.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.SByte.cs index 3ff7bbe113b0c..0d3355f2bb446 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddRoundedHighNarrowLower_Vector64_SByte() + private static void AddRoundedHighNarrowingLower_Vector64_SByte() { - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddRoundedHighNarrowLower_Vector64_SByte() } } - public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte + public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_SByte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_SByte testClass) { - var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_SByte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLo private DataTable _dataTable; - static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte() + static SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte() + public SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_SByte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte(); - var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_SByte(); + var result = AdvSimd.AddRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_SByte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.UInt16.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.UInt16.cs index d8c3191bcf669..09a517e548465 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddRoundedHighNarrowLower_Vector64_UInt16() + private static void AddRoundedHighNarrowingLower_Vector64_UInt16() { - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddRoundedHighNarrowLower_Vector64_UInt16() } } - public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16 + public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt16 testClass) { - var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLo private DataTable _dataTable; - static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16() + static SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16() + public SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16(); - var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt16(); + var result = AdvSimd.AddRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.UInt32.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.UInt32.cs index baab52fe7dae7..bd51ff2b4af55 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowLower.Vector64.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingLower.Vector64.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddRoundedHighNarrowLower_Vector64_UInt32() + private static void AddRoundedHighNarrowingLower_Vector64_UInt32() { - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddRoundedHighNarrowLower_Vector64_UInt32() } } - public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32 + public sealed unsafe class SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt32 testClass) { - var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__AddRoundedHighNarrowLo private DataTable _dataTable; - static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32() + static SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32() + public SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.AddRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.AddRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32(); - var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt32(); + var result = AdvSimd.AddRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__AddRoundedHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__AddRoundedHighNarrowingLower_Vector64_UInt32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.AddRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowLower( + var result = AdvSimd.AddRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.Byte.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.Byte.cs index e6abcafcc588b..f62db16fae2ed 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddRoundedHighNarrowUpper_Vector128_Byte() + private static void AddRoundedHighNarrowingUpper_Vector128_Byte() { - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddRoundedHighNarrowUpper_Vector128_Byte() } } - public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte + public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Byte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Byte testClass) { - var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Byte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowU private DataTable _dataTable; - static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte() + static SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte() + public SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Byte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)), AdvSimd.LoadVector128((UInt16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte(); - var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Byte(); + var result = AdvSimd.AddRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Byte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)), AdvSimd.LoadVector128((UInt16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.Int16.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.Int16.cs index bbfae2866920e..b2e8e80e0de3d 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddRoundedHighNarrowUpper_Vector128_Int16() + private static void AddRoundedHighNarrowingUpper_Vector128_Int16() { - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddRoundedHighNarrowUpper_Vector128_Int16() } } - public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16 + public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int16 testClass) { - var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowU private DataTable _dataTable; - static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16() + static SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16() + public SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)), AdvSimd.LoadVector128((Int32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16(); - var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int16(); + var result = AdvSimd.AddRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)), AdvSimd.LoadVector128((Int32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.Int32.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.Int32.cs index 9dc5d969279b1..f73507f28f3ea 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddRoundedHighNarrowUpper_Vector128_Int32() + private static void AddRoundedHighNarrowingUpper_Vector128_Int32() { - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddRoundedHighNarrowUpper_Vector128_Int32() } } - public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32 + public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int32 testClass) { - var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowU private DataTable _dataTable; - static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32() + static SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32() + public SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)), AdvSimd.LoadVector128((Int64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32(); - var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int32(); + var result = AdvSimd.AddRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_Int32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)), AdvSimd.LoadVector128((Int64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.SByte.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.SByte.cs index 5ac9c441385ec..b12db4a90614b 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddRoundedHighNarrowUpper_Vector128_SByte() + private static void AddRoundedHighNarrowingUpper_Vector128_SByte() { - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddRoundedHighNarrowUpper_Vector128_SByte() } } - public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte + public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_SByte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_SByte testClass) { - var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_SByte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowU private DataTable _dataTable; - static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte() + static SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte() + public SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_SByte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)), AdvSimd.LoadVector128((Int16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte(); - var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_SByte(); + var result = AdvSimd.AddRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_SByte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)), AdvSimd.LoadVector128((Int16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.UInt16.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.UInt16.cs index 7eddbc5f6d780..0e96972f6db9c 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddRoundedHighNarrowUpper_Vector128_UInt16() + private static void AddRoundedHighNarrowingUpper_Vector128_UInt16() { - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddRoundedHighNarrowUpper_Vector128_UInt16() } } - public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16 + public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt16 testClass) { - var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowU private DataTable _dataTable; - static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16() + static SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16() + public SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)), AdvSimd.LoadVector128((UInt32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16(); - var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt16(); + var result = AdvSimd.AddRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)), AdvSimd.LoadVector128((UInt32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.UInt32.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.UInt32.cs index fb7e068bd16de..03f2f544b4323 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowUpper.Vector128.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AddRoundedHighNarrowingUpper.Vector128.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void AddRoundedHighNarrowUpper_Vector128_UInt32() + private static void AddRoundedHighNarrowingUpper_Vector128_UInt32() { - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void AddRoundedHighNarrowUpper_Vector128_UInt32() } } - public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32 + public sealed unsafe class SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt32 testClass) { - var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__AddRoundedHighNarrowU private DataTable _dataTable; - static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32() + static SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32() + public SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.AddRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)), AdvSimd.LoadVector128((UInt64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.AddRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32(); - var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt32(); + var result = AdvSimd.AddRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__AddRoundedHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__AddRoundedHighNarrowingUpper_Vector128_UInt32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.AddRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.AddRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.AddRoundedHighNarrowUpper( + var result = AdvSimd.AddRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)), AdvSimd.LoadVector128((UInt64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.AddRoundedHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj index 0a2139adeb4b6..ccfb426682ad1 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj @@ -92,18 +92,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + @@ -135,18 +135,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + @@ -410,18 +410,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + @@ -800,30 +800,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj index ed52c2b89031c..de83f25f8e551 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj @@ -92,18 +92,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + @@ -135,18 +135,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + @@ -410,18 +410,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + @@ -800,30 +800,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.Int16.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.Int16.cs index 86ebd70207fda..c6bc0bca5bec5 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void ExtractAndNarrowLow_Vector128_Int16() + private static void ExtractNarrowingLower_Vector128_Int16() { - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int16(); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void ExtractAndNarrowLow_Vector128_Int16() } } - public sealed unsafe class SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int16 + public sealed unsafe class SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int16 { private struct DataTable { @@ -171,19 +171,19 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int16 testClass) + public void RunStructFldScenario(SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int16 testClass) { - var result = AdvSimd.ExtractAndNarrowLow(_fld1); + var result = AdvSimd.ExtractNarrowingLower(_fld1); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int16 testClass) + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int16 testClass) { fixed (Vector128* pFld1 = &_fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)) ); @@ -206,13 +206,13 @@ public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractAndNarrowLow_Vec private DataTable _dataTable; - static SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int16() + static SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); } - public SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int16() + public SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int16() { Succeeded = true; @@ -231,7 +231,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr) ); @@ -243,7 +243,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)) ); @@ -255,7 +255,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowLow), new Type[] { typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingLower), new Type[] { typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr) }); @@ -268,7 +268,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowLow), new Type[] { typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingLower), new Type[] { typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)) }); @@ -281,7 +281,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( _clsVar1 ); @@ -295,7 +295,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int16*)(pClsVar1)) ); @@ -309,7 +309,7 @@ public void RunLclVarScenario_UnsafeRead() TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); - var result = AdvSimd.ExtractAndNarrowLow(op1); + var result = AdvSimd.ExtractNarrowingLower(op1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, _dataTable.outArrayPtr); @@ -320,7 +320,7 @@ public void RunLclVarScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); - var result = AdvSimd.ExtractAndNarrowLow(op1); + var result = AdvSimd.ExtractNarrowingLower(op1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, _dataTable.outArrayPtr); @@ -330,8 +330,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int16(); - var result = AdvSimd.ExtractAndNarrowLow(test._fld1); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int16(); + var result = AdvSimd.ExtractNarrowingLower(test._fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, _dataTable.outArrayPtr); @@ -341,11 +341,11 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int16(); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int16(); fixed (Vector128* pFld1 = &test._fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)) ); @@ -358,7 +358,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.ExtractAndNarrowLow(_fld1); + var result = AdvSimd.ExtractNarrowingLower(_fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _dataTable.outArrayPtr); @@ -370,7 +370,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)) ); @@ -384,7 +384,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowLow(test._fld1); + var result = AdvSimd.ExtractNarrowingLower(test._fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, _dataTable.outArrayPtr); @@ -395,7 +395,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int16*)(&test._fld1)) ); @@ -468,7 +468,7 @@ private void ValidateResult(Int16[] firstOp, SByte[] result, [CallerMemberName] for (var i = 0; i < RetElementCount; i++) { - if (((SByte)firstOp[i]) != result[i]) + if (Helpers.ExtractNarrowing(firstOp[i]) != result[i]) { succeeded = false; break; @@ -477,7 +477,7 @@ private void ValidateResult(Int16[] firstOp, SByte[] result, [CallerMemberName] if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractAndNarrowLow)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractNarrowingLower)}(Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); TestLibrary.TestFramework.LogInformation(string.Empty); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.Int32.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.Int32.cs index b7184d0e1edfc..5f7391b3d1655 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void ExtractAndNarrowLow_Vector128_Int32() + private static void ExtractNarrowingLower_Vector128_Int32() { - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int32(); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void ExtractAndNarrowLow_Vector128_Int32() } } - public sealed unsafe class SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int32 + public sealed unsafe class SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int32 { private struct DataTable { @@ -171,19 +171,19 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int32 testClass) + public void RunStructFldScenario(SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int32 testClass) { - var result = AdvSimd.ExtractAndNarrowLow(_fld1); + var result = AdvSimd.ExtractNarrowingLower(_fld1); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int32 testClass) + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int32 testClass) { fixed (Vector128* pFld1 = &_fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)) ); @@ -206,13 +206,13 @@ public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractAndNarrowLow_Vec private DataTable _dataTable; - static SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int32() + static SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); } - public SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int32() + public SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int32() { Succeeded = true; @@ -231,7 +231,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr) ); @@ -243,7 +243,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)) ); @@ -255,7 +255,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowLow), new Type[] { typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingLower), new Type[] { typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr) }); @@ -268,7 +268,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowLow), new Type[] { typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingLower), new Type[] { typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)) }); @@ -281,7 +281,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( _clsVar1 ); @@ -295,7 +295,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int32*)(pClsVar1)) ); @@ -309,7 +309,7 @@ public void RunLclVarScenario_UnsafeRead() TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); - var result = AdvSimd.ExtractAndNarrowLow(op1); + var result = AdvSimd.ExtractNarrowingLower(op1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, _dataTable.outArrayPtr); @@ -320,7 +320,7 @@ public void RunLclVarScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); - var result = AdvSimd.ExtractAndNarrowLow(op1); + var result = AdvSimd.ExtractNarrowingLower(op1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, _dataTable.outArrayPtr); @@ -330,8 +330,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int32(); - var result = AdvSimd.ExtractAndNarrowLow(test._fld1); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int32(); + var result = AdvSimd.ExtractNarrowingLower(test._fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, _dataTable.outArrayPtr); @@ -341,11 +341,11 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int32(); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int32(); fixed (Vector128* pFld1 = &test._fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)) ); @@ -358,7 +358,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.ExtractAndNarrowLow(_fld1); + var result = AdvSimd.ExtractNarrowingLower(_fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _dataTable.outArrayPtr); @@ -370,7 +370,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)) ); @@ -384,7 +384,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowLow(test._fld1); + var result = AdvSimd.ExtractNarrowingLower(test._fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, _dataTable.outArrayPtr); @@ -395,7 +395,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int32*)(&test._fld1)) ); @@ -468,7 +468,7 @@ private void ValidateResult(Int32[] firstOp, Int16[] result, [CallerMemberName] for (var i = 0; i < RetElementCount; i++) { - if (((Int16)firstOp[i]) != result[i]) + if (Helpers.ExtractNarrowing(firstOp[i]) != result[i]) { succeeded = false; break; @@ -477,7 +477,7 @@ private void ValidateResult(Int32[] firstOp, Int16[] result, [CallerMemberName] if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractAndNarrowLow)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractNarrowingLower)}(Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); TestLibrary.TestFramework.LogInformation(string.Empty); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.Int64.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.Int64.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.Int64.cs index 3e74619f8c4a2..b409826445084 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.Int64.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.Int64.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void ExtractAndNarrowLow_Vector128_Int64() + private static void ExtractNarrowingLower_Vector128_Int64() { - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int64(); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int64(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void ExtractAndNarrowLow_Vector128_Int64() } } - public sealed unsafe class SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int64 + public sealed unsafe class SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int64 { private struct DataTable { @@ -171,19 +171,19 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int64 testClass) + public void RunStructFldScenario(SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int64 testClass) { - var result = AdvSimd.ExtractAndNarrowLow(_fld1); + var result = AdvSimd.ExtractNarrowingLower(_fld1); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int64 testClass) + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int64 testClass) { fixed (Vector128* pFld1 = &_fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)) ); @@ -206,13 +206,13 @@ public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractAndNarrowLow_Vec private DataTable _dataTable; - static SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int64() + static SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int64() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); } - public SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int64() + public SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int64() { Succeeded = true; @@ -231,7 +231,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr) ); @@ -243,7 +243,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)) ); @@ -255,7 +255,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowLow), new Type[] { typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingLower), new Type[] { typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr) }); @@ -268,7 +268,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowLow), new Type[] { typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingLower), new Type[] { typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)) }); @@ -281,7 +281,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( _clsVar1 ); @@ -295,7 +295,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int64*)(pClsVar1)) ); @@ -309,7 +309,7 @@ public void RunLclVarScenario_UnsafeRead() TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); - var result = AdvSimd.ExtractAndNarrowLow(op1); + var result = AdvSimd.ExtractNarrowingLower(op1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, _dataTable.outArrayPtr); @@ -320,7 +320,7 @@ public void RunLclVarScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); - var result = AdvSimd.ExtractAndNarrowLow(op1); + var result = AdvSimd.ExtractNarrowingLower(op1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, _dataTable.outArrayPtr); @@ -330,8 +330,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int64(); - var result = AdvSimd.ExtractAndNarrowLow(test._fld1); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int64(); + var result = AdvSimd.ExtractNarrowingLower(test._fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, _dataTable.outArrayPtr); @@ -341,11 +341,11 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_Int64(); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_Int64(); fixed (Vector128* pFld1 = &test._fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)) ); @@ -358,7 +358,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.ExtractAndNarrowLow(_fld1); + var result = AdvSimd.ExtractNarrowingLower(_fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _dataTable.outArrayPtr); @@ -370,7 +370,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)) ); @@ -384,7 +384,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowLow(test._fld1); + var result = AdvSimd.ExtractNarrowingLower(test._fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, _dataTable.outArrayPtr); @@ -395,7 +395,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((Int64*)(&test._fld1)) ); @@ -468,7 +468,7 @@ private void ValidateResult(Int64[] firstOp, Int32[] result, [CallerMemberName] for (var i = 0; i < RetElementCount; i++) { - if (((Int32)firstOp[i]) != result[i]) + if (Helpers.ExtractNarrowing(firstOp[i]) != result[i]) { succeeded = false; break; @@ -477,7 +477,7 @@ private void ValidateResult(Int64[] firstOp, Int32[] result, [CallerMemberName] if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractAndNarrowLow)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractNarrowingLower)}(Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); TestLibrary.TestFramework.LogInformation(string.Empty); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.UInt16.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.UInt16.cs index b57d6294cbd88..5c739b97a9941 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void ExtractAndNarrowLow_Vector128_UInt16() + private static void ExtractNarrowingLower_Vector128_UInt16() { - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt16(); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void ExtractAndNarrowLow_Vector128_UInt16() } } - public sealed unsafe class SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt16 + public sealed unsafe class SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt16 { private struct DataTable { @@ -171,19 +171,19 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt16 testClass) + public void RunStructFldScenario(SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt16 testClass) { - var result = AdvSimd.ExtractAndNarrowLow(_fld1); + var result = AdvSimd.ExtractNarrowingLower(_fld1); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt16 testClass) { fixed (Vector128* pFld1 = &_fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)) ); @@ -206,13 +206,13 @@ public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractAndNarrowLow_Vec private DataTable _dataTable; - static SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt16() + static SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); } - public SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt16() + public SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt16() { Succeeded = true; @@ -231,7 +231,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr) ); @@ -243,7 +243,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)) ); @@ -255,7 +255,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowLow), new Type[] { typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingLower), new Type[] { typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr) }); @@ -268,7 +268,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowLow), new Type[] { typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingLower), new Type[] { typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)) }); @@ -281,7 +281,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( _clsVar1 ); @@ -295,7 +295,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pClsVar1)) ); @@ -309,7 +309,7 @@ public void RunLclVarScenario_UnsafeRead() TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); - var result = AdvSimd.ExtractAndNarrowLow(op1); + var result = AdvSimd.ExtractNarrowingLower(op1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, _dataTable.outArrayPtr); @@ -320,7 +320,7 @@ public void RunLclVarScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); - var result = AdvSimd.ExtractAndNarrowLow(op1); + var result = AdvSimd.ExtractNarrowingLower(op1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, _dataTable.outArrayPtr); @@ -330,8 +330,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt16(); - var result = AdvSimd.ExtractAndNarrowLow(test._fld1); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt16(); + var result = AdvSimd.ExtractNarrowingLower(test._fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, _dataTable.outArrayPtr); @@ -341,11 +341,11 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt16(); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt16(); fixed (Vector128* pFld1 = &test._fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)) ); @@ -358,7 +358,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.ExtractAndNarrowLow(_fld1); + var result = AdvSimd.ExtractNarrowingLower(_fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _dataTable.outArrayPtr); @@ -370,7 +370,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)) ); @@ -384,7 +384,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowLow(test._fld1); + var result = AdvSimd.ExtractNarrowingLower(test._fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, _dataTable.outArrayPtr); @@ -395,7 +395,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt16*)(&test._fld1)) ); @@ -468,7 +468,7 @@ private void ValidateResult(UInt16[] firstOp, Byte[] result, [CallerMemberName] for (var i = 0; i < RetElementCount; i++) { - if (((Byte)firstOp[i]) != result[i]) + if (Helpers.ExtractNarrowing(firstOp[i]) != result[i]) { succeeded = false; break; @@ -477,7 +477,7 @@ private void ValidateResult(UInt16[] firstOp, Byte[] result, [CallerMemberName] if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractAndNarrowLow)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractNarrowingLower)}(Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); TestLibrary.TestFramework.LogInformation(string.Empty); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.UInt32.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.UInt32.cs index a5cce409add8c..8630a333377e4 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void ExtractAndNarrowLow_Vector128_UInt32() + private static void ExtractNarrowingLower_Vector128_UInt32() { - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt32(); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void ExtractAndNarrowLow_Vector128_UInt32() } } - public sealed unsafe class SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt32 + public sealed unsafe class SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt32 { private struct DataTable { @@ -171,19 +171,19 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt32 testClass) + public void RunStructFldScenario(SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt32 testClass) { - var result = AdvSimd.ExtractAndNarrowLow(_fld1); + var result = AdvSimd.ExtractNarrowingLower(_fld1); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt32 testClass) { fixed (Vector128* pFld1 = &_fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)) ); @@ -206,13 +206,13 @@ public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractAndNarrowLow_Vec private DataTable _dataTable; - static SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt32() + static SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); } - public SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt32() + public SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt32() { Succeeded = true; @@ -231,7 +231,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr) ); @@ -243,7 +243,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)) ); @@ -255,7 +255,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowLow), new Type[] { typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingLower), new Type[] { typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr) }); @@ -268,7 +268,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowLow), new Type[] { typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingLower), new Type[] { typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)) }); @@ -281,7 +281,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( _clsVar1 ); @@ -295,7 +295,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pClsVar1)) ); @@ -309,7 +309,7 @@ public void RunLclVarScenario_UnsafeRead() TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); - var result = AdvSimd.ExtractAndNarrowLow(op1); + var result = AdvSimd.ExtractNarrowingLower(op1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, _dataTable.outArrayPtr); @@ -320,7 +320,7 @@ public void RunLclVarScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); - var result = AdvSimd.ExtractAndNarrowLow(op1); + var result = AdvSimd.ExtractNarrowingLower(op1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, _dataTable.outArrayPtr); @@ -330,8 +330,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt32(); - var result = AdvSimd.ExtractAndNarrowLow(test._fld1); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt32(); + var result = AdvSimd.ExtractNarrowingLower(test._fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, _dataTable.outArrayPtr); @@ -341,11 +341,11 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt32(); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt32(); fixed (Vector128* pFld1 = &test._fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)) ); @@ -358,7 +358,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.ExtractAndNarrowLow(_fld1); + var result = AdvSimd.ExtractNarrowingLower(_fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _dataTable.outArrayPtr); @@ -370,7 +370,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)) ); @@ -384,7 +384,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowLow(test._fld1); + var result = AdvSimd.ExtractNarrowingLower(test._fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, _dataTable.outArrayPtr); @@ -395,7 +395,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt32*)(&test._fld1)) ); @@ -468,7 +468,7 @@ private void ValidateResult(UInt32[] firstOp, UInt16[] result, [CallerMemberName for (var i = 0; i < RetElementCount; i++) { - if (((UInt16)firstOp[i]) != result[i]) + if (Helpers.ExtractNarrowing(firstOp[i]) != result[i]) { succeeded = false; break; @@ -477,7 +477,7 @@ private void ValidateResult(UInt32[] firstOp, UInt16[] result, [CallerMemberName if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractAndNarrowLow)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractNarrowingLower)}(Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); TestLibrary.TestFramework.LogInformation(string.Empty); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.UInt64.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.UInt64.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.UInt64.cs index 8ff6d29b34c78..84abecc879988 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowLow.Vector128.UInt64.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingLower.Vector128.UInt64.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void ExtractAndNarrowLow_Vector128_UInt64() + private static void ExtractNarrowingLower_Vector128_UInt64() { - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt64(); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt64(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void ExtractAndNarrowLow_Vector128_UInt64() } } - public sealed unsafe class SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt64 + public sealed unsafe class SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt64 { private struct DataTable { @@ -171,19 +171,19 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt64 testClass) + public void RunStructFldScenario(SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt64 testClass) { - var result = AdvSimd.ExtractAndNarrowLow(_fld1); + var result = AdvSimd.ExtractNarrowingLower(_fld1); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt64 testClass) + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt64 testClass) { fixed (Vector128* pFld1 = &_fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)) ); @@ -206,13 +206,13 @@ public void RunStructFldScenario_Load(SimpleUnaryOpTest__ExtractAndNarrowLow_Vec private DataTable _dataTable; - static SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt64() + static SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt64() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); } - public SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt64() + public SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt64() { Succeeded = true; @@ -231,7 +231,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr) ); @@ -243,7 +243,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)) ); @@ -255,7 +255,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowLow), new Type[] { typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingLower), new Type[] { typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr) }); @@ -268,7 +268,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowLow), new Type[] { typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingLower), new Type[] { typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)) }); @@ -281,7 +281,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( _clsVar1 ); @@ -295,7 +295,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pClsVar1)) ); @@ -309,7 +309,7 @@ public void RunLclVarScenario_UnsafeRead() TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); - var result = AdvSimd.ExtractAndNarrowLow(op1); + var result = AdvSimd.ExtractNarrowingLower(op1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, _dataTable.outArrayPtr); @@ -320,7 +320,7 @@ public void RunLclVarScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); - var result = AdvSimd.ExtractAndNarrowLow(op1); + var result = AdvSimd.ExtractNarrowingLower(op1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, _dataTable.outArrayPtr); @@ -330,8 +330,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt64(); - var result = AdvSimd.ExtractAndNarrowLow(test._fld1); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt64(); + var result = AdvSimd.ExtractNarrowingLower(test._fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, _dataTable.outArrayPtr); @@ -341,11 +341,11 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleUnaryOpTest__ExtractAndNarrowLow_Vector128_UInt64(); + var test = new SimpleUnaryOpTest__ExtractNarrowingLower_Vector128_UInt64(); fixed (Vector128* pFld1 = &test._fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)) ); @@ -358,7 +358,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.ExtractAndNarrowLow(_fld1); + var result = AdvSimd.ExtractNarrowingLower(_fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _dataTable.outArrayPtr); @@ -370,7 +370,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) { - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)) ); @@ -384,7 +384,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowLow(test._fld1); + var result = AdvSimd.ExtractNarrowingLower(test._fld1); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, _dataTable.outArrayPtr); @@ -395,7 +395,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowLow( + var result = AdvSimd.ExtractNarrowingLower( AdvSimd.LoadVector128((UInt64*)(&test._fld1)) ); @@ -468,7 +468,7 @@ private void ValidateResult(UInt64[] firstOp, UInt32[] result, [CallerMemberName for (var i = 0; i < RetElementCount; i++) { - if (((UInt32)firstOp[i]) != result[i]) + if (Helpers.ExtractNarrowing(firstOp[i]) != result[i]) { succeeded = false; break; @@ -477,7 +477,7 @@ private void ValidateResult(UInt64[] firstOp, UInt32[] result, [CallerMemberName if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractAndNarrowLow)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractNarrowingLower)}(Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); TestLibrary.TestFramework.LogInformation(string.Empty); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.Int16.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.Int16.cs index 7443842e0e970..cc960def9015c 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void ExtractAndNarrowHigh_Vector128_Int16() + private static void ExtractNarrowingUpper_Vector128_Int16() { - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int16(); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void ExtractAndNarrowHigh_Vector128_Int16() } } - public sealed unsafe class SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int16 + public sealed unsafe class SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int16 testClass) { - var result = AdvSimd.ExtractAndNarrowHigh(_fld1, _fld2); + var result = AdvSimd.ExtractNarrowingUpper(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractAndNarrowHigh_V private DataTable _dataTable; - static SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int16() + static SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int16() + public SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowHigh), new Type[] { typeof(Vector64), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowHigh), new Type[] { typeof(Vector64), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector64* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.ExtractAndNarrowHigh(op1, op2); + var result = AdvSimd.ExtractNarrowingUpper(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.ExtractAndNarrowHigh(op1, op2); + var result = AdvSimd.ExtractNarrowingUpper(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int16(); - var result = AdvSimd.ExtractAndNarrowHigh(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int16(); + var result = AdvSimd.ExtractNarrowingUpper(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int16(); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.ExtractAndNarrowHigh(_fld1, _fld2); + var result = AdvSimd.ExtractNarrowingUpper(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowHigh(test._fld1, test._fld2); + var result = AdvSimd.ExtractNarrowingUpper(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((SByte*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)) ); @@ -506,25 +506,18 @@ private void ValidateResult(SByte[] left, Int16[] right, SByte[] result, [Caller { bool succeeded = true; - if (Helpers.ExtractAndNarrowHigh(0, left, right, result)) + for (var i = 0; i < RetElementCount; i++) { - succeeded = false; - } - else - { - for (var i = 1; i < RetElementCount; i++) + if (Helpers.ExtractNarrowingUpper(left, right, i) != result[i]) { - if (Helpers.ExtractAndNarrowHigh(i, left, right, result)) - { - succeeded = false; - break; - } + succeeded = false; + break; } } if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractAndNarrowHigh)}(Vector64, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractNarrowingUpper)}(Vector64, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.Int32.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.Int32.cs index 87d362dd9f5d3..a2add3e285969 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void ExtractAndNarrowHigh_Vector128_Int32() + private static void ExtractNarrowingUpper_Vector128_Int32() { - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int32(); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void ExtractAndNarrowHigh_Vector128_Int32() } } - public sealed unsafe class SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int32 + public sealed unsafe class SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int32 testClass) { - var result = AdvSimd.ExtractAndNarrowHigh(_fld1, _fld2); + var result = AdvSimd.ExtractNarrowingUpper(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractAndNarrowHigh_V private DataTable _dataTable; - static SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int32() + static SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int32() + public SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowHigh), new Type[] { typeof(Vector64), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowHigh), new Type[] { typeof(Vector64), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector64* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.ExtractAndNarrowHigh(op1, op2); + var result = AdvSimd.ExtractNarrowingUpper(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.ExtractAndNarrowHigh(op1, op2); + var result = AdvSimd.ExtractNarrowingUpper(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int32(); - var result = AdvSimd.ExtractAndNarrowHigh(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int32(); + var result = AdvSimd.ExtractNarrowingUpper(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int32(); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.ExtractAndNarrowHigh(_fld1, _fld2); + var result = AdvSimd.ExtractNarrowingUpper(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowHigh(test._fld1, test._fld2); + var result = AdvSimd.ExtractNarrowingUpper(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)) ); @@ -506,25 +506,18 @@ private void ValidateResult(Int16[] left, Int32[] right, Int16[] result, [Caller { bool succeeded = true; - if (Helpers.ExtractAndNarrowHigh(0, left, right, result)) + for (var i = 0; i < RetElementCount; i++) { - succeeded = false; - } - else - { - for (var i = 1; i < RetElementCount; i++) + if (Helpers.ExtractNarrowingUpper(left, right, i) != result[i]) { - if (Helpers.ExtractAndNarrowHigh(i, left, right, result)) - { - succeeded = false; - break; - } + succeeded = false; + break; } } if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractAndNarrowHigh)}(Vector64, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractNarrowingUpper)}(Vector64, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.Int64.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.Int64.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.Int64.cs index a8cf88a417fc4..b5316d0d700de 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.Int64.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.Int64.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void ExtractAndNarrowHigh_Vector128_Int64() + private static void ExtractNarrowingUpper_Vector128_Int64() { - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int64(); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int64(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void ExtractAndNarrowHigh_Vector128_Int64() } } - public sealed unsafe class SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int64 + public sealed unsafe class SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int64 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int64 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int64 testClass) { - var result = AdvSimd.ExtractAndNarrowHigh(_fld1, _fld2); + var result = AdvSimd.ExtractNarrowingUpper(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int64 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int64 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractAndNarrowHigh_V private DataTable _dataTable; - static SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int64() + static SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int64() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int64() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int64() + public SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int64() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowHigh), new Type[] { typeof(Vector64), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowHigh), new Type[] { typeof(Vector64), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector64* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.ExtractAndNarrowHigh(op1, op2); + var result = AdvSimd.ExtractNarrowingUpper(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.ExtractAndNarrowHigh(op1, op2); + var result = AdvSimd.ExtractNarrowingUpper(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int64(); - var result = AdvSimd.ExtractAndNarrowHigh(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int64(); + var result = AdvSimd.ExtractNarrowingUpper(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_Int64(); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_Int64(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.ExtractAndNarrowHigh(_fld1, _fld2); + var result = AdvSimd.ExtractNarrowingUpper(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowHigh(test._fld1, test._fld2); + var result = AdvSimd.ExtractNarrowingUpper(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)) ); @@ -506,25 +506,18 @@ private void ValidateResult(Int32[] left, Int64[] right, Int32[] result, [Caller { bool succeeded = true; - if (Helpers.ExtractAndNarrowHigh(0, left, right, result)) + for (var i = 0; i < RetElementCount; i++) { - succeeded = false; - } - else - { - for (var i = 1; i < RetElementCount; i++) + if (Helpers.ExtractNarrowingUpper(left, right, i) != result[i]) { - if (Helpers.ExtractAndNarrowHigh(i, left, right, result)) - { - succeeded = false; - break; - } + succeeded = false; + break; } } if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractAndNarrowHigh)}(Vector64, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractNarrowingUpper)}(Vector64, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.UInt16.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.UInt16.cs index e8a9d0f6127b4..6d0facc3ea7be 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void ExtractAndNarrowHigh_Vector128_UInt16() + private static void ExtractNarrowingUpper_Vector128_UInt16() { - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt16(); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void ExtractAndNarrowHigh_Vector128_UInt16() } } - public sealed unsafe class SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt16 + public sealed unsafe class SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt16 testClass) { - var result = AdvSimd.ExtractAndNarrowHigh(_fld1, _fld2); + var result = AdvSimd.ExtractNarrowingUpper(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractAndNarrowHigh_V private DataTable _dataTable; - static SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt16() + static SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt16() + public SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowHigh), new Type[] { typeof(Vector64), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowHigh), new Type[] { typeof(Vector64), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector64* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.ExtractAndNarrowHigh(op1, op2); + var result = AdvSimd.ExtractNarrowingUpper(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.ExtractAndNarrowHigh(op1, op2); + var result = AdvSimd.ExtractNarrowingUpper(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt16(); - var result = AdvSimd.ExtractAndNarrowHigh(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt16(); + var result = AdvSimd.ExtractNarrowingUpper(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt16(); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.ExtractAndNarrowHigh(_fld1, _fld2); + var result = AdvSimd.ExtractNarrowingUpper(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowHigh(test._fld1, test._fld2); + var result = AdvSimd.ExtractNarrowingUpper(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((Byte*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)) ); @@ -506,25 +506,18 @@ private void ValidateResult(Byte[] left, UInt16[] right, Byte[] result, [CallerM { bool succeeded = true; - if (Helpers.ExtractAndNarrowHigh(0, left, right, result)) + for (var i = 0; i < RetElementCount; i++) { - succeeded = false; - } - else - { - for (var i = 1; i < RetElementCount; i++) + if (Helpers.ExtractNarrowingUpper(left, right, i) != result[i]) { - if (Helpers.ExtractAndNarrowHigh(i, left, right, result)) - { - succeeded = false; - break; - } + succeeded = false; + break; } } if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractAndNarrowHigh)}(Vector64, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractNarrowingUpper)}(Vector64, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.UInt32.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.UInt32.cs index b82668cbb447e..85e46e6aaa8ab 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void ExtractAndNarrowHigh_Vector128_UInt32() + private static void ExtractNarrowingUpper_Vector128_UInt32() { - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt32(); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void ExtractAndNarrowHigh_Vector128_UInt32() } } - public sealed unsafe class SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt32 + public sealed unsafe class SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt32 testClass) { - var result = AdvSimd.ExtractAndNarrowHigh(_fld1, _fld2); + var result = AdvSimd.ExtractNarrowingUpper(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractAndNarrowHigh_V private DataTable _dataTable; - static SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt32() + static SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt32() + public SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowHigh), new Type[] { typeof(Vector64), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowHigh), new Type[] { typeof(Vector64), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector64* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.ExtractAndNarrowHigh(op1, op2); + var result = AdvSimd.ExtractNarrowingUpper(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.ExtractAndNarrowHigh(op1, op2); + var result = AdvSimd.ExtractNarrowingUpper(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt32(); - var result = AdvSimd.ExtractAndNarrowHigh(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt32(); + var result = AdvSimd.ExtractNarrowingUpper(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt32(); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.ExtractAndNarrowHigh(_fld1, _fld2); + var result = AdvSimd.ExtractNarrowingUpper(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowHigh(test._fld1, test._fld2); + var result = AdvSimd.ExtractNarrowingUpper(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)) ); @@ -506,25 +506,18 @@ private void ValidateResult(UInt16[] left, UInt32[] right, UInt16[] result, [Cal { bool succeeded = true; - if (Helpers.ExtractAndNarrowHigh(0, left, right, result)) + for (var i = 0; i < RetElementCount; i++) { - succeeded = false; - } - else - { - for (var i = 1; i < RetElementCount; i++) + if (Helpers.ExtractNarrowingUpper(left, right, i) != result[i]) { - if (Helpers.ExtractAndNarrowHigh(i, left, right, result)) - { - succeeded = false; - break; - } + succeeded = false; + break; } } if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractAndNarrowHigh)}(Vector64, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractNarrowingUpper)}(Vector64, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.UInt64.cs similarity index 90% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.UInt64.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.UInt64.cs index 08834020a778f..e1606c139aa8b 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractAndNarrowHigh.Vector128.UInt64.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ExtractNarrowingUpper.Vector128.UInt64.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void ExtractAndNarrowHigh_Vector128_UInt64() + private static void ExtractNarrowingUpper_Vector128_UInt64() { - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt64(); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt64(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void ExtractAndNarrowHigh_Vector128_UInt64() } } - public sealed unsafe class SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt64 + public sealed unsafe class SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt64 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt64 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt64 testClass) { - var result = AdvSimd.ExtractAndNarrowHigh(_fld1, _fld2); + var result = AdvSimd.ExtractNarrowingUpper(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt64 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt64 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__ExtractAndNarrowHigh_V private DataTable _dataTable; - static SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt64() + static SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt64() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt64() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt64() + public SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt64() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowHigh), new Type[] { typeof(Vector64), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractAndNarrowHigh), new Type[] { typeof(Vector64), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ExtractNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector64* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.ExtractAndNarrowHigh(op1, op2); + var result = AdvSimd.ExtractNarrowingUpper(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.ExtractAndNarrowHigh(op1, op2); + var result = AdvSimd.ExtractNarrowingUpper(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt64(); - var result = AdvSimd.ExtractAndNarrowHigh(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt64(); + var result = AdvSimd.ExtractNarrowingUpper(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__ExtractAndNarrowHigh_Vector128_UInt64(); + var test = new SimpleBinaryOpTest__ExtractNarrowingUpper_Vector128_UInt64(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.ExtractAndNarrowHigh(_fld1, _fld2); + var result = AdvSimd.ExtractNarrowingUpper(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowHigh(test._fld1, test._fld2); + var result = AdvSimd.ExtractNarrowingUpper(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.ExtractAndNarrowHigh( + var result = AdvSimd.ExtractNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)) ); @@ -506,25 +506,18 @@ private void ValidateResult(UInt32[] left, UInt64[] right, UInt32[] result, [Cal { bool succeeded = true; - if (Helpers.ExtractAndNarrowHigh(0, left, right, result)) + for (var i = 0; i < RetElementCount; i++) { - succeeded = false; - } - else - { - for (var i = 1; i < RetElementCount; i++) + if (Helpers.ExtractNarrowingUpper(left, right, i) != result[i]) { - if (Helpers.ExtractAndNarrowHigh(i, left, right, result)) - { - succeeded = false; - break; - } + succeeded = false; + break; } } if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractAndNarrowHigh)}(Vector64, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ExtractNarrowingUpper)}(Vector64, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs index cc7f28a388fbc..311885d4f1d37 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs @@ -96,18 +96,18 @@ static Program() ["Add.Vector128.UInt16"] = Add_Vector128_UInt16, ["Add.Vector128.UInt32"] = Add_Vector128_UInt32, ["Add.Vector128.UInt64"] = Add_Vector128_UInt64, - ["AddHighNarrowLower.Vector64.Byte"] = AddHighNarrowLower_Vector64_Byte, - ["AddHighNarrowLower.Vector64.Int16"] = AddHighNarrowLower_Vector64_Int16, - ["AddHighNarrowLower.Vector64.Int32"] = AddHighNarrowLower_Vector64_Int32, - ["AddHighNarrowLower.Vector64.SByte"] = AddHighNarrowLower_Vector64_SByte, - ["AddHighNarrowLower.Vector64.UInt16"] = AddHighNarrowLower_Vector64_UInt16, - ["AddHighNarrowLower.Vector64.UInt32"] = AddHighNarrowLower_Vector64_UInt32, - ["AddHighNarrowUpper.Vector128.Byte"] = AddHighNarrowUpper_Vector128_Byte, - ["AddHighNarrowUpper.Vector128.Int16"] = AddHighNarrowUpper_Vector128_Int16, - ["AddHighNarrowUpper.Vector128.Int32"] = AddHighNarrowUpper_Vector128_Int32, - ["AddHighNarrowUpper.Vector128.SByte"] = AddHighNarrowUpper_Vector128_SByte, - ["AddHighNarrowUpper.Vector128.UInt16"] = AddHighNarrowUpper_Vector128_UInt16, - ["AddHighNarrowUpper.Vector128.UInt32"] = AddHighNarrowUpper_Vector128_UInt32, + ["AddHighNarrowingLower.Vector64.Byte"] = AddHighNarrowingLower_Vector64_Byte, + ["AddHighNarrowingLower.Vector64.Int16"] = AddHighNarrowingLower_Vector64_Int16, + ["AddHighNarrowingLower.Vector64.Int32"] = AddHighNarrowingLower_Vector64_Int32, + ["AddHighNarrowingLower.Vector64.SByte"] = AddHighNarrowingLower_Vector64_SByte, + ["AddHighNarrowingLower.Vector64.UInt16"] = AddHighNarrowingLower_Vector64_UInt16, + ["AddHighNarrowingLower.Vector64.UInt32"] = AddHighNarrowingLower_Vector64_UInt32, + ["AddHighNarrowingUpper.Vector128.Byte"] = AddHighNarrowingUpper_Vector128_Byte, + ["AddHighNarrowingUpper.Vector128.Int16"] = AddHighNarrowingUpper_Vector128_Int16, + ["AddHighNarrowingUpper.Vector128.Int32"] = AddHighNarrowingUpper_Vector128_Int32, + ["AddHighNarrowingUpper.Vector128.SByte"] = AddHighNarrowingUpper_Vector128_SByte, + ["AddHighNarrowingUpper.Vector128.UInt16"] = AddHighNarrowingUpper_Vector128_UInt16, + ["AddHighNarrowingUpper.Vector128.UInt32"] = AddHighNarrowingUpper_Vector128_UInt32, ["AddPairwise.Vector64.Byte"] = AddPairwise_Vector64_Byte, ["AddPairwise.Vector64.Int16"] = AddPairwise_Vector64_Int16, ["AddPairwise.Vector64.Int32"] = AddPairwise_Vector64_Int32, @@ -139,18 +139,18 @@ static Program() ["AddPairwiseWideningAndAddScalar.Vector64.UInt32"] = AddPairwiseWideningAndAddScalar_Vector64_UInt32, ["AddPairwiseWideningScalar.Vector64.Int32"] = AddPairwiseWideningScalar_Vector64_Int32, ["AddPairwiseWideningScalar.Vector64.UInt32"] = AddPairwiseWideningScalar_Vector64_UInt32, - ["AddRoundedHighNarrowLower.Vector64.Byte"] = AddRoundedHighNarrowLower_Vector64_Byte, - ["AddRoundedHighNarrowLower.Vector64.Int16"] = AddRoundedHighNarrowLower_Vector64_Int16, - ["AddRoundedHighNarrowLower.Vector64.Int32"] = AddRoundedHighNarrowLower_Vector64_Int32, - ["AddRoundedHighNarrowLower.Vector64.SByte"] = AddRoundedHighNarrowLower_Vector64_SByte, - ["AddRoundedHighNarrowLower.Vector64.UInt16"] = AddRoundedHighNarrowLower_Vector64_UInt16, - ["AddRoundedHighNarrowLower.Vector64.UInt32"] = AddRoundedHighNarrowLower_Vector64_UInt32, - ["AddRoundedHighNarrowUpper.Vector128.Byte"] = AddRoundedHighNarrowUpper_Vector128_Byte, - ["AddRoundedHighNarrowUpper.Vector128.Int16"] = AddRoundedHighNarrowUpper_Vector128_Int16, - ["AddRoundedHighNarrowUpper.Vector128.Int32"] = AddRoundedHighNarrowUpper_Vector128_Int32, - ["AddRoundedHighNarrowUpper.Vector128.SByte"] = AddRoundedHighNarrowUpper_Vector128_SByte, - ["AddRoundedHighNarrowUpper.Vector128.UInt16"] = AddRoundedHighNarrowUpper_Vector128_UInt16, - ["AddRoundedHighNarrowUpper.Vector128.UInt32"] = AddRoundedHighNarrowUpper_Vector128_UInt32, + ["AddRoundedHighNarrowingLower.Vector64.Byte"] = AddRoundedHighNarrowingLower_Vector64_Byte, + ["AddRoundedHighNarrowingLower.Vector64.Int16"] = AddRoundedHighNarrowingLower_Vector64_Int16, + ["AddRoundedHighNarrowingLower.Vector64.Int32"] = AddRoundedHighNarrowingLower_Vector64_Int32, + ["AddRoundedHighNarrowingLower.Vector64.SByte"] = AddRoundedHighNarrowingLower_Vector64_SByte, + ["AddRoundedHighNarrowingLower.Vector64.UInt16"] = AddRoundedHighNarrowingLower_Vector64_UInt16, + ["AddRoundedHighNarrowingLower.Vector64.UInt32"] = AddRoundedHighNarrowingLower_Vector64_UInt32, + ["AddRoundedHighNarrowingUpper.Vector128.Byte"] = AddRoundedHighNarrowingUpper_Vector128_Byte, + ["AddRoundedHighNarrowingUpper.Vector128.Int16"] = AddRoundedHighNarrowingUpper_Vector128_Int16, + ["AddRoundedHighNarrowingUpper.Vector128.Int32"] = AddRoundedHighNarrowingUpper_Vector128_Int32, + ["AddRoundedHighNarrowingUpper.Vector128.SByte"] = AddRoundedHighNarrowingUpper_Vector128_SByte, + ["AddRoundedHighNarrowingUpper.Vector128.UInt16"] = AddRoundedHighNarrowingUpper_Vector128_UInt16, + ["AddRoundedHighNarrowingUpper.Vector128.UInt32"] = AddRoundedHighNarrowingUpper_Vector128_UInt32, ["AddSaturate.Vector64.Byte"] = AddSaturate_Vector64_Byte, ["AddSaturate.Vector64.Int16"] = AddSaturate_Vector64_Int16, ["AddSaturate.Vector64.Int32"] = AddSaturate_Vector64_Int32, @@ -414,18 +414,18 @@ static Program() ["Extract.Vector128.UInt16.1"] = Extract_Vector128_UInt16_1, ["Extract.Vector128.UInt32.1"] = Extract_Vector128_UInt32_1, ["Extract.Vector128.UInt64.1"] = Extract_Vector128_UInt64_1, - ["ExtractAndNarrowHigh.Vector128.Int16"] = ExtractAndNarrowHigh_Vector128_Int16, - ["ExtractAndNarrowHigh.Vector128.Int32"] = ExtractAndNarrowHigh_Vector128_Int32, - ["ExtractAndNarrowHigh.Vector128.Int64"] = ExtractAndNarrowHigh_Vector128_Int64, - ["ExtractAndNarrowHigh.Vector128.UInt16"] = ExtractAndNarrowHigh_Vector128_UInt16, - ["ExtractAndNarrowHigh.Vector128.UInt32"] = ExtractAndNarrowHigh_Vector128_UInt32, - ["ExtractAndNarrowHigh.Vector128.UInt64"] = ExtractAndNarrowHigh_Vector128_UInt64, - ["ExtractAndNarrowLow.Vector128.Int16"] = ExtractAndNarrowLow_Vector128_Int16, - ["ExtractAndNarrowLow.Vector128.Int32"] = ExtractAndNarrowLow_Vector128_Int32, - ["ExtractAndNarrowLow.Vector128.Int64"] = ExtractAndNarrowLow_Vector128_Int64, - ["ExtractAndNarrowLow.Vector128.UInt16"] = ExtractAndNarrowLow_Vector128_UInt16, - ["ExtractAndNarrowLow.Vector128.UInt32"] = ExtractAndNarrowLow_Vector128_UInt32, - ["ExtractAndNarrowLow.Vector128.UInt64"] = ExtractAndNarrowLow_Vector128_UInt64, + ["ExtractNarrowingUpper.Vector128.Int16"] = ExtractNarrowingUpper_Vector128_Int16, + ["ExtractNarrowingUpper.Vector128.Int32"] = ExtractNarrowingUpper_Vector128_Int32, + ["ExtractNarrowingUpper.Vector128.Int64"] = ExtractNarrowingUpper_Vector128_Int64, + ["ExtractNarrowingUpper.Vector128.UInt16"] = ExtractNarrowingUpper_Vector128_UInt16, + ["ExtractNarrowingUpper.Vector128.UInt32"] = ExtractNarrowingUpper_Vector128_UInt32, + ["ExtractNarrowingUpper.Vector128.UInt64"] = ExtractNarrowingUpper_Vector128_UInt64, + ["ExtractNarrowingLower.Vector128.Int16"] = ExtractNarrowingLower_Vector128_Int16, + ["ExtractNarrowingLower.Vector128.Int32"] = ExtractNarrowingLower_Vector128_Int32, + ["ExtractNarrowingLower.Vector128.Int64"] = ExtractNarrowingLower_Vector128_Int64, + ["ExtractNarrowingLower.Vector128.UInt16"] = ExtractNarrowingLower_Vector128_UInt16, + ["ExtractNarrowingLower.Vector128.UInt32"] = ExtractNarrowingLower_Vector128_UInt32, + ["ExtractNarrowingLower.Vector128.UInt64"] = ExtractNarrowingLower_Vector128_UInt64, ["ExtractVector64.Byte.1"] = ExtractVector64_Byte_1, ["ExtractVector64.Int16.1"] = ExtractVector64_Int16_1, ["ExtractVector64.Int32.1"] = ExtractVector64_Int32_1, @@ -804,30 +804,30 @@ static Program() ["Subtract.Vector128.UInt16"] = Subtract_Vector128_UInt16, ["Subtract.Vector128.UInt32"] = Subtract_Vector128_UInt32, ["Subtract.Vector128.UInt64"] = Subtract_Vector128_UInt64, - ["SubtractHighNarrowLower.Vector64.Byte"] = SubtractHighNarrowLower_Vector64_Byte, - ["SubtractHighNarrowLower.Vector64.Int16"] = SubtractHighNarrowLower_Vector64_Int16, - ["SubtractHighNarrowLower.Vector64.Int32"] = SubtractHighNarrowLower_Vector64_Int32, - ["SubtractHighNarrowLower.Vector64.SByte"] = SubtractHighNarrowLower_Vector64_SByte, - ["SubtractHighNarrowLower.Vector64.UInt16"] = SubtractHighNarrowLower_Vector64_UInt16, - ["SubtractHighNarrowLower.Vector64.UInt32"] = SubtractHighNarrowLower_Vector64_UInt32, - ["SubtractHighNarrowUpper.Vector128.Byte"] = SubtractHighNarrowUpper_Vector128_Byte, - ["SubtractHighNarrowUpper.Vector128.Int16"] = SubtractHighNarrowUpper_Vector128_Int16, - ["SubtractHighNarrowUpper.Vector128.Int32"] = SubtractHighNarrowUpper_Vector128_Int32, - ["SubtractHighNarrowUpper.Vector128.SByte"] = SubtractHighNarrowUpper_Vector128_SByte, - ["SubtractHighNarrowUpper.Vector128.UInt16"] = SubtractHighNarrowUpper_Vector128_UInt16, - ["SubtractHighNarrowUpper.Vector128.UInt32"] = SubtractHighNarrowUpper_Vector128_UInt32, - ["SubtractRoundedHighNarrowLower.Vector64.Byte"] = SubtractRoundedHighNarrowLower_Vector64_Byte, - ["SubtractRoundedHighNarrowLower.Vector64.Int16"] = SubtractRoundedHighNarrowLower_Vector64_Int16, - ["SubtractRoundedHighNarrowLower.Vector64.Int32"] = SubtractRoundedHighNarrowLower_Vector64_Int32, - ["SubtractRoundedHighNarrowLower.Vector64.SByte"] = SubtractRoundedHighNarrowLower_Vector64_SByte, - ["SubtractRoundedHighNarrowLower.Vector64.UInt16"] = SubtractRoundedHighNarrowLower_Vector64_UInt16, - ["SubtractRoundedHighNarrowLower.Vector64.UInt32"] = SubtractRoundedHighNarrowLower_Vector64_UInt32, - ["SubtractRoundedHighNarrowUpper.Vector128.Byte"] = SubtractRoundedHighNarrowUpper_Vector128_Byte, - ["SubtractRoundedHighNarrowUpper.Vector128.Int16"] = SubtractRoundedHighNarrowUpper_Vector128_Int16, - ["SubtractRoundedHighNarrowUpper.Vector128.Int32"] = SubtractRoundedHighNarrowUpper_Vector128_Int32, - ["SubtractRoundedHighNarrowUpper.Vector128.SByte"] = SubtractRoundedHighNarrowUpper_Vector128_SByte, - ["SubtractRoundedHighNarrowUpper.Vector128.UInt16"] = SubtractRoundedHighNarrowUpper_Vector128_UInt16, - ["SubtractRoundedHighNarrowUpper.Vector128.UInt32"] = SubtractRoundedHighNarrowUpper_Vector128_UInt32, + ["SubtractHighNarrowingLower.Vector64.Byte"] = SubtractHighNarrowingLower_Vector64_Byte, + ["SubtractHighNarrowingLower.Vector64.Int16"] = SubtractHighNarrowingLower_Vector64_Int16, + ["SubtractHighNarrowingLower.Vector64.Int32"] = SubtractHighNarrowingLower_Vector64_Int32, + ["SubtractHighNarrowingLower.Vector64.SByte"] = SubtractHighNarrowingLower_Vector64_SByte, + ["SubtractHighNarrowingLower.Vector64.UInt16"] = SubtractHighNarrowingLower_Vector64_UInt16, + ["SubtractHighNarrowingLower.Vector64.UInt32"] = SubtractHighNarrowingLower_Vector64_UInt32, + ["SubtractHighNarrowingUpper.Vector128.Byte"] = SubtractHighNarrowingUpper_Vector128_Byte, + ["SubtractHighNarrowingUpper.Vector128.Int16"] = SubtractHighNarrowingUpper_Vector128_Int16, + ["SubtractHighNarrowingUpper.Vector128.Int32"] = SubtractHighNarrowingUpper_Vector128_Int32, + ["SubtractHighNarrowingUpper.Vector128.SByte"] = SubtractHighNarrowingUpper_Vector128_SByte, + ["SubtractHighNarrowingUpper.Vector128.UInt16"] = SubtractHighNarrowingUpper_Vector128_UInt16, + ["SubtractHighNarrowingUpper.Vector128.UInt32"] = SubtractHighNarrowingUpper_Vector128_UInt32, + ["SubtractRoundedHighNarrowingLower.Vector64.Byte"] = SubtractRoundedHighNarrowingLower_Vector64_Byte, + ["SubtractRoundedHighNarrowingLower.Vector64.Int16"] = SubtractRoundedHighNarrowingLower_Vector64_Int16, + ["SubtractRoundedHighNarrowingLower.Vector64.Int32"] = SubtractRoundedHighNarrowingLower_Vector64_Int32, + ["SubtractRoundedHighNarrowingLower.Vector64.SByte"] = SubtractRoundedHighNarrowingLower_Vector64_SByte, + ["SubtractRoundedHighNarrowingLower.Vector64.UInt16"] = SubtractRoundedHighNarrowingLower_Vector64_UInt16, + ["SubtractRoundedHighNarrowingLower.Vector64.UInt32"] = SubtractRoundedHighNarrowingLower_Vector64_UInt32, + ["SubtractRoundedHighNarrowingUpper.Vector128.Byte"] = SubtractRoundedHighNarrowingUpper_Vector128_Byte, + ["SubtractRoundedHighNarrowingUpper.Vector128.Int16"] = SubtractRoundedHighNarrowingUpper_Vector128_Int16, + ["SubtractRoundedHighNarrowingUpper.Vector128.Int32"] = SubtractRoundedHighNarrowingUpper_Vector128_Int32, + ["SubtractRoundedHighNarrowingUpper.Vector128.SByte"] = SubtractRoundedHighNarrowingUpper_Vector128_SByte, + ["SubtractRoundedHighNarrowingUpper.Vector128.UInt16"] = SubtractRoundedHighNarrowingUpper_Vector128_UInt16, + ["SubtractRoundedHighNarrowingUpper.Vector128.UInt32"] = SubtractRoundedHighNarrowingUpper_Vector128_UInt32, ["SubtractSaturate.Vector64.Byte"] = SubtractSaturate_Vector64_Byte, ["SubtractSaturate.Vector64.Int16"] = SubtractSaturate_Vector64_Int16, ["SubtractSaturate.Vector64.Int32"] = SubtractSaturate_Vector64_Int32, diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.Byte.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.Byte.cs index e4eca0b5ec0c3..7c14bab8bceda 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractHighNarrowLower_Vector64_Byte() + private static void SubtractHighNarrowingLower_Vector64_Byte() { - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractHighNarrowLower_Vector64_Byte() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte + public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Byte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Byte testClass) { - var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Byte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLowe private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte() + static SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte() + public SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Byte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte(); - var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Byte(); + var result = AdvSimd.SubtractHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Byte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.Int16.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.Int16.cs index 6232f7360d1d3..35a4643252630 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractHighNarrowLower_Vector64_Int16() + private static void SubtractHighNarrowingLower_Vector64_Int16() { - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractHighNarrowLower_Vector64_Int16() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16 + public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int16 testClass) { - var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLowe private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16() + static SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16() + public SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16(); - var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int16(); + var result = AdvSimd.SubtractHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.Int32.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.Int32.cs index 5fd57683f17da..b724f5789340a 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractHighNarrowLower_Vector64_Int32() + private static void SubtractHighNarrowingLower_Vector64_Int32() { - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractHighNarrowLower_Vector64_Int32() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32 + public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int32 testClass) { - var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLowe private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32() + static SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32() + public SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32(); - var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int32(); + var result = AdvSimd.SubtractHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_Int32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.SByte.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.SByte.cs index 4156595e1a54a..bec44ddbbe0cc 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractHighNarrowLower_Vector64_SByte() + private static void SubtractHighNarrowingLower_Vector64_SByte() { - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractHighNarrowLower_Vector64_SByte() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte + public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_SByte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_SByte testClass) { - var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_SByte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLowe private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte() + static SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte() + public SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_SByte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte(); - var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_SByte(); + var result = AdvSimd.SubtractHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_SByte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.UInt16.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.UInt16.cs index 652291a79460d..cf9fcc96c1a4c 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractHighNarrowLower_Vector64_UInt16() + private static void SubtractHighNarrowingLower_Vector64_UInt16() { - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractHighNarrowLower_Vector64_UInt16() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16 + public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt16 testClass) { - var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLowe private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16() + static SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16() + public SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16(); - var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt16(); + var result = AdvSimd.SubtractHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.UInt32.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.UInt32.cs index a0db7ab73cc49..e1ae11ce88860 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowLower.Vector64.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingLower.Vector64.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractHighNarrowLower_Vector64_UInt32() + private static void SubtractHighNarrowingLower_Vector64_UInt32() { - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractHighNarrowLower_Vector64_UInt32() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32 + public sealed unsafe class SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt32 testClass) { - var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractHighNarrowLowe private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32() + static SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32() + public SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32(); - var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt32(); + var result = AdvSimd.SubtractHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__SubtractHighNarrowingLower_Vector64_UInt32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowLower( + var result = AdvSimd.SubtractHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.Byte.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.Byte.cs index a12435926fe8c..abd79e0284722 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractHighNarrowUpper_Vector128_Byte() + private static void SubtractHighNarrowingUpper_Vector128_Byte() { - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractHighNarrowUpper_Vector128_Byte() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte + public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Byte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Byte testClass) { - var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Byte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpp private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte() + static SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte() + public SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Byte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)), AdvSimd.LoadVector128((UInt16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte(); - var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Byte(); + var result = AdvSimd.SubtractHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Byte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)), AdvSimd.LoadVector128((UInt16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.Int16.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.Int16.cs index f2942febe2343..35c625d971cf1 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractHighNarrowUpper_Vector128_Int16() + private static void SubtractHighNarrowingUpper_Vector128_Int16() { - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractHighNarrowUpper_Vector128_Int16() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16 + public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int16 testClass) { - var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpp private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16() + static SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16() + public SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)), AdvSimd.LoadVector128((Int32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16(); - var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int16(); + var result = AdvSimd.SubtractHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)), AdvSimd.LoadVector128((Int32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.Int32.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.Int32.cs index 3b33e723b49b3..d31f07ce3f91f 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractHighNarrowUpper_Vector128_Int32() + private static void SubtractHighNarrowingUpper_Vector128_Int32() { - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractHighNarrowUpper_Vector128_Int32() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32 + public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int32 testClass) { - var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpp private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32() + static SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32() + public SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)), AdvSimd.LoadVector128((Int64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32(); - var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int32(); + var result = AdvSimd.SubtractHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_Int32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)), AdvSimd.LoadVector128((Int64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.SByte.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.SByte.cs index 7ba09a938529d..c1f3e06e1e84b 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractHighNarrowUpper_Vector128_SByte() + private static void SubtractHighNarrowingUpper_Vector128_SByte() { - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractHighNarrowUpper_Vector128_SByte() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte + public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_SByte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_SByte testClass) { - var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_SByte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpp private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte() + static SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte() + public SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_SByte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)), AdvSimd.LoadVector128((Int16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte(); - var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_SByte(); + var result = AdvSimd.SubtractHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_SByte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)), AdvSimd.LoadVector128((Int16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.UInt16.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.UInt16.cs index 374f10f1119d0..2ce1511a3bcc5 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractHighNarrowUpper_Vector128_UInt16() + private static void SubtractHighNarrowingUpper_Vector128_UInt16() { - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractHighNarrowUpper_Vector128_UInt16() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16 + public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt16 testClass) { - var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpp private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16() + static SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16() + public SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)), AdvSimd.LoadVector128((UInt32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16(); - var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt16(); + var result = AdvSimd.SubtractHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)), AdvSimd.LoadVector128((UInt32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.UInt32.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.UInt32.cs index 4111c8ef3c8ec..bb378397a8758 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowUpper.Vector128.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractHighNarrowingUpper.Vector128.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractHighNarrowUpper_Vector128_UInt32() + private static void SubtractHighNarrowingUpper_Vector128_UInt32() { - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractHighNarrowUpper_Vector128_UInt32() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32 + public sealed unsafe class SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt32 testClass) { - var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractHighNarrowUpp private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32() + static SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32() + public SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)), AdvSimd.LoadVector128((UInt64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32(); - var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt32(); + var result = AdvSimd.SubtractHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__SubtractHighNarrowingUpper_Vector128_UInt32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractHighNarrowUpper( + var result = AdvSimd.SubtractHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)), AdvSimd.LoadVector128((UInt64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.Byte.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.Byte.cs index 710e688d27d42..4eac8fc9b11c0 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractRoundedHighNarrowLower_Vector64_Byte() + private static void SubtractRoundedHighNarrowingLower_Vector64_Byte() { - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractRoundedHighNarrowLower_Vector64_Byte() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte + public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Byte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Byte testClass) { - var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Byte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNar private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte() + static SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte() + public SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Byte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte(); - var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Byte(); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Byte(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Byte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt16[] left, UInt16[] right, Byte[] result, [Calle if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.Int16.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.Int16.cs index b8af6dd6714ec..a538bca9192be 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractRoundedHighNarrowLower_Vector64_Int16() + private static void SubtractRoundedHighNarrowingLower_Vector64_Int16() { - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractRoundedHighNarrowLower_Vector64_Int16() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16 + public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int16 testClass) { - var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNar private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16() + static SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16() + public SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16(); - var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int16(); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int16(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.Int32.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.Int32.cs index 65c74cb30dc0e..e2c23aad0121d 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractRoundedHighNarrowLower_Vector64_Int32() + private static void SubtractRoundedHighNarrowingLower_Vector64_Int32() { - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractRoundedHighNarrowLower_Vector64_Int32() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32 + public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int32 testClass) { - var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNar private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32() + static SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32() + public SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32(); - var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int32(); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_Int32(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_Int32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int64*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int64[] left, Int64[] right, Int32[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.SByte.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.SByte.cs index b3dff057ddcf3..e1c53772276b8 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractRoundedHighNarrowLower_Vector64_SByte() + private static void SubtractRoundedHighNarrowingLower_Vector64_SByte() { - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractRoundedHighNarrowLower_Vector64_SByte() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte + public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_SByte { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_SByte testClass) { - var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_SByte testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNar private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte() + static SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte() + public SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_SByte() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte(); - var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_SByte(); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_SByte(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_SByte(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [Caller if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.UInt16.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.UInt16.cs index 0678507a1eb1e..d83de1959b87f 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractRoundedHighNarrowLower_Vector64_UInt16() + private static void SubtractRoundedHighNarrowingLower_Vector64_UInt16() { - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractRoundedHighNarrowLower_Vector64_UInt16() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16 + public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt16 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt16 testClass) { - var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt16 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNar private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16() + static SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16() + public SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt16() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16(); - var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt16(); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt16(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt16(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt32[] left, UInt32[] right, UInt16[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.UInt32.cs similarity index 91% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.UInt32.cs index abdaa0b05c407..ea17396a4306f 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowLower.Vector64.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingLower.Vector64.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractRoundedHighNarrowLower_Vector64_UInt32() + private static void SubtractRoundedHighNarrowingLower_Vector64_UInt32() { - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractRoundedHighNarrowLower_Vector64_UInt32() } } - public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32 + public sealed unsafe class SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt32 { private struct DataTable { @@ -182,20 +182,20 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario(SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt32 testClass) { - var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt32 testClass) { fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -223,7 +223,7 @@ public void RunStructFldScenario_Load(SimpleBinaryOpTest__SubtractRoundedHighNar private DataTable _dataTable; - static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32() + static SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -231,7 +231,7 @@ static SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); } - public SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32() + public SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt32() { Succeeded = true; @@ -253,7 +253,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) ); @@ -266,7 +266,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) ); @@ -279,7 +279,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr) @@ -293,7 +293,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowLower), new Type[] { typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingLower), new Type[] { typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)) @@ -307,7 +307,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( _clsVar1, _clsVar2 ); @@ -323,7 +323,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar1 = &_clsVar1) fixed (Vector128* pClsVar2 = &_clsVar2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)) ); @@ -339,7 +339,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); - var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -351,7 +351,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); - var result = AdvSimd.SubtractRoundedHighNarrowLower(op1, op2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(op1, op2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, _dataTable.outArrayPtr); @@ -361,8 +361,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32(); - var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt32(); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -372,12 +372,12 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowLower_Vector64_UInt32(); + var test = new SimpleBinaryOpTest__SubtractRoundedHighNarrowingLower_Vector64_UInt32(); fixed (Vector128* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -391,7 +391,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowLower(_fld1, _fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(_fld1, _fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); @@ -404,7 +404,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) { - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)) ); @@ -419,7 +419,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowLower(test._fld1, test._fld2); + var result = AdvSimd.SubtractRoundedHighNarrowingLower(test._fld1, test._fld2); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); @@ -430,7 +430,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowLower( + var result = AdvSimd.SubtractRoundedHighNarrowingLower( AdvSimd.LoadVector128((UInt64*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)) ); @@ -508,7 +508,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]) + if (Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]) { succeeded = false; break; @@ -517,7 +517,7 @@ private void ValidateResult(UInt64[] left, UInt64[] right, UInt32[] result, [Cal if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowLower)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowingLower)}(Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.Byte.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Byte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.Byte.cs index 5a91e9841e399..2dd7c3918c6e0 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Byte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.Byte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractRoundedHighNarrowUpper_Vector128_Byte() + private static void SubtractRoundedHighNarrowingUpper_Vector128_Byte() { - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Byte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractRoundedHighNarrowUpper_Vector128_Byte() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte + public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Byte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Byte testClass) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Byte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNa private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte() + static SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Byte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte() + public SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Byte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pClsVar1)), AdvSimd.LoadVector128((UInt16*)(pClsVar2)), AdvSimd.LoadVector128((UInt16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Byte(); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Byte(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Byte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(pFld1)), AdvSimd.LoadVector128((UInt16*)(pFld2)), AdvSimd.LoadVector128((UInt16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Byte*)(&test._fld1)), AdvSimd.LoadVector128((UInt16*)(&test._fld2)), AdvSimd.LoadVector128((UInt16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, UInt16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.Int16.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Int16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.Int16.cs index f2766313b1f5d..73b854f868af5 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Int16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.Int16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractRoundedHighNarrowUpper_Vector128_Int16() + private static void SubtractRoundedHighNarrowingUpper_Vector128_Int16() { - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractRoundedHighNarrowUpper_Vector128_Int16() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16 + public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int16 testClass) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNa private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16() + static SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16() + public SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pClsVar1)), AdvSimd.LoadVector128((Int32*)(pClsVar2)), AdvSimd.LoadVector128((Int32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int16(); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int16(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(pFld1)), AdvSimd.LoadVector128((Int32*)(pFld2)), AdvSimd.LoadVector128((Int32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int16*)(&test._fld1)), AdvSimd.LoadVector128((Int32*)(&test._fld2)), AdvSimd.LoadVector128((Int32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int32[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.Int32.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Int32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.Int32.cs index 29090eaed32a8..4ab22c7a31f63 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.Int32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.Int32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractRoundedHighNarrowUpper_Vector128_Int32() + private static void SubtractRoundedHighNarrowingUpper_Vector128_Int32() { - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractRoundedHighNarrowUpper_Vector128_Int32() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32 + public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int32 testClass) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNa private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32() + static SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32() + public SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pClsVar1)), AdvSimd.LoadVector128((Int64*)(pClsVar2)), AdvSimd.LoadVector128((Int64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int32(); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_Int32(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_Int32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(pFld1)), AdvSimd.LoadVector128((Int64*)(pFld2)), AdvSimd.LoadVector128((Int64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((Int32*)(&test._fld1)), AdvSimd.LoadVector128((Int64*)(&test._fld2)), AdvSimd.LoadVector128((Int64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int64[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.SByte.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.SByte.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.SByte.cs index 4158cf834c4b8..e2ecb71bfc068 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.SByte.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.SByte.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractRoundedHighNarrowUpper_Vector128_SByte() + private static void SubtractRoundedHighNarrowingUpper_Vector128_SByte() { - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_SByte(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractRoundedHighNarrowUpper_Vector128_SByte() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte + public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_SByte { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_SByte testClass) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_SByte testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNa private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte() + static SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_SByte() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte() + public SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_SByte() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pClsVar1)), AdvSimd.LoadVector128((Int16*)(pClsVar2)), AdvSimd.LoadVector128((Int16*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_SByte(); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_SByte(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_SByte(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(pFld1)), AdvSimd.LoadVector128((Int16*)(pFld2)), AdvSimd.LoadVector128((Int16*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((SByte*)(&test._fld1)), AdvSimd.LoadVector128((Int16*)(&test._fld2)), AdvSimd.LoadVector128((Int16*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(SByte[] firstOp, Int16[] secondOp, Int16[] thirdOp, if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.UInt16.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.UInt16.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.UInt16.cs index af38718e5770a..3080f3c0002dd 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.UInt16.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.UInt16.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractRoundedHighNarrowUpper_Vector128_UInt16() + private static void SubtractRoundedHighNarrowingUpper_Vector128_UInt16() { - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt16(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractRoundedHighNarrowUpper_Vector128_UInt16() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16 + public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt16 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt16 testClass) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt16 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNa private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16() + static SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt16() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16() + public SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt16() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pClsVar1)), AdvSimd.LoadVector128((UInt32*)(pClsVar2)), AdvSimd.LoadVector128((UInt32*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt16(); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt16(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt16(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(pFld1)), AdvSimd.LoadVector128((UInt32*)(pFld2)), AdvSimd.LoadVector128((UInt32*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt16*)(&test._fld1)), AdvSimd.LoadVector128((UInt32*)(&test._fld2)), AdvSimd.LoadVector128((UInt32*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt32[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.UInt32.cs similarity index 92% rename from src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.UInt32.cs rename to src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.UInt32.cs index 12d1186105614..da9245113a140 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowUpper.Vector128.UInt32.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SubtractRoundedHighNarrowingUpper.Vector128.UInt32.cs @@ -19,9 +19,9 @@ namespace JIT.HardwareIntrinsics.Arm { public static partial class Program { - private static void SubtractRoundedHighNarrowUpper_Vector128_UInt32() + private static void SubtractRoundedHighNarrowingUpper_Vector128_UInt32() { - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt32(); if (test.IsSupported) { @@ -110,7 +110,7 @@ private static void SubtractRoundedHighNarrowUpper_Vector128_UInt32() } } - public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32 + public sealed unsafe class SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt32 { private struct DataTable { @@ -193,21 +193,21 @@ public static TestStruct Create() return testStruct; } - public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario(SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt32 testClass) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(testClass._dataTable.outArrayPtr, result); testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr); } - public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32 testClass) + public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt32 testClass) { fixed (Vector64* pFld1 = &_fld1) fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -240,7 +240,7 @@ public void RunStructFldScenario_Load(SimpleTernaryOpTest__SubtractRoundedHighNa private DataTable _dataTable; - static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32() + static SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt32() { for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); @@ -250,7 +250,7 @@ static SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32() Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar3), ref Unsafe.As(ref _data3[0]), (uint)Unsafe.SizeOf>()); } - public SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32() + public SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt32() { Succeeded = true; @@ -275,7 +275,7 @@ public void RunBasicScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), Unsafe.Read>(_dataTable.inArray3Ptr) @@ -289,7 +289,7 @@ public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)) @@ -303,7 +303,7 @@ public void RunReflectionScenario_UnsafeRead() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { Unsafe.Read>(_dataTable.inArray1Ptr), Unsafe.Read>(_dataTable.inArray2Ptr), @@ -318,7 +318,7 @@ public void RunReflectionScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); - var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SubtractRoundedHighNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(Vector128) }) .Invoke(null, new object[] { AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), @@ -333,7 +333,7 @@ public void RunClsVarScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( _clsVar1, _clsVar2, _clsVar3 @@ -351,7 +351,7 @@ public void RunClsVarScenario_Load() fixed (Vector128* pClsVar2 = &_clsVar2) fixed (Vector128* pClsVar3 = &_clsVar3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pClsVar1)), AdvSimd.LoadVector128((UInt64*)(pClsVar2)), AdvSimd.LoadVector128((UInt64*)(pClsVar3)) @@ -369,7 +369,7 @@ public void RunLclVarScenario_UnsafeRead() var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); var op3 = Unsafe.Read>(_dataTable.inArray3Ptr); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -382,7 +382,7 @@ public void RunLclVarScenario_Load() var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); var op2 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); var op3 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray3Ptr)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(op1, op2, op3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(op1, op2, op3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); @@ -392,8 +392,8 @@ public void RunClassLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt32(); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -403,13 +403,13 @@ public void RunClassLclFldScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); - var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowUpper_Vector128_UInt32(); + var test = new SimpleTernaryOpTest__SubtractRoundedHighNarrowingUpper_Vector128_UInt32(); fixed (Vector64* pFld1 = &test._fld1) fixed (Vector128* pFld2 = &test._fld2) fixed (Vector128* pFld3 = &test._fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -424,7 +424,7 @@ public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(_fld1, _fld2, _fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(_fld1, _fld2, _fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); @@ -438,7 +438,7 @@ public void RunClassFldScenario_Load() fixed (Vector128* pFld2 = &_fld2) fixed (Vector128* pFld3 = &_fld3) { - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(pFld1)), AdvSimd.LoadVector128((UInt64*)(pFld2)), AdvSimd.LoadVector128((UInt64*)(pFld3)) @@ -454,7 +454,7 @@ public void RunStructLclFldScenario() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper(test._fld1, test._fld2, test._fld3); + var result = AdvSimd.SubtractRoundedHighNarrowingUpper(test._fld1, test._fld2, test._fld3); Unsafe.Write(_dataTable.outArrayPtr, result); ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr); @@ -465,7 +465,7 @@ public void RunStructLclFldScenario_Load() TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); var test = TestStruct.Create(); - var result = AdvSimd.SubtractRoundedHighNarrowUpper( + var result = AdvSimd.SubtractRoundedHighNarrowingUpper( AdvSimd.LoadVector64((UInt32*)(&test._fld1)), AdvSimd.LoadVector128((UInt64*)(&test._fld2)), AdvSimd.LoadVector128((UInt64*)(&test._fld3)) @@ -548,7 +548,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO for (var i = 0; i < RetElementCount; i++) { - if (Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]) + if (Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]) { succeeded = false; break; @@ -557,7 +557,7 @@ private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt64[] thirdO if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowUpper)}(Vector64, Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SubtractRoundedHighNarrowingUpper)}(Vector64, Vector128, Vector128): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})"); TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})"); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx index 4d1e1a79d56d4..8d9c695fb0a3b 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx @@ -188,18 +188,18 @@ private static readonly (string templateFileName, Dictionary tem ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrow(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), @@ -231,18 +231,18 @@ private static readonly (string templateFileName, Dictionary tem ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAddScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWidening(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWidening(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), @@ -506,18 +506,18 @@ private static readonly (string templateFileName, Dictionary tem ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ExtractAndNarrowHigh_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractAndNarrowHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ExtractAndNarrowHigh(0, left, right, result)", ["ValidateRemainingResults"] = "Helpers.ExtractAndNarrowHigh(i, left, right, result)"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ExtractAndNarrowHigh_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractAndNarrowHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ExtractAndNarrowHigh(0, left, right, result)", ["ValidateRemainingResults"] = "Helpers.ExtractAndNarrowHigh(i, left, right, result)"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ExtractAndNarrowHigh_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractAndNarrowHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ExtractAndNarrowHigh(0, left, right, result)", ["ValidateRemainingResults"] = "Helpers.ExtractAndNarrowHigh(i, left, right, result)"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ExtractAndNarrowHigh_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractAndNarrowHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Helpers.ExtractAndNarrowHigh(0, left, right, result)", ["ValidateRemainingResults"] = "Helpers.ExtractAndNarrowHigh(i, left, right, result)"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ExtractAndNarrowHigh_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractAndNarrowHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.ExtractAndNarrowHigh(0, left, right, result)", ["ValidateRemainingResults"] = "Helpers.ExtractAndNarrowHigh(i, left, right, result)"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ExtractAndNarrowHigh_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractAndNarrowHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.ExtractAndNarrowHigh(0, left, right, result)", ["ValidateRemainingResults"] = "Helpers.ExtractAndNarrowHigh(i, left, right, result)"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractAndNarrowLow_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractAndNarrowLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "((SByte)firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractAndNarrowLow_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractAndNarrowLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "((Int16)firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractAndNarrowLow_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractAndNarrowLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "((Int32)firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractAndNarrowLow_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractAndNarrowLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "((Byte)firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractAndNarrowLow_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractAndNarrowLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "((UInt16)firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractAndNarrowLow_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractAndNarrowLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "((UInt32)firstOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), @@ -896,30 +896,30 @@ private static readonly (string templateFileName, Dictionary tem ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrow(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrow(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index b22f7cd0f6078..f54f7375a35b6 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -1447,7 +1447,7 @@ public static float CompareTest(float left, float right) public static short AddPairwiseWideningAndAdd(short[] op1, sbyte[] op2, int i) => (short)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); - private static sbyte HighNarrow(short op1, bool round) + private static sbyte HighNarrowing(short op1, bool round) { ushort roundConst = 0; if (round) @@ -1457,13 +1457,13 @@ private static sbyte HighNarrow(short op1, bool round) return (sbyte)(((ushort)op1 + roundConst) >> (8 * sizeof(sbyte))); } - public static sbyte AddHighNarrow(short op1, short op2) => HighNarrow((short)(op1 + op2), round: false); + public static sbyte AddHighNarrowing(short op1, short op2) => HighNarrowing((short)(op1 + op2), round: false); - public static sbyte AddHighNarrowUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static sbyte AddHighNarrowingUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static sbyte AddRoundedHighNarrow(short op1, short op2) => HighNarrow((short)(op1 + op2), round: true); + public static sbyte AddRoundedHighNarrowing(short op1, short op2) => HighNarrowing((short)(op1 + op2), round: true); - public static short AddRoundedHighNarrowUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static short AddRoundedHighNarrowingUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static short AddWidening(sbyte op1, sbyte op2) => (short)((short)op1 + (short)op2); @@ -1473,6 +1473,10 @@ private static sbyte HighNarrow(short op1, bool round) public static short AddWideningUpper(short[] op1, sbyte[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); + public static sbyte ExtractNarrowing(short op1) => (sbyte)op1; + + public static sbyte ExtractNarrowingUpper(sbyte[] op1, short[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); + public static sbyte FusedAddHalving(sbyte op1, sbyte op2) => (sbyte)((ushort)((short)op1 + (short)op2) >> 1); public static sbyte FusedAddRoundedHalving(sbyte op1, sbyte op2) => (sbyte)((ushort)((short)op1 + (short)op2 + 1) >> 1); @@ -1491,13 +1495,13 @@ private static sbyte HighNarrow(short op1, bool round) public static short MultiplyWideningUpperAndSubtract(short[] op1, sbyte[] op2, sbyte[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static sbyte SubtractHighNarrow(short op1, short op2) => HighNarrow((short)(op1 - op2), round: false); + public static sbyte SubtractHighNarrowing(short op1, short op2) => HighNarrowing((short)(op1 - op2), round: false); - public static short SubtractHighNarrowUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static short SubtractHighNarrowingUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static sbyte SubtractRoundedHighNarrow(short op1, short op2) => HighNarrow((short)(op1 - op2), round: true); + public static sbyte SubtractRoundedHighNarrowing(short op1, short op2) => HighNarrowing((short)(op1 - op2), round: true); - public static short SubtractRoundedHighNarrowUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static short SubtractRoundedHighNarrowingUpper(sbyte[] op1, short[] op2, short[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static short SubtractWidening(sbyte op1, sbyte op2) => (short)((short)op1 - (short)op2); @@ -1519,7 +1523,7 @@ private static sbyte HighNarrow(short op1, bool round) public static int AddPairwiseWideningAndAdd(int[] op1, short[] op2, int i) => (int)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); - private static short HighNarrow(int op1, bool round) + private static short HighNarrowing(int op1, bool round) { uint roundConst = 0; if (round) @@ -1529,13 +1533,13 @@ private static short HighNarrow(int op1, bool round) return (short)(((uint)op1 + roundConst) >> (8 * sizeof(short))); } - public static short AddHighNarrow(int op1, int op2) => HighNarrow((int)(op1 + op2), round: false); + public static short AddHighNarrowing(int op1, int op2) => HighNarrowing((int)(op1 + op2), round: false); - public static short AddHighNarrowUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static short AddHighNarrowingUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static short AddRoundedHighNarrow(int op1, int op2) => HighNarrow((int)(op1 + op2), round: true); + public static short AddRoundedHighNarrowing(int op1, int op2) => HighNarrowing((int)(op1 + op2), round: true); - public static int AddRoundedHighNarrowUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static int AddRoundedHighNarrowingUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static int AddWidening(short op1, short op2) => (int)((int)op1 + (int)op2); @@ -1545,6 +1549,10 @@ private static short HighNarrow(int op1, bool round) public static int AddWideningUpper(int[] op1, short[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); + public static short ExtractNarrowing(int op1) => (short)op1; + + public static short ExtractNarrowingUpper(short[] op1, int[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); + public static short FusedAddHalving(short op1, short op2) => (short)((uint)((int)op1 + (int)op2) >> 1); public static short FusedAddRoundedHalving(short op1, short op2) => (short)((uint)((int)op1 + (int)op2 + 1) >> 1); @@ -1563,13 +1571,13 @@ private static short HighNarrow(int op1, bool round) public static int MultiplyWideningUpperAndSubtract(int[] op1, short[] op2, short[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static short SubtractHighNarrow(int op1, int op2) => HighNarrow((int)(op1 - op2), round: false); + public static short SubtractHighNarrowing(int op1, int op2) => HighNarrowing((int)(op1 - op2), round: false); - public static int SubtractHighNarrowUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static int SubtractHighNarrowingUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static short SubtractRoundedHighNarrow(int op1, int op2) => HighNarrow((int)(op1 - op2), round: true); + public static short SubtractRoundedHighNarrowing(int op1, int op2) => HighNarrowing((int)(op1 - op2), round: true); - public static int SubtractRoundedHighNarrowUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static int SubtractRoundedHighNarrowingUpper(short[] op1, int[] op2, int[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static int SubtractWidening(short op1, short op2) => (int)((int)op1 - (int)op2); @@ -1591,7 +1599,7 @@ private static short HighNarrow(int op1, bool round) public static long AddPairwiseWideningAndAdd(long[] op1, int[] op2, int i) => (long)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); - private static int HighNarrow(long op1, bool round) + private static int HighNarrowing(long op1, bool round) { ulong roundConst = 0; if (round) @@ -1601,13 +1609,13 @@ private static int HighNarrow(long op1, bool round) return (int)(((ulong)op1 + roundConst) >> (8 * sizeof(int))); } - public static int AddHighNarrow(long op1, long op2) => HighNarrow((long)(op1 + op2), round: false); + public static int AddHighNarrowing(long op1, long op2) => HighNarrowing((long)(op1 + op2), round: false); - public static int AddHighNarrowUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static int AddHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static int AddRoundedHighNarrow(long op1, long op2) => HighNarrow((long)(op1 + op2), round: true); + public static int AddRoundedHighNarrowing(long op1, long op2) => HighNarrowing((long)(op1 + op2), round: true); - public static long AddRoundedHighNarrowUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static long AddRoundedHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static long AddWidening(int op1, int op2) => (long)((long)op1 + (long)op2); @@ -1617,6 +1625,10 @@ private static int HighNarrow(long op1, bool round) public static long AddWideningUpper(long[] op1, int[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); + public static int ExtractNarrowing(long op1) => (int)op1; + + public static int ExtractNarrowingUpper(int[] op1, long[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); + public static int FusedAddHalving(int op1, int op2) => (int)((ulong)((long)op1 + (long)op2) >> 1); public static int FusedAddRoundedHalving(int op1, int op2) => (int)((ulong)((long)op1 + (long)op2 + 1) >> 1); @@ -1635,13 +1647,13 @@ private static int HighNarrow(long op1, bool round) public static long MultiplyWideningUpperAndSubtract(long[] op1, int[] op2, int[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static int SubtractHighNarrow(long op1, long op2) => HighNarrow((long)(op1 - op2), round: false); + public static int SubtractHighNarrowing(long op1, long op2) => HighNarrowing((long)(op1 - op2), round: false); - public static long SubtractHighNarrowUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static long SubtractHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static int SubtractRoundedHighNarrow(long op1, long op2) => HighNarrow((long)(op1 - op2), round: true); + public static int SubtractRoundedHighNarrowing(long op1, long op2) => HighNarrowing((long)(op1 - op2), round: true); - public static long SubtractRoundedHighNarrowUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static long SubtractRoundedHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static long SubtractWidening(int op1, int op2) => (long)((long)op1 - (long)op2); @@ -1663,7 +1675,7 @@ private static int HighNarrow(long op1, bool round) public static ushort AddPairwiseWideningAndAdd(ushort[] op1, byte[] op2, int i) => (ushort)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); - private static byte HighNarrow(ushort op1, bool round) + private static byte HighNarrowing(ushort op1, bool round) { ushort roundConst = 0; if (round) @@ -1673,13 +1685,13 @@ private static byte HighNarrow(ushort op1, bool round) return (byte)(((ushort)op1 + roundConst) >> (8 * sizeof(byte))); } - public static byte AddHighNarrow(ushort op1, ushort op2) => HighNarrow((ushort)(op1 + op2), round: false); + public static byte AddHighNarrowing(ushort op1, ushort op2) => HighNarrowing((ushort)(op1 + op2), round: false); - public static byte AddHighNarrowUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static byte AddHighNarrowingUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static byte AddRoundedHighNarrow(ushort op1, ushort op2) => HighNarrow((ushort)(op1 + op2), round: true); + public static byte AddRoundedHighNarrowing(ushort op1, ushort op2) => HighNarrowing((ushort)(op1 + op2), round: true); - public static ushort AddRoundedHighNarrowUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ushort AddRoundedHighNarrowingUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static ushort AddWidening(byte op1, byte op2) => (ushort)((ushort)op1 + (ushort)op2); @@ -1689,6 +1701,10 @@ private static byte HighNarrow(ushort op1, bool round) public static ushort AddWideningUpper(ushort[] op1, byte[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); + public static byte ExtractNarrowing(ushort op1) => (byte)op1; + + public static byte ExtractNarrowingUpper(byte[] op1, ushort[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); + public static byte FusedAddHalving(byte op1, byte op2) => (byte)((ushort)((ushort)op1 + (ushort)op2) >> 1); public static byte FusedAddRoundedHalving(byte op1, byte op2) => (byte)((ushort)((ushort)op1 + (ushort)op2 + 1) >> 1); @@ -1707,13 +1723,13 @@ private static byte HighNarrow(ushort op1, bool round) public static ushort MultiplyWideningUpperAndSubtract(ushort[] op1, byte[] op2, byte[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static byte SubtractHighNarrow(ushort op1, ushort op2) => HighNarrow((ushort)(op1 - op2), round: false); + public static byte SubtractHighNarrowing(ushort op1, ushort op2) => HighNarrowing((ushort)(op1 - op2), round: false); - public static ushort SubtractHighNarrowUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ushort SubtractHighNarrowingUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static byte SubtractRoundedHighNarrow(ushort op1, ushort op2) => HighNarrow((ushort)(op1 - op2), round: true); + public static byte SubtractRoundedHighNarrowing(ushort op1, ushort op2) => HighNarrowing((ushort)(op1 - op2), round: true); - public static ushort SubtractRoundedHighNarrowUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ushort SubtractRoundedHighNarrowingUpper(byte[] op1, ushort[] op2, ushort[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static ushort SubtractWidening(byte op1, byte op2) => (ushort)((ushort)op1 - (ushort)op2); @@ -1735,7 +1751,7 @@ private static byte HighNarrow(ushort op1, bool round) public static uint AddPairwiseWideningAndAdd(uint[] op1, ushort[] op2, int i) => (uint)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); - private static ushort HighNarrow(uint op1, bool round) + private static ushort HighNarrowing(uint op1, bool round) { uint roundConst = 0; if (round) @@ -1745,13 +1761,13 @@ private static ushort HighNarrow(uint op1, bool round) return (ushort)(((uint)op1 + roundConst) >> (8 * sizeof(ushort))); } - public static ushort AddHighNarrow(uint op1, uint op2) => HighNarrow((uint)(op1 + op2), round: false); + public static ushort AddHighNarrowing(uint op1, uint op2) => HighNarrowing((uint)(op1 + op2), round: false); - public static ushort AddHighNarrowUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ushort AddHighNarrowingUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static ushort AddRoundedHighNarrow(uint op1, uint op2) => HighNarrow((uint)(op1 + op2), round: true); + public static ushort AddRoundedHighNarrowing(uint op1, uint op2) => HighNarrowing((uint)(op1 + op2), round: true); - public static uint AddRoundedHighNarrowUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static uint AddRoundedHighNarrowingUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static uint AddWidening(ushort op1, ushort op2) => (uint)((uint)op1 + (uint)op2); @@ -1761,6 +1777,10 @@ private static ushort HighNarrow(uint op1, bool round) public static uint AddWideningUpper(uint[] op1, ushort[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); + public static ushort ExtractNarrowing(uint op1) => (ushort)op1; + + public static ushort ExtractNarrowingUpper(ushort[] op1, uint[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); + public static ushort FusedAddHalving(ushort op1, ushort op2) => (ushort)((uint)((uint)op1 + (uint)op2) >> 1); public static ushort FusedAddRoundedHalving(ushort op1, ushort op2) => (ushort)((uint)((uint)op1 + (uint)op2 + 1) >> 1); @@ -1779,13 +1799,13 @@ private static ushort HighNarrow(uint op1, bool round) public static uint MultiplyWideningUpperAndSubtract(uint[] op1, ushort[] op2, ushort[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static ushort SubtractHighNarrow(uint op1, uint op2) => HighNarrow((uint)(op1 - op2), round: false); + public static ushort SubtractHighNarrowing(uint op1, uint op2) => HighNarrowing((uint)(op1 - op2), round: false); - public static uint SubtractHighNarrowUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static uint SubtractHighNarrowingUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static ushort SubtractRoundedHighNarrow(uint op1, uint op2) => HighNarrow((uint)(op1 - op2), round: true); + public static ushort SubtractRoundedHighNarrowing(uint op1, uint op2) => HighNarrowing((uint)(op1 - op2), round: true); - public static uint SubtractRoundedHighNarrowUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static uint SubtractRoundedHighNarrowingUpper(ushort[] op1, uint[] op2, uint[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static uint SubtractWidening(ushort op1, ushort op2) => (uint)((uint)op1 - (uint)op2); @@ -1807,7 +1827,7 @@ private static ushort HighNarrow(uint op1, bool round) public static ulong AddPairwiseWideningAndAdd(ulong[] op1, uint[] op2, int i) => (ulong)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); - private static uint HighNarrow(ulong op1, bool round) + private static uint HighNarrowing(ulong op1, bool round) { ulong roundConst = 0; if (round) @@ -1817,13 +1837,13 @@ private static uint HighNarrow(ulong op1, bool round) return (uint)(((ulong)op1 + roundConst) >> (8 * sizeof(uint))); } - public static uint AddHighNarrow(ulong op1, ulong op2) => HighNarrow((ulong)(op1 + op2), round: false); + public static uint AddHighNarrowing(ulong op1, ulong op2) => HighNarrowing((ulong)(op1 + op2), round: false); - public static uint AddHighNarrowUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static uint AddHighNarrowingUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static uint AddRoundedHighNarrow(ulong op1, ulong op2) => HighNarrow((ulong)(op1 + op2), round: true); + public static uint AddRoundedHighNarrowing(ulong op1, ulong op2) => HighNarrowing((ulong)(op1 + op2), round: true); - public static ulong AddRoundedHighNarrowUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ulong AddRoundedHighNarrowingUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static ulong AddWidening(uint op1, uint op2) => (ulong)((ulong)op1 + (ulong)op2); @@ -1833,6 +1853,10 @@ private static uint HighNarrow(ulong op1, bool round) public static ulong AddWideningUpper(ulong[] op1, uint[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); + public static uint ExtractNarrowing(ulong op1) => (uint)op1; + + public static uint ExtractNarrowingUpper(uint[] op1, ulong[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); + public static uint FusedAddHalving(uint op1, uint op2) => (uint)((ulong)((ulong)op1 + (ulong)op2) >> 1); public static uint FusedAddRoundedHalving(uint op1, uint op2) => (uint)((ulong)((ulong)op1 + (ulong)op2 + 1) >> 1); @@ -1851,13 +1875,13 @@ private static uint HighNarrow(ulong op1, bool round) public static ulong MultiplyWideningUpperAndSubtract(ulong[] op1, uint[] op2, uint[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static uint SubtractHighNarrow(ulong op1, ulong op2) => HighNarrow((ulong)(op1 - op2), round: false); + public static uint SubtractHighNarrowing(ulong op1, ulong op2) => HighNarrowing((ulong)(op1 - op2), round: false); - public static ulong SubtractHighNarrowUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ulong SubtractHighNarrowingUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static uint SubtractRoundedHighNarrow(ulong op1, ulong op2) => HighNarrow((ulong)(op1 - op2), round: true); + public static uint SubtractRoundedHighNarrowing(ulong op1, ulong op2) => HighNarrowing((ulong)(op1 - op2), round: true); - public static ulong SubtractRoundedHighNarrowUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static ulong SubtractRoundedHighNarrowingUpper(uint[] op1, ulong[] op2, ulong[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static ulong SubtractWidening(uint op1, uint op2) => (ulong)((ulong)op1 - (ulong)op2); @@ -3112,60 +3136,6 @@ private static poly128_t PolynomialMult(long op1, long op2) public static long PolynomialMultiplyWideningHi64(long op1, long op2) => (long)PolynomialMult(op1, op2).hi; - public static bool ExtractAndNarrowHigh(int i, sbyte[] left, - short[] right, - sbyte[] result) - { - if (i < left.Length) - return left[i] != result[i]; - else - return (sbyte)right[i - left.Length] != result[i]; - } - public static bool ExtractAndNarrowHigh(int i, short[] left, - int[] right, - short[] result) - { - if (i < left.Length) - return left[i] != result[i]; - else - return (short)right[i - left.Length] != result[i]; - } - public static bool ExtractAndNarrowHigh(int i, int[] left, - long[] right, - int[] result) - { - if (i < left.Length) - return left[i] != result[i]; - else - return (int)right[i - left.Length] != result[i]; - } - public static bool ExtractAndNarrowHigh(int i, byte[] left, - ushort[] right, - byte[] result) - { - if (i < left.Length) - return left[i] != result[i]; - else - return (byte)right[i - left.Length] != result[i]; - } - public static bool ExtractAndNarrowHigh(int i, ushort[] left, - uint[] right, - ushort[] result) - { - if (i < left.Length) - return left[i] != result[i]; - else - return (ushort)right[i - left.Length] != result[i]; - } - public static bool ExtractAndNarrowHigh(int i, uint[] left, - ulong[] right, - uint[] result) - { - if (i < left.Length) - return left[i] != result[i]; - else - return (uint)right[i - left.Length] != result[i]; - } public static sbyte ExtractVector(sbyte[] op1, sbyte[] op2, int op3, int i) => (op3 + i < op1.Length) ? op1[op3 + i] : op2[op3 + i - op1.Length]; public static sbyte Insert(sbyte[] op1, int op2, sbyte op3, int i) => (op2 != i) ? op1[i] : op3; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt index 8552ab7e435e8..cc62c0a9a42aa 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt @@ -345,7 +345,7 @@ namespace JIT.HardwareIntrinsics.Arm public static <#= type.wide #> AddPairwiseWideningAndAdd(<#= type.wide #>[] op1, <#= type.name #>[] op2, int i) => (<#= type.wide #>)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1])); - private static <#= type.name #> HighNarrow(<#= type.wide #> op1, bool round) + private static <#= type.name #> HighNarrowing(<#= type.wide #> op1, bool round) { <#= type.wideUnsigned #> roundConst = 0; if (round) @@ -355,13 +355,13 @@ namespace JIT.HardwareIntrinsics.Arm return (<#= type.name #>)(((<#= type.wideUnsigned #>)op1 + roundConst) >> (8 * sizeof(<#= type.name #>))); } - public static <#= type.name #> AddHighNarrow(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrow((<#= type.wide #>)(op1 + op2), round: false); + public static <#= type.name #> AddHighNarrowing(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrowing((<#= type.wide #>)(op1 + op2), round: false); - public static <#= type.name #> AddHighNarrowUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static <#= type.name #> AddHighNarrowingUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : AddHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static <#= type.name #> AddRoundedHighNarrow(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrow((<#= type.wide #>)(op1 + op2), round: true); + public static <#= type.name #> AddRoundedHighNarrowing(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrowing((<#= type.wide #>)(op1 + op2), round: true); - public static <#= type.wide #> AddRoundedHighNarrowUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static <#= type.wide #> AddRoundedHighNarrowingUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : AddRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static <#= type.wide #> AddWidening(<#= type.name #> op1, <#= type.name #> op2) => (<#= type.wide #>)((<#= type.wide #>)op1 + (<#= type.wide #>)op2); @@ -371,6 +371,10 @@ namespace JIT.HardwareIntrinsics.Arm public static <#= type.wide #> AddWideningUpper(<#= type.wide #>[] op1, <#= type.name #>[] op2, int i) => AddWidening(op1[i], op2[i + op2.Length / 2]); + public static <#= type.name #> ExtractNarrowing(<#= type.wide #> op1) => (<#= type.name #>)op1; + + public static <#= type.name #> ExtractNarrowingUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, int i) => i < op1.Length ? op1[i] : ExtractNarrowing(op2[i - op1.Length]); + public static <#= type.name #> FusedAddHalving(<#= type.name #> op1, <#= type.name #> op2) => (<#= type.name #>)((<#= type.wideUnsigned #>)((<#= type.wide #>)op1 + (<#= type.wide #>)op2) >> 1); public static <#= type.name #> FusedAddRoundedHalving(<#= type.name #> op1, <#= type.name #> op2) => (<#= type.name #>)((<#= type.wideUnsigned #>)((<#= type.wide #>)op1 + (<#= type.wide #>)op2 + 1) >> 1); @@ -389,13 +393,13 @@ namespace JIT.HardwareIntrinsics.Arm public static <#= type.wide #> MultiplyWideningUpperAndSubtract(<#= type.wide #>[] op1, <#= type.name #>[] op2, <#= type.name #>[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); - public static <#= type.name #> SubtractHighNarrow(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrow((<#= type.wide #>)(op1 - op2), round: false); + public static <#= type.name #> SubtractHighNarrowing(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrowing((<#= type.wide #>)(op1 - op2), round: false); - public static <#= type.wide #> SubtractHighNarrowUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static <#= type.wide #> SubtractHighNarrowingUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); - public static <#= type.name #> SubtractRoundedHighNarrow(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrow((<#= type.wide #>)(op1 - op2), round: true); + public static <#= type.name #> SubtractRoundedHighNarrowing(<#= type.wide #> op1, <#= type.wide #> op2) => HighNarrowing((<#= type.wide #>)(op1 - op2), round: true); - public static <#= type.wide #> SubtractRoundedHighNarrowUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrow(op2[i - op1.Length], op3[i - op1.Length]); + public static <#= type.wide #> SubtractRoundedHighNarrowingUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, <#= type.wide #>[] op3, int i) => i < op1.Length ? op1[i] : SubtractRoundedHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]); public static <#= type.wide #> SubtractWidening(<#= type.name #> op1, <#= type.name #> op2) => (<#= type.wide #>)((<#= type.wide #>)op1 - (<#= type.wide #>)op2); @@ -774,26 +778,6 @@ namespace JIT.HardwareIntrinsics.Arm public static long PolynomialMultiplyWideningHi64(long op1, long op2) => (long)PolynomialMult(op1, op2).hi; <# - foreach (var type in new[] { (small: "sbyte", wide: "short"), - (small: "short", wide: "int"), - (small: "int", wide: "long"), - (small: "byte", wide: "ushort"), - (small: "ushort", wide: "uint"), - (small: "uint", wide: "ulong") }) - { -#> - public static bool ExtractAndNarrowHigh(int i, <#= type.small #>[] left, - <#= type.wide #>[] right, - <#= type.small #>[] result) - { - if (i < left.Length) - return left[i] != result[i]; - else - return (<#= type.small #>)right[i - left.Length] != result[i]; - } -<# - } - foreach (string typeName in new string[] { "sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong", "float", "double" }) { #> diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs index ed581eb676ddd..8f988f065faa8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs @@ -2515,84 +2515,84 @@ public new abstract class Arm64 : ArmBase.Arm64 /// A32: VADDHN.I16 Dd, Qn, Qm /// A64: ADDHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x4_t vaddhn_s32 (int32x4_t a, int32x4_t b) /// A32: VADDHN.I32 Dd, Qn, Qm /// A64: ADDHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x2_t vaddhn_s64 (int64x2_t a, int64x2_t b) /// A32: VADDHN.I64 Dd, Qn, Qm /// A64: ADDHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x8_t vaddhn_s16 (int16x8_t a, int16x8_t b) /// A32: VADDHN.I16 Dd, Qn, Qm /// A64: ADDHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x4_t vaddhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VADDHN.I32 Dd, Qn, Qm /// A64: ADDHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x2_t vaddhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VADDHN.I64 Dd, Qn, Qm /// A64: ADDHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x16_t vaddhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VADDHN.I16 Dd+1, Qn, Qm /// A64: ADDHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x8_t vaddhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VADDHN.I32 Dd+1, Qn, Qm /// A64: ADDHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x4_t vaddhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VADDHN.I64 Dd+1, Qn, Qm /// A64: ADDHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x16_t vaddhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VADDHN.I16 Dd+1, Qn, Qm /// A64: ADDHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x8_t vaddhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VADDHN.I32 Dd+1, Qn, Qm /// A64: ADDHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x4_t vaddhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VADDHN.I64 Dd+1, Qn, Qm /// A64: ADDHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x8_t vpadd_u8 (uint8x8_t a, uint8x8_t b) @@ -2816,84 +2816,84 @@ public new abstract class Arm64 : ArmBase.Arm64 /// A32: VRADDHN.I16 Dd, Qn, Qm /// A64: RADDHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddRoundedHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x4_t vraddhn_s32 (int32x4_t a, int32x4_t b) /// A32: VRADDHN.I32 Dd, Qn, Qm /// A64: RADDHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddRoundedHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x2_t vraddhn_s64 (int64x2_t a, int64x2_t b) /// A32: VRADDHN.I64 Dd, Qn, Qm /// A64: RADDHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddRoundedHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x8_t vraddhn_s16 (int16x8_t a, int16x8_t b) /// A32: VRADDHN.I16 Dd, Qn, Qm /// A64: RADDHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddRoundedHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x4_t vraddhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VRADDHN.I32 Dd, Qn, Qm /// A64: RADDHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddRoundedHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x2_t vraddhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VRADDHN.I64 Dd, Qn, Qm /// A64: RADDHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 AddRoundedHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x16_t vraddhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VRADDHN.I16 Dd+1, Qn, Qm /// A64: RADDHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x8_t vraddhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VRADDHN.I32 Dd+1, Qn, Qm /// A64: RADDHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x4_t vraddhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VRADDHN.I64 Dd+1, Qn, Qm /// A64: RADDHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x16_t vraddhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VRADDHN.I16 Dd+1, Qn, Qm /// A64: RADDHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x8_t vraddhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VRADDHN.I32 Dd+1, Qn, Qm /// A64: RADDHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x4_t vraddhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VRADDHN.I64 Dd+1, Qn, Qm /// A64: RADDHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 AddRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x8_t vqadd_u8 (uint8x8_t a, uint8x8_t b) @@ -4655,84 +4655,84 @@ public new abstract class Arm64 : ArmBase.Arm64 /// A32: VMOVN.I16 Dd+1, Qm /// A64: XTN2 Vd.16B, Vn.8H /// - public static Vector128 ExtractAndNarrowHigh (Vector64 lower, Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 ExtractNarrowingUpper(Vector64 lower, Vector128 value) { throw new PlatformNotSupportedException(); } /// /// int16x8_t vmovn_high_s32 (int16x4_t r, int32x4_t a) /// A32: VMOVN.I32 Dd+1, Qm /// A64: XTN2 Vd.8H, Vn.4S /// - public static Vector128 ExtractAndNarrowHigh (Vector64 lower, Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 ExtractNarrowingUpper(Vector64 lower, Vector128 value) { throw new PlatformNotSupportedException(); } /// /// int32x4_t vmovn_high_s64 (int32x2_t r, int64x2_t a) /// A32: VMOVN.I64 Dd+1, Qm /// A64: XTN2 Vd.4S, Vn.2D /// - public static Vector128 ExtractAndNarrowHigh (Vector64 lower, Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 ExtractNarrowingUpper(Vector64 lower, Vector128 value) { throw new PlatformNotSupportedException(); } /// /// uint8x16_t vmovn_high_u16 (uint8x8_t r, uint16x8_t a) /// A32: VMOVN.I16 Dd+1, Qm /// A64: XTN2 Vd.16B, Vn.8H /// - public static Vector128 ExtractAndNarrowHigh (Vector64 lower, Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 ExtractNarrowingUpper(Vector64 lower, Vector128 value) { throw new PlatformNotSupportedException(); } /// /// uint16x8_t vmovn_high_u32 (uint16x4_t r, uint32x4_t a) /// A32: VMOVN.I32 Dd+1, Qm /// A64: XTN2 Vd.8H, Vn.4S /// - public static Vector128 ExtractAndNarrowHigh (Vector64 lower, Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 ExtractNarrowingUpper(Vector64 lower, Vector128 value) { throw new PlatformNotSupportedException(); } /// /// uint32x4_t vmovn_high_u64 (uint32x2_t r, uint64x2_t a) /// A32: VMOVN.I64 Dd+1, Qm /// A64: XTN2 Vd.4S, Vn.2D /// - public static Vector128 ExtractAndNarrowHigh (Vector64 lower, Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector128 ExtractNarrowingUpper(Vector64 lower, Vector128 value) { throw new PlatformNotSupportedException(); } /// /// int8x8_t vmovn_s16 (int16x8_t a) /// A32: VMOVN.I16 Dd, Qm /// A64: XTN Vd.8B, Vn.8H /// - public static Vector64 ExtractAndNarrowLow (Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector64 ExtractNarrowingLower(Vector128 value) { throw new PlatformNotSupportedException(); } /// /// int16x4_t vmovn_s32 (int32x4_t a) /// A32: VMOVN.I32 Dd, Qm /// A64: XTN Vd.4H, Vn.4S /// - public static Vector64 ExtractAndNarrowLow (Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector64 ExtractNarrowingLower(Vector128 value) { throw new PlatformNotSupportedException(); } /// /// int32x2_t vmovn_s64 (int64x2_t a) /// A32: VMOVN.I64 Dd, Qm /// A64: XTN Vd.2S, Vn.2D /// - public static Vector64 ExtractAndNarrowLow (Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector64 ExtractNarrowingLower(Vector128 value) { throw new PlatformNotSupportedException(); } /// /// uint8x8_t vmovn_u16 (uint16x8_t a) /// A32: VMOVN.I16 Dd, Qm /// A64: XTN Vd.8B, Vn.8H /// - public static Vector64 ExtractAndNarrowLow (Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector64 ExtractNarrowingLower(Vector128 value) { throw new PlatformNotSupportedException(); } /// /// uint16x4_t vmovn_u32 (uint32x4_t a) /// A32: VMOVN.I32 Dd, Qm /// A64: XTN Vd.4H, Vn.4S /// - public static Vector64 ExtractAndNarrowLow (Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector64 ExtractNarrowingLower(Vector128 value) { throw new PlatformNotSupportedException(); } /// /// uint32x2_t vmovn_u64 (uint64x2_t a) /// A32: VMOVN.I64 Dd, Qm /// A64: XTN Vd.2S, Vn.2D /// - public static Vector64 ExtractAndNarrowLow (Vector128 value) { throw new PlatformNotSupportedException(); } + public static Vector64 ExtractNarrowingLower(Vector128 value) { throw new PlatformNotSupportedException(); } /// /// uint8x8_t vext_s8 (uint8x8_t a, uint8x8_t b, const int n) @@ -7406,168 +7406,168 @@ public new abstract class Arm64 : ArmBase.Arm64 /// A32: VSUBHN.I16 Dd, Qn, Qm /// A64: SUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x4_t vsubhn_s32 (int32x4_t a, int32x4_t b) /// A32: VSUBHN.I32 Dd, Qn, Qm /// A64: SUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x2_t vsubhn_s64 (int64x2_t a, int64x2_t b) /// A32: VSUBHN.I64 Dd, Qn, Qm /// A64: SUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x8_t vsubhn_s16 (int16x8_t a, int16x8_t b) /// A32: VSUBHN.I16 Dd, Qn, Qm /// A64: SUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x4_t vsubhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VSUBHN.I32 Dd, Qn, Qm /// A64: SUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x2_t vsubhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VSUBHN.I64 Dd, Qn, Qm /// A64: SUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x16_t vsubhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VSUBHN.I16 Dd+1, Qn, Qm /// A64: SUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x8_t vsubhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VSUBHN.I32 Dd+1, Qn, Qm /// A64: SUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x4_t vsubhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VSUBHN.I64 Dd+1, Qn, Qm /// A64: SUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x16_t vsubhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VSUBHN.I16 Dd+1, Qn, Qm /// A64: SUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x8_t vsubhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VSUBHN.I32 Dd+1, Qn, Qm /// A64: SUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x4_t vsubhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VSUBHN.I64 Dd+1, Qn, Qm /// A64: SUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x8_t vrsubhn_u16 (uint16x8_t a, uint16x8_t b) /// A32: VRSUBHN.I16 Dd, Qn, Qm /// A64: RSUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractRoundedHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x4_t vrsubhn_s32 (int32x4_t a, int32x4_t b) /// A32: VRSUBHN.I32 Dd, Qn, Qm /// A64: RSUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractRoundedHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x2_t vrsubhn_s64 (int64x2_t a, int64x2_t b) /// A32: VRSUBHN.I64 Dd, Qn, Qm /// A64: RSUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractRoundedHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x8_t vrsubhn_s16 (int16x8_t a, int16x8_t b) /// A32: VRSUBHN.I16 Dd, Qn, Qm /// A64: RSUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractRoundedHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x4_t vrsubhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VRSUBHN.I32 Dd, Qn, Qm /// A64: RSUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractRoundedHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x2_t vrsubhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VRSUBHN.I64 Dd, Qn, Qm /// A64: RSUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector64 SubtractRoundedHighNarrowingLower(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x16_t vrsubhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VRSUBHN.I16 Dd+1, Qn, Qm /// A64: RSUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int16x8_t vrsubhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VRSUBHN.I32 Dd+1, Qn, Qm /// A64: RSUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int32x4_t vrsubhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VRSUBHN.I64 Dd+1, Qn, Qm /// A64: RSUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// int8x16_t vrsubhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VRSUBHN.I16 Dd+1, Qn, Qm /// A64: RSUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint16x8_t vrsubhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VRSUBHN.I32 Dd+1, Qn, Qm /// A64: RSUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint32x4_t vrsubhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VRSUBHN.I64 Dd+1, Qn, Qm /// A64: RSUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + public static Vector128 SubtractRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// /// uint8x8_t vqsub_u8 (uint8x8_t a, uint8x8_t b) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs index 7f79a36693efa..27b265a963bd0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs @@ -2517,84 +2517,84 @@ public new abstract class Arm64 : ArmBase.Arm64 /// A32: VADDHN.I16 Dd, Qn, Qm /// A64: ADDHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) => AddHighNarrowLower(left, right); + public static Vector64 AddHighNarrowingLower(Vector128 left, Vector128 right) => AddHighNarrowingLower(left, right); /// /// int16x4_t vaddhn_s32 (int32x4_t a, int32x4_t b) /// A32: VADDHN.I32 Dd, Qn, Qm /// A64: ADDHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) => AddHighNarrowLower(left, right); + public static Vector64 AddHighNarrowingLower(Vector128 left, Vector128 right) => AddHighNarrowingLower(left, right); /// /// int32x2_t vaddhn_s64 (int64x2_t a, int64x2_t b) /// A32: VADDHN.I64 Dd, Qn, Qm /// A64: ADDHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) => AddHighNarrowLower(left, right); + public static Vector64 AddHighNarrowingLower(Vector128 left, Vector128 right) => AddHighNarrowingLower(left, right); /// /// int8x8_t vaddhn_s16 (int16x8_t a, int16x8_t b) /// A32: VADDHN.I16 Dd, Qn, Qm /// A64: ADDHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) => AddHighNarrowLower(left, right); + public static Vector64 AddHighNarrowingLower(Vector128 left, Vector128 right) => AddHighNarrowingLower(left, right); /// /// uint16x4_t vaddhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VADDHN.I32 Dd, Qn, Qm /// A64: ADDHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) => AddHighNarrowLower(left, right); + public static Vector64 AddHighNarrowingLower(Vector128 left, Vector128 right) => AddHighNarrowingLower(left, right); /// /// uint32x2_t vaddhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VADDHN.I64 Dd, Qn, Qm /// A64: ADDHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 AddHighNarrowLower(Vector128 left, Vector128 right) => AddHighNarrowLower(left, right); + public static Vector64 AddHighNarrowingLower(Vector128 left, Vector128 right) => AddHighNarrowingLower(left, right); /// /// uint8x16_t vaddhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VADDHN.I16 Dd+1, Qn, Qm /// A64: ADDHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowUpper(lower, left, right); + public static Vector128 AddHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowingUpper(lower, left, right); /// /// int16x8_t vaddhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VADDHN.I32 Dd+1, Qn, Qm /// A64: ADDHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowUpper(lower, left, right); + public static Vector128 AddHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowingUpper(lower, left, right); /// /// int32x4_t vaddhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VADDHN.I64 Dd+1, Qn, Qm /// A64: ADDHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowUpper(lower, left, right); + public static Vector128 AddHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowingUpper(lower, left, right); /// /// int8x16_t vaddhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VADDHN.I16 Dd+1, Qn, Qm /// A64: ADDHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowUpper(lower, left, right); + public static Vector128 AddHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowingUpper(lower, left, right); /// /// uint16x8_t vaddhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VADDHN.I32 Dd+1, Qn, Qm /// A64: ADDHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowUpper(lower, left, right); + public static Vector128 AddHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowingUpper(lower, left, right); /// /// uint32x4_t vaddhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VADDHN.I64 Dd+1, Qn, Qm /// A64: ADDHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 AddHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowUpper(lower, left, right); + public static Vector128 AddHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => AddHighNarrowingUpper(lower, left, right); /// /// uint8x8_t vpadd_u8 (uint8x8_t a, uint8x8_t b) @@ -2818,84 +2818,84 @@ public new abstract class Arm64 : ArmBase.Arm64 /// A32: VRADDHN.I16 Dd, Qn, Qm /// A64: RADDHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowLower(left, right); + public static Vector64 AddRoundedHighNarrowingLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowingLower(left, right); /// /// int16x4_t vraddhn_s32 (int32x4_t a, int32x4_t b) /// A32: VRADDHN.I32 Dd, Qn, Qm /// A64: RADDHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowLower(left, right); + public static Vector64 AddRoundedHighNarrowingLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowingLower(left, right); /// /// int32x2_t vraddhn_s64 (int64x2_t a, int64x2_t b) /// A32: VRADDHN.I64 Dd, Qn, Qm /// A64: RADDHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowLower(left, right); + public static Vector64 AddRoundedHighNarrowingLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowingLower(left, right); /// /// int8x8_t vraddhn_s16 (int16x8_t a, int16x8_t b) /// A32: VRADDHN.I16 Dd, Qn, Qm /// A64: RADDHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowLower(left, right); + public static Vector64 AddRoundedHighNarrowingLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowingLower(left, right); /// /// uint16x4_t vraddhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VRADDHN.I32 Dd, Qn, Qm /// A64: RADDHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowLower(left, right); + public static Vector64 AddRoundedHighNarrowingLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowingLower(left, right); /// /// uint32x2_t vraddhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VRADDHN.I64 Dd, Qn, Qm /// A64: RADDHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 AddRoundedHighNarrowLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowLower(left, right); + public static Vector64 AddRoundedHighNarrowingLower(Vector128 left, Vector128 right) => AddRoundedHighNarrowingLower(left, right); /// /// uint8x16_t vraddhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VRADDHN.I16 Dd+1, Qn, Qm /// A64: RADDHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowUpper(lower, left, right); + public static Vector128 AddRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowingUpper(lower, left, right); /// /// int16x8_t vraddhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VRADDHN.I32 Dd+1, Qn, Qm /// A64: RADDHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowUpper(lower, left, right); + public static Vector128 AddRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowingUpper(lower, left, right); /// /// int32x4_t vraddhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VRADDHN.I64 Dd+1, Qn, Qm /// A64: RADDHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowUpper(lower, left, right); + public static Vector128 AddRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowingUpper(lower, left, right); /// /// int8x16_t vraddhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VRADDHN.I16 Dd+1, Qn, Qm /// A64: RADDHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowUpper(lower, left, right); + public static Vector128 AddRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowingUpper(lower, left, right); /// /// uint16x8_t vraddhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VRADDHN.I32 Dd+1, Qn, Qm /// A64: RADDHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowUpper(lower, left, right); + public static Vector128 AddRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowingUpper(lower, left, right); /// /// uint32x4_t vraddhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VRADDHN.I64 Dd+1, Qn, Qm /// A64: RADDHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 AddRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowUpper(lower, left, right); + public static Vector128 AddRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => AddRoundedHighNarrowingUpper(lower, left, right); /// /// uint8x8_t vqadd_u8 (uint8x8_t a, uint8x8_t b) @@ -4657,84 +4657,84 @@ public new abstract class Arm64 : ArmBase.Arm64 /// A32: VMOVN.I16 Dd+1, Qm /// A64: XTN2 Vd.16B, Vn.8H /// - public static Vector128 ExtractAndNarrowHigh (Vector64 lower, Vector128 value) => ExtractAndNarrowHigh (lower, value); + public static Vector128 ExtractNarrowingUpper(Vector64 lower, Vector128 value) => ExtractNarrowingUpper(lower, value); /// /// int16x8_t vmovn_high_s32 (int16x4_t r, int32x4_t a) /// A32: VMOVN.I32 Dd+1, Qm /// A64: XTN2 Vd.8H, Vn.4S /// - public static Vector128 ExtractAndNarrowHigh (Vector64 lower, Vector128 value) => ExtractAndNarrowHigh (lower, value); + public static Vector128 ExtractNarrowingUpper(Vector64 lower, Vector128 value) => ExtractNarrowingUpper(lower, value); /// /// int32x4_t vmovn_high_s64 (int32x2_t r, int64x2_t a) /// A32: VMOVN.I64 Dd+1, Qm /// A64: XTN2 Vd.4S, Vn.2D /// - public static Vector128 ExtractAndNarrowHigh (Vector64 lower, Vector128 value) => ExtractAndNarrowHigh (lower, value); + public static Vector128 ExtractNarrowingUpper(Vector64 lower, Vector128 value) => ExtractNarrowingUpper(lower, value); /// /// uint8x16_t vmovn_high_u16 (uint8x8_t r, uint16x8_t a) /// A32: VMOVN.I16 Dd+1, Qm /// A64: XTN2 Vd.16B, Vn.8H /// - public static Vector128 ExtractAndNarrowHigh (Vector64 lower, Vector128 value) => ExtractAndNarrowHigh (lower, value); + public static Vector128 ExtractNarrowingUpper(Vector64 lower, Vector128 value) => ExtractNarrowingUpper(lower, value); /// /// uint16x8_t vmovn_high_u32 (uint16x4_t r, uint32x4_t a) /// A32: VMOVN.I32 Dd+1, Qm /// A64: XTN2 Vd.8H, Vn.4S /// - public static Vector128 ExtractAndNarrowHigh (Vector64 lower, Vector128 value) => ExtractAndNarrowHigh (lower, value); + public static Vector128 ExtractNarrowingUpper(Vector64 lower, Vector128 value) => ExtractNarrowingUpper(lower, value); /// /// uint32x4_t vmovn_high_u64 (uint32x2_t r, uint64x2_t a) /// A32: VMOVN.I64 Dd+1, Qm /// A64: XTN2 Vd.4S, Vn.2D /// - public static Vector128 ExtractAndNarrowHigh (Vector64 lower, Vector128 value) => ExtractAndNarrowHigh (lower, value); + public static Vector128 ExtractNarrowingUpper(Vector64 lower, Vector128 value) => ExtractNarrowingUpper(lower, value); /// /// int8x8_t vmovn_s16 (int16x8_t a) /// A32: VMOVN.I16 Dd, Qm /// A64: XTN Vd.8B, Vn.8H /// - public static Vector64 ExtractAndNarrowLow (Vector128 value) => ExtractAndNarrowLow (value); + public static Vector64 ExtractNarrowingLower(Vector128 value) => ExtractNarrowingLower(value); /// /// int16x4_t vmovn_s32 (int32x4_t a) /// A32: VMOVN.I32 Dd, Qm /// A64: XTN Vd.4H, Vn.4S /// - public static Vector64 ExtractAndNarrowLow (Vector128 value) => ExtractAndNarrowLow (value); + public static Vector64 ExtractNarrowingLower(Vector128 value) => ExtractNarrowingLower(value); /// /// int32x2_t vmovn_s64 (int64x2_t a) /// A32: VMOVN.I64 Dd, Qm /// A64: XTN Vd.2S, Vn.2D /// - public static Vector64 ExtractAndNarrowLow (Vector128 value) => ExtractAndNarrowLow (value); + public static Vector64 ExtractNarrowingLower(Vector128 value) => ExtractNarrowingLower(value); /// /// uint8x8_t vmovn_u16 (uint16x8_t a) /// A32: VMOVN.I16 Dd, Qm /// A64: XTN Vd.8B, Vn.8H /// - public static Vector64 ExtractAndNarrowLow (Vector128 value) => ExtractAndNarrowLow (value); + public static Vector64 ExtractNarrowingLower(Vector128 value) => ExtractNarrowingLower(value); /// /// uint16x4_t vmovn_u32 (uint32x4_t a) /// A32: VMOVN.I32 Dd, Qm /// A64: XTN Vd.4H, Vn.4S /// - public static Vector64 ExtractAndNarrowLow (Vector128 value) => ExtractAndNarrowLow (value); + public static Vector64 ExtractNarrowingLower(Vector128 value) => ExtractNarrowingLower(value); /// /// uint32x2_t vmovn_u64 (uint64x2_t a) /// A32: VMOVN.I64 Dd, Qm /// A64: XTN Vd.2S, Vn.2D /// - public static Vector64 ExtractAndNarrowLow (Vector128 value) => ExtractAndNarrowLow (value); + public static Vector64 ExtractNarrowingLower(Vector128 value) => ExtractNarrowingLower(value); /// /// uint8x8_t vext_s8 (uint8x8_t a, uint8x8_t b, const int n) @@ -7408,168 +7408,168 @@ public new abstract class Arm64 : ArmBase.Arm64 /// A32: VSUBHN.I16 Dd, Qn, Qm /// A64: SUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) => SubtractHighNarrowLower(left, right); + public static Vector64 SubtractHighNarrowingLower(Vector128 left, Vector128 right) => SubtractHighNarrowingLower(left, right); /// /// int16x4_t vsubhn_s32 (int32x4_t a, int32x4_t b) /// A32: VSUBHN.I32 Dd, Qn, Qm /// A64: SUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) => SubtractHighNarrowLower(left, right); + public static Vector64 SubtractHighNarrowingLower(Vector128 left, Vector128 right) => SubtractHighNarrowingLower(left, right); /// /// int32x2_t vsubhn_s64 (int64x2_t a, int64x2_t b) /// A32: VSUBHN.I64 Dd, Qn, Qm /// A64: SUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) => SubtractHighNarrowLower(left, right); + public static Vector64 SubtractHighNarrowingLower(Vector128 left, Vector128 right) => SubtractHighNarrowingLower(left, right); /// /// int8x8_t vsubhn_s16 (int16x8_t a, int16x8_t b) /// A32: VSUBHN.I16 Dd, Qn, Qm /// A64: SUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) => SubtractHighNarrowLower(left, right); + public static Vector64 SubtractHighNarrowingLower(Vector128 left, Vector128 right) => SubtractHighNarrowingLower(left, right); /// /// uint16x4_t vsubhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VSUBHN.I32 Dd, Qn, Qm /// A64: SUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) => SubtractHighNarrowLower(left, right); + public static Vector64 SubtractHighNarrowingLower(Vector128 left, Vector128 right) => SubtractHighNarrowingLower(left, right); /// /// uint32x2_t vsubhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VSUBHN.I64 Dd, Qn, Qm /// A64: SUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractHighNarrowLower(Vector128 left, Vector128 right) => SubtractHighNarrowLower(left, right); + public static Vector64 SubtractHighNarrowingLower(Vector128 left, Vector128 right) => SubtractHighNarrowingLower(left, right); /// /// uint8x16_t vsubhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VSUBHN.I16 Dd+1, Qn, Qm /// A64: SUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowUpper(lower, left, right); + public static Vector128 SubtractHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowingUpper(lower, left, right); /// /// int16x8_t vsubhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VSUBHN.I32 Dd+1, Qn, Qm /// A64: SUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowUpper(lower, left, right); + public static Vector128 SubtractHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowingUpper(lower, left, right); /// /// int32x4_t vsubhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VSUBHN.I64 Dd+1, Qn, Qm /// A64: SUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowUpper(lower, left, right); + public static Vector128 SubtractHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowingUpper(lower, left, right); /// /// int8x16_t vsubhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VSUBHN.I16 Dd+1, Qn, Qm /// A64: SUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowUpper(lower, left, right); + public static Vector128 SubtractHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowingUpper(lower, left, right); /// /// uint16x8_t vsubhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VSUBHN.I32 Dd+1, Qn, Qm /// A64: SUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowUpper(lower, left, right); + public static Vector128 SubtractHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowingUpper(lower, left, right); /// /// uint32x4_t vsubhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VSUBHN.I64 Dd+1, Qn, Qm /// A64: SUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowUpper(lower, left, right); + public static Vector128 SubtractHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractHighNarrowingUpper(lower, left, right); /// /// uint8x8_t vrsubhn_u16 (uint16x8_t a, uint16x8_t b) /// A32: VRSUBHN.I16 Dd, Qn, Qm /// A64: RSUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowLower(left, right); + public static Vector64 SubtractRoundedHighNarrowingLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowingLower(left, right); /// /// int16x4_t vrsubhn_s32 (int32x4_t a, int32x4_t b) /// A32: VRSUBHN.I32 Dd, Qn, Qm /// A64: RSUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowLower(left, right); + public static Vector64 SubtractRoundedHighNarrowingLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowingLower(left, right); /// /// int32x2_t vrsubhn_s64 (int64x2_t a, int64x2_t b) /// A32: VRSUBHN.I64 Dd, Qn, Qm /// A64: RSUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowLower(left, right); + public static Vector64 SubtractRoundedHighNarrowingLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowingLower(left, right); /// /// int8x8_t vrsubhn_s16 (int16x8_t a, int16x8_t b) /// A32: VRSUBHN.I16 Dd, Qn, Qm /// A64: RSUBHN Vd.8B, Vn.8H, Vm.8H /// - public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowLower(left, right); + public static Vector64 SubtractRoundedHighNarrowingLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowingLower(left, right); /// /// uint16x4_t vrsubhn_u32 (uint32x4_t a, uint32x4_t b) /// A32: VRSUBHN.I32 Dd, Qn, Qm /// A64: RSUBHN Vd.4H, Vn.4S, Vm.4S /// - public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowLower(left, right); + public static Vector64 SubtractRoundedHighNarrowingLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowingLower(left, right); /// /// uint32x2_t vrsubhn_u64 (uint64x2_t a, uint64x2_t b) /// A32: VRSUBHN.I64 Dd, Qn, Qm /// A64: RSUBHN Vd.2S, Vn.2D, Vm.2D /// - public static Vector64 SubtractRoundedHighNarrowLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowLower(left, right); + public static Vector64 SubtractRoundedHighNarrowingLower(Vector128 left, Vector128 right) => SubtractRoundedHighNarrowingLower(left, right); /// /// uint8x16_t vrsubhn_high_u16 (uint8x8_t r, uint16x8_t a, uint16x8_t b) /// A32: VRSUBHN.I16 Dd+1, Qn, Qm /// A64: RSUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowUpper(lower, left, right); + public static Vector128 SubtractRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowingUpper(lower, left, right); /// /// int16x8_t vrsubhn_high_s32 (int16x4_t r, int32x4_t a, int32x4_t b) /// A32: VRSUBHN.I32 Dd+1, Qn, Qm /// A64: RSUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowUpper(lower, left, right); + public static Vector128 SubtractRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowingUpper(lower, left, right); /// /// int32x4_t vrsubhn_high_s64 (int32x2_t r, int64x2_t a, int64x2_t b) /// A32: VRSUBHN.I64 Dd+1, Qn, Qm /// A64: RSUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowUpper(lower, left, right); + public static Vector128 SubtractRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowingUpper(lower, left, right); /// /// int8x16_t vrsubhn_high_s16 (int8x8_t r, int16x8_t a, int16x8_t b) /// A32: VRSUBHN.I16 Dd+1, Qn, Qm /// A64: RSUBHN2 Vd.16B, Vn.8H, Vm.8H /// - public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowUpper(lower, left, right); + public static Vector128 SubtractRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowingUpper(lower, left, right); /// /// uint16x8_t vrsubhn_high_u32 (uint16x4_t r, uint32x4_t a, uint32x4_t b) /// A32: VRSUBHN.I32 Dd+1, Qn, Qm /// A64: RSUBHN2 Vd.8H, Vn.4S, Vm.4S /// - public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowUpper(lower, left, right); + public static Vector128 SubtractRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowingUpper(lower, left, right); /// /// uint32x4_t vrsubhn_high_u64 (uint32x2_t r, uint64x2_t a, uint64x2_t b) /// A32: VRSUBHN.I64 Dd+1, Qn, Qm /// A64: RSUBHN2 Vd.4S, Vn.2D, Vm.2D /// - public static Vector128 SubtractRoundedHighNarrowUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowUpper(lower, left, right); + public static Vector128 SubtractRoundedHighNarrowingUpper(Vector64 lower, Vector128 left, Vector128 right) => SubtractRoundedHighNarrowingUpper(lower, left, right); /// /// uint8x8_t vqsub_u8 (uint8x8_t a, uint8x8_t b) diff --git a/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs b/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs index e903bf390fadc..d404129038d17 100644 --- a/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs +++ b/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs @@ -96,18 +96,18 @@ public abstract partial class AdvSimd : System.Runtime.Intrinsics.Arm.ArmBase public static System.Runtime.Intrinsics.Vector64 Add(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Add(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Add(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 AddPairwise(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 AddPairwise(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 AddPairwise(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } @@ -139,18 +139,18 @@ public abstract partial class AdvSimd : System.Runtime.Intrinsics.Arm.ArmBase public static System.Runtime.Intrinsics.Vector64 AddPairwiseWideningAndAddScalar(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value) { throw null; } public static System.Runtime.Intrinsics.Vector64 AddPairwiseWideningScalar(System.Runtime.Intrinsics.Vector64 value) { throw null; } public static System.Runtime.Intrinsics.Vector64 AddPairwiseWideningScalar(System.Runtime.Intrinsics.Vector64 value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 AddRoundedHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AddRoundedHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 AddSaturate(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 AddSaturate(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 AddSaturate(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } @@ -400,18 +400,18 @@ public abstract partial class AdvSimd : System.Runtime.Intrinsics.Arm.ArmBase public static float Extract(System.Runtime.Intrinsics.Vector64 vector, byte index) { throw null; } public static ushort Extract(System.Runtime.Intrinsics.Vector64 vector, byte index) { throw null; } public static uint Extract(System.Runtime.Intrinsics.Vector64 vector, byte index) { throw null; } - public static System.Runtime.Intrinsics.Vector128 ExtractAndNarrowHigh(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value) { throw null; } - public static System.Runtime.Intrinsics.Vector128 ExtractAndNarrowHigh(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value) { throw null; } - public static System.Runtime.Intrinsics.Vector128 ExtractAndNarrowHigh(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value) { throw null; } - public static System.Runtime.Intrinsics.Vector128 ExtractAndNarrowHigh(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value) { throw null; } - public static System.Runtime.Intrinsics.Vector128 ExtractAndNarrowHigh(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value) { throw null; } - public static System.Runtime.Intrinsics.Vector128 ExtractAndNarrowHigh(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 ExtractAndNarrowLow(System.Runtime.Intrinsics.Vector128 value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 ExtractAndNarrowLow(System.Runtime.Intrinsics.Vector128 value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 ExtractAndNarrowLow(System.Runtime.Intrinsics.Vector128 value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 ExtractAndNarrowLow(System.Runtime.Intrinsics.Vector128 value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 ExtractAndNarrowLow(System.Runtime.Intrinsics.Vector128 value) { throw null; } - public static System.Runtime.Intrinsics.Vector64 ExtractAndNarrowLow(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ExtractNarrowingLower(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ExtractNarrowingLower(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ExtractNarrowingLower(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ExtractNarrowingLower(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ExtractNarrowingLower(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ExtractNarrowingLower(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ExtractNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 lower, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 lower, byte index) { throw null; } public static System.Runtime.Intrinsics.Vector128 ExtractVector128(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 lower, byte index) { throw null; } @@ -790,30 +790,30 @@ public abstract partial class AdvSimd : System.Runtime.Intrinsics.Arm.ArmBase public static System.Runtime.Intrinsics.Vector64 Subtract(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Subtract(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Subtract(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } - public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector64 SubtractRoundedHighNarrowingLower(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SubtractRoundedHighNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 SubtractSaturate(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 SubtractSaturate(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 SubtractSaturate(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } From e5516bb2b188e56b47a758c9cbf0a7f1adf90dd0 Mon Sep 17 00:00:00 2001 From: Ivan Date: Fri, 22 May 2020 15:57:25 -0500 Subject: [PATCH 349/420] =?UTF-8?q?Renamed=20pInitRegZeroed=20to=20pInitRe?= =?UTF-8?q?gModified,=20initRegZeroed=20to=20initRegM=E2=80=A6=20(#36321)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/coreclr/src/jit/codegen.h | 16 +-- src/coreclr/src/jit/codegenarm.cpp | 21 ++-- src/coreclr/src/jit/codegenarm64.cpp | 31 +++--- src/coreclr/src/jit/codegenarmarch.cpp | 10 +- src/coreclr/src/jit/codegencommon.cpp | 131 +++++++++++++------------ src/coreclr/src/jit/codegenxarch.cpp | 51 +++++----- 6 files changed, 135 insertions(+), 125 deletions(-) diff --git a/src/coreclr/src/jit/codegen.h b/src/coreclr/src/jit/codegen.h index 2d6167fb8916b..e48e51049a09f 100644 --- a/src/coreclr/src/jit/codegen.h +++ b/src/coreclr/src/jit/codegen.h @@ -342,12 +342,12 @@ class CodeGen final : public CodeGenInterface void genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowestCalleeSavedOffset, int spDelta); void genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, int lowestCalleeSavedOffset, int spDelta); - void genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroed); + void genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegModified); #else void genPushCalleeSavedRegisters(); #endif - void genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn); + void genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegModified, regMaskTP maskArgRegsLiveIn); #if defined(TARGET_ARM) @@ -435,18 +435,18 @@ class CodeGen final : public CodeGenInterface void genZeroInitFltRegs(const regMaskTP& initFltRegs, const regMaskTP& initDblRegs, const regNumber& initReg); - regNumber genGetZeroReg(regNumber initReg, bool* pInitRegZeroed); + regNumber genGetZeroReg(regNumber initReg, bool* pInitRegModified); - void genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, bool* pInitRegZeroed); + void genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, bool* pInitRegModified); - void genReportGenericContextArg(regNumber initReg, bool* pInitRegZeroed); + void genReportGenericContextArg(regNumber initReg, bool* pInitRegModified); - void genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed); + void genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified); void genFinalizeFrame(); #ifdef PROFILING_SUPPORTED - void genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed); + void genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified); void genProfilingLeaveCallback(unsigned helper); #endif // PROFILING_SUPPORTED @@ -512,7 +512,7 @@ class CodeGen final : public CodeGenInterface void genFuncletEpilog(); void genCaptureFuncletPrologEpilogInfo(); - void genSetPSPSym(regNumber initReg, bool* pInitRegZeroed); + void genSetPSPSym(regNumber initReg, bool* pInitRegModified); void genUpdateCurrentFunclet(BasicBlock* block); #if defined(TARGET_ARM) diff --git a/src/coreclr/src/jit/codegenarm.cpp b/src/coreclr/src/jit/codegenarm.cpp index 6ddb1ff166356..015ac03a68b01 100644 --- a/src/coreclr/src/jit/codegenarm.cpp +++ b/src/coreclr/src/jit/codegenarm.cpp @@ -1648,14 +1648,14 @@ void CodeGen::genCodeForMulLong(GenTreeMultiRegOp* node) // genProfilingEnterCallback: Generate the profiling function enter callback. // // Arguments: -// initReg - register to use as scratch register -// pInitRegZeroed - OUT parameter. *pInitRegZeroed set to 'false' if 'initReg' is -// not zero after this call. +// initReg - register to use as scratch register +// pInitRegModified - OUT parameter. *pInitRegModified set to 'true' if and only if +// this call sets 'initReg' to a non-zero value. // // Return Value: // None // -void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) +void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified) { assert(compiler->compGeneratingProlog); @@ -1688,7 +1688,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) if (initReg == argReg) { - *pInitRegZeroed = false; + *pInitRegModified = true; } } @@ -1818,14 +1818,17 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper) // Arguments: // frameSize - the size of the stack frame being allocated. // initReg - register to use as a scratch register. -// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if +// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if // this call sets 'initReg' to a non-zero value. // maskArgRegsLiveIn - incoming argument registers that are currently live. // // Return value: // None // -void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn) +void CodeGen::genAllocLclFrame(unsigned frameSize, + regNumber initReg, + bool* pInitRegModified, + regMaskTP maskArgRegsLiveIn) { assert(compiler->compGeneratingProlog); @@ -1855,7 +1858,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni } regSet.verifyRegUsed(initReg); - *pInitRegZeroed = false; // The initReg does not contain zero + *pInitRegModified = true; instGen_Set_Reg_To_Imm(EA_PTRSIZE, initReg, frameSize); compiler->unwindPadding(); @@ -1875,7 +1878,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni if ((genRegMask(initReg) & (RBM_STACK_PROBE_HELPER_ARG | RBM_STACK_PROBE_HELPER_CALL_TARGET | RBM_STACK_PROBE_HELPER_TRASH)) != RBM_NONE) { - *pInitRegZeroed = false; + *pInitRegModified = true; } } diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index 79fd8fb6b6b4c..91b5885f17463 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -4898,14 +4898,14 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode) // genProfilingEnterCallback: Generate the profiling function enter callback. // // Arguments: -// initReg - register to use as scratch register -// pInitRegZeroed - OUT parameter. *pInitRegZeroed set to 'false' if 'initReg' is -// not zero after this call. +// initReg - register to use as scratch register +// pInitRegModified - OUT parameter. *pInitRegModified set to 'true' if 'initReg' is +// not zero after this call. // // Return Value: // None // -void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) +void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified) { assert(compiler->compGeneratingProlog); @@ -4933,7 +4933,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) if ((genRegMask(initReg) & RBM_PROFILER_ENTER_TRASH) != RBM_NONE) { - *pInitRegZeroed = false; + *pInitRegModified = true; } } @@ -9377,16 +9377,19 @@ void CodeGen::genArm64EmitterUnitTests() // on Windows as well just to be consistent, even though it should not be necessary. // // Arguments: -// frameSize - the size of the stack frame being allocated. -// initReg - register to use as a scratch register. -// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if -// this call sets 'initReg' to a non-zero value. -// maskArgRegsLiveIn - incoming argument registers that are currently live. +// frameSize - the size of the stack frame being allocated. +// initReg - register to use as a scratch register. +// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if +// this call sets 'initReg' to a non-zero value. +// maskArgRegsLiveIn - incoming argument registers that are currently live. // // Return value: // None // -void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn) +void CodeGen::genAllocLclFrame(unsigned frameSize, + regNumber initReg, + bool* pInitRegModified, + regMaskTP maskArgRegsLiveIn) { assert(compiler->compGeneratingProlog); @@ -9423,7 +9426,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni instGen_Set_Reg_To_Imm(EA_PTRSIZE, initReg, -(ssize_t)probeOffset); GetEmitter()->emitIns_R_R_R(INS_ldr, EA_4BYTE, REG_ZR, REG_SPBASE, initReg); regSet.verifyRegUsed(initReg); - *pInitRegZeroed = false; // The initReg does not contain zero + *pInitRegModified = true; lastTouchDelta -= pageSize; } @@ -9483,7 +9486,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni GetEmitter()->emitIns_R_R(INS_cmp, EA_PTRSIZE, rLimit, rOffset); // If equal, we need to probe again GetEmitter()->emitIns_J(INS_bls, NULL, -4); - *pInitRegZeroed = false; // The initReg does not contain zero + *pInitRegModified = true; compiler->unwindPadding(); @@ -9498,7 +9501,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni compiler->unwindPadding(); regSet.verifyRegUsed(initReg); - *pInitRegZeroed = false; // The initReg does not contain zero + *pInitRegModified = true; } } diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index cb1a495c058c3..c305408485fb5 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -562,14 +562,14 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla // genSetGSSecurityCookie: Set the "GS" security cookie in the prolog. // // Arguments: -// initReg - register to use as a scratch register -// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if -// this call sets 'initReg' to a non-zero value. +// initReg - register to use as a scratch register +// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if +// this call sets 'initReg' to a non-zero value. // // Return Value: // None // -void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed) +void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified) { assert(compiler->compGeneratingProlog); @@ -593,7 +593,7 @@ void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed) GetEmitter()->emitIns_S_R(INS_str, EA_PTRSIZE, initReg, compiler->lvaGSSecurityCookie, 0); } - *pInitRegZeroed = false; + *pInitRegModified = true; } //--------------------------------------------------------------------- diff --git a/src/coreclr/src/jit/codegencommon.cpp b/src/coreclr/src/jit/codegencommon.cpp index a3c47a2ba2225..10129250671e9 100644 --- a/src/coreclr/src/jit/codegencommon.cpp +++ b/src/coreclr/src/jit/codegencommon.cpp @@ -4848,7 +4848,7 @@ void CodeGen::genCheckUseBlockInit() */ #if defined(TARGET_ARM64) -void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroed) +void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegModified) #else void CodeGen::genPushCalleeSavedRegisters() #endif @@ -5337,7 +5337,8 @@ void CodeGen::genPushCalleeSavedRegisters() JITDUMP(" spAdjustment2=%d\n", spAdjustment2); - genPrologSaveRegPair(REG_FP, REG_LR, alignmentAdjustment2, -spAdjustment2, false, initReg, pInitRegZeroed); + genPrologSaveRegPair(REG_FP, REG_LR, alignmentAdjustment2, -spAdjustment2, false, initReg, + pInitRegModified); offset += spAdjustment2; // Now subtract off the #outsz (or the rest of the #outsz if it was unaligned, and the above "sub" @@ -5357,13 +5358,13 @@ void CodeGen::genPushCalleeSavedRegisters() // We've already established the frame pointer, so no need to report the stack pointer change to unwind // info. - genStackPointerAdjustment(-spAdjustment3, initReg, pInitRegZeroed, /* reportUnwindData */ false); + genStackPointerAdjustment(-spAdjustment3, initReg, pInitRegModified, /* reportUnwindData */ false); offset += spAdjustment3; } else { genPrologSaveRegPair(REG_FP, REG_LR, compiler->lvaOutgoingArgSpaceSize, -remainingFrameSz, false, initReg, - pInitRegZeroed); + pInitRegModified); offset += remainingFrameSz; offsetSpToSavedFp = compiler->lvaOutgoingArgSpaceSize; @@ -5395,7 +5396,7 @@ void CodeGen::genPushCalleeSavedRegisters() JITDUMP(" remainingFrameSz=%d\n", remainingFrameSz); // We've already established the frame pointer, so no need to report the stack pointer change to unwind info. - genStackPointerAdjustment(-remainingFrameSz, initReg, pInitRegZeroed, /* reportUnwindData */ false); + genStackPointerAdjustment(-remainingFrameSz, initReg, pInitRegModified, /* reportUnwindData */ false); offset += remainingFrameSz; } else @@ -6124,17 +6125,17 @@ void CodeGen::genPopCalleeSavedRegisters(bool jmpEpilog) #endif // TARGET* -// We need a register with value zero. Zero the initReg, if necessary, and set *pInitRegZeroed if so. +// We need a register with value zero. Zero the initReg, if necessary, and set *pInitRegModified if so. // Return the register to use. On ARM64, we never touch the initReg, and always just return REG_ZR. -regNumber CodeGen::genGetZeroReg(regNumber initReg, bool* pInitRegZeroed) +regNumber CodeGen::genGetZeroReg(regNumber initReg, bool* pInitRegModified) { #ifdef TARGET_ARM64 return REG_ZR; #else // !TARGET_ARM64 - if (*pInitRegZeroed == false) + if (*pInitRegModified) { instGen_Set_Reg_To_Zero(EA_PTRSIZE, initReg); - *pInitRegZeroed = true; + *pInitRegModified = false; } return initReg; #endif // !TARGET_ARM64 @@ -6144,14 +6145,14 @@ regNumber CodeGen::genGetZeroReg(regNumber initReg, bool* pInitRegZeroed) // genZeroInitFrame: Zero any untracked pointer locals and/or initialize memory for locspace // // Arguments: -// untrLclHi - (Untracked locals High-Offset) The upper bound offset at which the zero init -// code will end initializing memory (not inclusive). -// untrLclLo - (Untracked locals Low-Offset) The lower bound at which the zero init code will -// start zero initializing memory. -// initReg - A scratch register (that gets set to zero on some platforms). -// pInitRegZeroed - Sets a flag that tells the callee whether or not the initReg register got zeroed. +// untrLclHi - (Untracked locals High-Offset) The upper bound offset at which the zero init +// code will end initializing memory (not inclusive). +// untrLclLo - (Untracked locals Low-Offset) The lower bound at which the zero init code will +// start zero initializing memory. +// initReg - A scratch register (that gets set to zero on some platforms). +// pInitRegModified - Sets a flag that tells the callee whether or not the initReg register got zeroed. // -void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, bool* pInitRegZeroed) +void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, bool* pInitRegModified) { assert(compiler->compGeneratingProlog); @@ -6226,8 +6227,8 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, #else // !define(TARGET_ARM) - rAddr = initReg; - *pInitRegZeroed = false; + rAddr = initReg; + *pInitRegModified = true; #endif // !defined(TARGET_ARM) @@ -6268,7 +6269,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, // Load immediate into the InitReg register instGen_Set_Reg_To_Imm(EA_PTRSIZE, initReg, (ssize_t)untrLclLo); GetEmitter()->emitIns_R_R_R(INS_add, EA_PTRSIZE, rAddr, genFramePointerReg(), initReg); - *pInitRegZeroed = false; + *pInitRegModified = true; } if (useLoop) @@ -6280,7 +6281,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, } #if defined(TARGET_ARM) - rZero1 = genGetZeroReg(initReg, pInitRegZeroed); + rZero1 = genGetZeroReg(initReg, pInitRegModified); instGen_Set_Reg_To_Zero(EA_PTRSIZE, rZero2); target_ssize_t stmImm = (target_ssize_t)(genRegMask(rZero1) | genRegMask(rZero2)); #endif // TARGET_ARM @@ -6369,7 +6370,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, #endif if (blkSize < minSimdSize) { - zeroReg = genGetZeroReg(initReg, pInitRegZeroed); + zeroReg = genGetZeroReg(initReg, pInitRegModified); int i = 0; for (; i + REGSIZE_BYTES <= blkSize; i += REGSIZE_BYTES) @@ -6431,7 +6432,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, assert(alignmentLoBlkSize < XMM_REGSIZE_BYTES); assert((alignedLclLo - alignmentLoBlkSize) == untrLclLo); - zeroReg = genGetZeroReg(initReg, pInitRegZeroed); + zeroReg = genGetZeroReg(initReg, pInitRegModified); int i = 0; for (; i + REGSIZE_BYTES <= alignmentLoBlkSize; i += REGSIZE_BYTES) @@ -6539,7 +6540,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, emit->emitIns_J(INS_jne, nullptr, -5); // initReg will be zero at end of the loop - *pInitRegZeroed = true; + *pInitRegModified = false; } if (untrLclHi != alignedLclHi) @@ -6548,7 +6549,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, assert(alignmentHiBlkSize < XMM_REGSIZE_BYTES); assert((alignedLclHi + alignmentHiBlkSize) == untrLclHi); - zeroReg = genGetZeroReg(initReg, pInitRegZeroed); + zeroReg = genGetZeroReg(initReg, pInitRegModified); int i = 0; for (; i + REGSIZE_BYTES <= alignmentHiBlkSize; i += REGSIZE_BYTES) @@ -6615,13 +6616,13 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, if (layout->IsGCPtr(i)) { GetEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, - genGetZeroReg(initReg, pInitRegZeroed), varNum, i * REGSIZE_BYTES); + genGetZeroReg(initReg, pInitRegModified), varNum, i * REGSIZE_BYTES); } } } else { - regNumber zeroReg = genGetZeroReg(initReg, pInitRegZeroed); + regNumber zeroReg = genGetZeroReg(initReg, pInitRegModified); // zero out the whole thing rounded up to a single stack slot size unsigned lclSize = roundUp(compiler->lvaLclSize(varNum), (unsigned)sizeof(int)); @@ -6653,7 +6654,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, // printf("initialize untracked spillTmp [EBP-%04X]\n", stkOffs); - inst_ST_RV(ins_Store(TYP_I_IMPL), tempThis, 0, genGetZeroReg(initReg, pInitRegZeroed), TYP_I_IMPL); + inst_ST_RV(ins_Store(TYP_I_IMPL), tempThis, 0, genGetZeroReg(initReg, pInitRegModified), TYP_I_IMPL); } } @@ -6788,7 +6789,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, * ICodeManager::GetParamTypeArg(). */ -void CodeGen::genReportGenericContextArg(regNumber initReg, bool* pInitRegZeroed) +void CodeGen::genReportGenericContextArg(regNumber initReg, bool* pInitRegModified) { // For OSR the original method has set this up for us. if (compiler->opts.IsOSR()) @@ -6853,8 +6854,8 @@ void CodeGen::genReportGenericContextArg(regNumber initReg, bool* pInitRegZeroed // We will just use the initReg since it is an available register // and we are probably done using it anyway... - reg = initReg; - *pInitRegZeroed = false; + reg = initReg; + *pInitRegModified = true; // mov reg, [compiler->info.compTypeCtxtArg] GetEmitter()->emitIns_R_AR(ins_Load(TYP_I_IMPL), EA_PTRSIZE, reg, genFramePointerReg(), varDsc->lvStkOffs); @@ -7698,9 +7699,9 @@ void CodeGen::genFnProlog() /* Choose the register to use for zero initialization */ - regNumber initReg = REG_SCRATCH; // Unless we find a better register below - bool initRegZeroed = false; - regMaskTP excludeMask = intRegState.rsCalleeRegArgMaskLiveIn; + regNumber initReg = REG_SCRATCH; // Unless we find a better register below + bool initRegModified = true; + regMaskTP excludeMask = intRegState.rsCalleeRegArgMaskLiveIn; regMaskTP tempMask; // We should not use the special PINVOKE registers as the initReg @@ -7833,11 +7834,11 @@ void CodeGen::genFnProlog() // been calculated to be one of the callee-saved registers (say, if all the integer argument registers are // in use, and perhaps with other conditions being satisfied). This is ok in other cases, after the callee-saved // registers have been saved. So instead of letting genAllocLclFrame use initReg as a temporary register, - // always use REG_SCRATCH. We don't care if it trashes it, so ignore the initRegZeroed output argument. - bool ignoreInitRegZeroed = false; - genAllocLclFrame(compiler->compLclFrameSize, REG_SCRATCH, &ignoreInitRegZeroed, + // always use REG_SCRATCH. We don't care if it trashes it, so ignore the initRegModified output argument. + bool ignoreInitRegModified = true; + genAllocLclFrame(compiler->compLclFrameSize, REG_SCRATCH, &ignoreInitRegModified, intRegState.rsCalleeRegArgMaskLiveIn); - genPushCalleeSavedRegisters(initReg, &initRegZeroed); + genPushCalleeSavedRegisters(initReg, &initRegModified); #else // !TARGET_ARM64 genPushCalleeSavedRegisters(); #endif // !TARGET_ARM64 @@ -7881,7 +7882,7 @@ void CodeGen::genFnProlog() if (maskStackAlloc == RBM_NONE) { - genAllocLclFrame(compiler->compLclFrameSize, initReg, &initRegZeroed, intRegState.rsCalleeRegArgMaskLiveIn); + genAllocLclFrame(compiler->compLclFrameSize, initReg, &initRegModified, intRegState.rsCalleeRegArgMaskLiveIn); } #endif // !TARGET_ARM64 @@ -7944,11 +7945,11 @@ void CodeGen::genFnProlog() // Zero out the frame as needed // - genZeroInitFrame(untrLclHi, untrLclLo, initReg, &initRegZeroed); + genZeroInitFrame(untrLclHi, untrLclLo, initReg, &initRegModified); #if defined(FEATURE_EH_FUNCLETS) - genSetPSPSym(initReg, &initRegZeroed); + genSetPSPSym(initReg, &initRegModified); #else // !FEATURE_EH_FUNCLETS @@ -7961,10 +7962,10 @@ void CodeGen::genFnProlog() // Zero out the slot for nesting level 0 unsigned firstSlotOffs = filterEndOffsetSlotOffs - TARGET_POINTER_SIZE; - if (!initRegZeroed) + if (initRegModified) { instGen_Set_Reg_To_Zero(EA_PTRSIZE, initReg); - initRegZeroed = true; + initRegModified = false; } GetEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, initReg, compiler->lvaShadowSPslotsVar, @@ -7973,7 +7974,7 @@ void CodeGen::genFnProlog() #endif // !FEATURE_EH_FUNCLETS - genReportGenericContextArg(initReg, &initRegZeroed); + genReportGenericContextArg(initReg, &initRegModified); #ifdef JIT32_GCENCODER // Initialize the LocalAllocSP slot if there is localloc in the function. @@ -7985,7 +7986,7 @@ void CodeGen::genFnProlog() // Set up the GS security cookie - genSetGSSecurityCookie(initReg, &initRegZeroed); + genSetGSSecurityCookie(initReg, &initRegModified); #ifdef PROFILING_SUPPORTED @@ -7993,7 +7994,7 @@ void CodeGen::genFnProlog() // OSR methods aren't called, so don't have enter hooks. if (!compiler->opts.IsOSR()) { - genProfilingEnterCallback(initReg, &initRegZeroed); + genProfilingEnterCallback(initReg, &initRegModified); } #endif // PROFILING_SUPPORTED @@ -8055,15 +8056,15 @@ void CodeGen::genFnProlog() } else { - xtraReg = REG_SCRATCH; - initRegZeroed = false; + xtraReg = REG_SCRATCH; + initRegModified = true; } genFnPrologCalleeRegArgs(xtraReg, &xtraRegClobbered, regState); if (xtraRegClobbered) { - initRegZeroed = false; + initRegModified = true; } } } @@ -8083,7 +8084,7 @@ void CodeGen::genFnProlog() if (regMask & initRegs) { // Check if we have already zeroed this register - if ((reg == initReg) && initRegZeroed) + if ((reg == initReg) && !initRegModified) { continue; } @@ -8092,7 +8093,7 @@ void CodeGen::genFnProlog() instGen_Set_Reg_To_Zero(EA_PTRSIZE, reg); if (reg == initReg) { - initRegZeroed = true; + initRegModified = false; } } } @@ -8104,17 +8105,17 @@ void CodeGen::genFnProlog() // If initReg is not in initRegs then we will use REG_SCRATCH if ((genRegMask(initReg) & initRegs) == 0) { - initReg = REG_SCRATCH; - initRegZeroed = false; + initReg = REG_SCRATCH; + initRegModified = true; } #ifdef TARGET_ARM // This is needed only for Arm since it can use a zero initialized int register // to initialize vfp registers. - if (!initRegZeroed) + if (initRegModified) { instGen_Set_Reg_To_Zero(EA_PTRSIZE, initReg); - initRegZeroed = true; + initRegModified = false; } #endif // TARGET_ARM @@ -9121,12 +9122,12 @@ void CodeGen::genFuncletProlog(BasicBlock* block) maskArgRegsLiveIn = RBM_R0; } - regNumber initReg = REG_R3; // R3 is never live on entry to a funclet, so it can be trashed - bool initRegZeroed = false; + regNumber initReg = REG_R3; // R3 is never live on entry to a funclet, so it can be trashed + bool initRegModified = true; if (maskStackAlloc == RBM_NONE) { - genAllocLclFrame(genFuncletInfo.fiSpDelta, initReg, &initRegZeroed, maskArgRegsLiveIn); + genAllocLclFrame(genFuncletInfo.fiSpDelta, initReg, &initRegModified, maskArgRegsLiveIn); } // This is the end of the OS-reported prolog for purposes of unwinding @@ -9423,10 +9424,10 @@ void CodeGen::genFuncletProlog(BasicBlock* block) maskArgRegsLiveIn = RBM_ARG_0 | RBM_ARG_2; } - regNumber initReg = REG_EBP; // We already saved EBP, so it can be trashed - bool initRegZeroed = false; + regNumber initReg = REG_EBP; // We already saved EBP, so it can be trashed + bool initRegModified = true; - genAllocLclFrame(genFuncletInfo.fiSpDelta, initReg, &initRegZeroed, maskArgRegsLiveIn); + genAllocLclFrame(genFuncletInfo.fiSpDelta, initReg, &initRegModified, maskArgRegsLiveIn); // Callee saved float registers are copied to stack in their assigned stack slots // after allocating space for them as part of funclet frame. @@ -9765,7 +9766,7 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo() * correctly reported, the PSPSym could be omitted in some cases.) *********************************** */ -void CodeGen::genSetPSPSym(regNumber initReg, bool* pInitRegZeroed) +void CodeGen::genSetPSPSym(regNumber initReg, bool* pInitRegModified) { assert(compiler->compGeneratingProlog); @@ -9811,8 +9812,8 @@ void CodeGen::genSetPSPSym(regNumber initReg, bool* pInitRegZeroed) // We will just use the initReg since it is an available register // and we are probably done using it anyway... - regNumber regTmp = initReg; - *pInitRegZeroed = false; + regNumber regTmp = initReg; + *pInitRegModified = true; GetEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, regTmp, regBase, callerSPOffs); GetEmitter()->emitIns_S_R(INS_str, EA_PTRSIZE, regTmp, compiler->lvaPSPSym, 0); @@ -9823,8 +9824,8 @@ void CodeGen::genSetPSPSym(regNumber initReg, bool* pInitRegZeroed) // We will just use the initReg since it is an available register // and we are probably done using it anyway... - regNumber regTmp = initReg; - *pInitRegZeroed = false; + regNumber regTmp = initReg; + *pInitRegModified = true; GetEmitter()->emitIns_R_R_Imm(INS_add, EA_PTRSIZE, regTmp, REG_SPBASE, SPtoCallerSPdelta); GetEmitter()->emitIns_S_R(INS_str, EA_PTRSIZE, regTmp, compiler->lvaPSPSym, 0); diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index f365138a91227..2b7a5556532dc 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -54,14 +54,14 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla // genSetGSSecurityCookie: Set the "GS" security cookie in the prolog. // // Arguments: -// initReg - register to use as a scratch register -// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if -// this call sets 'initReg' to a non-zero value. +// initReg - register to use as a scratch register +// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if +// this call sets 'initReg' to a non-zero value. // // Return Value: // None // -void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed) +void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified) { assert(compiler->compGeneratingProlog); @@ -85,7 +85,7 @@ void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed) // initReg = #GlobalSecurityCookieVal64; [frame.GSSecurityCookie] = initReg genSetRegToIcon(initReg, compiler->gsGlobalSecurityCookieVal, TYP_I_IMPL); GetEmitter()->emitIns_S_R(INS_mov, EA_PTRSIZE, initReg, compiler->lvaGSSecurityCookie, 0); - *pInitRegZeroed = false; + *pInitRegModified = true; } else #endif @@ -106,7 +106,7 @@ void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed) GetEmitter()->emitIns_S_R(INS_mov, EA_PTRSIZE, REG_EAX, compiler->lvaGSSecurityCookie, 0); if (initReg == REG_EAX) { - *pInitRegZeroed = false; + *pInitRegModified = true; } } } @@ -1995,16 +1995,19 @@ void CodeGen::genMultiRegStoreToLocal(GenTree* treeNode) // genAllocLclFrame: Probe the stack and allocate the local stack frame - subtract from SP. // // Arguments: -// frameSize - the size of the stack frame being allocated. -// initReg - register to use as a scratch register. -// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if -// this call sets 'initReg' to a non-zero value. -// maskArgRegsLiveIn - incoming argument registers that are currently live. +// frameSize - the size of the stack frame being allocated. +// initReg - register to use as a scratch register. +// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if +// this call sets 'initReg' to a non-zero value. +// maskArgRegsLiveIn - incoming argument registers that are currently live. // // Return value: // None // -void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn) +void CodeGen::genAllocLclFrame(unsigned frameSize, + regNumber initReg, + bool* pInitRegModified, + regMaskTP maskArgRegsLiveIn) { assert(compiler->compGeneratingProlog); @@ -2088,7 +2091,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni if (initReg == REG_DEFAULT_HELPER_CALL_TARGET) { - *pInitRegZeroed = false; + *pInitRegModified = true; } static_assert_no_msg((RBM_STACK_PROBE_HELPER_TRASH & RBM_STACK_PROBE_HELPER_ARG) == RBM_NONE); @@ -2098,7 +2101,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni if (initReg == REG_STACK_PROBE_HELPER_ARG) { - *pInitRegZeroed = false; + *pInitRegModified = true; } } @@ -8495,9 +8498,9 @@ void CodeGen::genAmd64EmitterUnitTests() // genProfilingEnterCallback: Generate the profiling function enter callback. // // Arguments: -// initReg - register to use as scratch register -// pInitRegZeroed - OUT parameter. *pInitRegZeroed set to 'false' if 'initReg' is -// not zero after this call. +// initReg - register to use as scratch register +// pInitRegModified - OUT parameter. *pInitRegModified set to 'true' if 'initReg' is +// not zero after this call. // // Return Value: // None @@ -8516,7 +8519,7 @@ void CodeGen::genAmd64EmitterUnitTests() // 4. All registers are preserved. // 5. The helper pops the FunctionIDOrClientID argument from the stack. // -void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) +void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified) { assert(compiler->compGeneratingProlog); @@ -8661,14 +8664,14 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper) // genProfilingEnterCallback: Generate the profiling function enter callback. // // Arguments: -// initReg - register to use as scratch register -// pInitRegZeroed - OUT parameter. *pInitRegZeroed set to 'false' if 'initReg' is -// not zero after this call. +// initReg - register to use as scratch register +// pInitRegModified - OUT parameter. *pInitRegModified set to 'true' if 'initReg' is +// not zero after this call. // // Return Value: // None // -void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) +void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified) { assert(compiler->compGeneratingProlog); @@ -8805,7 +8808,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) // If initReg is one of RBM_CALLEE_TRASH, then it needs to be zero'ed before using. if ((RBM_CALLEE_TRASH & genRegMask(initReg)) != 0) { - *pInitRegZeroed = false; + *pInitRegModified = true; } #else // !defined(UNIX_AMD64_ABI) @@ -8854,7 +8857,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) // If initReg is one of RBM_CALLEE_TRASH, then it needs to be zero'ed before using. if ((RBM_CALLEE_TRASH & genRegMask(initReg)) != 0) { - *pInitRegZeroed = false; + *pInitRegModified = true; } #endif // !defined(UNIX_AMD64_ABI) From 8a775407b482dd626c49f5a5e2c65328fe2412d1 Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Fri, 22 May 2020 17:21:02 -0400 Subject: [PATCH 350/420] Add MONO_LOADER_LIBRARY_NAME define (#36835) --- src/mono/mono/metadata/loader-internals.h | 10 ++++++++++ src/mono/mono/metadata/native-library.c | 10 +--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/mono/mono/metadata/loader-internals.h b/src/mono/mono/metadata/loader-internals.h index 476376ce5d25f..07f6e7186c885 100644 --- a/src/mono/mono/metadata/loader-internals.h +++ b/src/mono/mono/metadata/loader-internals.h @@ -13,6 +13,16 @@ #include #include +#ifdef ENABLE_NETCORE +#if defined(TARGET_OSX) +#define MONO_LOADER_LIBRARY_NAME "libcoreclr.dylib" +#elif defined(TARGET_ANDROID) +#define MONO_LOADER_LIBRARY_NAME "libruntime-android.so" +#else +#define MONO_LOADER_LIBRARY_NAME "libcoreclr.so" +#endif +#endif + typedef struct _MonoLoadedImages MonoLoadedImages; typedef struct _MonoAssemblyLoadContext MonoAssemblyLoadContext; diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c index be893b11a766e..6b441a96e93ed 100644 --- a/src/mono/mono/metadata/native-library.c +++ b/src/mono/mono/metadata/native-library.c @@ -1268,15 +1268,7 @@ lookup_pinvoke_call_impl (MonoMethod *method, MonoLookupPInvokeStatus *status_ou #if defined(ENABLE_NETCORE) && !defined(HOST_WIN32) if (strcmp (new_scope, "__Internal") == 0) { g_free ((char *)new_scope); -#if defined(TARGET_OSX) - new_scope = g_strdup ("libcoreclr.dylib"); -#else -#if defined(TARGET_ANDROID) - new_scope = g_strdup ("libruntime-android.so"); -#else - new_scope = g_strdup ("libcoreclr.so"); -#endif -#endif + new_scope = g_strdup (MONO_LOADER_LIBRARY_NAME); goto retry_with_libcoreclr; } #endif From 702e2d060846acb08aa832a9715298fa978ab9ff Mon Sep 17 00:00:00 2001 From: monojenkins Date: Fri, 22 May 2020 17:23:26 -0400 Subject: [PATCH 351/420] Fixing make dist after implementation of static ICU Shim. (#36795) Fixing make dist after implementation of static ICU Shim. Co-authored-by: thaystg --- src/mono/mono/metadata/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/Makefile.am b/src/mono/mono/metadata/Makefile.am index 6a4bf4e7238eb..2ba687b890e2b 100644 --- a/src/mono/mono/metadata/Makefile.am +++ b/src/mono/mono/metadata/Makefile.am @@ -140,7 +140,7 @@ if ENABLE_NETCORE if HAVE_SYS_ICU shim_libraries = libmonoruntime-shimglobalization.la -libmonoruntime_shimglobalization_la_SOURCES = \ +nodist_libmonoruntime_shimglobalization_la_SOURCES = \ @ICU_SHIM_PATH@/pal_calendarData.c \ @ICU_SHIM_PATH@/pal_casing.c \ @ICU_SHIM_PATH@/pal_collation.c \ From 2d343933de876291bc58403b0b0243a988731d15 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Fri, 22 May 2020 17:49:34 -0400 Subject: [PATCH 352/420] Improve obsoletion message for IgnoreNullValues (#36886) --- .../System/Text/Json/Serialization/JsonSerializerOptions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs index 27dc1fe336964..05b2aec0a2faa 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs @@ -199,7 +199,7 @@ public int DefaultBufferSize /// Thrown if this property is set after serialization or deserialization has occurred. /// or has been set to a non-default value. These properties cannot be used together. /// - [Obsolete("Use DefaultIgnoreCondition instead.", error: false)] + [Obsolete("To ignore null values when serializing, set DefaultIgnoreCondition to JsonIgnoreCondition.WhenWritingDefault.", error: false)] [EditorBrowsable(EditorBrowsableState.Never)] public bool IgnoreNullValues { @@ -211,7 +211,7 @@ public bool IgnoreNullValues { VerifyMutable(); - if (value == true && _defaultIgnoreCondition != JsonIgnoreCondition.Never) + if (value && _defaultIgnoreCondition != JsonIgnoreCondition.Never) { Debug.Assert(_defaultIgnoreCondition == JsonIgnoreCondition.WhenWritingDefault); throw new InvalidOperationException(SR.DefaultIgnoreConditionAlreadySpecified); From efb8f5f8328ec6d45a066f079a33337eee15fc7f Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Fri, 22 May 2020 16:00:45 -0700 Subject: [PATCH 353/420] Disable System.Numerics.Tests.Vector3Tests.Vector3InequalityTest on arm64 (#36906) --- src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs b/src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs index ec930798c362d..be50353cc2d06 100644 --- a/src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs +++ b/src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs @@ -967,6 +967,7 @@ public void Vector3NegateTest() // A test for operator != (Vector3f, Vector3f) [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/36905", typeof(PlatformDetection), nameof(PlatformDetection.IsNotArm64Process))] public void Vector3InequalityTest() { Vector3 a = new Vector3(1.0f, 2.0f, 3.0f); From 0117a0c57a75a2a500b901ce18ff37b496227175 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Sat, 23 May 2020 00:58:02 +0100 Subject: [PATCH 354/420] Pipelines performance tweaks (#36815) * Pipelines performance tweaks * Packaging * Don't use Unsafe for array cast * Remove Unsafe use --- .../src/System/IO/Pipelines/BufferSegment.cs | 23 +++++++++---------- .../src/System/IO/Pipelines/Pipe.cs | 20 +++++++++------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/BufferSegment.cs b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/BufferSegment.cs index ffc27059d504f..800b141426083 100644 --- a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/BufferSegment.cs +++ b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/BufferSegment.cs @@ -10,7 +10,8 @@ namespace System.IO.Pipelines { internal sealed class BufferSegment : ReadOnlySequenceSegment { - private object? _memoryOwner; + private IMemoryOwner? _memoryOwner; + private byte[]? _array; private BufferSegment? _next; private int _end; @@ -55,36 +56,35 @@ public void SetOwnedMemory(IMemoryOwner memoryOwner) public void SetOwnedMemory(byte[] arrayPoolBuffer) { - _memoryOwner = arrayPoolBuffer; + _array = arrayPoolBuffer; AvailableMemory = arrayPoolBuffer; } public void ResetMemory() { - if (_memoryOwner is IMemoryOwner owner) + IMemoryOwner? memoryOwner = _memoryOwner; + if (memoryOwner != null) { - owner.Dispose(); + _memoryOwner = null; + memoryOwner.Dispose(); } else { - Debug.Assert(_memoryOwner is byte[]); - byte[] poolArray = (byte[])_memoryOwner; - ArrayPool.Shared.Return(poolArray); + Debug.Assert(_array != null); + ArrayPool.Shared.Return(_array); + _array = null; } - // Order of below field clears is significant as it clears in a sequential order - // https://github.com/dotnet/corefx/pull/35256#issuecomment-462800477 Next = null; RunningIndex = 0; Memory = default; - _memoryOwner = null; _next = null; _end = 0; AvailableMemory = default; } // Exposed for testing - internal object? MemoryOwner => _memoryOwner; + internal object? MemoryOwner => (object?)_memoryOwner ?? _array; public Memory AvailableMemory { get; private set; } @@ -124,6 +124,5 @@ internal static long GetLength(long startPosition, BufferSegment endSegment, int { return (endSegment.RunningIndex + (uint)endIndex) - startPosition; } - } } diff --git a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs index d66d40d11e71c..b92832c053dad 100644 --- a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs +++ b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs @@ -69,6 +69,9 @@ public sealed partial class Pipe private BufferSegment? _readHead; private int _readHeadIndex; + private readonly int _maxPooledBufferSize; + private bool _disposed; + // The extent of the bytes available to the PipeReader to consume private BufferSegment? _readTail; private int _readTailIndex; @@ -81,7 +84,6 @@ public sealed partial class Pipe // Determines what current operation is in flight (reading/writing) private PipeOperationState _operationState; - private bool _disposed; internal long Length => _unconsumedBytes; @@ -111,6 +113,7 @@ public Pipe(PipeOptions options) // If we're using the default pool then mark it as null since we're just going to use the // array pool under the covers _pool = options.Pool == MemoryPool.Shared ? null : options.Pool; + _maxPooledBufferSize = _pool?.MaxBufferSize ?? 0; _minimumSegmentSize = options.MinimumSegmentSize; _pauseWriterThreshold = options.PauseWriterThreshold; _resumeWriterThreshold = options.ResumeWriterThreshold; @@ -223,16 +226,17 @@ private BufferSegment AllocateSegment(int sizeHint) { BufferSegment newSegment = CreateSegmentUnsynchronized(); - if (_pool is null || sizeHint > _pool.MaxBufferSize) + int maxSize = _maxPooledBufferSize; + if (_pool != null && sizeHint <= maxSize) { - // Use the array pool - int sizeToRequest = GetSegmentSize(sizeHint); - newSegment.SetOwnedMemory(ArrayPool.Shared.Rent(sizeToRequest)); + // Use the specified pool as it fits + newSegment.SetOwnedMemory(_pool.Rent(GetSegmentSize(sizeHint, maxSize))); } else { - // Use the specified pool as it fits - newSegment.SetOwnedMemory(_pool.Rent(GetSegmentSize(sizeHint, _pool.MaxBufferSize))); + // Use the array pool + int sizeToRequest = GetSegmentSize(sizeHint); + newSegment.SetOwnedMemory(ArrayPool.Shared.Rent(sizeToRequest)); } _writingHeadMemory = newSegment.AvailableMemory; @@ -245,7 +249,7 @@ private int GetSegmentSize(int sizeHint, int maxBufferSize = int.MaxValue) // First we need to handle case where hint is smaller than minimum segment size sizeHint = Math.Max(_minimumSegmentSize, sizeHint); // After that adjust it to fit into pools max buffer size - var adjustedToMaximumSize = Math.Min(maxBufferSize, sizeHint); + int adjustedToMaximumSize = Math.Min(maxBufferSize, sizeHint); return adjustedToMaximumSize; } From a56d6a8034f5cb5ad58f9e29eb61edcc792f4b86 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Fri, 22 May 2020 17:13:41 -0700 Subject: [PATCH 355/420] Remove System.Globalization.Native shim from shared framework (#36904) * Remove System.Globalization.Native shim from shared framework * Add System.Globalization.Native sources to mono paths in pipeline --- eng/pipelines/runtime.yml | 2 + .../PinvokeAnalyzerExceptionList.analyzerdata | 39 +------------------ src/coreclr/src/vm/dllimport.cpp | 2 +- .../netcoreapp/pkg/Directory.Build.props | 2 - .../Common/src/Interop/Interop.Libraries.cs | 2 +- src/libraries/Native/Unix/CMakeLists.txt | 4 -- 6 files changed, 5 insertions(+), 46 deletions(-) diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 47df45a852015..b490d0deeed24 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -78,6 +78,8 @@ jobs: - subset: mono include: - src/libraries/System.Private.CoreLib/* + - src/libraries/Native/Unix/System.Globalization.Native/* + - src/libraries/Native/Unix/Common/* exclude: - eng/Version.Details.xml - '*.md' diff --git a/src/coreclr/src/System.Private.CoreLib/PinvokeAnalyzerExceptionList.analyzerdata b/src/coreclr/src/System.Private.CoreLib/PinvokeAnalyzerExceptionList.analyzerdata index f2570c7c958ee..e1c58c0c50381 100644 --- a/src/coreclr/src/System.Private.CoreLib/PinvokeAnalyzerExceptionList.analyzerdata +++ b/src/coreclr/src/System.Private.CoreLib/PinvokeAnalyzerExceptionList.analyzerdata @@ -7,41 +7,4 @@ user32.dll!GetProcessWindowStation user32.dll!GetUserObjectInformationW -kernel32.dll!GetGeoInfo - - -libSystem.Globalization.Native!GlobalizationNative_ChangeCase -libSystem.Globalization.Native!GlobalizationNative_ChangeCaseInvariant -libSystem.Globalization.Native!GlobalizationNative_ChangeCaseTurkish -libSystem.Globalization.Native!GlobalizationNative_CloseSortHandle -libSystem.Globalization.Native!GlobalizationNative_CompareString -libSystem.Globalization.Native!GlobalizationNative_CompareStringOrdinalIgnoreCase -libSystem.Globalization.Native!GlobalizationNative_EndsWith -libSystem.Globalization.Native!GlobalizationNative_EnumCalendarInfo -libSystem.Globalization.Native!GlobalizationNative_GetCalendarInfo -libSystem.Globalization.Native!GlobalizationNative_GetCalendars -libSystem.Globalization.Native!GlobalizationNative_GetDefaultLocaleName -libSystem.Globalization.Native!GlobalizationNative_GetICUVersion -libSystem.Globalization.Native!GlobalizationNative_GetJapaneseEraStartDate -libSystem.Globalization.Native!GlobalizationNative_GetLatestJapaneseEra -libSystem.Globalization.Native!GlobalizationNative_GetLocaleInfoGroupingSizes -libSystem.Globalization.Native!GlobalizationNative_GetLocaleInfoInt -libSystem.Globalization.Native!GlobalizationNative_GetLocaleInfoString -libSystem.Globalization.Native!GlobalizationNative_GetLocaleName -libSystem.Globalization.Native!GlobalizationNative_GetLocales -libSystem.Globalization.Native!GlobalizationNative_GetLocaleTimeFormat -libSystem.Globalization.Native!GlobalizationNative_GetSortHandle -libSystem.Globalization.Native!GlobalizationNative_GetSortKey -libSystem.Globalization.Native!GlobalizationNative_GetSortVersion -libSystem.Globalization.Native!GlobalizationNative_GetTimeZoneDisplayName -libSystem.Globalization.Native!GlobalizationNative_IndexOf -libSystem.Globalization.Native!GlobalizationNative_IndexOfOrdinalIgnoreCase -libSystem.Globalization.Native!GlobalizationNative_InitICUFunctions -libSystem.Globalization.Native!GlobalizationNative_IsNormalized -libSystem.Globalization.Native!GlobalizationNative_IsPredefinedLocale -libSystem.Globalization.Native!GlobalizationNative_LastIndexOf -libSystem.Globalization.Native!GlobalizationNative_LoadICU -libSystem.Globalization.Native!GlobalizationNative_NormalizeString -libSystem.Globalization.Native!GlobalizationNative_StartsWith -libSystem.Globalization.Native!GlobalizationNative_ToAscii -libSystem.Globalization.Native!GlobalizationNative_ToUnicode +kernel32.dll!GetGeoInfo \ No newline at end of file diff --git a/src/coreclr/src/vm/dllimport.cpp b/src/coreclr/src/vm/dllimport.cpp index b2f1ee1f94e8d..99a63ac3f5b11 100644 --- a/src/coreclr/src/vm/dllimport.cpp +++ b/src/coreclr/src/vm/dllimport.cpp @@ -4797,7 +4797,7 @@ void NDirect::PopulateNDirectMethodDesc(NDirectMethodDesc* pNMD, PInvokeStaticSi if (callConv == pmCallConvThiscall) ndirectflags |= NDirectMethodDesc::kThisCall; - if (pNMD->GetLoaderModule()->IsSystem() && (strcmp(szLibName, "QCall") == 0 || strcmp(szLibName, "libSystem.Globalization.Native") == 0)) + if (pNMD->GetLoaderModule()->IsSystem() && strcmp(szLibName, "QCall") == 0) { ndirectflags |= NDirectMethodDesc::kIsQCall; } diff --git a/src/installer/pkg/projects/netcoreapp/pkg/Directory.Build.props b/src/installer/pkg/projects/netcoreapp/pkg/Directory.Build.props index befd427101bea..e616a7cfc1f9a 100644 --- a/src/installer/pkg/projects/netcoreapp/pkg/Directory.Build.props +++ b/src/installer/pkg/projects/netcoreapp/pkg/Directory.Build.props @@ -14,7 +14,6 @@ - @@ -24,7 +23,6 @@ - diff --git a/src/libraries/Common/src/Interop/Interop.Libraries.cs b/src/libraries/Common/src/Interop/Interop.Libraries.cs index 9a64a909e35ca..d58d6a2126a4d 100644 --- a/src/libraries/Common/src/Interop/Interop.Libraries.cs +++ b/src/libraries/Common/src/Interop/Interop.Libraries.cs @@ -9,7 +9,7 @@ internal static partial class Libraries #if MONO internal const string GlobalizationNative = "__Internal"; #else - internal const string GlobalizationNative = "libSystem.Globalization.Native"; + internal const string GlobalizationNative = "QCall"; #endif } } diff --git a/src/libraries/Native/Unix/CMakeLists.txt b/src/libraries/Native/Unix/CMakeLists.txt index 1d1db4873abfe..aafa771b5a775 100644 --- a/src/libraries/Native/Unix/CMakeLists.txt +++ b/src/libraries/Native/Unix/CMakeLists.txt @@ -203,22 +203,18 @@ if(CLR_CMAKE_TARGET_BROWSER) # skip for now elseif(CLR_CMAKE_TARGET_IOS) add_subdirectory(System.Net.Security.Native) - #add_subdirectory(System.Globalization.Native) # TODO: reenable # System.Security.Cryptography.Native is intentionally disabled on iOS # it is only used for interacting with OpenSSL which isn't useful there elseif(CLR_CMAKE_TARGET_TVOS) #add_subdirectory(System.Net.Security.Native) # no gssapi on tvOS, see https://developer.apple.com/documentation/gss - #add_subdirectory(System.Globalization.Native) # TODO: reenable # System.Security.Cryptography.Native is intentionally disabled on tvOS # it is only used for interacting with OpenSSL which isn't useful there elseif(CLR_CMAKE_TARGET_ANDROID AND NOT CROSS_ROOTFS) - add_subdirectory(System.Globalization.Native) #add_subdirectory(System.Net.Security.Native) # TODO: reenable if (NOT "$ENV{ANDROID_OPENSSL_AAR}" STREQUAL "") add_subdirectory(System.Security.Cryptography.Native) endif() else() - add_subdirectory(System.Globalization.Native) add_subdirectory(System.Net.Security.Native) add_subdirectory(System.Security.Cryptography.Native) endif() From fdef317e512853e752fbd230b8458ef922e467c5 Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Sat, 23 May 2020 02:15:28 +0200 Subject: [PATCH 356/420] Remove dead Exception handling code in Uri (#36865) --- .../System.Private.Uri/src/System/Uri.cs | 32 ++++++-------- .../System.Private.Uri/src/System/UriExt.cs | 43 ++++++++----------- .../src/System/UriScheme.cs | 6 +-- 3 files changed, 31 insertions(+), 50 deletions(-) diff --git a/src/libraries/System.Private.Uri/src/System/Uri.cs b/src/libraries/System.Private.Uri/src/System/Uri.cs index 80277e12f7aca..9c9e681546e0f 100644 --- a/src/libraries/System.Private.Uri/src/System/Uri.cs +++ b/src/libraries/System.Private.Uri/src/System/Uri.cs @@ -480,19 +480,15 @@ private void CreateUri(Uri baseUri, string? relativeUri, bool dontEscape) // Parse relativeUri and populate Uri internal data. CreateThis(relativeUri, dontEscape, UriKind.RelativeOrAbsolute); - UriFormatException? e; if (baseUri.Syntax!.IsSimple) { // Resolve Uris if possible OR get merged Uri String to re-parse below - Uri? uriResult = ResolveHelper(baseUri, this, ref relativeUri, ref dontEscape, out e); - - if (e != null) - throw e; + Uri? uriResult = ResolveHelper(baseUri, this, ref relativeUri, ref dontEscape); // If resolved into a Uri then we build from that Uri if (uriResult != null) { - if ((object)uriResult != (object)this) + if (!ReferenceEquals(this, uriResult)) CreateThisFromUri(uriResult); return; @@ -501,7 +497,7 @@ private void CreateUri(Uri baseUri, string? relativeUri, bool dontEscape) else { dontEscape = false; - relativeUri = baseUri.Syntax.InternalResolve(baseUri, this, out e); + relativeUri = baseUri.Syntax.InternalResolve(baseUri, this, out UriFormatException? e); if (e != null) throw e; } @@ -528,20 +524,16 @@ public Uri(Uri baseUri, Uri relativeUri) CreateThisFromUri(relativeUri); string? newUriString = null; - UriFormatException? e; bool dontEscape; if (baseUri.Syntax!.IsSimple) { dontEscape = InFact(Flags.UserEscaped); - Uri? resolvedRelativeUri = ResolveHelper(baseUri, this, ref newUriString, ref dontEscape, out e); - - if (e != null) - throw e; + Uri? resolvedRelativeUri = ResolveHelper(baseUri, this, ref newUriString, ref dontEscape); if (resolvedRelativeUri != null) { - if ((object)resolvedRelativeUri != (object)this) + if (!ReferenceEquals(this, resolvedRelativeUri)) CreateThisFromUri(resolvedRelativeUri); DebugSetLeftCtor(); @@ -551,7 +543,7 @@ public Uri(Uri baseUri, Uri relativeUri) else { dontEscape = false; - newUriString = baseUri.Syntax.InternalResolve(baseUri, this, out e); + newUriString = baseUri.Syntax.InternalResolve(baseUri, this, out UriFormatException? e); if (e != null) throw e; } @@ -568,7 +560,7 @@ public Uri(Uri baseUri, Uri relativeUri) // The assumptions: // - baseUri is a valid absolute Uri // - relative part is not null and not empty - private static unsafe ParsingError GetCombinedString(Uri baseUri, string relativeStr, + private static unsafe void GetCombinedString(Uri baseUri, string relativeStr, bool dontEscape, ref string? result) { // NB: This is not RFC2396 compliant although it is inline with w3c.org recommendations @@ -610,7 +602,7 @@ public Uri(Uri baseUri, Uri relativeUri) // This is the place where we switch the scheme. // Return relative part as the result Uri. result = relativeStr; - return ParsingError.None; + return; } } break; @@ -620,11 +612,11 @@ public Uri(Uri baseUri, Uri relativeUri) if (relativeStr.Length == 0) { result = baseUri.OriginalString; - return ParsingError.None; } - - result = CombineUri(baseUri, relativeStr, dontEscape ? UriFormat.UriEscaped : UriFormat.SafeUnescaped); - return ParsingError.None; + else + { + result = CombineUri(baseUri, relativeStr, dontEscape ? UriFormat.UriEscaped : UriFormat.SafeUnescaped); + } } private static UriFormatException? GetException(ParsingError err) diff --git a/src/libraries/System.Private.Uri/src/System/UriExt.cs b/src/libraries/System.Private.Uri/src/System/UriExt.cs index 5f40d02e0569f..a9e94e88820f0 100644 --- a/src/libraries/System.Private.Uri/src/System/UriExt.cs +++ b/src/libraries/System.Private.Uri/src/System/UriExt.cs @@ -302,24 +302,23 @@ public static bool TryCreate(Uri? baseUri, Uri? relativeUri, [NotNullWhen(true)] if (baseUri.IsNotAbsoluteUri) return false; - UriFormatException? e; + UriFormatException? e = null; string? newUriString = null; bool dontEscape; if (baseUri.Syntax.IsSimple) { dontEscape = relativeUri.UserEscaped; - result = ResolveHelper(baseUri, relativeUri, ref newUriString, ref dontEscape, out e); - Debug.Assert(e is null || result is null); + result = ResolveHelper(baseUri, relativeUri, ref newUriString, ref dontEscape); } else { dontEscape = false; newUriString = baseUri.Syntax.InternalResolve(baseUri, relativeUri, out e); - } - if (e != null) - return false; + if (e != null) + return false; + } if (result is null) result = CreateHelper(newUriString!, dontEscape, UriKind.Absolute, ref e); @@ -665,13 +664,11 @@ private Uri(Flags flags, UriParser? uriParser, string uri) // to return combined URI strings from both Uris // otherwise if e != null on output the operation has failed // - internal static Uri? ResolveHelper(Uri baseUri, Uri? relativeUri, ref string? newUriString, ref bool userEscaped, - out UriFormatException? e) + internal static Uri? ResolveHelper(Uri baseUri, Uri? relativeUri, ref string? newUriString, ref bool userEscaped) { Debug.Assert(!baseUri.IsNotAbsoluteUri && !baseUri.UserDrivenParsing, "Uri::ResolveHelper()|baseUri is not Absolute or is controlled by User Parser."); - e = null; - string relativeStr = string.Empty; + string relativeStr; if ((object?)relativeUri != null) { @@ -739,16 +736,9 @@ private Uri(Flags flags, UriParser? uriParser, string uri) // If we are here then input like "http://host/path/" + "C:\x" will produce the result http://host/path/c:/x } + GetCombinedString(baseUri, relativeStr, userEscaped, ref newUriString); - ParsingError err = GetCombinedString(baseUri, relativeStr, userEscaped, ref newUriString); - - if (err != ParsingError.None) - { - e = GetException(err); - return null; - } - - if ((object?)newUriString == (object)baseUri._string) + if (ReferenceEquals(newUriString, baseUri._string)) return baseUri; return null; @@ -871,18 +861,19 @@ internal bool IsBaseOfHelper(Uri uriLink) { //a relative uri could have quite tricky form, it's better to fix it now. string? newUriString = null; - UriFormatException? e; bool dontEscape = false; - uriLink = ResolveHelper(this, uriLink, ref newUriString, ref dontEscape, out e)!; - if (e != null) - return false; + uriLink = ResolveHelper(this, uriLink, ref newUriString, ref dontEscape)!; + + if (uriLink is null) + { + UriFormatException? e = null; - if ((object?)uriLink == null) uriLink = CreateHelper(newUriString!, dontEscape, UriKind.Absolute, ref e)!; - if (e != null) - return false; + if (e != null) + return false; + } } if (Syntax.SchemeName != uriLink.Syntax.SchemeName) diff --git a/src/libraries/System.Private.Uri/src/System/UriScheme.cs b/src/libraries/System.Private.Uri/src/System/UriScheme.cs index 0675b41204a87..cc6be42d79b79 100644 --- a/src/libraries/System.Private.Uri/src/System/UriScheme.cs +++ b/src/libraries/System.Private.Uri/src/System/UriScheme.cs @@ -104,13 +104,11 @@ protected virtual void InitializeAndValidate(Uri uri, out UriFormatException? pa if (!baseUri.IsAbsoluteUri) throw new InvalidOperationException(SR.net_uri_NotAbsolute); - string? newUriString = null; bool userEscaped = false; - Uri? result = Uri.ResolveHelper(baseUri, relativeUri, ref newUriString, ref userEscaped, out parsingError); + parsingError = null; - if (parsingError != null) - return null; + Uri? result = Uri.ResolveHelper(baseUri, relativeUri, ref newUriString, ref userEscaped); if (result != null) return result.OriginalString; From 75141e1783a448f5637fc59695467df9645b2280 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 22 May 2020 17:50:33 -0700 Subject: [PATCH 357/420] Make Vector256 dependent on AVX instruction set (#36895) --- src/coreclr/src/inc/corinfoinstructionset.h | 4 ++ src/coreclr/src/jit/hwintrinsic.cpp | 43 +++++++++++++++---- .../JitInterface/CorInfoInstructionSet.cs | 8 ++++ .../ThunkGenerator/InstructionSetDesc.txt | 1 + 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/coreclr/src/inc/corinfoinstructionset.h b/src/coreclr/src/inc/corinfoinstructionset.h index 8040819439a00..8e667bc29b07b 100644 --- a/src/coreclr/src/inc/corinfoinstructionset.h +++ b/src/coreclr/src/inc/corinfoinstructionset.h @@ -274,6 +274,8 @@ inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_Ins resultflags.RemoveInstructionSet(InstructionSet_PCLMULQDQ); if (resultflags.HasInstructionSet(InstructionSet_POPCNT) && !resultflags.HasInstructionSet(InstructionSet_SSE42)) resultflags.RemoveInstructionSet(InstructionSet_POPCNT); + if (resultflags.HasInstructionSet(InstructionSet_Vector256) && !resultflags.HasInstructionSet(InstructionSet_AVX)) + resultflags.RemoveInstructionSet(InstructionSet_Vector256); #endif // TARGET_AMD64 #ifdef TARGET_X86 if (resultflags.HasInstructionSet(InstructionSet_SSE) && !resultflags.HasInstructionSet(InstructionSet_X86Base)) @@ -304,6 +306,8 @@ inline CORINFO_InstructionSetFlags EnsureInstructionSetFlagsAreValid(CORINFO_Ins resultflags.RemoveInstructionSet(InstructionSet_PCLMULQDQ); if (resultflags.HasInstructionSet(InstructionSet_POPCNT) && !resultflags.HasInstructionSet(InstructionSet_SSE42)) resultflags.RemoveInstructionSet(InstructionSet_POPCNT); + if (resultflags.HasInstructionSet(InstructionSet_Vector256) && !resultflags.HasInstructionSet(InstructionSet_AVX)) + resultflags.RemoveInstructionSet(InstructionSet_Vector256); #endif // TARGET_X86 } while (!oldflags.Equals(resultflags)); diff --git a/src/coreclr/src/jit/hwintrinsic.cpp b/src/coreclr/src/jit/hwintrinsic.cpp index cd197c7f27844..1089470adc45e 100644 --- a/src/coreclr/src/jit/hwintrinsic.cpp +++ b/src/coreclr/src/jit/hwintrinsic.cpp @@ -607,15 +607,42 @@ static bool isSupportedBaseType(NamedIntrinsic intrinsic, var_types baseType) } #ifdef TARGET_XARCH - assert((intrinsic >= NI_Vector128_As && intrinsic <= NI_Vector128_AsUInt64) || - (intrinsic >= NI_Vector128_get_AllBitsSet && intrinsic <= NI_Vector128_WithElement) || - (intrinsic >= NI_Vector256_As && intrinsic <= NI_Vector256_AsUInt64) || - (intrinsic >= NI_Vector256_get_AllBitsSet && intrinsic <= NI_Vector256_WithElement)); + assert((intrinsic == NI_Vector128_As) || (intrinsic == NI_Vector128_AsByte) || + (intrinsic == NI_Vector128_AsDouble) || (intrinsic == NI_Vector128_AsInt16) || + (intrinsic == NI_Vector128_AsInt32) || (intrinsic == NI_Vector128_AsInt64) || + (intrinsic == NI_Vector128_AsSByte) || (intrinsic == NI_Vector128_AsSingle) || + (intrinsic == NI_Vector128_AsUInt16) || (intrinsic == NI_Vector128_AsUInt32) || + (intrinsic == NI_Vector128_AsUInt64) || (intrinsic == NI_Vector128_get_AllBitsSet) || + (intrinsic == NI_Vector128_get_Count) || (intrinsic == NI_Vector128_get_Zero) || + (intrinsic == NI_Vector128_GetElement) || (intrinsic == NI_Vector128_WithElement) || + (intrinsic == NI_Vector128_ToScalar) || (intrinsic == NI_Vector128_ToVector256) || + (intrinsic == NI_Vector128_ToVector256Unsafe) || (intrinsic == NI_Vector256_As) || + (intrinsic == NI_Vector256_AsByte) || (intrinsic == NI_Vector256_AsDouble) || + (intrinsic == NI_Vector256_AsInt16) || (intrinsic == NI_Vector256_AsInt32) || + (intrinsic == NI_Vector256_AsInt64) || (intrinsic == NI_Vector256_AsSByte) || + (intrinsic == NI_Vector256_AsSingle) || (intrinsic == NI_Vector256_AsUInt16) || + (intrinsic == NI_Vector256_AsUInt32) || (intrinsic == NI_Vector256_AsUInt64) || + (intrinsic == NI_Vector256_get_AllBitsSet) || (intrinsic == NI_Vector256_get_Count) || + (intrinsic == NI_Vector256_get_Zero) || (intrinsic == NI_Vector256_GetElement) || + (intrinsic == NI_Vector256_WithElement) || (intrinsic == NI_Vector256_GetLower) || + (intrinsic == NI_Vector256_ToScalar)); #else - assert((intrinsic >= NI_Vector64_AsByte && intrinsic <= NI_Vector64_AsUInt32) || - (intrinsic >= NI_Vector64_get_AllBitsSet && intrinsic <= NI_Vector64_ToVector128Unsafe) || - (intrinsic >= NI_Vector128_As && intrinsic <= NI_Vector128_AsUInt64) || - (intrinsic >= NI_Vector128_get_AllBitsSet && intrinsic <= NI_Vector128_ToScalar)); + assert((intrinsic == NI_Vector64_AsByte) || (intrinsic == NI_Vector64_AsInt16) || + (intrinsic == NI_Vector64_AsInt32) || (intrinsic == NI_Vector64_AsSByte) || + (intrinsic == NI_Vector64_AsSingle) || (intrinsic == NI_Vector64_AsUInt16) || + (intrinsic == NI_Vector64_AsUInt32) || (intrinsic == NI_Vector64_get_AllBitsSet) || + (intrinsic == NI_Vector64_get_Count) || (intrinsic == NI_Vector64_get_Zero) || + (intrinsic == NI_Vector64_GetElement) || (intrinsic == NI_Vector64_ToScalar) || + (intrinsic == NI_Vector64_ToVector128) || (intrinsic == NI_Vector64_ToVector128Unsafe) || + (intrinsic == NI_Vector128_As) || (intrinsic == NI_Vector128_AsByte) || + (intrinsic == NI_Vector128_AsDouble) || (intrinsic == NI_Vector128_AsInt16) || + (intrinsic == NI_Vector128_AsInt32) || (intrinsic == NI_Vector128_AsInt64) || + (intrinsic == NI_Vector128_AsSByte) || (intrinsic == NI_Vector128_AsSingle) || + (intrinsic == NI_Vector128_AsUInt16) || (intrinsic == NI_Vector128_AsUInt32) || + (intrinsic == NI_Vector128_AsUInt64) || (intrinsic == NI_Vector128_get_AllBitsSet) || + (intrinsic == NI_Vector128_get_Count) || (intrinsic == NI_Vector128_get_Zero) || + (intrinsic == NI_Vector128_GetElement) || (intrinsic == NI_Vector128_GetLower) || + (intrinsic == NI_Vector128_ToScalar)); #endif return false; } diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoInstructionSet.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoInstructionSet.cs index 51638ce5dae76..dae2003712ff1 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoInstructionSet.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoInstructionSet.cs @@ -254,6 +254,8 @@ public static InstructionSetFlags ExpandInstructionSetByImplicationHelper(Target resultflags.AddInstructionSet(InstructionSet.X64_SSE2); if (resultflags.HasInstructionSet(InstructionSet.X64_POPCNT)) resultflags.AddInstructionSet(InstructionSet.X64_SSE42); + if (resultflags.HasInstructionSet(InstructionSet.X64_Vector256)) + resultflags.AddInstructionSet(InstructionSet.X64_AVX); break; case TargetArchitecture.X86: @@ -285,6 +287,8 @@ public static InstructionSetFlags ExpandInstructionSetByImplicationHelper(Target resultflags.AddInstructionSet(InstructionSet.X86_SSE2); if (resultflags.HasInstructionSet(InstructionSet.X86_POPCNT)) resultflags.AddInstructionSet(InstructionSet.X86_SSE42); + if (resultflags.HasInstructionSet(InstructionSet.X86_Vector256)) + resultflags.AddInstructionSet(InstructionSet.X86_AVX); break; } @@ -373,6 +377,8 @@ private static InstructionSetFlags ExpandInstructionSetByReverseImplicationHelpe resultflags.AddInstructionSet(InstructionSet.X64_PCLMULQDQ); if (resultflags.HasInstructionSet(InstructionSet.X64_SSE42)) resultflags.AddInstructionSet(InstructionSet.X64_POPCNT); + if (resultflags.HasInstructionSet(InstructionSet.X64_AVX)) + resultflags.AddInstructionSet(InstructionSet.X64_Vector256); break; case TargetArchitecture.X86: @@ -404,6 +410,8 @@ private static InstructionSetFlags ExpandInstructionSetByReverseImplicationHelpe resultflags.AddInstructionSet(InstructionSet.X86_PCLMULQDQ); if (resultflags.HasInstructionSet(InstructionSet.X86_SSE42)) resultflags.AddInstructionSet(InstructionSet.X86_POPCNT); + if (resultflags.HasInstructionSet(InstructionSet.X86_AVX)) + resultflags.AddInstructionSet(InstructionSet.X86_Vector256); break; } diff --git a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt index 479aea6562cef..44a9139982108 100644 --- a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt +++ b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt @@ -50,6 +50,7 @@ instructionset ,X86 ,Popcnt , ,15 ,POPCNT ,popcnt implication ,X86 ,POPCNT ,SSE42 instructionset ,X86 , , , ,Vector128, instructionset ,X86 , , , ,Vector256, +implication ,X86 ,Vector256 ,AVX ; Definition of X64 instruction sets (Define ) definearch ,X64 ,64Bit ,X64 From a26363e47a22dda533ed28f589ec7fed3e794dc4 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Fri, 22 May 2020 19:44:35 -0700 Subject: [PATCH 358/420] [Arm64] ASIMD Shift Intrinsics (#36830) * ShiftArithmetic * ShiftArithmeticRounded * ShiftArithmeticRoundedSaturate * ShiftArithmeticRoundedSaturateScalar * ShiftArithmeticRoundedScalar * ShiftArithmeticSaturate * ShiftArithmeticSaturateScalar * ShiftArithmeticScalar * ShiftLeftLogical * ShiftLeftLogicalSaturate * ShiftLeftLogicalSaturateScalar * ShiftLeftLogicalSaturateUnsigned * ShiftLeftLogicalSaturateUnsignedScalar * ShiftLeftLogicalScalar * ShiftLeftLogicalWideningLower * ShiftLeftLogicalWideningUpper * ShiftLogical * ShiftLogicalRounded * ShiftLogicalRoundedSaturate * ShiftLogicalRoundedSaturateScalar * ShiftLogicalRoundedScalar * ShiftLogicalSaturate * ShiftLogicalSaturateScalar * ShiftLogicalScalar * ShiftRightArithmetic * ShiftRightArithmeticAdd * ShiftRightArithmeticAddScalar * ShiftRightArithmeticNarrowingSaturateLower * ShiftRightArithmeticNarrowingSaturateUnsignedLower * ShiftRightArithmeticNarrowingSaturateUnsignedUpper * ShiftRightArithmeticNarrowingSaturateUpper * ShiftRightArithmeticRounded * ShiftRightArithmeticRoundedAdd * ShiftRightArithmeticRoundedAddScalar * ShiftRightArithmeticRoundedNarrowingSaturateLower * ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower * ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper * ShiftRightArithmeticRoundedNarrowingSaturateUpper * ShiftRightArithmeticRoundedScalar * ShiftRightArithmeticScalar * ShiftRightLogical * ShiftRightLogicalAdd * ShiftRightLogicalAddScalar * ShiftRightLogicalNarrowingLower * ShiftRightLogicalNarrowingSaturateLower * ShiftRightLogicalNarrowingSaturateUpper * ShiftRightLogicalNarrowingUpper * ShiftRightLogicalRounded * ShiftRightLogicalRoundedAdd * ShiftRightLogicalRoundedAddScalar * ShiftRightLogicalRoundedNarrowingLower * ShiftRightLogicalRoundedNarrowingSaturateLower * ShiftRightLogicalRoundedNarrowingSaturateUpper * ShiftRightLogicalRoundedNarrowingUpper * ShiftRightLogicalRoundedScalar * ShiftRightLogicalScalar * SignExtendWideningLower * SignExtendWideningUpper * ZeroExtendWideningLower * ZeroExtendWideningUpper * ShiftArithmeticRoundedSaturateScalar * ShiftArithmeticSaturateScalar * ShiftLeftLogicalSaturateScalar * ShiftLeftLogicalSaturateUnsignedScalar * ShiftLogicalRoundedSaturateScalar * ShiftLogicalSaturateScalar * ShiftRightArithmeticNarrowingSaturateScalar * ShiftRightArithmeticNarrowingSaturateUnsignedScalar * ShiftRightArithmeticRoundedNarrowingSaturateScalar * ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar * ShiftRightLogicalNarrowingSaturateScalar * ShiftRightLogicalRoundedNarrowingSaturateScalar --- src/coreclr/src/jit/codegen.h | 5 +- src/coreclr/src/jit/compiler.h | 3 +- src/coreclr/src/jit/hwintrinsic.cpp | 52 +- src/coreclr/src/jit/hwintrinsic.h | 3 +- src/coreclr/src/jit/hwintrinsicarm64.cpp | 83 +- .../src/jit/hwintrinsiccodegenarm64.cpp | 109 +- src/coreclr/src/jit/hwintrinsiclistarm64.h | 618 ++-- src/coreclr/src/jit/lowerarmarch.cpp | 48 + src/coreclr/src/jit/lsraarm64.cpp | 71 +- .../Arm/AdvSimd.Arm64/AdvSimd.Arm64_r.csproj | 51 + .../Arm/AdvSimd.Arm64/AdvSimd.Arm64_ro.csproj | 51 + ...SelectedScalarToVector128.V128.Double.1.cs | 1 + ...eSelectedScalarToVector128.V128.Int64.1.cs | 1 + ...SelectedScalarToVector128.V128.UInt64.1.cs | 1 + .../AdvSimd.Arm64/Program.AdvSimd.Arm64.cs | 51 + ...ticRoundedSaturateScalar.Vector64.Int16.cs | 537 ++++ ...ticRoundedSaturateScalar.Vector64.Int32.cs | 537 ++++ ...ticRoundedSaturateScalar.Vector64.SByte.cs | 537 ++++ ...ArithmeticSaturateScalar.Vector64.Int16.cs | 537 ++++ ...ArithmeticSaturateScalar.Vector64.Int32.cs | 537 ++++ ...ArithmeticSaturateScalar.Vector64.SByte.cs | 537 ++++ ...ftLogicalSaturateScalar.Vector64.Byte.7.cs | 507 +++ ...LogicalSaturateScalar.Vector64.Int16.15.cs | 507 +++ ...LogicalSaturateScalar.Vector64.Int32.31.cs | 507 +++ ...tLogicalSaturateScalar.Vector64.SByte.1.cs | 507 +++ ...LogicalSaturateScalar.Vector64.UInt16.1.cs | 507 +++ ...LogicalSaturateScalar.Vector64.UInt32.1.cs | 507 +++ ...SaturateUnsignedScalar.Vector64.Int16.5.cs | 507 +++ ...SaturateUnsignedScalar.Vector64.Int32.7.cs | 507 +++ ...SaturateUnsignedScalar.Vector64.SByte.3.cs | 507 +++ ...icalRoundedSaturateScalar.Vector64.Byte.cs | 537 ++++ ...calRoundedSaturateScalar.Vector64.Int16.cs | 537 ++++ ...calRoundedSaturateScalar.Vector64.Int32.cs | 537 ++++ ...calRoundedSaturateScalar.Vector64.SByte.cs | 537 ++++ ...alRoundedSaturateScalar.Vector64.UInt16.cs | 537 ++++ ...alRoundedSaturateScalar.Vector64.UInt32.cs | 537 ++++ ...hiftLogicalSaturateScalar.Vector64.Byte.cs | 537 ++++ ...iftLogicalSaturateScalar.Vector64.Int16.cs | 537 ++++ ...iftLogicalSaturateScalar.Vector64.Int32.cs | 537 ++++ ...iftLogicalSaturateScalar.Vector64.SByte.cs | 537 ++++ ...ftLogicalSaturateScalar.Vector64.UInt16.cs | 537 ++++ ...ftLogicalSaturateScalar.Vector64.UInt32.cs | 537 ++++ ...rrowingSaturateScalar.Vector64.Int16.16.cs | 507 +++ ...rrowingSaturateScalar.Vector64.Int32.32.cs | 507 +++ ...arrowingSaturateScalar.Vector64.SByte.8.cs | 507 +++ ...gSaturateUnsignedScalar.Vector64.Byte.3.cs | 507 +++ ...aturateUnsignedScalar.Vector64.UInt16.5.cs | 507 +++ ...aturateUnsignedScalar.Vector64.UInt32.7.cs | 507 +++ ...rrowingSaturateScalar.Vector64.Int16.32.cs | 507 +++ ...rrowingSaturateScalar.Vector64.Int32.64.cs | 507 +++ ...rrowingSaturateScalar.Vector64.SByte.16.cs | 507 +++ ...gSaturateUnsignedScalar.Vector64.Byte.1.cs | 507 +++ ...aturateUnsignedScalar.Vector64.UInt16.1.cs | 507 +++ ...aturateUnsignedScalar.Vector64.UInt32.1.cs | 507 +++ ...NarrowingSaturateScalar.Vector64.Byte.5.cs | 507 +++ ...arrowingSaturateScalar.Vector64.Int16.7.cs | 507 +++ ...rrowingSaturateScalar.Vector64.Int32.11.cs | 507 +++ ...arrowingSaturateScalar.Vector64.SByte.3.cs | 507 +++ ...rrowingSaturateScalar.Vector64.UInt16.5.cs | 507 +++ ...rrowingSaturateScalar.Vector64.UInt32.7.cs | 507 +++ ...NarrowingSaturateScalar.Vector64.Byte.1.cs | 507 +++ ...arrowingSaturateScalar.Vector64.Int16.1.cs | 507 +++ ...arrowingSaturateScalar.Vector64.Int32.1.cs | 507 +++ ...arrowingSaturateScalar.Vector64.SByte.1.cs | 507 +++ ...rrowingSaturateScalar.Vector64.UInt16.1.cs | 507 +++ ...rrowingSaturateScalar.Vector64.UInt32.1.cs | 507 +++ .../Arm/AdvSimd/AdvSimd_r.csproj | 333 ++ .../Arm/AdvSimd/AdvSimd_ro.csproj | 333 ++ ...teSelectedScalarToVector128.V128.Byte.8.cs | 1 + ...eSelectedScalarToVector128.V128.Int16.4.cs | 1 + ...eSelectedScalarToVector128.V128.Int32.2.cs | 1 + ...eSelectedScalarToVector128.V128.SByte.8.cs | 1 + ...SelectedScalarToVector128.V128.Single.2.cs | 1 + ...SelectedScalarToVector128.V128.UInt16.4.cs | 1 + ...SelectedScalarToVector128.V128.UInt32.2.cs | 1 + ...ateSelectedScalarToVector128.V64.Byte.1.cs | 1 + ...teSelectedScalarToVector128.V64.Int16.1.cs | 1 + ...teSelectedScalarToVector128.V64.Int32.1.cs | 1 + ...teSelectedScalarToVector128.V64.SByte.1.cs | 1 + ...eSelectedScalarToVector128.V64.Single.1.cs | 1 + ...eSelectedScalarToVector128.V64.UInt16.1.cs | 1 + ...eSelectedScalarToVector128.V64.UInt32.1.cs | 1 + ...ateSelectedScalarToVector64.V128.Byte.8.cs | 1 + ...teSelectedScalarToVector64.V128.Int16.4.cs | 1 + ...teSelectedScalarToVector64.V128.Int32.2.cs | 1 + ...teSelectedScalarToVector64.V128.SByte.8.cs | 1 + ...eSelectedScalarToVector64.V128.Single.2.cs | 1 + ...eSelectedScalarToVector64.V128.UInt16.4.cs | 1 + ...eSelectedScalarToVector64.V128.UInt32.2.cs | 1 + ...cateSelectedScalarToVector64.V64.Byte.1.cs | 1 + ...ateSelectedScalarToVector64.V64.Int16.1.cs | 1 + ...ateSelectedScalarToVector64.V64.Int32.1.cs | 1 + ...ateSelectedScalarToVector64.V64.SByte.1.cs | 1 + ...teSelectedScalarToVector64.V64.Single.1.cs | 1 + ...teSelectedScalarToVector64.V64.UInt16.1.cs | 1 + ...teSelectedScalarToVector64.V64.UInt32.1.cs | 1 + .../Arm/AdvSimd/Program.AdvSimd.cs | 333 ++ .../ShiftArithmetic.Vector128.Int16.cs | 530 +++ .../ShiftArithmetic.Vector128.Int32.cs | 530 +++ .../ShiftArithmetic.Vector128.Int64.cs | 530 +++ .../ShiftArithmetic.Vector128.SByte.cs | 530 +++ .../AdvSimd/ShiftArithmetic.Vector64.Int16.cs | 530 +++ .../AdvSimd/ShiftArithmetic.Vector64.Int32.cs | 530 +++ .../AdvSimd/ShiftArithmetic.Vector64.SByte.cs | 530 +++ .../ShiftArithmeticRounded.Vector128.Int16.cs | 530 +++ .../ShiftArithmeticRounded.Vector128.Int32.cs | 530 +++ .../ShiftArithmeticRounded.Vector128.Int64.cs | 530 +++ .../ShiftArithmeticRounded.Vector128.SByte.cs | 530 +++ .../ShiftArithmeticRounded.Vector64.Int16.cs | 530 +++ .../ShiftArithmeticRounded.Vector64.Int32.cs | 530 +++ .../ShiftArithmeticRounded.Vector64.SByte.cs | 530 +++ ...ithmeticRoundedSaturate.Vector128.Int16.cs | 530 +++ ...ithmeticRoundedSaturate.Vector128.Int32.cs | 530 +++ ...ithmeticRoundedSaturate.Vector128.Int64.cs | 530 +++ ...ithmeticRoundedSaturate.Vector128.SByte.cs | 530 +++ ...rithmeticRoundedSaturate.Vector64.Int16.cs | 530 +++ ...rithmeticRoundedSaturate.Vector64.Int32.cs | 530 +++ ...rithmeticRoundedSaturate.Vector64.SByte.cs | 530 +++ ...ticRoundedSaturateScalar.Vector64.Int64.cs | 537 ++++ ...tArithmeticRoundedScalar.Vector64.Int64.cs | 537 ++++ ...ShiftArithmeticSaturate.Vector128.Int16.cs | 530 +++ ...ShiftArithmeticSaturate.Vector128.Int32.cs | 530 +++ ...ShiftArithmeticSaturate.Vector128.Int64.cs | 530 +++ ...ShiftArithmeticSaturate.Vector128.SByte.cs | 530 +++ .../ShiftArithmeticSaturate.Vector64.Int16.cs | 530 +++ .../ShiftArithmeticSaturate.Vector64.Int32.cs | 530 +++ .../ShiftArithmeticSaturate.Vector64.SByte.cs | 530 +++ ...ArithmeticSaturateScalar.Vector64.Int64.cs | 537 ++++ .../ShiftArithmeticScalar.Vector64.Int64.cs | 537 ++++ .../ShiftLeftLogical.Vector128.Byte.1.cs | 500 +++ .../ShiftLeftLogical.Vector128.Int16.1.cs | 500 +++ .../ShiftLeftLogical.Vector128.Int64.1.cs | 500 +++ .../ShiftLeftLogical.Vector128.SByte.1.cs | 500 +++ .../ShiftLeftLogical.Vector128.UInt16.1.cs | 500 +++ .../ShiftLeftLogical.Vector128.UInt32.1.cs | 500 +++ .../ShiftLeftLogical.Vector128.UInt64.1.cs | 500 +++ .../ShiftLeftLogical.Vector64.Byte.1.cs | 500 +++ .../ShiftLeftLogical.Vector64.Int16.1.cs | 500 +++ .../ShiftLeftLogical.Vector64.Int32.1.cs | 500 +++ .../ShiftLeftLogical.Vector64.SByte.1.cs | 500 +++ .../ShiftLeftLogical.Vector64.UInt16.1.cs | 500 +++ .../ShiftLeftLogical.Vector64.UInt32.1.cs | 500 +++ ...iftLeftLogicalSaturate.Vector128.Byte.1.cs | 500 +++ ...ftLeftLogicalSaturate.Vector128.Int16.1.cs | 500 +++ ...ftLeftLogicalSaturate.Vector128.Int32.1.cs | 500 +++ ...ftLeftLogicalSaturate.Vector128.Int64.1.cs | 500 +++ ...ftLeftLogicalSaturate.Vector128.SByte.1.cs | 500 +++ ...tLeftLogicalSaturate.Vector128.UInt16.1.cs | 500 +++ ...tLeftLogicalSaturate.Vector128.UInt32.1.cs | 500 +++ ...tLeftLogicalSaturate.Vector128.UInt64.1.cs | 500 +++ ...hiftLeftLogicalSaturate.Vector64.Byte.1.cs | 500 +++ ...iftLeftLogicalSaturate.Vector64.Int16.1.cs | 500 +++ ...iftLeftLogicalSaturate.Vector64.Int32.1.cs | 500 +++ ...iftLeftLogicalSaturate.Vector64.SByte.1.cs | 500 +++ ...ftLeftLogicalSaturate.Vector64.UInt16.1.cs | 500 +++ ...ftLeftLogicalSaturate.Vector64.UInt32.1.cs | 500 +++ ...tLogicalSaturateScalar.Vector64.Int64.1.cs | 507 +++ ...LogicalSaturateScalar.Vector64.UInt64.1.cs | 507 +++ ...gicalSaturateUnsigned.Vector128.Int16.1.cs | 500 +++ ...gicalSaturateUnsigned.Vector128.Int32.1.cs | 500 +++ ...gicalSaturateUnsigned.Vector128.Int64.1.cs | 500 +++ ...gicalSaturateUnsigned.Vector128.SByte.1.cs | 500 +++ ...ogicalSaturateUnsigned.Vector64.Int16.1.cs | 500 +++ ...ogicalSaturateUnsigned.Vector64.Int32.1.cs | 500 +++ ...ogicalSaturateUnsigned.Vector64.SByte.1.cs | 500 +++ ...SaturateUnsignedScalar.Vector64.Int64.1.cs | 507 +++ ...ShiftLeftLogicalScalar.Vector64.Int64.1.cs | 507 +++ ...hiftLeftLogicalScalar.Vector64.UInt64.1.cs | 507 +++ ...eftLogicalWideningLower.Vector64.Byte.1.cs | 500 +++ ...ftLogicalWideningLower.Vector64.Int16.1.cs | 500 +++ ...ftLogicalWideningLower.Vector64.Int32.1.cs | 500 +++ ...ftLogicalWideningLower.Vector64.SByte.1.cs | 500 +++ ...tLogicalWideningLower.Vector64.UInt16.1.cs | 500 +++ ...tLogicalWideningLower.Vector64.UInt32.1.cs | 500 +++ ...ftLogicalWideningUpper.Vector128.Byte.1.cs | 500 +++ ...tLogicalWideningUpper.Vector128.Int16.1.cs | 500 +++ ...tLogicalWideningUpper.Vector128.Int32.1.cs | 500 +++ ...tLogicalWideningUpper.Vector128.SByte.1.cs | 500 +++ ...LogicalWideningUpper.Vector128.UInt16.1.cs | 500 +++ ...LogicalWideningUpper.Vector128.UInt32.1.cs | 500 +++ .../AdvSimd/ShiftLogical.Vector128.Byte.cs | 530 +++ .../AdvSimd/ShiftLogical.Vector128.Int16.cs | 530 +++ .../AdvSimd/ShiftLogical.Vector128.Int32.cs | 530 +++ .../AdvSimd/ShiftLogical.Vector128.Int64.cs | 530 +++ .../AdvSimd/ShiftLogical.Vector128.SByte.cs | 530 +++ .../AdvSimd/ShiftLogical.Vector128.UInt16.cs | 530 +++ .../AdvSimd/ShiftLogical.Vector128.UInt32.cs | 530 +++ .../AdvSimd/ShiftLogical.Vector128.UInt64.cs | 530 +++ .../Arm/AdvSimd/ShiftLogical.Vector64.Byte.cs | 530 +++ .../AdvSimd/ShiftLogical.Vector64.Int16.cs | 530 +++ .../AdvSimd/ShiftLogical.Vector64.Int32.cs | 530 +++ .../AdvSimd/ShiftLogical.Vector64.SByte.cs | 530 +++ .../AdvSimd/ShiftLogical.Vector64.UInt16.cs | 530 +++ .../AdvSimd/ShiftLogical.Vector64.UInt32.cs | 530 +++ .../ShiftLogicalRounded.Vector128.Byte.cs | 530 +++ .../ShiftLogicalRounded.Vector128.Int16.cs | 530 +++ .../ShiftLogicalRounded.Vector128.Int32.cs | 530 +++ .../ShiftLogicalRounded.Vector128.Int64.cs | 530 +++ .../ShiftLogicalRounded.Vector128.SByte.cs | 530 +++ .../ShiftLogicalRounded.Vector128.UInt16.cs | 530 +++ .../ShiftLogicalRounded.Vector128.UInt32.cs | 530 +++ .../ShiftLogicalRounded.Vector128.UInt64.cs | 530 +++ .../ShiftLogicalRounded.Vector64.Byte.cs | 530 +++ .../ShiftLogicalRounded.Vector64.Int16.cs | 530 +++ .../ShiftLogicalRounded.Vector64.Int32.cs | 530 +++ .../ShiftLogicalRounded.Vector64.SByte.cs | 530 +++ .../ShiftLogicalRounded.Vector64.UInt16.cs | 530 +++ .../ShiftLogicalRounded.Vector64.UInt32.cs | 530 +++ ...ftLogicalRoundedSaturate.Vector128.Byte.cs | 530 +++ ...tLogicalRoundedSaturate.Vector128.Int16.cs | 530 +++ ...tLogicalRoundedSaturate.Vector128.Int32.cs | 530 +++ ...tLogicalRoundedSaturate.Vector128.Int64.cs | 530 +++ ...tLogicalRoundedSaturate.Vector128.SByte.cs | 530 +++ ...LogicalRoundedSaturate.Vector128.UInt16.cs | 530 +++ ...LogicalRoundedSaturate.Vector128.UInt32.cs | 530 +++ ...LogicalRoundedSaturate.Vector128.UInt64.cs | 530 +++ ...iftLogicalRoundedSaturate.Vector64.Byte.cs | 530 +++ ...ftLogicalRoundedSaturate.Vector64.Int16.cs | 530 +++ ...ftLogicalRoundedSaturate.Vector64.Int32.cs | 530 +++ ...ftLogicalRoundedSaturate.Vector64.SByte.cs | 530 +++ ...tLogicalRoundedSaturate.Vector64.UInt16.cs | 530 +++ ...tLogicalRoundedSaturate.Vector64.UInt32.cs | 530 +++ ...calRoundedSaturateScalar.Vector64.Int64.cs | 537 ++++ ...alRoundedSaturateScalar.Vector64.UInt64.cs | 537 ++++ ...hiftLogicalRoundedScalar.Vector64.Int64.cs | 537 ++++ ...iftLogicalRoundedScalar.Vector64.UInt64.cs | 537 ++++ .../ShiftLogicalSaturate.Vector128.Byte.cs | 530 +++ .../ShiftLogicalSaturate.Vector128.Int16.cs | 530 +++ .../ShiftLogicalSaturate.Vector128.Int32.cs | 530 +++ .../ShiftLogicalSaturate.Vector128.Int64.cs | 530 +++ .../ShiftLogicalSaturate.Vector128.SByte.cs | 530 +++ .../ShiftLogicalSaturate.Vector128.UInt16.cs | 530 +++ .../ShiftLogicalSaturate.Vector128.UInt32.cs | 530 +++ .../ShiftLogicalSaturate.Vector128.UInt64.cs | 530 +++ .../ShiftLogicalSaturate.Vector64.Byte.cs | 530 +++ .../ShiftLogicalSaturate.Vector64.Int16.cs | 530 +++ .../ShiftLogicalSaturate.Vector64.Int32.cs | 530 +++ .../ShiftLogicalSaturate.Vector64.SByte.cs | 530 +++ .../ShiftLogicalSaturate.Vector64.UInt16.cs | 530 +++ .../ShiftLogicalSaturate.Vector64.UInt32.cs | 530 +++ ...iftLogicalSaturateScalar.Vector64.Int64.cs | 537 ++++ ...ftLogicalSaturateScalar.Vector64.UInt64.cs | 537 ++++ .../ShiftLogicalScalar.Vector64.Int64.cs | 537 ++++ .../ShiftLogicalScalar.Vector64.UInt64.cs | 537 ++++ .../ShiftRightArithmetic.Vector128.Int16.1.cs | 500 +++ .../ShiftRightArithmetic.Vector128.Int32.1.cs | 500 +++ .../ShiftRightArithmetic.Vector128.Int64.1.cs | 500 +++ .../ShiftRightArithmetic.Vector128.SByte.1.cs | 500 +++ .../ShiftRightArithmetic.Vector64.Int16.1.cs | 500 +++ .../ShiftRightArithmetic.Vector64.Int32.1.cs | 500 +++ .../ShiftRightArithmetic.Vector64.SByte.1.cs | 500 +++ ...iftRightArithmeticAdd.Vector128.Int16.1.cs | 416 +++ ...iftRightArithmeticAdd.Vector128.Int32.1.cs | 416 +++ ...iftRightArithmeticAdd.Vector128.Int64.1.cs | 416 +++ ...iftRightArithmeticAdd.Vector128.SByte.1.cs | 416 +++ ...hiftRightArithmeticAdd.Vector64.Int16.1.cs | 416 +++ ...hiftRightArithmeticAdd.Vector64.Int32.1.cs | 416 +++ ...hiftRightArithmeticAdd.Vector64.SByte.1.cs | 416 +++ ...ghtArithmeticAddScalar.Vector64.Int64.1.cs | 423 +++ ...NarrowingSaturateLower.Vector64.Int16.1.cs | 500 +++ ...NarrowingSaturateLower.Vector64.Int32.1.cs | 500 +++ ...NarrowingSaturateLower.Vector64.SByte.1.cs | 500 +++ ...ngSaturateUnsignedLower.Vector64.Byte.1.cs | 500 +++ ...SaturateUnsignedLower.Vector64.UInt16.1.cs | 500 +++ ...SaturateUnsignedLower.Vector64.UInt32.1.cs | 500 +++ ...gSaturateUnsignedUpper.Vector128.Byte.1.cs | 416 +++ ...aturateUnsignedUpper.Vector128.UInt16.1.cs | 416 +++ ...aturateUnsignedUpper.Vector128.UInt32.1.cs | 416 +++ ...arrowingSaturateUpper.Vector128.Int16.1.cs | 416 +++ ...arrowingSaturateUpper.Vector128.Int32.1.cs | 416 +++ ...arrowingSaturateUpper.Vector128.SByte.1.cs | 416 +++ ...ightArithmeticRounded.Vector128.Int16.1.cs | 500 +++ ...ightArithmeticRounded.Vector128.Int32.1.cs | 500 +++ ...ightArithmeticRounded.Vector128.Int64.1.cs | 500 +++ ...ightArithmeticRounded.Vector128.SByte.1.cs | 500 +++ ...RightArithmeticRounded.Vector64.Int16.1.cs | 500 +++ ...RightArithmeticRounded.Vector64.Int32.1.cs | 500 +++ ...RightArithmeticRounded.Vector64.SByte.1.cs | 500 +++ ...tArithmeticRoundedAdd.Vector128.Int16.1.cs | 416 +++ ...tArithmeticRoundedAdd.Vector128.Int32.1.cs | 416 +++ ...tArithmeticRoundedAdd.Vector128.Int64.1.cs | 416 +++ ...tArithmeticRoundedAdd.Vector128.SByte.1.cs | 416 +++ ...htArithmeticRoundedAdd.Vector64.Int16.1.cs | 416 +++ ...htArithmeticRoundedAdd.Vector64.Int32.1.cs | 416 +++ ...htArithmeticRoundedAdd.Vector64.SByte.1.cs | 416 +++ ...hmeticRoundedAddScalar.Vector64.Int64.1.cs | 423 +++ ...NarrowingSaturateLower.Vector64.Int16.1.cs | 500 +++ ...NarrowingSaturateLower.Vector64.Int32.1.cs | 500 +++ ...NarrowingSaturateLower.Vector64.SByte.1.cs | 500 +++ ...ngSaturateUnsignedLower.Vector64.Byte.1.cs | 500 +++ ...SaturateUnsignedLower.Vector64.UInt16.1.cs | 500 +++ ...SaturateUnsignedLower.Vector64.UInt32.1.cs | 500 +++ ...gSaturateUnsignedUpper.Vector128.Byte.1.cs | 416 +++ ...aturateUnsignedUpper.Vector128.UInt16.1.cs | 416 +++ ...aturateUnsignedUpper.Vector128.UInt32.1.cs | 416 +++ ...arrowingSaturateUpper.Vector128.Int16.1.cs | 416 +++ ...arrowingSaturateUpper.Vector128.Int32.1.cs | 416 +++ ...arrowingSaturateUpper.Vector128.SByte.1.cs | 416 +++ ...rithmeticRoundedScalar.Vector64.Int64.1.cs | 507 +++ ...tRightArithmeticScalar.Vector64.Int64.1.cs | 507 +++ .../ShiftRightLogical.Vector128.Byte.1.cs | 500 +++ .../ShiftRightLogical.Vector128.Int16.1.cs | 500 +++ .../ShiftRightLogical.Vector128.Int32.1.cs | 500 +++ .../ShiftRightLogical.Vector128.Int64.1.cs | 500 +++ .../ShiftRightLogical.Vector128.SByte.1.cs | 500 +++ .../ShiftRightLogical.Vector128.UInt16.1.cs | 500 +++ .../ShiftRightLogical.Vector128.UInt32.1.cs | 500 +++ .../ShiftRightLogical.Vector128.UInt64.1.cs | 500 +++ .../ShiftRightLogical.Vector64.Byte.1.cs | 500 +++ .../ShiftRightLogical.Vector64.Int16.1.cs | 500 +++ .../ShiftRightLogical.Vector64.Int32.1.cs | 500 +++ .../ShiftRightLogical.Vector64.SByte.1.cs | 500 +++ .../ShiftRightLogical.Vector64.UInt16.1.cs | 500 +++ .../ShiftRightLogical.Vector64.UInt32.1.cs | 500 +++ .../ShiftRightLogicalAdd.Vector128.Byte.1.cs | 416 +++ .../ShiftRightLogicalAdd.Vector128.Int16.1.cs | 416 +++ .../ShiftRightLogicalAdd.Vector128.Int32.1.cs | 416 +++ .../ShiftRightLogicalAdd.Vector128.Int64.1.cs | 416 +++ .../ShiftRightLogicalAdd.Vector128.SByte.1.cs | 416 +++ ...ShiftRightLogicalAdd.Vector128.UInt16.1.cs | 416 +++ ...ShiftRightLogicalAdd.Vector128.UInt32.1.cs | 416 +++ ...ShiftRightLogicalAdd.Vector128.UInt64.1.cs | 416 +++ .../ShiftRightLogicalAdd.Vector64.Byte.1.cs | 416 +++ .../ShiftRightLogicalAdd.Vector64.Int16.1.cs | 416 +++ .../ShiftRightLogicalAdd.Vector64.Int32.1.cs | 416 +++ .../ShiftRightLogicalAdd.Vector64.SByte.1.cs | 416 +++ .../ShiftRightLogicalAdd.Vector64.UInt16.1.cs | 416 +++ .../ShiftRightLogicalAdd.Vector64.UInt32.1.cs | 416 +++ ...tRightLogicalAddScalar.Vector64.Int64.1.cs | 423 +++ ...RightLogicalAddScalar.Vector64.UInt64.1.cs | 423 +++ ...htLogicalNarrowingLower.Vector64.Byte.1.cs | 500 +++ ...tLogicalNarrowingLower.Vector64.Int16.1.cs | 500 +++ ...tLogicalNarrowingLower.Vector64.Int32.1.cs | 500 +++ ...tLogicalNarrowingLower.Vector64.SByte.1.cs | 500 +++ ...LogicalNarrowingLower.Vector64.UInt16.1.cs | 500 +++ ...LogicalNarrowingLower.Vector64.UInt32.1.cs | 500 +++ ...lNarrowingSaturateLower.Vector64.Byte.1.cs | 500 +++ ...NarrowingSaturateLower.Vector64.Int16.1.cs | 500 +++ ...NarrowingSaturateLower.Vector64.Int32.1.cs | 500 +++ ...NarrowingSaturateLower.Vector64.SByte.1.cs | 500 +++ ...arrowingSaturateLower.Vector64.UInt16.1.cs | 500 +++ ...arrowingSaturateLower.Vector64.UInt32.1.cs | 500 +++ ...NarrowingSaturateUpper.Vector128.Byte.1.cs | 416 +++ ...arrowingSaturateUpper.Vector128.Int16.1.cs | 416 +++ ...arrowingSaturateUpper.Vector128.Int32.1.cs | 416 +++ ...arrowingSaturateUpper.Vector128.SByte.1.cs | 416 +++ ...rrowingSaturateUpper.Vector128.UInt16.1.cs | 416 +++ ...rrowingSaturateUpper.Vector128.UInt32.1.cs | 416 +++ ...tLogicalNarrowingUpper.Vector128.Byte.1.cs | 416 +++ ...LogicalNarrowingUpper.Vector128.Int16.1.cs | 416 +++ ...LogicalNarrowingUpper.Vector128.Int32.1.cs | 416 +++ ...LogicalNarrowingUpper.Vector128.SByte.1.cs | 416 +++ ...ogicalNarrowingUpper.Vector128.UInt16.1.cs | 416 +++ ...ogicalNarrowingUpper.Vector128.UInt32.1.cs | 416 +++ ...iftRightLogicalRounded.Vector128.Byte.1.cs | 500 +++ ...ftRightLogicalRounded.Vector128.Int16.1.cs | 500 +++ ...ftRightLogicalRounded.Vector128.Int32.1.cs | 500 +++ ...ftRightLogicalRounded.Vector128.Int64.1.cs | 500 +++ ...ftRightLogicalRounded.Vector128.SByte.1.cs | 500 +++ ...tRightLogicalRounded.Vector128.UInt16.1.cs | 500 +++ ...tRightLogicalRounded.Vector128.UInt32.1.cs | 500 +++ ...tRightLogicalRounded.Vector128.UInt64.1.cs | 500 +++ ...hiftRightLogicalRounded.Vector64.Byte.1.cs | 500 +++ ...iftRightLogicalRounded.Vector64.Int16.1.cs | 500 +++ ...iftRightLogicalRounded.Vector64.Int32.1.cs | 500 +++ ...iftRightLogicalRounded.Vector64.SByte.1.cs | 500 +++ ...ftRightLogicalRounded.Vector64.UInt16.1.cs | 500 +++ ...ftRightLogicalRounded.Vector64.UInt32.1.cs | 500 +++ ...RightLogicalRoundedAdd.Vector128.Byte.1.cs | 416 +++ ...ightLogicalRoundedAdd.Vector128.Int16.1.cs | 416 +++ ...ightLogicalRoundedAdd.Vector128.Int32.1.cs | 416 +++ ...ightLogicalRoundedAdd.Vector128.Int64.1.cs | 416 +++ ...ightLogicalRoundedAdd.Vector128.SByte.1.cs | 416 +++ ...ghtLogicalRoundedAdd.Vector128.UInt16.1.cs | 416 +++ ...ghtLogicalRoundedAdd.Vector128.UInt32.1.cs | 416 +++ ...ghtLogicalRoundedAdd.Vector128.UInt64.1.cs | 416 +++ ...tRightLogicalRoundedAdd.Vector64.Byte.1.cs | 416 +++ ...RightLogicalRoundedAdd.Vector64.Int16.1.cs | 416 +++ ...RightLogicalRoundedAdd.Vector64.Int32.1.cs | 416 +++ ...RightLogicalRoundedAdd.Vector64.SByte.1.cs | 416 +++ ...ightLogicalRoundedAdd.Vector64.UInt16.1.cs | 416 +++ ...ightLogicalRoundedAdd.Vector64.UInt32.1.cs | 416 +++ ...ogicalRoundedAddScalar.Vector64.Int64.1.cs | 423 +++ ...gicalRoundedAddScalar.Vector64.UInt64.1.cs | 423 +++ ...alRoundedNarrowingLower.Vector64.Byte.1.cs | 500 +++ ...lRoundedNarrowingLower.Vector64.Int16.1.cs | 500 +++ ...lRoundedNarrowingLower.Vector64.Int32.1.cs | 500 +++ ...lRoundedNarrowingLower.Vector64.SByte.1.cs | 500 +++ ...RoundedNarrowingLower.Vector64.UInt16.1.cs | 500 +++ ...RoundedNarrowingLower.Vector64.UInt32.1.cs | 500 +++ ...dNarrowingSaturateLower.Vector64.Byte.1.cs | 500 +++ ...NarrowingSaturateLower.Vector64.Int16.1.cs | 500 +++ ...NarrowingSaturateLower.Vector64.Int32.1.cs | 500 +++ ...NarrowingSaturateLower.Vector64.SByte.1.cs | 500 +++ ...arrowingSaturateLower.Vector64.UInt16.1.cs | 500 +++ ...arrowingSaturateLower.Vector64.UInt32.1.cs | 500 +++ ...NarrowingSaturateUpper.Vector128.Byte.1.cs | 416 +++ ...arrowingSaturateUpper.Vector128.Int16.1.cs | 416 +++ ...arrowingSaturateUpper.Vector128.Int32.1.cs | 416 +++ ...arrowingSaturateUpper.Vector128.SByte.1.cs | 416 +++ ...rrowingSaturateUpper.Vector128.UInt16.1.cs | 416 +++ ...rrowingSaturateUpper.Vector128.UInt32.1.cs | 416 +++ ...lRoundedNarrowingUpper.Vector128.Byte.1.cs | 416 +++ ...RoundedNarrowingUpper.Vector128.Int16.1.cs | 416 +++ ...RoundedNarrowingUpper.Vector128.Int32.1.cs | 416 +++ ...RoundedNarrowingUpper.Vector128.SByte.1.cs | 416 +++ ...oundedNarrowingUpper.Vector128.UInt16.1.cs | 416 +++ ...oundedNarrowingUpper.Vector128.UInt32.1.cs | 416 +++ ...htLogicalRoundedScalar.Vector64.Int64.1.cs | 507 +++ ...tLogicalRoundedScalar.Vector64.UInt64.1.cs | 507 +++ ...hiftRightLogicalScalar.Vector64.Int64.1.cs | 507 +++ ...iftRightLogicalScalar.Vector64.UInt64.1.cs | 507 +++ .../SignExtendWideningLower.Vector64.Int16.cs | 489 +++ .../SignExtendWideningLower.Vector64.Int32.cs | 489 +++ .../SignExtendWideningLower.Vector64.SByte.cs | 489 +++ ...SignExtendWideningUpper.Vector128.Int16.cs | 489 +++ ...SignExtendWideningUpper.Vector128.Int32.cs | 489 +++ ...SignExtendWideningUpper.Vector128.SByte.cs | 489 +++ .../ZeroExtendWideningLower.Vector64.Byte.cs | 489 +++ .../ZeroExtendWideningLower.Vector64.Int16.cs | 489 +++ .../ZeroExtendWideningLower.Vector64.Int32.cs | 489 +++ .../ZeroExtendWideningLower.Vector64.SByte.cs | 489 +++ ...ZeroExtendWideningLower.Vector64.UInt16.cs | 489 +++ ...ZeroExtendWideningLower.Vector64.UInt32.cs | 489 +++ .../ZeroExtendWideningUpper.Vector128.Byte.cs | 489 +++ ...ZeroExtendWideningUpper.Vector128.Int16.cs | 489 +++ ...ZeroExtendWideningUpper.Vector128.Int32.cs | 489 +++ ...ZeroExtendWideningUpper.Vector128.SByte.cs | 489 +++ ...eroExtendWideningUpper.Vector128.UInt16.cs | 489 +++ ...eroExtendWideningUpper.Vector128.UInt32.cs | 489 +++ .../Arm/Shared/GenerateTests.csx | 2845 ++++++++++------- .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 1671 +++++++++- .../HardwareIntrinsics/Arm/Shared/Helpers.tt | 458 ++- .../Shared/_ImmBinaryOpTestTemplate.template | 409 +++ .../Shared/_ImmUnaryOpTestTemplate.template | 1 + .../Arm/AdvSimd.PlatformNotSupported.cs | 2843 +++++++++++++++- .../System/Runtime/Intrinsics/Arm/AdvSimd.cs | 2843 +++++++++++++++- .../System.Runtime.Intrinsics.Experimental.cs | 384 +++ 438 files changed, 200480 insertions(+), 1875 deletions(-) create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticRoundedSaturateScalar.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticRoundedSaturateScalar.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticRoundedSaturateScalar.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticSaturateScalar.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticSaturateScalar.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticSaturateScalar.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.Byte.7.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.Int16.15.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.Int32.31.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int16.5.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int32.7.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.SByte.3.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int16.16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int32.32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateScalar.Vector64.SByte.8.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.Byte.3.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt16.5.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt32.7.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int16.32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int32.64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.SByte.16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.Byte.5.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int16.7.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int32.11.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.SByte.3.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt16.5.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt32.7.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturateScalar.Vector64.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedScalar.Vector64.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturateScalar.Vector64.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticScalar.Vector64.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.UInt64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.UInt64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateScalar.Vector64.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateScalar.Vector64.UInt64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalScalar.Vector64.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalScalar.Vector64.UInt64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.UInt64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.UInt64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.UInt64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturateScalar.Vector64.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturateScalar.Vector64.UInt64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedScalar.Vector64.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedScalar.Vector64.UInt64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.UInt64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturateScalar.Vector64.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturateScalar.Vector64.UInt64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalScalar.Vector64.Int64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalScalar.Vector64.UInt64.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAddScalar.Vector64.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateLower.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUpper.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAddScalar.Vector64.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedScalar.Vector64.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticScalar.Vector64.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.UInt64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.UInt64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAddScalar.Vector64.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAddScalar.Vector64.UInt64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.UInt64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.UInt64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAddScalar.Vector64.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAddScalar.Vector64.UInt64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.Byte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.SByte.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt16.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt32.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedScalar.Vector64.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedScalar.Vector64.UInt64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalScalar.Vector64.Int64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalScalar.Vector64.UInt64.1.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningLower.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningLower.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningLower.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningUpper.Vector128.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningUpper.Vector128.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningUpper.Vector128.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.Byte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.Int16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.Int32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.SByte.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.UInt16.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.UInt32.cs create mode 100644 src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmBinaryOpTestTemplate.template diff --git a/src/coreclr/src/jit/codegen.h b/src/coreclr/src/jit/codegen.h index e48e51049a09f..d6b53ef475d7a 100644 --- a/src/coreclr/src/jit/codegen.h +++ b/src/coreclr/src/jit/codegen.h @@ -1060,7 +1060,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // Returns true after the last call to EmitCaseEnd() (i.e. this signals that code generation is done). bool Done() const { - return immValue == immUpperBound; + return (immValue > immUpperBound); } // Returns a value of the immediate operand that should be used for a case. @@ -1081,7 +1081,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX bool TestImmOpZeroOrOne() const { assert(NonConstImmOp()); - return immUpperBound == 2; + return (immLowerBound == 0) && (immUpperBound == 1); } emitter* GetEmitter() const @@ -1093,6 +1093,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX BasicBlock* endLabel; BasicBlock* nonZeroLabel; int immValue; + int immLowerBound; int immUpperBound; regNumber nonConstImmReg; regNumber branchTargetReg; diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index 1fd8d8d547568..e1521d63b2cd2 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -3771,7 +3771,8 @@ class Compiler GenTree* getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass, bool expectAddr = false); GenTree* impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, var_types baseType); - GenTree* addRangeCheckIfNeeded(NamedIntrinsic intrinsic, GenTree* lastOp, bool mustExpand, int immUpperBound); + GenTree* addRangeCheckIfNeeded( + NamedIntrinsic intrinsic, GenTree* lastOp, bool mustExpand, int immLowerBound, int immUpperBound); #ifdef TARGET_XARCH GenTree* impBaseIntrinsic(NamedIntrinsic intrinsic, diff --git a/src/coreclr/src/jit/hwintrinsic.cpp b/src/coreclr/src/jit/hwintrinsic.cpp index 1089470adc45e..16332b859894b 100644 --- a/src/coreclr/src/jit/hwintrinsic.cpp +++ b/src/coreclr/src/jit/hwintrinsic.cpp @@ -511,13 +511,15 @@ GenTree* Compiler::getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE // intrinsic -- intrinsic ID // immOp -- the immediate operand of the intrinsic // mustExpand -- true if the compiler is compiling the fallback(GT_CALL) of this intrinsics -// immUpperBound -- upper bound for a value of the immediate operand (for a non-full-range imm-intrinsic) +// immLowerBound -- lower incl. bound for a value of the immediate operand (for a non-full-range imm-intrinsic) +// immUpperBound -- upper incl. bound for a value of the immediate operand (for a non-full-range imm-intrinsic) // // Return Value: // add a GT_HW_INTRINSIC_CHK node for non-full-range imm-intrinsic, which would throw ArgumentOutOfRangeException // when the imm-argument is not in the valid range // -GenTree* Compiler::addRangeCheckIfNeeded(NamedIntrinsic intrinsic, GenTree* immOp, bool mustExpand, int immUpperBound) +GenTree* Compiler::addRangeCheckIfNeeded( + NamedIntrinsic intrinsic, GenTree* immOp, bool mustExpand, int immLowerBound, int immUpperBound) { assert(immOp != nullptr); // Full-range imm-intrinsics do not need the range-check @@ -531,19 +533,37 @@ GenTree* Compiler::addRangeCheckIfNeeded(NamedIntrinsic intrinsic, GenTree* immO ) { assert(!immOp->IsCnsIntOrI()); - GenTree* upperBoundNode = gtNewIconNode(immUpperBound, TYP_INT); - GenTree* index = nullptr; - if ((immOp->gtFlags & GTF_SIDE_EFFECT) != 0) - { - index = fgInsertCommaFormTemp(&immOp); - } - else + assert(varTypeIsUnsigned(immOp)); + + // Bounds check for value of an immediate operand + // (immLowerBound <= immOp) && (immOp <= immUpperBound) + // + // implemented as a single comparison in the form of + // + // if ((immOp - immLowerBound) >= (immUpperBound - immLowerBound + 1)) + // { + // throw new ArgumentOutOfRangeException(); + // } + // + // The value of (immUpperBound - immLowerBound + 1) is denoted as adjustedUpperBound. + + const ssize_t adjustedUpperBound = (ssize_t)immUpperBound - immLowerBound + 1; + GenTree* adjustedUpperBoundNode = gtNewIconNode(adjustedUpperBound, TYP_INT); + + GenTree* immOpDup = nullptr; + + immOp = impCloneExpr(immOp, &immOpDup, NO_CLASS_HANDLE, (unsigned)CHECK_SPILL_ALL, + nullptr DEBUGARG("Clone an immediate operand for immediate value bounds check")); + + if (immLowerBound != 0) { - index = gtCloneExpr(immOp); + immOpDup = gtNewOperNode(GT_SUB, TYP_INT, immOpDup, gtNewIconNode(immLowerBound, TYP_INT)); } + GenTreeBoundsChk* hwIntrinsicChk = new (this, GT_HW_INTRINSIC_CHK) - GenTreeBoundsChk(GT_HW_INTRINSIC_CHK, TYP_VOID, index, upperBoundNode, SCK_RNGCHK_FAIL); + GenTreeBoundsChk(GT_HW_INTRINSIC_CHK, TYP_VOID, immOpDup, adjustedUpperBoundNode, SCK_RNGCHK_FAIL); hwIntrinsicChk->gtThrowKind = SCK_ARG_RNG_EXCPN; + return gtNewOperNode(GT_COMMA, immOp->TypeGet(), hwIntrinsicChk, immOp); } else @@ -776,6 +796,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, var_types argType = TYP_UNKNOWN; CORINFO_CLASS_HANDLE argClass; + int immLowerBound = 0; int immUpperBound = 0; if (immOp != nullptr) @@ -783,11 +804,12 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, #if defined(TARGET_XARCH) immUpperBound = HWIntrinsicInfo::lookupImmUpperBound(intrinsic); #elif defined(TARGET_ARM64) - immUpperBound = HWIntrinsicInfo::lookupImmUpperBound(intrinsic, simdSize, baseType); + HWIntrinsicInfo::lookupImmBounds(intrinsic, simdSize, baseType, &immLowerBound, &immUpperBound); #endif } assert(numArgs >= 0); + if (!isScalar && ((HWIntrinsicInfo::lookupIns(intrinsic, baseType) == INS_invalid) || ((simdSize != 8) && (simdSize != 16) && (simdSize != 32)))) { @@ -835,7 +857,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass))); op2 = getArgForHWIntrinsic(argType, argClass); - op2 = addRangeCheckIfNeeded(intrinsic, op2, mustExpand, immUpperBound); + op2 = addRangeCheckIfNeeded(intrinsic, op2, mustExpand, immLowerBound, immUpperBound); argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, argList, &argClass))); op1 = getArgForHWIntrinsic(argType, argClass); @@ -886,12 +908,12 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, #ifdef TARGET_ARM64 if (intrinsic == NI_AdvSimd_Insert) { - op2 = addRangeCheckIfNeeded(intrinsic, op2, mustExpand, immUpperBound); + op2 = addRangeCheckIfNeeded(intrinsic, op2, mustExpand, immLowerBound, immUpperBound); } else #endif { - op3 = addRangeCheckIfNeeded(intrinsic, op3, mustExpand, immUpperBound); + op3 = addRangeCheckIfNeeded(intrinsic, op3, mustExpand, immLowerBound, immUpperBound); } retNode = isScalar ? gtNewScalarHWIntrinsicNode(retType, op1, op2, op3, intrinsic) diff --git a/src/coreclr/src/jit/hwintrinsic.h b/src/coreclr/src/jit/hwintrinsic.h index 7e5fe7905d454..34a92d858e43d 100644 --- a/src/coreclr/src/jit/hwintrinsic.h +++ b/src/coreclr/src/jit/hwintrinsic.h @@ -272,7 +272,8 @@ struct HWIntrinsicInfo #if defined(TARGET_XARCH) static int lookupImmUpperBound(NamedIntrinsic intrinsic); #elif defined(TARGET_ARM64) - static int lookupImmUpperBound(NamedIntrinsic intrinsic, int simdSize, var_types baseType); + static void lookupImmBounds( + NamedIntrinsic intrinsic, int simdSize, var_types baseType, int* lowerBound, int* upperBound); #else #error Unsupported platform #endif diff --git a/src/coreclr/src/jit/hwintrinsicarm64.cpp b/src/coreclr/src/jit/hwintrinsicarm64.cpp index a7d5c213f824f..dc7bbcab49f04 100644 --- a/src/coreclr/src/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/src/jit/hwintrinsicarm64.cpp @@ -177,19 +177,24 @@ bool HWIntrinsicInfo::isScalarIsa(CORINFO_InstructionSet isa) } //------------------------------------------------------------------------ -// lookupImmUpperBound: Gets the upper bound for the imm-value of a given NamedIntrinsic +// lookupImmBounds: Gets the lower and upper bounds for the imm-value of a given NamedIntrinsic // // Arguments: // intrinsic -- NamedIntrinsic associated with the HWIntrinsic to lookup // simdType -- vector size // baseType -- base type of the Vector64/128 +// pImmLowerBound [OUT] - The lower incl. bound for a value of the intrinsic immediate operand +// pImmUpperBound [OUT] - The upper incl. bound for a value of the intrinsic immediate operand // -// Return Value: -// The upper bound for a value of the intrinsic immediate operand -int HWIntrinsicInfo::lookupImmUpperBound(NamedIntrinsic intrinsic, int simdSize, var_types baseType) +void HWIntrinsicInfo::lookupImmBounds( + NamedIntrinsic intrinsic, int simdSize, var_types baseType, int* pImmLowerBound, int* pImmUpperBound) { assert(HWIntrinsicInfo::lookupCategory(intrinsic) == HW_Category_IMM); + assert(pImmLowerBound != nullptr); + assert(pImmUpperBound != nullptr); + + int immLowerBound = 0; int immUpperBound = 0; if (HWIntrinsicInfo::HasFullRangeImm(intrinsic)) @@ -209,15 +214,74 @@ int HWIntrinsicInfo::lookupImmUpperBound(NamedIntrinsic intrinsic, int simdSize, case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128: case NI_Vector64_GetElement: case NI_Vector128_GetElement: - immUpperBound = Compiler::getSIMDVectorLength(simdSize, baseType); + immUpperBound = Compiler::getSIMDVectorLength(simdSize, baseType) - 1; break; + case NI_AdvSimd_ShiftLeftLogical: + case NI_AdvSimd_ShiftLeftLogicalSaturate: + case NI_AdvSimd_ShiftLeftLogicalSaturateScalar: + case NI_AdvSimd_ShiftLeftLogicalSaturateUnsigned: + case NI_AdvSimd_ShiftLeftLogicalSaturateUnsignedScalar: + case NI_AdvSimd_ShiftLeftLogicalScalar: + case NI_AdvSimd_ShiftLeftLogicalWideningLower: + case NI_AdvSimd_ShiftLeftLogicalWideningUpper: + case NI_AdvSimd_Arm64_ShiftLeftLogicalSaturateScalar: + case NI_AdvSimd_Arm64_ShiftLeftLogicalSaturateUnsignedScalar: + // The left shift amount is in the range 0 to the element width in bits minus 1. + immUpperBound = BITS_PER_BYTE * genTypeSize(baseType) - 1; + break; + + case NI_AdvSimd_ShiftRightArithmetic: + case NI_AdvSimd_ShiftRightArithmeticAdd: + case NI_AdvSimd_ShiftRightArithmeticAddScalar: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateUnsignedLower: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateUnsignedUpper: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightArithmeticRounded: + case NI_AdvSimd_ShiftRightArithmeticRoundedAdd: + case NI_AdvSimd_ShiftRightArithmeticRoundedAddScalar: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightArithmeticRoundedScalar: + case NI_AdvSimd_ShiftRightArithmeticScalar: + case NI_AdvSimd_ShiftRightLogical: + case NI_AdvSimd_ShiftRightLogicalAdd: + case NI_AdvSimd_ShiftRightLogicalAddScalar: + case NI_AdvSimd_ShiftRightLogicalNarrowingLower: + case NI_AdvSimd_ShiftRightLogicalNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightLogicalNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightLogicalNarrowingUpper: + case NI_AdvSimd_ShiftRightLogicalRounded: + case NI_AdvSimd_ShiftRightLogicalRoundedAdd: + case NI_AdvSimd_ShiftRightLogicalRoundedAddScalar: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingLower: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingUpper: + case NI_AdvSimd_ShiftRightLogicalRoundedScalar: + case NI_AdvSimd_ShiftRightLogicalScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticNarrowingSaturateScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticNarrowingSaturateUnsignedScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticRoundedNarrowingSaturateScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar: + case NI_AdvSimd_Arm64_ShiftRightLogicalNarrowingSaturateScalar: + case NI_AdvSimd_Arm64_ShiftRightLogicalRoundedNarrowingSaturateScalar: + // The right shift amount, in the range 1 to the element width in bits. + immLowerBound = 1; + immUpperBound = BITS_PER_BYTE * genTypeSize(baseType); + break; default: unreached(); } } - return immUpperBound; + assert(immLowerBound <= immUpperBound); + + *pImmLowerBound = immLowerBound; + *pImmUpperBound = immUpperBound; } //------------------------------------------------------------------------ @@ -236,7 +300,12 @@ bool HWIntrinsicInfo::isInImmRange(NamedIntrinsic id, int ival, int simdSize, va { assert(HWIntrinsicInfo::lookupCategory(id) == HW_Category_IMM); - return ival <= lookupImmUpperBound(id, simdSize, baseType) && ival >= 0; + int immLowerBound = 0; + int immUpperBound = 0; + + lookupImmBounds(id, simdSize, baseType, &immLowerBound, &immUpperBound); + + return (immLowerBound <= ival) && (ival <= immUpperBound); } //------------------------------------------------------------------------ diff --git a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp index f722ea75d5c0a..179c1807e118a 100644 --- a/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp @@ -47,15 +47,16 @@ CodeGen::HWIntrinsicImmOpHelper::HWIntrinsicImmOpHelper(CodeGen* codeGen, GenTre nonConstImmReg = REG_NA; immValue = (int)immOp->AsIntCon()->IconValue(); - immUpperBound = immValue + 1; + immLowerBound = immValue; + immUpperBound = immValue; } else { - nonConstImmReg = immOp->GetRegNum(); + HWIntrinsicInfo::lookupImmBounds(intrin->gtHWIntrinsicId, intrin->gtSIMDSize, intrin->gtSIMDBaseType, + &immLowerBound, &immUpperBound); - immValue = 0; - immUpperBound = - HWIntrinsicInfo::lookupImmUpperBound(intrin->gtHWIntrinsicId, intrin->gtSIMDSize, intrin->gtSIMDBaseType); + nonConstImmReg = immOp->GetRegNum(); + immValue = immLowerBound; if (TestImmOpZeroOrOne()) { @@ -110,6 +111,15 @@ void CodeGen::HWIntrinsicImmOpHelper::EmitBegin() GetEmitter()->emitIns_R_L(INS_adr, EA_8BYTE, beginLabel, branchTargetReg); GetEmitter()->emitIns_R_R_R_I(INS_add, EA_8BYTE, branchTargetReg, branchTargetReg, nonConstImmReg, 3, INS_OPTS_LSL); + + // If the lower bound is non zero we need to adjust the branch target value by subtracting + // (immLowerBound << 3). + if (immLowerBound != 0) + { + GetEmitter()->emitIns_R_R_I(INS_sub, EA_8BYTE, branchTargetReg, branchTargetReg, + ((ssize_t)immLowerBound << 3)); + } + GetEmitter()->emitIns_R(INS_br, EA_8BYTE, branchTargetReg); } @@ -136,7 +146,7 @@ void CodeGen::HWIntrinsicImmOpHelper::EmitCaseEnd() if (NonConstImmOp()) { - const bool isLastCase = (immValue + 1 == immUpperBound); + const bool isLastCase = (immValue == immUpperBound); if (isLastCase) { @@ -658,6 +668,93 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) } break; + case NI_AdvSimd_ShiftLeftLogicalSaturateScalar: + case NI_AdvSimd_ShiftLeftLogicalSaturateUnsignedScalar: + case NI_AdvSimd_ShiftLeftLogicalScalar: + case NI_AdvSimd_ShiftRightArithmeticRoundedScalar: + case NI_AdvSimd_ShiftRightArithmeticScalar: + case NI_AdvSimd_ShiftRightLogicalRoundedScalar: + case NI_AdvSimd_ShiftRightLogicalScalar: + case NI_AdvSimd_Arm64_ShiftLeftLogicalSaturateScalar: + case NI_AdvSimd_Arm64_ShiftLeftLogicalSaturateUnsignedScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticNarrowingSaturateScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticNarrowingSaturateUnsignedScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticRoundedNarrowingSaturateScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar: + case NI_AdvSimd_Arm64_ShiftRightLogicalNarrowingSaturateScalar: + case NI_AdvSimd_Arm64_ShiftRightLogicalRoundedNarrowingSaturateScalar: + opt = INS_OPTS_NONE; + emitSize = emitTypeSize(intrin.baseType); + __fallthrough; + + case NI_AdvSimd_ShiftLeftLogical: + case NI_AdvSimd_ShiftLeftLogicalSaturate: + case NI_AdvSimd_ShiftLeftLogicalSaturateUnsigned: + case NI_AdvSimd_ShiftLeftLogicalWideningLower: + case NI_AdvSimd_ShiftLeftLogicalWideningUpper: + case NI_AdvSimd_ShiftRightArithmetic: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateUnsignedLower: + case NI_AdvSimd_ShiftRightArithmeticRounded: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower: + case NI_AdvSimd_ShiftRightLogical: + case NI_AdvSimd_ShiftRightLogicalNarrowingLower: + case NI_AdvSimd_ShiftRightLogicalNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightLogicalRounded: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingLower: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingSaturateLower: + { + HWIntrinsicImmOpHelper helper(this, intrin.op2, node); + + for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) + { + const int shiftAmount = helper.ImmValue(); + + GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, op1Reg, shiftAmount, opt); + } + } + break; + + case NI_AdvSimd_ShiftRightArithmeticAddScalar: + case NI_AdvSimd_ShiftRightArithmeticRoundedAddScalar: + case NI_AdvSimd_ShiftRightLogicalAddScalar: + case NI_AdvSimd_ShiftRightLogicalRoundedAddScalar: + opt = INS_OPTS_NONE; + emitSize = emitTypeSize(intrin.baseType); + __fallthrough; + + case NI_AdvSimd_ShiftRightArithmeticAdd: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateUnsignedUpper: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightArithmeticRoundedAdd: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightLogicalAdd: + case NI_AdvSimd_ShiftRightLogicalNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightLogicalNarrowingUpper: + case NI_AdvSimd_ShiftRightLogicalRoundedAdd: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingUpper: + { + assert(isRMW); + + if (targetReg != op1Reg) + { + GetEmitter()->emitIns_R_R(INS_mov, emitTypeSize(node), targetReg, op1Reg); + } + + HWIntrinsicImmOpHelper helper(this, intrin.op3, node); + + for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) + { + const int shiftAmount = helper.ImmValue(); + + GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, op2Reg, shiftAmount, opt); + } + } + break; + default: unreached(); } diff --git a/src/coreclr/src/jit/hwintrinsiclistarm64.h b/src/coreclr/src/jit/hwintrinsiclistarm64.h index dc6436de9a77d..be8a0d552da75 100644 --- a/src/coreclr/src/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/src/jit/hwintrinsiclistarm64.h @@ -12,321 +12,393 @@ #ifdef FEATURE_HW_INTRINSICS // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// ISA Function name SIMD size NumArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA Function name SIMD size Number of arguments Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // Vector64 Intrinsics -HARDWARE_INTRINSIC(Vector64, AsByte, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector64, AsInt16, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector64, AsInt32, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector64, AsSByte, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector64, AsSingle, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector64, AsUInt16, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector64, AsUInt32, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector64, Create, 8, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mov, INS_mov, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) -HARDWARE_INTRINSIC(Vector64, CreateScalarUnsafe, 8, 1, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_invalid, INS_invalid, INS_fmov, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(Vector64, get_AllBitsSet, 8, 0, {INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(Vector64, get_Count, 8, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) -HARDWARE_INTRINSIC(Vector64, get_Zero, 8, 0, {INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(Vector64, GetElement, 8, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_NoJmpTableIMM|HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(Vector64, op_Equality, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) -HARDWARE_INTRINSIC(Vector64, op_Inequality, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) -HARDWARE_INTRINSIC(Vector64, ToScalar, 8, 1, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector64, ToVector128, 8, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(Vector64, ToVector128Unsafe, 8, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector64, AsByte, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, AsInt16, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, AsInt32, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, AsSByte, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, AsSingle, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, AsUInt16, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, AsUInt32, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, Create, 8, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mov, INS_mov, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector64, CreateScalarUnsafe, 8, 1, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_invalid, INS_invalid, INS_fmov, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector64, get_AllBitsSet, 8, 0, {INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector64, get_Count, 8, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector64, get_Zero, 8, 0, {INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector64, GetElement, 8, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_NoJmpTableIMM|HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector64, op_Equality, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector64, op_Inequality, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector64, ToScalar, 8, 1, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, ToVector128, 8, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector64, ToVector128Unsafe, 8, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// ISA Function name SIMD size NumArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA Function name SIMD size Number of arguments Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // Vector128 Intrinsics -HARDWARE_INTRINSIC(Vector128, As, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, AsByte, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, AsDouble, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, AsInt16, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, AsInt32, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, AsInt64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, AsSByte, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, AsSingle, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, AsUInt16, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, AsUInt32, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, AsUInt64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, Create, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) -HARDWARE_INTRINSIC(Vector128, CreateScalarUnsafe, 16, 1, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_fmov, INS_fmov}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, 16, 0, {INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(Vector128, get_Count, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) -HARDWARE_INTRINSIC(Vector128, get_Zero, 16, 0, {INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(Vector128, GetElement, 16, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_NoJmpTableIMM|HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(Vector128, GetLower, 16, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(Vector128, op_Equality, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) -HARDWARE_INTRINSIC(Vector128, op_Inequality, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) -HARDWARE_INTRINSIC(Vector128, ToScalar, 16, 1, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, As, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, AsByte, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, AsDouble, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, AsInt16, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, AsInt32, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, AsInt64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, AsSByte, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, AsSingle, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, AsUInt16, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, AsUInt32, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, AsUInt64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, Create, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector128, CreateScalarUnsafe, 16, 1, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_fmov, INS_fmov}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, 16, 0, {INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector128, get_Count, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector128, get_Zero, 16, 0, {INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector128, GetElement, 16, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_NoJmpTableIMM|HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector128, GetLower, 16, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector128, op_Equality, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector128, op_Inequality, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector128, ToScalar, 16, 1, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// ISA Function name SIMD size NumArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA Function name SIMD size Number of arguments Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // AdvSimd Intrinsics -HARDWARE_INTRINSIC(AdvSimd, Abs, -1, 1, {INS_abs, INS_invalid, INS_abs, INS_invalid, INS_abs, INS_invalid, INS_invalid, INS_invalid, INS_fabs, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd, AbsScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fabs, INS_fabs}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, AbsoluteCompareGreaterThan, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facgt, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, AbsoluteCompareGreaterThanOrEqual, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facge, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, AbsoluteCompareLessThan, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facgt, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, AbsoluteCompareLessThanOrEqual, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facge, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifference, -1, 2, {INS_sabd, INS_uabd, INS_sabd, INS_uabd, INS_sabd, INS_uabd, INS_invalid, INS_invalid, INS_fabd, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceAdd, -1, 3, {INS_saba, INS_uaba, INS_saba, INS_uaba, INS_saba, INS_uaba, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningLower, 8, 2, {INS_sabdl, INS_uabdl, INS_sabdl, INS_uabdl, INS_sabdl, INS_uabdl, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningLowerAndAdd, 8, 3, {INS_sabal, INS_uabal, INS_sabal, INS_uabal, INS_sabal, INS_uabal, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) -HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningUpper, 16, 2, {INS_sabdl2, INS_uabdl2, INS_sabdl2, INS_uabdl2, INS_sabdl2, INS_uabdl2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningUpperAndAdd, 16, 3, {INS_sabal2, INS_uabal2, INS_sabal2, INS_uabal2, INS_sabal2, INS_uabal2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) -HARDWARE_INTRINSIC(AdvSimd, Add, -1, 2, {INS_add, INS_add, INS_add, INS_add, INS_add, INS_add, INS_add, INS_add, INS_fadd, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, AddHighNarrowingLower, 8, 2, {INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, AddHighNarrowingUpper, 16, 3, {INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, AddPairwise, 8, 2, {INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_invalid, INS_invalid, INS_faddp, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWidening, -1, 1, {INS_saddlp, INS_uaddlp, INS_saddlp, INS_uaddlp, INS_saddlp, INS_uaddlp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWideningAndAdd, -1, 2, {INS_sadalp, INS_uadalp, INS_sadalp, INS_uadalp, INS_sadalp, INS_uadalp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) -HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWideningAndAddScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sadalp, INS_uadalp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) -HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWideningScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_saddlp, INS_uaddlp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd, AddRoundedHighNarrowingLower, 8, 2, {INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, AddRoundedHighNarrowingUpper, 16, 3, {INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, AddSaturate, -1, 2, {INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, AddSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqadd, INS_uqadd, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, AddScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_add, INS_add, INS_fadd, INS_fadd}, HW_Category_SIMDScalar, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, AddWideningLower, 8, 2, {INS_saddl, INS_uaddl, INS_saddl, INS_uaddl, INS_saddl, INS_uaddl, INS_saddw, INS_uaddw, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromSecondArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, AddWideningUpper, 16, 2, {INS_saddl2, INS_uaddl2, INS_saddl2, INS_uaddl2, INS_saddl2, INS_uaddl2, INS_saddw2, INS_uaddw2, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromSecondArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, And, -1, 2, {INS_and, INS_and, INS_and, INS_and, INS_and, INS_and, INS_and, INS_and, INS_and, INS_and}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, BitwiseClear, -1, 2, {INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, BitwiseSelect, -1, 3, {INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, Ceiling, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frintp, INS_frintp}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, CompareEqual, -1, 2, {INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_invalid, INS_invalid, INS_fcmeq, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, CompareGreaterThan, -1, 2, {INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_invalid, INS_invalid, INS_fcmgt, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, CompareGreaterThanOrEqual, -1, 2, {INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_invalid, INS_invalid, INS_fcmge, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, CompareLessThan, -1, 2, {INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_invalid, INS_invalid, INS_fcmgt, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, CompareLessThanOrEqual, -1, 2, {INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_invalid, INS_invalid, INS_fcmge, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, CompareTest, -1, 2, {INS_cmtst, INS_cmtst, INS_cmtst, INS_cmtst, INS_cmtst, INS_cmtst, INS_invalid, INS_invalid, INS_cmtst, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, DivideScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fdiv, INS_fdiv}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, DuplicateSelectedScalarToVector64, -1, 2, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, DuplicateSelectedScalarToVector128, -1, 2, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, DuplicateToVector64, 8, 1, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, DuplicateToVector128, 16, 1, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, Extract, -1, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, ExtractNarrowingUpper, 16, 2, {INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, ExtractNarrowingLower, 8, 1, {INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, ExtractVector64, 8, 3, {INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_invalid, INS_invalid, INS_ext, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, ExtractVector128, 16, 3, {INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, Floor, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frintm, INS_frintm}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, FusedAddHalving, -1, 2, {INS_shadd, INS_uhadd, INS_shadd, INS_uhadd, INS_shadd, INS_uhadd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, FusedAddRoundedHalving, -1, 2, {INS_srhadd, INS_urhadd, INS_srhadd, INS_urhadd, INS_srhadd, INS_urhadd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, FusedMultiplyAdd, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmla, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, FusedMultiplyAddScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmadd, INS_fmadd}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, FusedMultiplyAddNegatedScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fnmadd, INS_fnmadd}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, FusedMultiplySubtract, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmls, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, FusedMultiplySubtractScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmsub, INS_fmsub}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, FusedMultiplySubtractNegatedScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fnmsub, INS_fnmsub}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, FusedSubtractHalving, -1, 2, {INS_shsub, INS_uhsub, INS_shsub, INS_uhsub, INS_shsub, INS_uhsub, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, Insert, -1, 3, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, LeadingSignCount, -1, 1, {INS_cls, INS_invalid, INS_cls, INS_invalid, INS_cls, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, LeadingZeroCount, -1, 1, {INS_clz, INS_clz, INS_clz, INS_clz, INS_clz, INS_clz, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, LoadVector64, 8, 1, {INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1}, HW_Category_MemoryLoad, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, LoadVector128, 16, 1, {INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1}, HW_Category_MemoryLoad, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, Max, -1, 2, {INS_smax, INS_umax, INS_smax, INS_umax, INS_smax, INS_umax, INS_invalid, INS_invalid, INS_fmax, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, MaxNumber, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxnm, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, MaxNumberScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxnm, INS_fmaxnm}, HW_Category_SIMDScalar, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, MaxPairwise, 8, 2, {INS_smaxp, INS_umaxp, INS_smaxp, INS_umaxp, INS_smaxp, INS_umaxp, INS_invalid, INS_invalid, INS_fmaxp, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, Min, -1, 2, {INS_smin, INS_umin, INS_smin, INS_umin, INS_smin, INS_umin, INS_invalid, INS_invalid, INS_fmin, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, MinNumber, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminnm, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, MinNumberScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminnm, INS_fminnm}, HW_Category_SIMDScalar, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, MinPairwise, 8, 2, {INS_sminp, INS_uminp, INS_sminp, INS_uminp, INS_sminp, INS_uminp, INS_invalid, INS_invalid, INS_fminp, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, Multiply, -1, 2, {INS_mul, INS_mul, INS_mul, INS_mul, INS_mul, INS_mul, INS_invalid, INS_invalid, INS_fmul, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, MultiplyScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmul, INS_fmul}, HW_Category_SIMDScalar, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, MultiplyAdd, -1, 3, {INS_mla, INS_mla, INS_mla, INS_mla, INS_mla, INS_mla, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, MultiplySubtract, -1, 3, {INS_mls, INS_mls, INS_mls, INS_mls, INS_mls, INS_mls, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, MultiplyWideningLower, 8, 2, {INS_smull, INS_umull, INS_smull, INS_umull, INS_smull, INS_umull, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd, MultiplyWideningLowerAndAdd, 8, 3, {INS_smlal, INS_umlal, INS_smlal, INS_umlal, INS_smlal, INS_umlal, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) -HARDWARE_INTRINSIC(AdvSimd, MultiplyWideningLowerAndSubtract, 8, 3, {INS_smlsl, INS_umlsl, INS_smlsl, INS_umlsl, INS_smlsl, INS_umlsl, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) -HARDWARE_INTRINSIC(AdvSimd, MultiplyWideningUpper, 16, 2, {INS_smull2, INS_umull2, INS_smull2, INS_umull2, INS_smull2, INS_umull2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd, MultiplyWideningUpperAndAdd, 16, 3, {INS_smlal2, INS_umlal2, INS_smlal2, INS_umlal2, INS_smlal2, INS_umlal2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) -HARDWARE_INTRINSIC(AdvSimd, MultiplyWideningUpperAndSubtract, 16, 3, {INS_smlsl2, INS_umlsl2, INS_smlsl2, INS_umlsl2, INS_smlsl2, INS_umlsl2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) -HARDWARE_INTRINSIC(AdvSimd, Negate, -1, 1, {INS_neg, INS_invalid, INS_neg, INS_invalid, INS_neg, INS_invalid, INS_invalid, INS_invalid, INS_fneg, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, NegateScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fneg, INS_fneg}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, Not, -1, 1, {INS_mvn, INS_mvn, INS_mvn, INS_mvn, INS_mvn, INS_mvn, INS_mvn, INS_mvn, INS_mvn, INS_mvn}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, Or, -1, 2, {INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, OrNot, -1, 2, {INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, PolynomialMultiply, -1, 2, {INS_pmul, INS_pmul, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, PolynomialMultiplyWideningLower, 8, 2, {INS_pmull, INS_pmull, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd, PolynomialMultiplyWideningUpper, 16, 2, {INS_pmull2, INS_pmull2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd, PopCount, -1, 1, {INS_cnt, INS_cnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, ReciprocalEstimate, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_urecpe, INS_invalid, INS_invalid, INS_frecpe, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, ReciprocalSquareRootEstimate, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ursqrte, INS_invalid, INS_invalid, INS_frsqrte, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, ReciprocalSquareRootStep, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frsqrts, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, ReciprocalStep, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frecps, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd, SqrtScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fsqrt, INS_fsqrt}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, Store, -1, 2, {INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1}, HW_Category_MemoryStore, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) -HARDWARE_INTRINSIC(AdvSimd, Subtract, -1, 2, {INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_fsub, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, SubtractHighNarrowingLower, 8, 2, {INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, SubtractHighNarrowingUpper, 16, 3, {INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, SubtractRoundedHighNarrowingLower, 8, 2, {INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, SubtractRoundedHighNarrowingUpper, 16, 3, {INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, SubtractSaturate, -1, 2, {INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, SubtractSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqsub, INS_uqsub, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, SubtractScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sub, INS_sub, INS_fsub, INS_fsub}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, SubtractWideningLower, 8, 2, {INS_ssubl, INS_usubl, INS_ssubl, INS_usubl, INS_ssubl, INS_usubl, INS_ssubw, INS_usubw, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromSecondArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, SubtractWideningUpper, 16, 2, {INS_ssubl2, INS_usubl2, INS_ssubl2, INS_usubl2, INS_ssubl2, INS_usubl2, INS_ssubw2, INS_usubw2, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromSecondArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd, VectorTableLookup, 8, 2, {INS_tbl, INS_tbl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd, VectorTableLookupExtension, 8, 3, {INS_tbx, INS_tbx, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd, Xor, -1, 2, {INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, Abs, -1, 1, {INS_abs, INS_invalid, INS_abs, INS_invalid, INS_abs, INS_invalid, INS_invalid, INS_invalid, INS_fabs, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, AbsScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fabs, INS_fabs}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, AbsoluteCompareGreaterThan, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facgt, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, AbsoluteCompareGreaterThanOrEqual, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facge, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, AbsoluteCompareLessThan, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facgt, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, AbsoluteCompareLessThanOrEqual, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facge, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifference, -1, 2, {INS_sabd, INS_uabd, INS_sabd, INS_uabd, INS_sabd, INS_uabd, INS_invalid, INS_invalid, INS_fabd, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceAdd, -1, 3, {INS_saba, INS_uaba, INS_saba, INS_uaba, INS_saba, INS_uaba, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningLower, 8, 2, {INS_sabdl, INS_uabdl, INS_sabdl, INS_uabdl, INS_sabdl, INS_uabdl, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningLowerAndAdd, 8, 3, {INS_sabal, INS_uabal, INS_sabal, INS_uabal, INS_sabal, INS_uabal, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningUpper, 16, 2, {INS_sabdl2, INS_uabdl2, INS_sabdl2, INS_uabdl2, INS_sabdl2, INS_uabdl2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, AbsoluteDifferenceWideningUpperAndAdd, 16, 3, {INS_sabal2, INS_uabal2, INS_sabal2, INS_uabal2, INS_sabal2, INS_uabal2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(AdvSimd, Add, -1, 2, {INS_add, INS_add, INS_add, INS_add, INS_add, INS_add, INS_add, INS_add, INS_fadd, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, AddHighNarrowingLower, 8, 2, {INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_addhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, AddHighNarrowingUpper, 16, 3, {INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_addhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, AddPairwise, 8, 2, {INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_invalid, INS_invalid, INS_faddp, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWidening, -1, 1, {INS_saddlp, INS_uaddlp, INS_saddlp, INS_uaddlp, INS_saddlp, INS_uaddlp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWideningAndAdd, -1, 2, {INS_sadalp, INS_uadalp, INS_sadalp, INS_uadalp, INS_sadalp, INS_uadalp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWideningAndAddScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sadalp, INS_uadalp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(AdvSimd, AddPairwiseWideningScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_saddlp, INS_uaddlp, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, AddRoundedHighNarrowingLower, 8, 2, {INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_raddhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, AddRoundedHighNarrowingUpper, 16, 3, {INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_raddhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, AddSaturate, -1, 2, {INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, AddSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqadd, INS_uqadd, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, AddScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_add, INS_add, INS_fadd, INS_fadd}, HW_Category_SIMDScalar, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, AddWideningLower, 8, 2, {INS_saddl, INS_uaddl, INS_saddl, INS_uaddl, INS_saddl, INS_uaddl, INS_saddw, INS_uaddw, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromSecondArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, AddWideningUpper, 16, 2, {INS_saddl2, INS_uaddl2, INS_saddl2, INS_uaddl2, INS_saddl2, INS_uaddl2, INS_saddw2, INS_uaddw2, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromSecondArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, And, -1, 2, {INS_and, INS_and, INS_and, INS_and, INS_and, INS_and, INS_and, INS_and, INS_and, INS_and}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, BitwiseClear, -1, 2, {INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic, INS_bic}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, BitwiseSelect, -1, 3, {INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, Ceiling, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frintp, INS_frintp}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, CompareEqual, -1, 2, {INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_invalid, INS_invalid, INS_fcmeq, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, CompareGreaterThan, -1, 2, {INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_invalid, INS_invalid, INS_fcmgt, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, CompareGreaterThanOrEqual, -1, 2, {INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_invalid, INS_invalid, INS_fcmge, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, CompareLessThan, -1, 2, {INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_invalid, INS_invalid, INS_fcmgt, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, CompareLessThanOrEqual, -1, 2, {INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_invalid, INS_invalid, INS_fcmge, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, CompareTest, -1, 2, {INS_cmtst, INS_cmtst, INS_cmtst, INS_cmtst, INS_cmtst, INS_cmtst, INS_invalid, INS_invalid, INS_cmtst, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, DivideScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fdiv, INS_fdiv}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, DuplicateSelectedScalarToVector64, -1, 2, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, DuplicateSelectedScalarToVector128, -1, 2, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, DuplicateToVector64, 8, 1, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, DuplicateToVector128, 16, 1, {INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_dup, INS_invalid, INS_invalid, INS_dup, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, Extract, -1, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ExtractNarrowingUpper, 16, 2, {INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_xtn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ExtractNarrowingLower, 8, 1, {INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_xtn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ExtractVector64, 8, 3, {INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_invalid, INS_invalid, INS_ext, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ExtractVector128, 16, 3, {INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext, INS_ext}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, Floor, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frintm, INS_frintm}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, FusedAddHalving, -1, 2, {INS_shadd, INS_uhadd, INS_shadd, INS_uhadd, INS_shadd, INS_uhadd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, FusedAddRoundedHalving, -1, 2, {INS_srhadd, INS_urhadd, INS_srhadd, INS_urhadd, INS_srhadd, INS_urhadd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, FusedMultiplyAdd, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmla, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, FusedMultiplyAddScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmadd, INS_fmadd}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, FusedMultiplyAddNegatedScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fnmadd, INS_fnmadd}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, FusedMultiplySubtract, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmls, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, FusedMultiplySubtractScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmsub, INS_fmsub}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, FusedMultiplySubtractNegatedScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fnmsub, INS_fnmsub}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, FusedSubtractHalving, -1, 2, {INS_shsub, INS_uhsub, INS_shsub, INS_uhsub, INS_shsub, INS_uhsub, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, Insert, -1, 3, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, LeadingSignCount, -1, 1, {INS_cls, INS_invalid, INS_cls, INS_invalid, INS_cls, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, LeadingZeroCount, -1, 1, {INS_clz, INS_clz, INS_clz, INS_clz, INS_clz, INS_clz, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, LoadVector64, 8, 1, {INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1}, HW_Category_MemoryLoad, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, LoadVector128, 16, 1, {INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1, INS_ld1}, HW_Category_MemoryLoad, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, Max, -1, 2, {INS_smax, INS_umax, INS_smax, INS_umax, INS_smax, INS_umax, INS_invalid, INS_invalid, INS_fmax, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, MaxNumber, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxnm, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, MaxNumberScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxnm, INS_fmaxnm}, HW_Category_SIMDScalar, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, MaxPairwise, 8, 2, {INS_smaxp, INS_umaxp, INS_smaxp, INS_umaxp, INS_smaxp, INS_umaxp, INS_invalid, INS_invalid, INS_fmaxp, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, Min, -1, 2, {INS_smin, INS_umin, INS_smin, INS_umin, INS_smin, INS_umin, INS_invalid, INS_invalid, INS_fmin, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, MinNumber, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminnm, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, MinNumberScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminnm, INS_fminnm}, HW_Category_SIMDScalar, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, MinPairwise, 8, 2, {INS_sminp, INS_uminp, INS_sminp, INS_uminp, INS_sminp, INS_uminp, INS_invalid, INS_invalid, INS_fminp, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, Multiply, -1, 2, {INS_mul, INS_mul, INS_mul, INS_mul, INS_mul, INS_mul, INS_invalid, INS_invalid, INS_fmul, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, MultiplyScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmul, INS_fmul}, HW_Category_SIMDScalar, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, MultiplyAdd, -1, 3, {INS_mla, INS_mla, INS_mla, INS_mla, INS_mla, INS_mla, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, MultiplySubtract, -1, 3, {INS_mls, INS_mls, INS_mls, INS_mls, INS_mls, INS_mls, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, MultiplyWideningLower, 8, 2, {INS_smull, INS_umull, INS_smull, INS_umull, INS_smull, INS_umull, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, MultiplyWideningLowerAndAdd, 8, 3, {INS_smlal, INS_umlal, INS_smlal, INS_umlal, INS_smlal, INS_umlal, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(AdvSimd, MultiplyWideningLowerAndSubtract, 8, 3, {INS_smlsl, INS_umlsl, INS_smlsl, INS_umlsl, INS_smlsl, INS_umlsl, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(AdvSimd, MultiplyWideningUpper, 16, 2, {INS_smull2, INS_umull2, INS_smull2, INS_umull2, INS_smull2, INS_umull2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, MultiplyWideningUpperAndAdd, 16, 3, {INS_smlal2, INS_umlal2, INS_smlal2, INS_umlal2, INS_smlal2, INS_umlal2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(AdvSimd, MultiplyWideningUpperAndSubtract, 16, 3, {INS_smlsl2, INS_umlsl2, INS_smlsl2, INS_umlsl2, INS_smlsl2, INS_umlsl2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(AdvSimd, Negate, -1, 1, {INS_neg, INS_invalid, INS_neg, INS_invalid, INS_neg, INS_invalid, INS_invalid, INS_invalid, INS_fneg, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, NegateScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fneg, INS_fneg}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, Not, -1, 1, {INS_mvn, INS_mvn, INS_mvn, INS_mvn, INS_mvn, INS_mvn, INS_mvn, INS_mvn, INS_mvn, INS_mvn}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, Or, -1, 2, {INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr, INS_orr}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, OrNot, -1, 2, {INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn, INS_orn}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, PolynomialMultiply, -1, 2, {INS_pmul, INS_pmul, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, PolynomialMultiplyWideningLower, 8, 2, {INS_pmull, INS_pmull, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, PolynomialMultiplyWideningUpper, 16, 2, {INS_pmull2, INS_pmull2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, PopCount, -1, 1, {INS_cnt, INS_cnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ReciprocalEstimate, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_urecpe, INS_invalid, INS_invalid, INS_frecpe, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ReciprocalSquareRootEstimate, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ursqrte, INS_invalid, INS_invalid, INS_frsqrte, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ReciprocalSquareRootStep, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frsqrts, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, ReciprocalStep, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frecps, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, ShiftArithmetic, -1, 2, {INS_sshl, INS_invalid, INS_sshl, INS_invalid, INS_sshl, INS_invalid, INS_sshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftArithmeticRounded, -1, 2, {INS_srshl, INS_invalid, INS_srshl, INS_invalid, INS_srshl, INS_invalid, INS_srshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftArithmeticRoundedSaturate, -1, 2, {INS_sqrshl, INS_invalid, INS_sqrshl, INS_invalid, INS_sqrshl, INS_invalid, INS_sqrshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftArithmeticRoundedSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqrshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftArithmeticRoundedScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_srshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftArithmeticSaturate, -1, 2, {INS_sqshl, INS_invalid, INS_sqshl, INS_invalid, INS_sqshl, INS_invalid, INS_sqshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftArithmeticSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftArithmeticScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogical, -1, 2, {INS_shl, INS_shl, INS_shl, INS_shl, INS_shl, INS_shl, INS_shl, INS_shl, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalSaturate, -1, 2, {INS_sqshl, INS_uqshl, INS_sqshl, INS_uqshl, INS_sqshl, INS_uqshl, INS_sqshl, INS_uqshl, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqshl, INS_uqshl, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalSaturateUnsigned, -1, 2, {INS_sqshlu, INS_invalid, INS_sqshlu, INS_invalid, INS_sqshlu, INS_invalid, INS_sqshlu, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalSaturateUnsignedScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqshlu, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_shl, INS_shl, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalWideningLower, 8, 2, {INS_sshll, INS_ushll, INS_sshll, INS_ushll, INS_sshll, INS_ushll, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalWideningUpper, 16, 2, {INS_sshll2, INS_ushll2, INS_sshll2, INS_ushll2, INS_sshll2, INS_ushll2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftLogical, -1, 2, {INS_ushl, INS_ushl, INS_ushl, INS_ushl, INS_ushl, INS_ushl, INS_ushl, INS_ushl, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftLogicalRounded, -1, 2, {INS_urshl, INS_urshl, INS_urshl, INS_urshl, INS_urshl, INS_urshl, INS_urshl, INS_urshl, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftLogicalRoundedSaturate, -1, 2, {INS_uqrshl, INS_uqrshl, INS_uqrshl, INS_uqrshl, INS_uqrshl, INS_uqrshl, INS_uqrshl, INS_uqrshl, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftLogicalRoundedSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_uqrshl, INS_uqrshl, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftLogicalRoundedScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_urshl, INS_urshl, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftLogicalSaturate, -1, 2, {INS_uqshl, INS_uqshl, INS_uqshl, INS_uqshl, INS_uqshl, INS_uqshl, INS_uqshl, INS_uqshl, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftLogicalSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_uqshl, INS_uqshl, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftLogicalScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ushl, INS_ushl, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmetic, -1, 2, {INS_sshr, INS_invalid, INS_sshr, INS_invalid, INS_sshr, INS_invalid, INS_sshr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticAdd, -1, 3, {INS_ssra, INS_invalid, INS_ssra, INS_invalid, INS_ssra, INS_invalid, INS_ssra, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticAddScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ssra, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticNarrowingSaturateLower, 8, 2, {INS_sqshrn, INS_invalid, INS_sqshrn, INS_invalid, INS_sqshrn, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticNarrowingSaturateUnsignedLower, 8, 2, {INS_invalid, INS_sqshrun, INS_invalid, INS_sqshrun, INS_invalid, INS_sqshrun, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticNarrowingSaturateUnsignedUpper, 16, 3, {INS_invalid, INS_sqshrun2, INS_invalid, INS_sqshrun2, INS_invalid, INS_sqshrun2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticNarrowingSaturateUpper, 16, 3, {INS_sqshrn2, INS_invalid, INS_sqshrn2, INS_invalid, INS_sqshrn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticRounded, -1, 2, {INS_srshr, INS_invalid, INS_srshr, INS_invalid, INS_srshr, INS_invalid, INS_srshr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticRoundedAdd, -1, 3, {INS_srsra, INS_invalid, INS_srsra, INS_invalid, INS_srsra, INS_invalid, INS_srsra, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticRoundedAddScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_srsra, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticRoundedNarrowingSaturateLower, 8, 2, {INS_sqrshrn, INS_invalid, INS_sqrshrn, INS_invalid, INS_sqrshrn, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower, 8, 2, {INS_invalid, INS_sqrshrun, INS_invalid, INS_sqrshrun, INS_invalid, INS_sqrshrun, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper, 16, 3, {INS_invalid, INS_sqrshrun2, INS_invalid, INS_sqrshrun2, INS_invalid, INS_sqrshrun2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticRoundedNarrowingSaturateUpper, 16, 3, {INS_sqrshrn2, INS_invalid, INS_sqrshrn2, INS_invalid, INS_sqrshrn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticRoundedScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_srshr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sshr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogical, -1, 2, {INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalAdd, -1, 3, {INS_usra, INS_usra, INS_usra, INS_usra, INS_usra, INS_usra, INS_usra, INS_usra, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalAddScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_usra, INS_usra, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalNarrowingLower, 8, 2, {INS_shrn, INS_shrn, INS_shrn, INS_shrn, INS_shrn, INS_shrn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalNarrowingSaturateLower, 8, 2, {INS_uqshrn, INS_uqshrn, INS_uqshrn, INS_uqshrn, INS_uqshrn, INS_uqshrn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalNarrowingSaturateUpper, 16, 3, {INS_uqshrn2, INS_uqshrn2, INS_uqshrn2, INS_uqshrn2, INS_uqshrn2, INS_uqshrn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalNarrowingUpper, 16, 3, {INS_shrn2, INS_shrn2, INS_shrn2, INS_shrn2, INS_shrn2, INS_shrn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalRounded, -1, 2, {INS_urshr, INS_urshr, INS_urshr, INS_urshr, INS_urshr, INS_urshr, INS_urshr, INS_urshr, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalRoundedAdd, -1, 3, {INS_ursra, INS_ursra, INS_ursra, INS_ursra, INS_ursra, INS_ursra, INS_ursra, INS_ursra, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalRoundedAddScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ursra, INS_ursra, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalRoundedNarrowingLower, 8, 2, {INS_rshrn, INS_rshrn, INS_rshrn, INS_rshrn, INS_rshrn, INS_rshrn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalRoundedNarrowingSaturateLower, 8, 2, {INS_uqrshrn, INS_uqrshrn, INS_uqrshrn, INS_uqrshrn, INS_uqrshrn, INS_uqrshrn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalRoundedNarrowingSaturateUpper, 16, 3, {INS_uqrshrn2, INS_uqrshrn2, INS_uqrshrn2, INS_uqrshrn2, INS_uqrshrn2, INS_uqrshrn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalRoundedNarrowingUpper, 16, 3, {INS_rshrn2, INS_rshrn2, INS_rshrn2, INS_rshrn2, INS_rshrn2, INS_rshrn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalRoundedScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_urshr, INS_urshr, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ushr, INS_ushr, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, SignExtendWideningLower, 8, 1, {INS_sxtl, INS_invalid, INS_sxtl, INS_invalid, INS_sxtl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, SignExtendWideningUpper, 16, 1, {INS_sxtl2, INS_invalid, INS_sxtl2, INS_invalid, INS_sxtl2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, SqrtScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fsqrt, INS_fsqrt}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, Store, -1, 2, {INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1}, HW_Category_MemoryStore, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(AdvSimd, Subtract, -1, 2, {INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_fsub, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, SubtractHighNarrowingLower, 8, 2, {INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_subhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, SubtractHighNarrowingUpper, 16, 3, {INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_subhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, SubtractRoundedHighNarrowingLower, 8, 2, {INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_rsubhn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, SubtractRoundedHighNarrowingUpper, 16, 3, {INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_rsubhn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, SubtractSaturate, -1, 2, {INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, SubtractSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqsub, INS_uqsub, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, SubtractScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sub, INS_sub, INS_fsub, INS_fsub}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, SubtractWideningLower, 8, 2, {INS_ssubl, INS_usubl, INS_ssubl, INS_usubl, INS_ssubl, INS_usubl, INS_ssubw, INS_usubw, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromSecondArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, SubtractWideningUpper, 16, 2, {INS_ssubl2, INS_usubl2, INS_ssubl2, INS_usubl2, INS_ssubl2, INS_usubl2, INS_ssubw2, INS_usubw2, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromSecondArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd, VectorTableLookup, 8, 2, {INS_tbl, INS_tbl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd, VectorTableLookupExtension, 8, 3, {INS_tbx, INS_tbx, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd, Xor, -1, 2, {INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd, ZeroExtendWideningLower, 8, 1, {INS_uxtl, INS_uxtl, INS_uxtl, INS_uxtl, INS_uxtl, INS_uxtl, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd, ZeroExtendWideningUpper, 16, 1, {INS_uxtl2, INS_uxtl2, INS_uxtl2, INS_uxtl2, INS_uxtl2, INS_uxtl2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// ISA Function name SIMD size NumArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA Function name SIMD size Number of arguments Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // AdvSimd 64-bit only Intrinsics -HARDWARE_INTRINSIC(AdvSimd_Arm64, Abs, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_abs, INS_invalid, INS_invalid, INS_fabs}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_abs, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareGreaterThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facgt}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareGreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facge}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareGreaterThanOrEqualScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facge, INS_facge}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareGreaterThanScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facgt, INS_facgt}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareLessThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facgt}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareLessThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facge}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareLessThanOrEqualScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facge, INS_facge}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareLessThanScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facgt, INS_facgt}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteDifference, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fabd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteDifferenceScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fabd, INS_fabd}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, Add, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fadd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AddAcross, -1, 1, {INS_addv, INS_addv, INS_addv, INS_addv, INS_addv, INS_addv, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AddPairwise, 16, 2, {INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_faddp, INS_faddp}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AddPairwiseScalar, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_addp, INS_addp, INS_faddp, INS_faddp}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd_Arm64, AddSaturateScalar, 8, 2, {INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmeq, INS_cmeq, INS_invalid, INS_fcmeq}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareEqualScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmeq, INS_cmeq, INS_fcmeq, INS_fcmeq}, HW_Category_SIMDScalar, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareGreaterThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmgt, INS_cmhi, INS_invalid, INS_fcmgt}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareGreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmge, INS_cmhs, INS_invalid, INS_fcmge}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareGreaterThanOrEqualScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmge, INS_cmhs, INS_fcmge, INS_fcmge}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareGreaterThanScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmgt, INS_cmhi, INS_fcmgt, INS_fcmgt}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareLessThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmgt, INS_cmhi, INS_invalid, INS_fcmgt}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareLessThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmge, INS_cmhs, INS_invalid, INS_fcmge}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareLessThanOrEqualScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmge, INS_cmhs, INS_fcmge, INS_fcmge}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareLessThanScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmgt, INS_cmhi, INS_fcmgt, INS_fcmgt}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareTest, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmtst, INS_cmtst, INS_invalid, INS_cmtst}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareTestScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmtst, INS_cmtst, INS_invalid, INS_cmtst}, HW_Category_SIMDScalar, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, Divide, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fdiv, INS_fdiv}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, DuplicateSelectedScalarToVector128, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_dup, INS_dup, INS_invalid, INS_dup}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd_Arm64, DuplicateToVector64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mov, INS_mov, INS_invalid, INS_fmov}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd_Arm64, DuplicateToVector128, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_dup, INS_dup, INS_invalid, INS_dup}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) -HARDWARE_INTRINSIC(AdvSimd_Arm64, FusedMultiplyAdd, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmla}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd_Arm64, FusedMultiplySubtract, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmls}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd_Arm64, Max, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmax}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxAcross, -1, 1, {INS_smaxv, INS_umaxv, INS_smaxv, INS_umaxv, INS_smaxv, INS_umaxv, INS_invalid, INS_invalid, INS_fmaxv, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxNumber, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxnm}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxNumberAcross, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxnmv, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxNumberPairwise, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxnmp, INS_fmaxnmp}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxNumberPairwiseScalar, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxnmp, INS_fmaxnmp}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxPairwise, 16, 2, {INS_smaxp, INS_umaxp, INS_smaxp, INS_umaxp, INS_smaxp, INS_umaxp, INS_invalid, INS_invalid, INS_fmaxp, INS_fmaxp}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxPairwiseScalar, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxp, INS_fmaxp}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmax, INS_fmax}, HW_Category_SIMDScalar, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, Min, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmin}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MinAcross, -1, 1, {INS_sminv, INS_uminv, INS_sminv, INS_uminv, INS_sminv, INS_uminv, INS_invalid, INS_invalid, INS_fminv, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MinNumber, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminnm}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MinNumberAcross, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminnmv, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MinNumberPairwise, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminnmp, INS_fminnmp}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MinNumberPairwiseScalar, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminnmp, INS_fminnmp}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MinPairwise, 16, 2, {INS_sminp, INS_uminp, INS_sminp, INS_uminp, INS_sminp, INS_uminp, INS_invalid, INS_invalid, INS_fminp, INS_fminp}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MinPairwiseScalar, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminp, INS_fminp}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MinScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmin, INS_fmin}, HW_Category_SIMDScalar, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, Multiply, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmul}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MultiplyExtended, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmulx, INS_fmulx}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, MultiplyExtendedScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmulx, INS_fmulx}, HW_Category_SIMDScalar, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, Negate, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_neg, INS_invalid, INS_invalid, INS_fneg}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, NegateScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_neg, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalEstimate, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frecpe}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalEstimateScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frecpe, INS_frecpe}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalExponentScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frecpx, INS_frecpx}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalSquareRootEstimate, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frsqrte}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalSquareRootEstimateScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frsqrte, INS_frsqrte}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalSquareRootStep, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frsqrts}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalSquareRootStepScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frsqrts, INS_frsqrts}, HW_Category_SIMDScalar, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalStep, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frecps}, HW_Category_SimpleSIMD, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalStepScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frecps, INS_frecps}, HW_Category_SIMDScalar, HW_Flag_Commutative) -HARDWARE_INTRINSIC(AdvSimd_Arm64, ReverseElementBits, -1, 1, {INS_rbit, INS_rbit, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, Sqrt, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fsqrt, INS_fsqrt}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, Subtract, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fsub}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, SubtractSaturateScalar, 8, 2, {INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, TransposeEven, -1, 2, {INS_trn1, INS_trn1, INS_trn1, INS_trn1, INS_trn1, INS_trn1, INS_trn1, INS_trn1, INS_trn1, INS_trn1}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, TransposeOdd, -1, 2, {INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, UnzipEven, -1, 2, {INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, UnzipOdd, -1, 2, {INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, VectorTableLookup, 16, 2, {INS_tbl, INS_tbl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, VectorTableLookupExtension, 16, 3, {INS_tbx, INS_tbx, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(AdvSimd_Arm64, ZipHigh, -1, 2, {INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AdvSimd_Arm64, ZipLow, -1, 2, {INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, Abs, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_abs, INS_invalid, INS_invalid, INS_fabs}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_abs, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareGreaterThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facgt}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareGreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facge}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareGreaterThanOrEqualScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facge, INS_facge}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareGreaterThanScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facgt, INS_facgt}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareLessThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facgt}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareLessThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facge}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareLessThanOrEqualScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facge, INS_facge}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteCompareLessThanScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_facgt, INS_facgt}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteDifference, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fabd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AbsoluteDifferenceScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fabd, INS_fabd}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, Add, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fadd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AddAcross, -1, 1, {INS_addv, INS_addv, INS_addv, INS_addv, INS_addv, INS_addv, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AddPairwise, 16, 2, {INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_addp, INS_faddp, INS_faddp}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AddPairwiseScalar, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_addp, INS_addp, INS_faddp, INS_faddp}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd_Arm64, AddSaturateScalar, 8, 2, {INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmeq, INS_cmeq, INS_invalid, INS_fcmeq}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareEqualScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmeq, INS_cmeq, INS_fcmeq, INS_fcmeq}, HW_Category_SIMDScalar, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareGreaterThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmgt, INS_cmhi, INS_invalid, INS_fcmgt}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareGreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmge, INS_cmhs, INS_invalid, INS_fcmge}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareGreaterThanOrEqualScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmge, INS_cmhs, INS_fcmge, INS_fcmge}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareGreaterThanScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmgt, INS_cmhi, INS_fcmgt, INS_fcmgt}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareLessThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmgt, INS_cmhi, INS_invalid, INS_fcmgt}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareLessThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmge, INS_cmhs, INS_invalid, INS_fcmge}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareLessThanOrEqualScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmge, INS_cmhs, INS_fcmge, INS_fcmge}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareLessThanScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmgt, INS_cmhi, INS_fcmgt, INS_fcmgt}, HW_Category_SIMDScalar, HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareTest, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmtst, INS_cmtst, INS_invalid, INS_cmtst}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareTestScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmtst, INS_cmtst, INS_invalid, INS_cmtst}, HW_Category_SIMDScalar, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, Divide, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fdiv, INS_fdiv}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, DuplicateSelectedScalarToVector128, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_dup, INS_dup, INS_invalid, INS_dup}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, DuplicateToVector64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mov, INS_mov, INS_invalid, INS_fmov}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, DuplicateToVector128, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_dup, INS_dup, INS_invalid, INS_dup}, HW_Category_SimpleSIMD, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, FusedMultiplyAdd, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmla}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd_Arm64, FusedMultiplySubtract, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmls}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd_Arm64, Max, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmax}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxAcross, -1, 1, {INS_smaxv, INS_umaxv, INS_smaxv, INS_umaxv, INS_smaxv, INS_umaxv, INS_invalid, INS_invalid, INS_fmaxv, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxNumber, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxnm}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxNumberAcross, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxnmv, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxNumberPairwise, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxnmp, INS_fmaxnmp}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxNumberPairwiseScalar, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxnmp, INS_fmaxnmp}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxPairwise, 16, 2, {INS_smaxp, INS_umaxp, INS_smaxp, INS_umaxp, INS_smaxp, INS_umaxp, INS_invalid, INS_invalid, INS_fmaxp, INS_fmaxp}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxPairwiseScalar, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmaxp, INS_fmaxp}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MaxScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmax, INS_fmax}, HW_Category_SIMDScalar, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, Min, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmin}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MinAcross, -1, 1, {INS_sminv, INS_uminv, INS_sminv, INS_uminv, INS_sminv, INS_uminv, INS_invalid, INS_invalid, INS_fminv, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MinNumber, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminnm}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MinNumberAcross, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminnmv, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MinNumberPairwise, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminnmp, INS_fminnmp}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MinNumberPairwiseScalar, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminnmp, INS_fminnmp}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MinPairwise, 16, 2, {INS_sminp, INS_uminp, INS_sminp, INS_uminp, INS_sminp, INS_uminp, INS_invalid, INS_invalid, INS_fminp, INS_fminp}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MinPairwiseScalar, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fminp, INS_fminp}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MinScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmin, INS_fmin}, HW_Category_SIMDScalar, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, Multiply, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmul}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MultiplyExtended, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmulx, INS_fmulx}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, MultiplyExtendedScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fmulx, INS_fmulx}, HW_Category_SIMDScalar, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, Negate, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_neg, INS_invalid, INS_invalid, INS_fneg}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, NegateScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_neg, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalEstimate, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frecpe}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalEstimateScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frecpe, INS_frecpe}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalExponentScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frecpx, INS_frecpx}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalSquareRootEstimate, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frsqrte}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalSquareRootEstimateScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frsqrte, INS_frsqrte}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalSquareRootStep, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frsqrts}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalSquareRootStepScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frsqrts, INS_frsqrts}, HW_Category_SIMDScalar, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalStep, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frecps}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ReciprocalStepScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frecps, INS_frecps}, HW_Category_SIMDScalar, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ReverseElementBits, -1, 1, {INS_rbit, INS_rbit, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ShiftArithmeticRoundedSaturateScalar, 8, 2, {INS_sqrshl, INS_invalid, INS_sqrshl, INS_invalid, INS_sqrshl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ShiftArithmeticSaturateScalar, 8, 2, {INS_sqshl, INS_invalid, INS_sqshl, INS_invalid, INS_sqshl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ShiftLeftLogicalSaturateScalar, 8, 2, {INS_sqshl, INS_uqshl, INS_sqshl, INS_uqshl, INS_sqshl, INS_uqshl, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ShiftLeftLogicalSaturateUnsignedScalar, 8, 2, {INS_sqshlu, INS_invalid, INS_sqshlu, INS_invalid, INS_sqshlu, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ShiftLogicalRoundedSaturateScalar, 8, 2, {INS_uqrshl, INS_uqrshl, INS_uqrshl, INS_uqrshl, INS_uqrshl, INS_uqrshl, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ShiftLogicalSaturateScalar, 8, 2, {INS_uqshl, INS_uqshl, INS_uqshl, INS_uqshl, INS_uqshl, INS_uqshl, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ShiftRightArithmeticNarrowingSaturateScalar, 8, 2, {INS_sqshrn, INS_invalid, INS_sqshrn, INS_invalid, INS_sqshrn, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ShiftRightArithmeticNarrowingSaturateUnsignedScalar, 8, 2, {INS_invalid, INS_sqshrun, INS_invalid, INS_sqshrun, INS_invalid, INS_sqshrun, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ShiftRightArithmeticRoundedNarrowingSaturateScalar, 8, 2, {INS_sqrshrn, INS_invalid, INS_sqrshrn, INS_invalid, INS_sqrshrn, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar, 8, 2, {INS_invalid, INS_sqrshrun, INS_invalid, INS_sqrshrun, INS_invalid, INS_sqrshrun, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ShiftRightLogicalNarrowingSaturateScalar, 8, 2, {INS_uqshrn, INS_uqshrn, INS_uqshrn, INS_uqshrn, INS_uqshrn, INS_uqshrn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ShiftRightLogicalRoundedNarrowingSaturateScalar, 8, 2, {INS_uqrshrn, INS_uqrshrn, INS_uqrshrn, INS_uqrshrn, INS_uqrshrn, INS_uqrshrn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_SupportsContainment|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(AdvSimd_Arm64, Sqrt, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fsqrt, INS_fsqrt}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, Subtract, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fsub}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, SubtractSaturateScalar, 8, 2, {INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_sqsub, INS_uqsub, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, TransposeEven, -1, 2, {INS_trn1, INS_trn1, INS_trn1, INS_trn1, INS_trn1, INS_trn1, INS_trn1, INS_trn1, INS_trn1, INS_trn1}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, TransposeOdd, -1, 2, {INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, UnzipEven, -1, 2, {INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, UnzipOdd, -1, 2, {INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, VectorTableLookup, 16, 2, {INS_tbl, INS_tbl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, VectorTableLookupExtension, 16, 3, {INS_tbx, INS_tbx, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ZipHigh, -1, 2, {INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AdvSimd_Arm64, ZipLow, -1, 2, {INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// ISA Function name SIMD size NumArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA Function name SIMD size Number of arguments Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // AES Intrinsics -HARDWARE_INTRINSIC(Aes, Decrypt, 16, 2, {INS_invalid, INS_aesd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Aes, Encrypt, 16, 2, {INS_invalid, INS_aese, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Aes, InverseMixColumns, 16, 1, {INS_invalid, INS_aesimc, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(Aes, MixColumns, 16, 1, {INS_invalid, INS_aesmc, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(Aes, PolynomialMultiplyWideningLower, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pmull, INS_pmull, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Aes, PolynomialMultiplyWideningUpper, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pmull2, INS_pmull2, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Aes, Decrypt, 16, 2, {INS_invalid, INS_aesd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Aes, Encrypt, 16, 2, {INS_invalid, INS_aese, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Aes, InverseMixColumns, 16, 1, {INS_invalid, INS_aesimc, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(Aes, MixColumns, 16, 1, {INS_invalid, INS_aesmc, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(Aes, PolynomialMultiplyWideningLower, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pmull, INS_pmull, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Aes, PolynomialMultiplyWideningUpper, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pmull2, INS_pmull2, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative|HW_Flag_BaseTypeFromFirstArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// ISA Function name SIMD size NumArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA Function name SIMD size Number of arguments Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // Base Intrinsics -HARDWARE_INTRINSIC(ArmBase, LeadingZeroCount, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_clz, INS_clz, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(ArmBase, ReverseElementBits, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_rbit, INS_rbit, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(ArmBase, LeadingZeroCount, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_clz, INS_clz, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(ArmBase, ReverseElementBits, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_rbit, INS_rbit, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFlag) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// ISA Function name SIMD size NumArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA Function name SIMD size Number of arguments Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // Base 64-bit only Intrinsics -HARDWARE_INTRINSIC(ArmBase_Arm64, LeadingSignCount, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cls, INS_invalid, INS_cls, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(ArmBase_Arm64, LeadingZeroCount, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_clz, INS_clz, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(ArmBase_Arm64, ReverseElementBits, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_rbit, INS_rbit, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(ArmBase_Arm64, LeadingSignCount, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cls, INS_invalid, INS_cls, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(ArmBase_Arm64, LeadingZeroCount, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_clz, INS_clz, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(ArmBase_Arm64, ReverseElementBits, 0, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_rbit, INS_rbit, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_NoFlag) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// ISA Function name SIMD size NumArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA Function name SIMD size Number of arguments Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // CRC32 Intrinsics -HARDWARE_INTRINSIC(Crc32, ComputeCrc32, 0, 2, {INS_invalid, INS_crc32b, INS_invalid, INS_crc32h, INS_invalid, INS_crc32w, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) -HARDWARE_INTRINSIC(Crc32, ComputeCrc32C, 0, 2, {INS_invalid, INS_crc32cb, INS_invalid, INS_crc32ch, INS_invalid, INS_crc32cw, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(Crc32, ComputeCrc32, 0, 2, {INS_invalid, INS_crc32b, INS_invalid, INS_crc32h, INS_invalid, INS_crc32w, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(Crc32, ComputeCrc32C, 0, 2, {INS_invalid, INS_crc32cb, INS_invalid, INS_crc32ch, INS_invalid, INS_crc32cw, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// ISA Function name SIMD size NumArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA Function name SIMD size Number of arguments Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // CRC32 64-bit only Intrinsics -HARDWARE_INTRINSIC(Crc32_Arm64, ComputeCrc32, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_crc32x, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) -HARDWARE_INTRINSIC(Crc32_Arm64, ComputeCrc32C, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_crc32cx, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(Crc32_Arm64, ComputeCrc32, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_crc32x, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) +HARDWARE_INTRINSIC(Crc32_Arm64, ComputeCrc32C, 0, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_crc32cx, INS_invalid, INS_invalid}, HW_Category_Scalar, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// ISA Function name SIMD size NumArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA Function name SIMD size Number of arguments Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // SHA1 Intrinsics -HARDWARE_INTRINSIC(Sha1, FixedRotate, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha1h, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(Sha1, HashUpdateChoose, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha1c, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sha1, HashUpdateMajority, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha1m, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sha1, HashUpdateParity, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha1p, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sha1, ScheduleUpdate0, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha1su0, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sha1, ScheduleUpdate1, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha1su1, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sha1, FixedRotate, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha1h, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(Sha1, HashUpdateChoose, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha1c, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sha1, HashUpdateMajority, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha1m, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sha1, HashUpdateParity, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha1p, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sha1, ScheduleUpdate0, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha1su0, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sha1, ScheduleUpdate1, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha1su1, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** -// ISA Function name SIMD size NumArg Instructions Category Flags -// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// ISA Function name SIMD size Number of arguments Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // SHA256 Intrinsics -HARDWARE_INTRINSIC(Sha256, HashUpdate1, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha256h, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sha256, HashUpdate2, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha256h2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sha256, ScheduleUpdate0, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha256su0, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sha256, ScheduleUpdate1, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha256su1, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sha256, HashUpdate1, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha256h, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sha256, HashUpdate2, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha256h2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sha256, ScheduleUpdate0, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha256su0, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sha256, ScheduleUpdate1, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sha256su1, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics) #endif // FEATURE_HW_INTRINSIC diff --git a/src/coreclr/src/jit/lowerarmarch.cpp b/src/coreclr/src/jit/lowerarmarch.cpp index c47cb7ee4e9ff..fdebf70ecb9f1 100644 --- a/src/coreclr/src/jit/lowerarmarch.cpp +++ b/src/coreclr/src/jit/lowerarmarch.cpp @@ -1376,7 +1376,39 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AdvSimd_DuplicateSelectedScalarToVector64: case NI_AdvSimd_DuplicateSelectedScalarToVector128: case NI_AdvSimd_Extract: + case NI_AdvSimd_ShiftLeftLogical: + case NI_AdvSimd_ShiftLeftLogicalSaturate: + case NI_AdvSimd_ShiftLeftLogicalSaturateScalar: + case NI_AdvSimd_ShiftLeftLogicalSaturateUnsigned: + case NI_AdvSimd_ShiftLeftLogicalSaturateUnsignedScalar: + case NI_AdvSimd_ShiftLeftLogicalScalar: + case NI_AdvSimd_ShiftLeftLogicalWideningLower: + case NI_AdvSimd_ShiftLeftLogicalWideningUpper: + case NI_AdvSimd_ShiftRightArithmetic: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateUnsignedLower: + case NI_AdvSimd_ShiftRightArithmeticRounded: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower: + case NI_AdvSimd_ShiftRightArithmeticRoundedScalar: + case NI_AdvSimd_ShiftRightArithmeticScalar: + case NI_AdvSimd_ShiftRightLogical: + case NI_AdvSimd_ShiftRightLogicalNarrowingLower: + case NI_AdvSimd_ShiftRightLogicalNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightLogicalRounded: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingLower: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightLogicalRoundedScalar: + case NI_AdvSimd_ShiftRightLogicalScalar: case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128: + case NI_AdvSimd_Arm64_ShiftLeftLogicalSaturateScalar: + case NI_AdvSimd_Arm64_ShiftLeftLogicalSaturateUnsignedScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticNarrowingSaturateScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticNarrowingSaturateUnsignedScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticRoundedNarrowingSaturateScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar: + case NI_AdvSimd_Arm64_ShiftRightLogicalNarrowingSaturateScalar: + case NI_AdvSimd_Arm64_ShiftRightLogicalRoundedNarrowingSaturateScalar: case NI_Vector64_GetElement: case NI_Vector128_GetElement: if (intrin.op2->IsCnsIntOrI()) @@ -1387,6 +1419,22 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AdvSimd_ExtractVector64: case NI_AdvSimd_ExtractVector128: + case NI_AdvSimd_ShiftRightArithmeticAdd: + case NI_AdvSimd_ShiftRightArithmeticAddScalar: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateUnsignedUpper: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightArithmeticRoundedAdd: + case NI_AdvSimd_ShiftRightArithmeticRoundedAddScalar: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightLogicalAdd: + case NI_AdvSimd_ShiftRightLogicalAddScalar: + case NI_AdvSimd_ShiftRightLogicalNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightLogicalNarrowingUpper: + case NI_AdvSimd_ShiftRightLogicalRoundedAdd: + case NI_AdvSimd_ShiftRightLogicalRoundedAddScalar: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingUpper: if (intrin.op3->IsCnsIntOrI()) { MakeSrcContained(node, intrin.op3); diff --git a/src/coreclr/src/jit/lsraarm64.cpp b/src/coreclr/src/jit/lsraarm64.cpp index 2c93dd860ffbb..c7146d6872af0 100644 --- a/src/coreclr/src/jit/lsraarm64.cpp +++ b/src/coreclr/src/jit/lsraarm64.cpp @@ -985,13 +985,22 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) int srcCount = 0; int dstCount = intrinsicTree->IsValue() ? 1 : 0; - // We may need to allocate an additional general-purpose register when an intrinsic has a non-const immediate - // operand and the intrinsic does not have an alternative non-const fallback form. - // However, for a case when the operand can take only two possible values - zero and one - // the codegen will use cbnz to do conditional branch. - bool mayNeedBranchTargetReg = (intrin.category == HW_Category_IMM) && !HWIntrinsicInfo::NoJmpTableImm(intrin.id) && - (HWIntrinsicInfo::lookupImmUpperBound(intrin.id, intrinsicTree->gtSIMDSize, - intrinsicTree->gtSIMDBaseType) != 2); + bool mayNeedBranchTargetReg = false; + + if ((intrin.category == HW_Category_IMM) && !HWIntrinsicInfo::NoJmpTableImm(intrin.id)) + { + // We may need to allocate an additional general-purpose register when an intrinsic has a non-const immediate + // operand and the intrinsic does not have an alternative non-const fallback form. + // However, for a case when the operand can take only two possible values - zero and one + // the codegen will use cbnz to do conditional branch. + + int immLowerBound = 0; + int immUpperBound = 0; + + HWIntrinsicInfo::lookupImmBounds(intrin.id, intrinsicTree->gtSIMDSize, intrinsicTree->gtSIMDBaseType, + &immLowerBound, &immUpperBound); + mayNeedBranchTargetReg = (immLowerBound != 0) || (immUpperBound != 1); + } if (mayNeedBranchTargetReg) { @@ -1003,12 +1012,60 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) case NI_AdvSimd_DuplicateSelectedScalarToVector128: case NI_AdvSimd_Extract: case NI_AdvSimd_Insert: + case NI_AdvSimd_ShiftLeftLogical: + case NI_AdvSimd_ShiftLeftLogicalSaturate: + case NI_AdvSimd_ShiftLeftLogicalSaturateScalar: + case NI_AdvSimd_ShiftLeftLogicalSaturateUnsigned: + case NI_AdvSimd_ShiftLeftLogicalSaturateUnsignedScalar: + case NI_AdvSimd_ShiftLeftLogicalScalar: + case NI_AdvSimd_ShiftLeftLogicalWideningLower: + case NI_AdvSimd_ShiftLeftLogicalWideningUpper: + case NI_AdvSimd_ShiftRightArithmetic: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateUnsignedLower: + case NI_AdvSimd_ShiftRightArithmeticRounded: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower: + case NI_AdvSimd_ShiftRightArithmeticRoundedScalar: + case NI_AdvSimd_ShiftRightArithmeticScalar: + case NI_AdvSimd_ShiftRightLogical: + case NI_AdvSimd_ShiftRightLogicalNarrowingLower: + case NI_AdvSimd_ShiftRightLogicalNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightLogicalRounded: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingLower: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingSaturateLower: + case NI_AdvSimd_ShiftRightLogicalRoundedScalar: + case NI_AdvSimd_ShiftRightLogicalScalar: case NI_AdvSimd_Arm64_DuplicateSelectedScalarToVector128: + case NI_AdvSimd_Arm64_ShiftLeftLogicalSaturateScalar: + case NI_AdvSimd_Arm64_ShiftLeftLogicalSaturateUnsignedScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticNarrowingSaturateScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticNarrowingSaturateUnsignedScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticRoundedNarrowingSaturateScalar: + case NI_AdvSimd_Arm64_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar: + case NI_AdvSimd_Arm64_ShiftRightLogicalNarrowingSaturateScalar: + case NI_AdvSimd_Arm64_ShiftRightLogicalRoundedNarrowingSaturateScalar: needBranchTargetReg = !intrin.op2->isContainedIntOrIImmed(); break; case NI_AdvSimd_ExtractVector64: case NI_AdvSimd_ExtractVector128: + case NI_AdvSimd_ShiftRightArithmeticAdd: + case NI_AdvSimd_ShiftRightArithmeticAddScalar: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateUnsignedUpper: + case NI_AdvSimd_ShiftRightArithmeticNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightArithmeticRoundedAdd: + case NI_AdvSimd_ShiftRightArithmeticRoundedAddScalar: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper: + case NI_AdvSimd_ShiftRightArithmeticRoundedNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightLogicalAdd: + case NI_AdvSimd_ShiftRightLogicalAddScalar: + case NI_AdvSimd_ShiftRightLogicalNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightLogicalNarrowingUpper: + case NI_AdvSimd_ShiftRightLogicalRoundedAdd: + case NI_AdvSimd_ShiftRightLogicalRoundedAddScalar: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingSaturateUpper: + case NI_AdvSimd_ShiftRightLogicalRoundedNarrowingUpper: needBranchTargetReg = !intrin.op3->isContainedIntOrIImmed(); break; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_r.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_r.csproj index 81b0fa0de4f7b..ce448a4678881 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_r.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_r.csproj @@ -201,6 +201,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_ro.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_ro.csproj index 1fed9e48643cf..89c0b55761949 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_ro.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/AdvSimd.Arm64_ro.csproj @@ -201,6 +201,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Double.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Double.1.cs index 3de99be40433b..b169f5ce0e6b1 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Double.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Double.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Double); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Double); + private static readonly byte Imm = 1; private static Double[] _data = new Double[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Int64.1.cs index e45da2e0c8e52..aa7692084ecd1 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Int64.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.Int64.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; private static Int64[] _data = new Int64[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.UInt64.1.cs index 662352e5de00e..c958bf8e36de1 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.UInt64.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/DuplicateSelectedScalarToVector128.V128.UInt64.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; private static UInt64[] _data = new UInt64[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64.cs index 3ef5be975b4b2..b77756ecac2d5 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/Program.AdvSimd.Arm64.cs @@ -205,6 +205,57 @@ static Program() ["ReverseElementBits.Vector128.SByte"] = ReverseElementBits_Vector128_SByte, ["ReverseElementBits.Vector64.Byte"] = ReverseElementBits_Vector64_Byte, ["ReverseElementBits.Vector64.SByte"] = ReverseElementBits_Vector64_SByte, + ["ShiftArithmeticRoundedSaturateScalar.Vector64.Int16"] = ShiftArithmeticRoundedSaturateScalar_Vector64_Int16, + ["ShiftArithmeticRoundedSaturateScalar.Vector64.Int32"] = ShiftArithmeticRoundedSaturateScalar_Vector64_Int32, + ["ShiftArithmeticRoundedSaturateScalar.Vector64.SByte"] = ShiftArithmeticRoundedSaturateScalar_Vector64_SByte, + ["ShiftArithmeticSaturateScalar.Vector64.Int16"] = ShiftArithmeticSaturateScalar_Vector64_Int16, + ["ShiftArithmeticSaturateScalar.Vector64.Int32"] = ShiftArithmeticSaturateScalar_Vector64_Int32, + ["ShiftArithmeticSaturateScalar.Vector64.SByte"] = ShiftArithmeticSaturateScalar_Vector64_SByte, + ["ShiftLeftLogicalSaturateScalar.Vector64.Byte.7"] = ShiftLeftLogicalSaturateScalar_Vector64_Byte_7, + ["ShiftLeftLogicalSaturateScalar.Vector64.Int16.15"] = ShiftLeftLogicalSaturateScalar_Vector64_Int16_15, + ["ShiftLeftLogicalSaturateScalar.Vector64.Int32.31"] = ShiftLeftLogicalSaturateScalar_Vector64_Int32_31, + ["ShiftLeftLogicalSaturateScalar.Vector64.SByte.1"] = ShiftLeftLogicalSaturateScalar_Vector64_SByte_1, + ["ShiftLeftLogicalSaturateScalar.Vector64.UInt16.1"] = ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1, + ["ShiftLeftLogicalSaturateScalar.Vector64.UInt32.1"] = ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1, + ["ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int16.5"] = ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5, + ["ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int32.7"] = ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7, + ["ShiftLeftLogicalSaturateUnsignedScalar.Vector64.SByte.3"] = ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3, + ["ShiftLogicalRoundedSaturateScalar.Vector64.Byte"] = ShiftLogicalRoundedSaturateScalar_Vector64_Byte, + ["ShiftLogicalRoundedSaturateScalar.Vector64.Int16"] = ShiftLogicalRoundedSaturateScalar_Vector64_Int16, + ["ShiftLogicalRoundedSaturateScalar.Vector64.Int32"] = ShiftLogicalRoundedSaturateScalar_Vector64_Int32, + ["ShiftLogicalRoundedSaturateScalar.Vector64.SByte"] = ShiftLogicalRoundedSaturateScalar_Vector64_SByte, + ["ShiftLogicalRoundedSaturateScalar.Vector64.UInt16"] = ShiftLogicalRoundedSaturateScalar_Vector64_UInt16, + ["ShiftLogicalRoundedSaturateScalar.Vector64.UInt32"] = ShiftLogicalRoundedSaturateScalar_Vector64_UInt32, + ["ShiftLogicalSaturateScalar.Vector64.Byte"] = ShiftLogicalSaturateScalar_Vector64_Byte, + ["ShiftLogicalSaturateScalar.Vector64.Int16"] = ShiftLogicalSaturateScalar_Vector64_Int16, + ["ShiftLogicalSaturateScalar.Vector64.Int32"] = ShiftLogicalSaturateScalar_Vector64_Int32, + ["ShiftLogicalSaturateScalar.Vector64.SByte"] = ShiftLogicalSaturateScalar_Vector64_SByte, + ["ShiftLogicalSaturateScalar.Vector64.UInt16"] = ShiftLogicalSaturateScalar_Vector64_UInt16, + ["ShiftLogicalSaturateScalar.Vector64.UInt32"] = ShiftLogicalSaturateScalar_Vector64_UInt32, + ["ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int16.16"] = ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16, + ["ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int32.32"] = ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32, + ["ShiftRightArithmeticNarrowingSaturateScalar.Vector64.SByte.8"] = ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8, + ["ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.Byte.3"] = ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3, + ["ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt16.5"] = ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5, + ["ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt32.7"] = ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7, + ["ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int16.32"] = ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32, + ["ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int32.64"] = ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64, + ["ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.SByte.16"] = ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.Byte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1, + ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.Byte.5"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5, + ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int16.7"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7, + ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int32.11"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11, + ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.SByte.3"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3, + ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt16.5"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5, + ["ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt32.7"] = ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7, + ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Byte.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1, + ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int16.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int16_1, + ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int32.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int32_1, + ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.SByte.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_SByte_1, + ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt16.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1, + ["ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt32.1"] = ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1, ["Sqrt.Vector64.Single"] = Sqrt_Vector64_Single, ["Sqrt.Vector128.Double"] = Sqrt_Vector128_Double, ["Sqrt.Vector128.Single"] = Sqrt_Vector128_Single, diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticRoundedSaturateScalar.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticRoundedSaturateScalar.Vector64.Int16.cs new file mode 100644 index 0000000000000..e51ebd01974e7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticRoundedSaturateScalar.Vector64.Int16.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRoundedSaturateScalar_Vector64_Int16() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRoundedSaturateScalar_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int16 testClass) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int16(); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticRoundedSaturateScalar.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticRoundedSaturateScalar.Vector64.Int32.cs new file mode 100644 index 0000000000000..9f6ad9c149212 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticRoundedSaturateScalar.Vector64.Int32.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRoundedSaturateScalar_Vector64_Int32() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRoundedSaturateScalar_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int32 testClass) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int32(); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticRoundedSaturateScalar.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticRoundedSaturateScalar.Vector64.SByte.cs new file mode 100644 index 0000000000000..39f57a814afe8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticRoundedSaturateScalar.Vector64.SByte.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRoundedSaturateScalar_Vector64_SByte() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRoundedSaturateScalar_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_SByte testClass) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_SByte(); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((SByte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftArithmeticRoundedSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticSaturateScalar.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticSaturateScalar.Vector64.Int16.cs new file mode 100644 index 0000000000000..d81b16d685d5f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticSaturateScalar.Vector64.Int16.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticSaturateScalar_Vector64_Int16() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticSaturateScalar_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int16 testClass) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftArithmeticSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftArithmeticSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int16(); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftArithmeticSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticSaturateScalar.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticSaturateScalar.Vector64.Int32.cs new file mode 100644 index 0000000000000..3d7ce320d0d36 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticSaturateScalar.Vector64.Int32.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticSaturateScalar_Vector64_Int32() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticSaturateScalar_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int32 testClass) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftArithmeticSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftArithmeticSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int32(); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftArithmeticSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticSaturateScalar.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticSaturateScalar.Vector64.SByte.cs new file mode 100644 index 0000000000000..1d9646ea270ef --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftArithmeticSaturateScalar.Vector64.SByte.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticSaturateScalar_Vector64_SByte() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticSaturateScalar_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_SByte testClass) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftArithmeticSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftArithmeticSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_SByte(); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((SByte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftArithmeticSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.Byte.7.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.Byte.7.cs new file mode 100644 index 0000000000000..9898c2ed2f7a6 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.Byte.7.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateScalar_Vector64_Byte_7() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Byte_7(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Byte_7 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Byte_7 testClass) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(_fld, 7); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Byte_7 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Byte*)(pFld)), + 7 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 7; + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Byte_7() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Byte_7() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + _clsVar, + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Byte*)(pClsVar)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Byte_7(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Byte_7(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Byte*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(_fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Byte*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Byte*)(&test._fld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar)}(Vector64, 7): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.Int16.15.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.Int16.15.cs new file mode 100644 index 0000000000000..0dfb9d9d160bc --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.Int16.15.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateScalar_Vector64_Int16_15() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int16_15(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int16_15 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int16_15 testClass) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(_fld, 15); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int16_15 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 15 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 15; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int16_15() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int16_15() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)15 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)15 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + _clsVar, + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(firstOp, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(firstOp, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int16_15(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(test._fld, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int16_15(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(_fld, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(test._fld, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar)}(Vector64, 15): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.Int32.31.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.Int32.31.cs new file mode 100644 index 0000000000000..27a1c7f270356 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.Int32.31.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateScalar_Vector64_Int32_31() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int32_31(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int32_31 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int32_31 testClass) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(_fld, 31); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int32_31 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 31 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 31; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int32_31() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int32_31() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + _clsVar, + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(firstOp, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(firstOp, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int32_31(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(test._fld, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int32_31(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(_fld, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(test._fld, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar)}(Vector64, 31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..0f49096fe10e9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.SByte.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateScalar_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_SByte_1 testClass) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_SByte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_SByte_1(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_SByte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..200e3b5ad23b0 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.UInt16.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..bff709b139225 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateScalar.Vector64.UInt32.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int16.5.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int16.5.cs new file mode 100644 index 0000000000000..552b63a5892a3 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int16.5.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5 testClass) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(_fld, 5); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 5 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 5; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)5 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)5 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + _clsVar, + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(firstOp, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(firstOp, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(test._fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(_fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(test._fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar)}(Vector64, 5): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int32.7.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int32.7.cs new file mode 100644 index 0000000000000..187916162c85f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int32.7.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7 testClass) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(_fld, 7); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 7 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 7; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + _clsVar, + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(_fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar)}(Vector64, 7): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.SByte.3.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.SByte.3.cs new file mode 100644 index 0000000000000..a8d31f1d364ea --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.SByte.3.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3 testClass) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(_fld, 3); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((SByte*)(pFld)), + 3 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 3; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)3 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + (byte)3 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + _clsVar, + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((SByte*)(pClsVar)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(firstOp, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(firstOp, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(test._fld, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((SByte*)(pFld)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(_fld, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((SByte*)(pFld)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar(test._fld, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((SByte*)(&test._fld)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLeftLogicalSaturateUnsignedScalar)}(Vector64, 3): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.Byte.cs new file mode 100644 index 0000000000000..ad9f8e72d368c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.Byte.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturateScalar_Vector64_Byte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturateScalar_Vector64_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, SByte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Byte testClass) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Byte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Byte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Byte(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Byte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Byte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] left, SByte[] right, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.Int16.cs new file mode 100644 index 0000000000000..20143758c29f9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.Int16.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturateScalar_Vector64_Int16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturateScalar_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int16 testClass) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int16(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.Int32.cs new file mode 100644 index 0000000000000..92071ffef73ea --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.Int32.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturateScalar_Vector64_Int32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturateScalar_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int32 testClass) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int32(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.SByte.cs new file mode 100644 index 0000000000000..e8511d443045c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.SByte.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturateScalar_Vector64_SByte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturateScalar_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_SByte testClass) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_SByte(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((SByte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.UInt16.cs new file mode 100644 index 0000000000000..0663f9fddee97 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.UInt16.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturateScalar_Vector64_UInt16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturateScalar_Vector64_UInt16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, Int16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt16 testClass) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt16(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] left, Int16[] right, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.UInt32.cs new file mode 100644 index 0000000000000..12b7c1f1b565a --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalRoundedSaturateScalar.Vector64.UInt32.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturateScalar_Vector64_UInt32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturateScalar_Vector64_UInt32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, Int32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt32 testClass) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt32(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] left, Int32[] right, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLogicalRoundedSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.Byte.cs new file mode 100644 index 0000000000000..cfa1bcea9697a --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.Byte.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturateScalar_Vector64_Byte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturateScalar_Vector64_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, SByte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Byte testClass) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Byte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Byte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Byte(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Byte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Byte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] left, SByte[] right, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.Int16.cs new file mode 100644 index 0000000000000..db01153ab4159 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.Int16.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturateScalar_Vector64_Int16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturateScalar_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int16 testClass) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int16(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.Int32.cs new file mode 100644 index 0000000000000..6ffcf55329a5d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.Int32.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturateScalar_Vector64_Int32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturateScalar_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int32 testClass) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int32(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.SByte.cs new file mode 100644 index 0000000000000..2e618dfaec8d4 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.SByte.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturateScalar_Vector64_SByte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturateScalar_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_SByte testClass) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_SByte(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((SByte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.UInt16.cs new file mode 100644 index 0000000000000..d0a505b457d59 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.UInt16.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturateScalar_Vector64_UInt16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturateScalar_Vector64_UInt16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, Int16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt16 testClass) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt16(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] left, Int16[] right, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.UInt32.cs new file mode 100644 index 0000000000000..1c64baf6e8d1e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftLogicalSaturateScalar.Vector64.UInt32.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturateScalar_Vector64_UInt32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturateScalar_Vector64_UInt32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, Int32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt32 testClass) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt32(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] left, Int32[] right, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftLogicalSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int16.16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int16.16.cs new file mode 100644 index 0000000000000..5eb798d368167 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int16.16.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16 testClass) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(_fld, 16); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 16 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 16; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + _clsVar, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(_fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar)}(Vector64, 16): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int32.32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int32.32.cs new file mode 100644 index 0000000000000..5d8f85004073a --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateScalar.Vector64.Int32.32.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32 testClass) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(_fld, 32); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 32 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 32; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + _clsVar, + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(_fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar)}(Vector64, 32): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateScalar.Vector64.SByte.8.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateScalar.Vector64.SByte.8.cs new file mode 100644 index 0000000000000..daab20f1b12de --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateScalar.Vector64.SByte.8.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8 testClass) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(_fld, 8); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 8 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 8; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)8 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)8 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + _clsVar, + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(firstOp, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(firstOp, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(test._fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(_fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar(test._fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateScalar)}(Vector64, 8): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.Byte.3.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.Byte.3.cs new file mode 100644 index 0000000000000..9f5359e268095 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.Byte.3.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3 testClass) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(_fld, 3); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 3 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 3; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)3 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)3 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + _clsVar, + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(firstOp, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(firstOp, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(test._fld, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(_fld, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(test._fld, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar)}(Vector64, 3): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt16.5.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt16.5.cs new file mode 100644 index 0000000000000..434cea9dcaf7c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt16.5.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5 testClass) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(_fld, 5); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 5 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 5; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)5 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)5 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + _clsVar, + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(firstOp, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(firstOp, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(test._fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(_fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(test._fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar)}(Vector64, 5): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt32.7.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt32.7.cs new file mode 100644 index 0000000000000..86c7c041a9525 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticNarrowingSaturateUnsignedScalar.Vector64.UInt32.7.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7 testClass) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(_fld, 7); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 7 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 7; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + _clsVar, + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(_fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightArithmeticNarrowingSaturateUnsignedScalar)}(Vector64, 7): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int16.32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int16.32.cs new file mode 100644 index 0000000000000..98b04fbbce92a --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int16.32.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32 testClass) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(_fld, 16); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 16 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 16; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + _clsVar, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(firstOp, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(_fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(test._fld, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar)}(Vector64, 16): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int32.64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int32.64.cs new file mode 100644 index 0000000000000..bf7f10cda4efb --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.Int32.64.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64 testClass) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(_fld, 32); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 32 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 32; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + (byte)32 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + _clsVar, + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(firstOp, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(_fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(test._fld, 32); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld)), + 32 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar)}(Vector64, 32): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.SByte.16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.SByte.16.cs new file mode 100644 index 0000000000000..837dda2f3dad6 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateScalar.Vector64.SByte.16.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16 testClass) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(_fld, 8); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 8 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 8; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)8 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)8 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + _clsVar, + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(firstOp, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(firstOp, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(test._fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(_fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar(test._fld, 8); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 8 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateScalar)}(Vector64, 8): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..2a46e7220c734 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.Byte.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1 testClass) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(_fld, 7); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 7 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 7; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + _clsVar, + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(_fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar)}(Vector64, 7): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..20d8e9468a086 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt16.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(_fld, 15); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 15 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 15; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)15 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)15 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + _clsVar, + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(firstOp, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(firstOp, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(test._fld, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(_fld, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(test._fld, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar)}(Vector64, 15): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..a8d369928b0b3 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar.Vector64.UInt32.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(_fld, 31); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 31 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 31; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + (byte)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + _clsVar, + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(firstOp, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(firstOp, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(test._fld, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(_fld, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(test._fld, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar)}(Vector64, 31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.Byte.5.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.Byte.5.cs new file mode 100644 index 0000000000000..d93c5c41e333c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.Byte.5.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5 testClass) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(_fld, 7); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 7 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 7; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + _clsVar, + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pClsVar)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(_fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(&test._fld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar)}(Vector64, 7): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int16.7.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int16.7.cs new file mode 100644 index 0000000000000..bbed7640cf233 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int16.7.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7 testClass) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(_fld, 15); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 15 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 15; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)15 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)15 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + _clsVar, + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(firstOp, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(firstOp, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(test._fld, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(_fld, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(test._fld, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar)}(Vector64, 15): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int32.11.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int32.11.cs new file mode 100644 index 0000000000000..f723d24d6e8a6 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.Int32.11.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11 testClass) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(_fld, 31); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 31 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 31; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + (byte)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + _clsVar, + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(firstOp, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(firstOp, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(test._fld, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(_fld, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(test._fld, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar)}(Vector64, 31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.SByte.3.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.SByte.3.cs new file mode 100644 index 0000000000000..26b8eef08c981 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.SByte.3.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3 testClass) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(_fld, 7); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 7 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 7; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + _clsVar, + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(_fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar)}(Vector64, 7): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt16.5.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt16.5.cs new file mode 100644 index 0000000000000..e0f63f4958e09 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt16.5.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5 testClass) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(_fld, 15); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 15 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 15; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)15 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + (byte)15 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + _clsVar, + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pClsVar)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(firstOp, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(firstOp, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(test._fld, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(_fld, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(test._fld, 15); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(&test._fld)), + 15 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar)}(Vector64, 15): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt32.7.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt32.7.cs new file mode 100644 index 0000000000000..7aad4513eee3b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalNarrowingSaturateScalar.Vector64.UInt32.7.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7 testClass) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(_fld, 31); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 31 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 31; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)), + (byte)31 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + _clsVar, + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pClsVar)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(firstOp, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(firstOp, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(test._fld, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(_fld, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar(test._fld, 31); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(&test._fld)), + 31 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightLogicalNarrowingSaturateScalar)}(Vector64, 31): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..d20fc959a862e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Byte.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1 testClass) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(_fld, 3); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 3 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 3; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)3 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + (byte)3 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + _clsVar, + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pClsVar)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(firstOp, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(firstOp, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(test._fld, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(_fld, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(test._fld, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt16*)(&test._fld)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar)}(Vector64, 3): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..3d6e9e01ea4a9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int16.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int16_1 testClass) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(_fld, 5); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 5 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 5; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)5 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)5 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + _clsVar, + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(firstOp, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(firstOp, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int16_1(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(test._fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(_fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(pFld)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(test._fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar)}(Vector64, 5): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..c888b3177953c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.Int32.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int32_1 testClass) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(_fld, 7); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 7 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 7; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + _clsVar, + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int32_1(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(_fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar)}(Vector64, 7): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..d2b9d58955666 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.SByte.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_SByte_1 testClass) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(_fld, 3); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_SByte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 3 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 3; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)3 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)3 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + _clsVar, + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(firstOp, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(firstOp, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_SByte_1(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(test._fld, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_SByte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(_fld, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(pFld)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(test._fld, 3); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 3 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar)}(Vector64, 3): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..ed3f2d6b72439 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt16.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(_fld, 5); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 5 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 5; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)5 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + (byte)5 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + _clsVar, + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pClsVar)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(firstOp, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(firstOp, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(test._fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(_fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(test._fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt32*)(&test._fld)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar)}(Vector64, 5): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..6c650928ce485 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd.Arm64/ShiftRightLogicalRoundedNarrowingSaturateScalar.Vector64.UInt32.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(_fld, 7); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 7 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 7; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.Arm64.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)), + (byte)7 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + _clsVar, + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pClsVar)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(firstOp, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(_fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar(test._fld, 7); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(&test._fld)), + 7 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.ShiftRightLogicalRoundedNarrowingSaturateScalar)}(Vector64, 7): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj index ccfb426682ad1..7f2d981717c87 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_r.csproj @@ -762,6 +762,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -892,6 +1213,18 @@ + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj index de83f25f8e551..a6abd34f4f1ea 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/AdvSimd_ro.csproj @@ -762,6 +762,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -892,6 +1213,18 @@ + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Byte.8.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Byte.8.cs index f15b8ac49234e..cf9cd8e290ceb 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Byte.8.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Byte.8.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 8; private static Byte[] _data = new Byte[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int16.4.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int16.4.cs index 8765c46f43a3f..a1fa2b1b9b09e 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int16.4.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int16.4.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 4; private static Int16[] _data = new Int16[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int32.2.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int32.2.cs index aaa7c39fae2dd..60a88d0d8dcd8 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int32.2.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Int32.2.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 2; private static Int32[] _data = new Int32[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.SByte.8.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.SByte.8.cs index b0309d47d6bf1..a57c8b9184bf3 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.SByte.8.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.SByte.8.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 8; private static SByte[] _data = new SByte[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Single.2.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Single.2.cs index ba32b9e060cea..e6378b48f8972 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Single.2.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.Single.2.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Single); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Single); + private static readonly byte Imm = 2; private static Single[] _data = new Single[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt16.4.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt16.4.cs index dffc8bb44d774..e88f362ef45ba 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt16.4.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt16.4.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 4; private static UInt16[] _data = new UInt16[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt32.2.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt32.2.cs index d69e9052b2fc3..b41fc8315838c 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt32.2.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V128.UInt32.2.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 2; private static UInt32[] _data = new UInt32[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Byte.1.cs index cf194dad18516..bf906543afbc0 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Byte.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Byte.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; private static Byte[] _data = new Byte[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int16.1.cs index 791ebe4c671e0..0719e0b733efd 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int16.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int16.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; private static Int16[] _data = new Int16[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int32.1.cs index bf54562526a25..1ec386a4d2669 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int32.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Int32.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; private static Int32[] _data = new Int32[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.SByte.1.cs index 6c837d1d8f684..6f4e005cd56fb 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.SByte.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.SByte.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; private static SByte[] _data = new SByte[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Single.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Single.1.cs index c1700350e048d..f4868930b7b4e 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Single.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.Single.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Single); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Single); + private static readonly byte Imm = 1; private static Single[] _data = new Single[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt16.1.cs index 6cea89d585e46..e961e091b660c 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt16.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt16.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; private static UInt16[] _data = new UInt16[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt32.1.cs index 015062711019c..b68310f9d6225 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt32.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector128.V64.UInt32.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; private static UInt32[] _data = new UInt32[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Byte.8.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Byte.8.cs index 1742b87a96d55..fecce603592ff 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Byte.8.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Byte.8.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 8; private static Byte[] _data = new Byte[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int16.4.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int16.4.cs index 37f41d0b040a9..3215c5acbba28 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int16.4.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int16.4.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 4; private static Int16[] _data = new Int16[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int32.2.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int32.2.cs index 2e65fe0387f25..07b58d8aee742 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int32.2.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Int32.2.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 2; private static Int32[] _data = new Int32[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.SByte.8.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.SByte.8.cs index 1e06e79d7fd17..0e795bdf5716e 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.SByte.8.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.SByte.8.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 8; private static SByte[] _data = new SByte[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Single.2.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Single.2.cs index 78acaf5c71a13..aab9d496e1439 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Single.2.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.Single.2.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Single); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Single); + private static readonly byte Imm = 2; private static Single[] _data = new Single[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt16.4.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt16.4.cs index bccbfcc568194..afa70cf115708 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt16.4.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt16.4.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 4; private static UInt16[] _data = new UInt16[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt32.2.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt32.2.cs index c996ec79f20dd..c6c51495eb00f 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt32.2.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V128.UInt32.2.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 2; private static UInt32[] _data = new UInt32[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Byte.1.cs index c00b1017bc64d..e3cfeffb5da8a 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Byte.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Byte.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; private static Byte[] _data = new Byte[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int16.1.cs index 916e8c9301cec..3d41d9be238ef 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int16.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int16.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; private static Int16[] _data = new Int16[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int32.1.cs index feea52b04ec89..711584eb3964e 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int32.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Int32.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; private static Int32[] _data = new Int32[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.SByte.1.cs index 70d504eaf1649..7d8c97b4f785b 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.SByte.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.SByte.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; private static SByte[] _data = new SByte[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Single.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Single.1.cs index 4c16760a53829..4afa6ce2cddf6 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Single.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.Single.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Single); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Single); + private static readonly byte Imm = 1; private static Single[] _data = new Single[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt16.1.cs index 809df830e91ba..3323e524af933 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt16.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt16.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; private static UInt16[] _data = new UInt16[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt32.1.cs index 67852ad55787d..cbbca5b59655d 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt32.1.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/DuplicateSelectedScalarToVector64.V64.UInt32.1.cs @@ -198,6 +198,7 @@ public void RunStructFldScenario_Load(ImmUnaryOpTest__DuplicateSelectedScalarToV private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; private static UInt32[] _data = new UInt32[Op1ElementCount]; diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs index 311885d4f1d37..636a26238b564 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/Program.AdvSimd.cs @@ -766,6 +766,327 @@ static Program() ["ReciprocalSquareRootStep.Vector128.Single"] = ReciprocalSquareRootStep_Vector128_Single, ["ReciprocalStep.Vector64.Single"] = ReciprocalStep_Vector64_Single, ["ReciprocalStep.Vector128.Single"] = ReciprocalStep_Vector128_Single, + ["ShiftArithmetic.Vector64.Int16"] = ShiftArithmetic_Vector64_Int16, + ["ShiftArithmetic.Vector64.Int32"] = ShiftArithmetic_Vector64_Int32, + ["ShiftArithmetic.Vector64.SByte"] = ShiftArithmetic_Vector64_SByte, + ["ShiftArithmetic.Vector128.Int16"] = ShiftArithmetic_Vector128_Int16, + ["ShiftArithmetic.Vector128.Int32"] = ShiftArithmetic_Vector128_Int32, + ["ShiftArithmetic.Vector128.Int64"] = ShiftArithmetic_Vector128_Int64, + ["ShiftArithmetic.Vector128.SByte"] = ShiftArithmetic_Vector128_SByte, + ["ShiftArithmeticRounded.Vector64.Int16"] = ShiftArithmeticRounded_Vector64_Int16, + ["ShiftArithmeticRounded.Vector64.Int32"] = ShiftArithmeticRounded_Vector64_Int32, + ["ShiftArithmeticRounded.Vector64.SByte"] = ShiftArithmeticRounded_Vector64_SByte, + ["ShiftArithmeticRounded.Vector128.Int16"] = ShiftArithmeticRounded_Vector128_Int16, + ["ShiftArithmeticRounded.Vector128.Int32"] = ShiftArithmeticRounded_Vector128_Int32, + ["ShiftArithmeticRounded.Vector128.Int64"] = ShiftArithmeticRounded_Vector128_Int64, + ["ShiftArithmeticRounded.Vector128.SByte"] = ShiftArithmeticRounded_Vector128_SByte, + ["ShiftArithmeticRoundedSaturate.Vector64.Int16"] = ShiftArithmeticRoundedSaturate_Vector64_Int16, + ["ShiftArithmeticRoundedSaturate.Vector64.Int32"] = ShiftArithmeticRoundedSaturate_Vector64_Int32, + ["ShiftArithmeticRoundedSaturate.Vector64.SByte"] = ShiftArithmeticRoundedSaturate_Vector64_SByte, + ["ShiftArithmeticRoundedSaturate.Vector128.Int16"] = ShiftArithmeticRoundedSaturate_Vector128_Int16, + ["ShiftArithmeticRoundedSaturate.Vector128.Int32"] = ShiftArithmeticRoundedSaturate_Vector128_Int32, + ["ShiftArithmeticRoundedSaturate.Vector128.Int64"] = ShiftArithmeticRoundedSaturate_Vector128_Int64, + ["ShiftArithmeticRoundedSaturate.Vector128.SByte"] = ShiftArithmeticRoundedSaturate_Vector128_SByte, + ["ShiftArithmeticRoundedSaturateScalar.Vector64.Int64"] = ShiftArithmeticRoundedSaturateScalar_Vector64_Int64, + ["ShiftArithmeticRoundedScalar.Vector64.Int64"] = ShiftArithmeticRoundedScalar_Vector64_Int64, + ["ShiftArithmeticSaturate.Vector64.Int16"] = ShiftArithmeticSaturate_Vector64_Int16, + ["ShiftArithmeticSaturate.Vector64.Int32"] = ShiftArithmeticSaturate_Vector64_Int32, + ["ShiftArithmeticSaturate.Vector64.SByte"] = ShiftArithmeticSaturate_Vector64_SByte, + ["ShiftArithmeticSaturate.Vector128.Int16"] = ShiftArithmeticSaturate_Vector128_Int16, + ["ShiftArithmeticSaturate.Vector128.Int32"] = ShiftArithmeticSaturate_Vector128_Int32, + ["ShiftArithmeticSaturate.Vector128.Int64"] = ShiftArithmeticSaturate_Vector128_Int64, + ["ShiftArithmeticSaturate.Vector128.SByte"] = ShiftArithmeticSaturate_Vector128_SByte, + ["ShiftArithmeticSaturateScalar.Vector64.Int64"] = ShiftArithmeticSaturateScalar_Vector64_Int64, + ["ShiftArithmeticScalar.Vector64.Int64"] = ShiftArithmeticScalar_Vector64_Int64, + ["ShiftLeftLogical.Vector64.Byte.1"] = ShiftLeftLogical_Vector64_Byte_1, + ["ShiftLeftLogical.Vector64.Int16.1"] = ShiftLeftLogical_Vector64_Int16_1, + ["ShiftLeftLogical.Vector64.Int32.1"] = ShiftLeftLogical_Vector64_Int32_1, + ["ShiftLeftLogical.Vector64.SByte.1"] = ShiftLeftLogical_Vector64_SByte_1, + ["ShiftLeftLogical.Vector64.UInt16.1"] = ShiftLeftLogical_Vector64_UInt16_1, + ["ShiftLeftLogical.Vector64.UInt32.1"] = ShiftLeftLogical_Vector64_UInt32_1, + ["ShiftLeftLogical.Vector128.Byte.1"] = ShiftLeftLogical_Vector128_Byte_1, + ["ShiftLeftLogical.Vector128.Int16.1"] = ShiftLeftLogical_Vector128_Int16_1, + ["ShiftLeftLogical.Vector128.Int64.1"] = ShiftLeftLogical_Vector128_Int64_1, + ["ShiftLeftLogical.Vector128.SByte.1"] = ShiftLeftLogical_Vector128_SByte_1, + ["ShiftLeftLogical.Vector128.UInt16.1"] = ShiftLeftLogical_Vector128_UInt16_1, + ["ShiftLeftLogical.Vector128.UInt32.1"] = ShiftLeftLogical_Vector128_UInt32_1, + ["ShiftLeftLogical.Vector128.UInt64.1"] = ShiftLeftLogical_Vector128_UInt64_1, + ["ShiftLeftLogicalSaturate.Vector64.Byte.1"] = ShiftLeftLogicalSaturate_Vector64_Byte_1, + ["ShiftLeftLogicalSaturate.Vector64.Int16.1"] = ShiftLeftLogicalSaturate_Vector64_Int16_1, + ["ShiftLeftLogicalSaturate.Vector64.Int32.1"] = ShiftLeftLogicalSaturate_Vector64_Int32_1, + ["ShiftLeftLogicalSaturate.Vector64.SByte.1"] = ShiftLeftLogicalSaturate_Vector64_SByte_1, + ["ShiftLeftLogicalSaturate.Vector64.UInt16.1"] = ShiftLeftLogicalSaturate_Vector64_UInt16_1, + ["ShiftLeftLogicalSaturate.Vector64.UInt32.1"] = ShiftLeftLogicalSaturate_Vector64_UInt32_1, + ["ShiftLeftLogicalSaturate.Vector128.Byte.1"] = ShiftLeftLogicalSaturate_Vector128_Byte_1, + ["ShiftLeftLogicalSaturate.Vector128.Int16.1"] = ShiftLeftLogicalSaturate_Vector128_Int16_1, + ["ShiftLeftLogicalSaturate.Vector128.Int32.1"] = ShiftLeftLogicalSaturate_Vector128_Int32_1, + ["ShiftLeftLogicalSaturate.Vector128.Int64.1"] = ShiftLeftLogicalSaturate_Vector128_Int64_1, + ["ShiftLeftLogicalSaturate.Vector128.SByte.1"] = ShiftLeftLogicalSaturate_Vector128_SByte_1, + ["ShiftLeftLogicalSaturate.Vector128.UInt16.1"] = ShiftLeftLogicalSaturate_Vector128_UInt16_1, + ["ShiftLeftLogicalSaturate.Vector128.UInt32.1"] = ShiftLeftLogicalSaturate_Vector128_UInt32_1, + ["ShiftLeftLogicalSaturate.Vector128.UInt64.1"] = ShiftLeftLogicalSaturate_Vector128_UInt64_1, + ["ShiftLeftLogicalSaturateScalar.Vector64.Int64.1"] = ShiftLeftLogicalSaturateScalar_Vector64_Int64_1, + ["ShiftLeftLogicalSaturateScalar.Vector64.UInt64.1"] = ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector64.Int16.1"] = ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector64.Int32.1"] = ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector64.SByte.1"] = ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector128.Int16.1"] = ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector128.Int32.1"] = ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector128.Int64.1"] = ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1, + ["ShiftLeftLogicalSaturateUnsigned.Vector128.SByte.1"] = ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1, + ["ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int64.1"] = ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1, + ["ShiftLeftLogicalScalar.Vector64.Int64.1"] = ShiftLeftLogicalScalar_Vector64_Int64_1, + ["ShiftLeftLogicalScalar.Vector64.UInt64.1"] = ShiftLeftLogicalScalar_Vector64_UInt64_1, + ["ShiftLeftLogicalWideningLower.Vector64.Byte.1"] = ShiftLeftLogicalWideningLower_Vector64_Byte_1, + ["ShiftLeftLogicalWideningLower.Vector64.Int16.1"] = ShiftLeftLogicalWideningLower_Vector64_Int16_1, + ["ShiftLeftLogicalWideningLower.Vector64.Int32.1"] = ShiftLeftLogicalWideningLower_Vector64_Int32_1, + ["ShiftLeftLogicalWideningLower.Vector64.SByte.1"] = ShiftLeftLogicalWideningLower_Vector64_SByte_1, + ["ShiftLeftLogicalWideningLower.Vector64.UInt16.1"] = ShiftLeftLogicalWideningLower_Vector64_UInt16_1, + ["ShiftLeftLogicalWideningLower.Vector64.UInt32.1"] = ShiftLeftLogicalWideningLower_Vector64_UInt32_1, + ["ShiftLeftLogicalWideningUpper.Vector128.Byte.1"] = ShiftLeftLogicalWideningUpper_Vector128_Byte_1, + ["ShiftLeftLogicalWideningUpper.Vector128.Int16.1"] = ShiftLeftLogicalWideningUpper_Vector128_Int16_1, + ["ShiftLeftLogicalWideningUpper.Vector128.Int32.1"] = ShiftLeftLogicalWideningUpper_Vector128_Int32_1, + ["ShiftLeftLogicalWideningUpper.Vector128.SByte.1"] = ShiftLeftLogicalWideningUpper_Vector128_SByte_1, + ["ShiftLeftLogicalWideningUpper.Vector128.UInt16.1"] = ShiftLeftLogicalWideningUpper_Vector128_UInt16_1, + ["ShiftLeftLogicalWideningUpper.Vector128.UInt32.1"] = ShiftLeftLogicalWideningUpper_Vector128_UInt32_1, + ["ShiftLogical.Vector64.Byte"] = ShiftLogical_Vector64_Byte, + ["ShiftLogical.Vector64.Int16"] = ShiftLogical_Vector64_Int16, + ["ShiftLogical.Vector64.Int32"] = ShiftLogical_Vector64_Int32, + ["ShiftLogical.Vector64.SByte"] = ShiftLogical_Vector64_SByte, + ["ShiftLogical.Vector64.UInt16"] = ShiftLogical_Vector64_UInt16, + ["ShiftLogical.Vector64.UInt32"] = ShiftLogical_Vector64_UInt32, + ["ShiftLogical.Vector128.Byte"] = ShiftLogical_Vector128_Byte, + ["ShiftLogical.Vector128.Int16"] = ShiftLogical_Vector128_Int16, + ["ShiftLogical.Vector128.Int32"] = ShiftLogical_Vector128_Int32, + ["ShiftLogical.Vector128.Int64"] = ShiftLogical_Vector128_Int64, + ["ShiftLogical.Vector128.SByte"] = ShiftLogical_Vector128_SByte, + ["ShiftLogical.Vector128.UInt16"] = ShiftLogical_Vector128_UInt16, + ["ShiftLogical.Vector128.UInt32"] = ShiftLogical_Vector128_UInt32, + ["ShiftLogical.Vector128.UInt64"] = ShiftLogical_Vector128_UInt64, + ["ShiftLogicalRounded.Vector64.Byte"] = ShiftLogicalRounded_Vector64_Byte, + ["ShiftLogicalRounded.Vector64.Int16"] = ShiftLogicalRounded_Vector64_Int16, + ["ShiftLogicalRounded.Vector64.Int32"] = ShiftLogicalRounded_Vector64_Int32, + ["ShiftLogicalRounded.Vector64.SByte"] = ShiftLogicalRounded_Vector64_SByte, + ["ShiftLogicalRounded.Vector64.UInt16"] = ShiftLogicalRounded_Vector64_UInt16, + ["ShiftLogicalRounded.Vector64.UInt32"] = ShiftLogicalRounded_Vector64_UInt32, + ["ShiftLogicalRounded.Vector128.Byte"] = ShiftLogicalRounded_Vector128_Byte, + ["ShiftLogicalRounded.Vector128.Int16"] = ShiftLogicalRounded_Vector128_Int16, + ["ShiftLogicalRounded.Vector128.Int32"] = ShiftLogicalRounded_Vector128_Int32, + ["ShiftLogicalRounded.Vector128.Int64"] = ShiftLogicalRounded_Vector128_Int64, + ["ShiftLogicalRounded.Vector128.SByte"] = ShiftLogicalRounded_Vector128_SByte, + ["ShiftLogicalRounded.Vector128.UInt16"] = ShiftLogicalRounded_Vector128_UInt16, + ["ShiftLogicalRounded.Vector128.UInt32"] = ShiftLogicalRounded_Vector128_UInt32, + ["ShiftLogicalRounded.Vector128.UInt64"] = ShiftLogicalRounded_Vector128_UInt64, + ["ShiftLogicalRoundedSaturate.Vector64.Byte"] = ShiftLogicalRoundedSaturate_Vector64_Byte, + ["ShiftLogicalRoundedSaturate.Vector64.Int16"] = ShiftLogicalRoundedSaturate_Vector64_Int16, + ["ShiftLogicalRoundedSaturate.Vector64.Int32"] = ShiftLogicalRoundedSaturate_Vector64_Int32, + ["ShiftLogicalRoundedSaturate.Vector64.SByte"] = ShiftLogicalRoundedSaturate_Vector64_SByte, + ["ShiftLogicalRoundedSaturate.Vector64.UInt16"] = ShiftLogicalRoundedSaturate_Vector64_UInt16, + ["ShiftLogicalRoundedSaturate.Vector64.UInt32"] = ShiftLogicalRoundedSaturate_Vector64_UInt32, + ["ShiftLogicalRoundedSaturate.Vector128.Byte"] = ShiftLogicalRoundedSaturate_Vector128_Byte, + ["ShiftLogicalRoundedSaturate.Vector128.Int16"] = ShiftLogicalRoundedSaturate_Vector128_Int16, + ["ShiftLogicalRoundedSaturate.Vector128.Int32"] = ShiftLogicalRoundedSaturate_Vector128_Int32, + ["ShiftLogicalRoundedSaturate.Vector128.Int64"] = ShiftLogicalRoundedSaturate_Vector128_Int64, + ["ShiftLogicalRoundedSaturate.Vector128.SByte"] = ShiftLogicalRoundedSaturate_Vector128_SByte, + ["ShiftLogicalRoundedSaturate.Vector128.UInt16"] = ShiftLogicalRoundedSaturate_Vector128_UInt16, + ["ShiftLogicalRoundedSaturate.Vector128.UInt32"] = ShiftLogicalRoundedSaturate_Vector128_UInt32, + ["ShiftLogicalRoundedSaturate.Vector128.UInt64"] = ShiftLogicalRoundedSaturate_Vector128_UInt64, + ["ShiftLogicalRoundedSaturateScalar.Vector64.Int64"] = ShiftLogicalRoundedSaturateScalar_Vector64_Int64, + ["ShiftLogicalRoundedSaturateScalar.Vector64.UInt64"] = ShiftLogicalRoundedSaturateScalar_Vector64_UInt64, + ["ShiftLogicalRoundedScalar.Vector64.Int64"] = ShiftLogicalRoundedScalar_Vector64_Int64, + ["ShiftLogicalRoundedScalar.Vector64.UInt64"] = ShiftLogicalRoundedScalar_Vector64_UInt64, + ["ShiftLogicalSaturate.Vector64.Byte"] = ShiftLogicalSaturate_Vector64_Byte, + ["ShiftLogicalSaturate.Vector64.Int16"] = ShiftLogicalSaturate_Vector64_Int16, + ["ShiftLogicalSaturate.Vector64.Int32"] = ShiftLogicalSaturate_Vector64_Int32, + ["ShiftLogicalSaturate.Vector64.SByte"] = ShiftLogicalSaturate_Vector64_SByte, + ["ShiftLogicalSaturate.Vector64.UInt16"] = ShiftLogicalSaturate_Vector64_UInt16, + ["ShiftLogicalSaturate.Vector64.UInt32"] = ShiftLogicalSaturate_Vector64_UInt32, + ["ShiftLogicalSaturate.Vector128.Byte"] = ShiftLogicalSaturate_Vector128_Byte, + ["ShiftLogicalSaturate.Vector128.Int16"] = ShiftLogicalSaturate_Vector128_Int16, + ["ShiftLogicalSaturate.Vector128.Int32"] = ShiftLogicalSaturate_Vector128_Int32, + ["ShiftLogicalSaturate.Vector128.Int64"] = ShiftLogicalSaturate_Vector128_Int64, + ["ShiftLogicalSaturate.Vector128.SByte"] = ShiftLogicalSaturate_Vector128_SByte, + ["ShiftLogicalSaturate.Vector128.UInt16"] = ShiftLogicalSaturate_Vector128_UInt16, + ["ShiftLogicalSaturate.Vector128.UInt32"] = ShiftLogicalSaturate_Vector128_UInt32, + ["ShiftLogicalSaturate.Vector128.UInt64"] = ShiftLogicalSaturate_Vector128_UInt64, + ["ShiftLogicalSaturateScalar.Vector64.Int64"] = ShiftLogicalSaturateScalar_Vector64_Int64, + ["ShiftLogicalSaturateScalar.Vector64.UInt64"] = ShiftLogicalSaturateScalar_Vector64_UInt64, + ["ShiftLogicalScalar.Vector64.Int64"] = ShiftLogicalScalar_Vector64_Int64, + ["ShiftLogicalScalar.Vector64.UInt64"] = ShiftLogicalScalar_Vector64_UInt64, + ["ShiftRightArithmetic.Vector64.Int16.1"] = ShiftRightArithmetic_Vector64_Int16_1, + ["ShiftRightArithmetic.Vector64.Int32.1"] = ShiftRightArithmetic_Vector64_Int32_1, + ["ShiftRightArithmetic.Vector64.SByte.1"] = ShiftRightArithmetic_Vector64_SByte_1, + ["ShiftRightArithmetic.Vector128.Int16.1"] = ShiftRightArithmetic_Vector128_Int16_1, + ["ShiftRightArithmetic.Vector128.Int32.1"] = ShiftRightArithmetic_Vector128_Int32_1, + ["ShiftRightArithmetic.Vector128.Int64.1"] = ShiftRightArithmetic_Vector128_Int64_1, + ["ShiftRightArithmetic.Vector128.SByte.1"] = ShiftRightArithmetic_Vector128_SByte_1, + ["ShiftRightArithmeticAdd.Vector64.Int16.1"] = ShiftRightArithmeticAdd_Vector64_Int16_1, + ["ShiftRightArithmeticAdd.Vector64.Int32.1"] = ShiftRightArithmeticAdd_Vector64_Int32_1, + ["ShiftRightArithmeticAdd.Vector64.SByte.1"] = ShiftRightArithmeticAdd_Vector64_SByte_1, + ["ShiftRightArithmeticAdd.Vector128.Int16.1"] = ShiftRightArithmeticAdd_Vector128_Int16_1, + ["ShiftRightArithmeticAdd.Vector128.Int32.1"] = ShiftRightArithmeticAdd_Vector128_Int32_1, + ["ShiftRightArithmeticAdd.Vector128.Int64.1"] = ShiftRightArithmeticAdd_Vector128_Int64_1, + ["ShiftRightArithmeticAdd.Vector128.SByte.1"] = ShiftRightArithmeticAdd_Vector128_SByte_1, + ["ShiftRightArithmeticAddScalar.Vector64.Int64.1"] = ShiftRightArithmeticAddScalar_Vector64_Int64_1, + ["ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int16.1"] = ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1, + ["ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int32.1"] = ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1, + ["ShiftRightArithmeticNarrowingSaturateLower.Vector64.SByte.1"] = ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1, + ["ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.Byte.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1, + ["ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt16.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1, + ["ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt32.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1, + ["ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.Byte.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_Byte_1, + ["ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt16.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt16_1, + ["ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt32.1"] = ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt32_1, + ["ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int16.1"] = ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int16_1, + ["ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int32.1"] = ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int32_1, + ["ShiftRightArithmeticNarrowingSaturateUpper.Vector128.SByte.1"] = ShiftRightArithmeticNarrowingSaturateUpper_Vector128_SByte_1, + ["ShiftRightArithmeticRounded.Vector64.Int16.1"] = ShiftRightArithmeticRounded_Vector64_Int16_1, + ["ShiftRightArithmeticRounded.Vector64.Int32.1"] = ShiftRightArithmeticRounded_Vector64_Int32_1, + ["ShiftRightArithmeticRounded.Vector64.SByte.1"] = ShiftRightArithmeticRounded_Vector64_SByte_1, + ["ShiftRightArithmeticRounded.Vector128.Int16.1"] = ShiftRightArithmeticRounded_Vector128_Int16_1, + ["ShiftRightArithmeticRounded.Vector128.Int32.1"] = ShiftRightArithmeticRounded_Vector128_Int32_1, + ["ShiftRightArithmeticRounded.Vector128.Int64.1"] = ShiftRightArithmeticRounded_Vector128_Int64_1, + ["ShiftRightArithmeticRounded.Vector128.SByte.1"] = ShiftRightArithmeticRounded_Vector128_SByte_1, + ["ShiftRightArithmeticRoundedAdd.Vector64.Int16.1"] = ShiftRightArithmeticRoundedAdd_Vector64_Int16_1, + ["ShiftRightArithmeticRoundedAdd.Vector64.Int32.1"] = ShiftRightArithmeticRoundedAdd_Vector64_Int32_1, + ["ShiftRightArithmeticRoundedAdd.Vector64.SByte.1"] = ShiftRightArithmeticRoundedAdd_Vector64_SByte_1, + ["ShiftRightArithmeticRoundedAdd.Vector128.Int16.1"] = ShiftRightArithmeticRoundedAdd_Vector128_Int16_1, + ["ShiftRightArithmeticRoundedAdd.Vector128.Int32.1"] = ShiftRightArithmeticRoundedAdd_Vector128_Int32_1, + ["ShiftRightArithmeticRoundedAdd.Vector128.Int64.1"] = ShiftRightArithmeticRoundedAdd_Vector128_Int64_1, + ["ShiftRightArithmeticRoundedAdd.Vector128.SByte.1"] = ShiftRightArithmeticRoundedAdd_Vector128_SByte_1, + ["ShiftRightArithmeticRoundedAddScalar.Vector64.Int64.1"] = ShiftRightArithmeticRoundedAddScalar_Vector64_Int64_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.SByte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.Byte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.Byte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_Byte_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt16_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt32_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int16.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int16_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int32.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int32_1, + ["ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.SByte.1"] = ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_SByte_1, + ["ShiftRightArithmeticRoundedScalar.Vector64.Int64.1"] = ShiftRightArithmeticRoundedScalar_Vector64_Int64_1, + ["ShiftRightArithmeticScalar.Vector64.Int64.1"] = ShiftRightArithmeticScalar_Vector64_Int64_1, + ["ShiftRightLogical.Vector64.Byte.1"] = ShiftRightLogical_Vector64_Byte_1, + ["ShiftRightLogical.Vector64.Int16.1"] = ShiftRightLogical_Vector64_Int16_1, + ["ShiftRightLogical.Vector64.Int32.1"] = ShiftRightLogical_Vector64_Int32_1, + ["ShiftRightLogical.Vector64.SByte.1"] = ShiftRightLogical_Vector64_SByte_1, + ["ShiftRightLogical.Vector64.UInt16.1"] = ShiftRightLogical_Vector64_UInt16_1, + ["ShiftRightLogical.Vector64.UInt32.1"] = ShiftRightLogical_Vector64_UInt32_1, + ["ShiftRightLogical.Vector128.Byte.1"] = ShiftRightLogical_Vector128_Byte_1, + ["ShiftRightLogical.Vector128.Int16.1"] = ShiftRightLogical_Vector128_Int16_1, + ["ShiftRightLogical.Vector128.Int32.1"] = ShiftRightLogical_Vector128_Int32_1, + ["ShiftRightLogical.Vector128.Int64.1"] = ShiftRightLogical_Vector128_Int64_1, + ["ShiftRightLogical.Vector128.SByte.1"] = ShiftRightLogical_Vector128_SByte_1, + ["ShiftRightLogical.Vector128.UInt16.1"] = ShiftRightLogical_Vector128_UInt16_1, + ["ShiftRightLogical.Vector128.UInt32.1"] = ShiftRightLogical_Vector128_UInt32_1, + ["ShiftRightLogical.Vector128.UInt64.1"] = ShiftRightLogical_Vector128_UInt64_1, + ["ShiftRightLogicalAdd.Vector64.Byte.1"] = ShiftRightLogicalAdd_Vector64_Byte_1, + ["ShiftRightLogicalAdd.Vector64.Int16.1"] = ShiftRightLogicalAdd_Vector64_Int16_1, + ["ShiftRightLogicalAdd.Vector64.Int32.1"] = ShiftRightLogicalAdd_Vector64_Int32_1, + ["ShiftRightLogicalAdd.Vector64.SByte.1"] = ShiftRightLogicalAdd_Vector64_SByte_1, + ["ShiftRightLogicalAdd.Vector64.UInt16.1"] = ShiftRightLogicalAdd_Vector64_UInt16_1, + ["ShiftRightLogicalAdd.Vector64.UInt32.1"] = ShiftRightLogicalAdd_Vector64_UInt32_1, + ["ShiftRightLogicalAdd.Vector128.Byte.1"] = ShiftRightLogicalAdd_Vector128_Byte_1, + ["ShiftRightLogicalAdd.Vector128.Int16.1"] = ShiftRightLogicalAdd_Vector128_Int16_1, + ["ShiftRightLogicalAdd.Vector128.Int32.1"] = ShiftRightLogicalAdd_Vector128_Int32_1, + ["ShiftRightLogicalAdd.Vector128.Int64.1"] = ShiftRightLogicalAdd_Vector128_Int64_1, + ["ShiftRightLogicalAdd.Vector128.SByte.1"] = ShiftRightLogicalAdd_Vector128_SByte_1, + ["ShiftRightLogicalAdd.Vector128.UInt16.1"] = ShiftRightLogicalAdd_Vector128_UInt16_1, + ["ShiftRightLogicalAdd.Vector128.UInt32.1"] = ShiftRightLogicalAdd_Vector128_UInt32_1, + ["ShiftRightLogicalAdd.Vector128.UInt64.1"] = ShiftRightLogicalAdd_Vector128_UInt64_1, + ["ShiftRightLogicalAddScalar.Vector64.Int64.1"] = ShiftRightLogicalAddScalar_Vector64_Int64_1, + ["ShiftRightLogicalAddScalar.Vector64.UInt64.1"] = ShiftRightLogicalAddScalar_Vector64_UInt64_1, + ["ShiftRightLogicalNarrowingLower.Vector64.Byte.1"] = ShiftRightLogicalNarrowingLower_Vector64_Byte_1, + ["ShiftRightLogicalNarrowingLower.Vector64.Int16.1"] = ShiftRightLogicalNarrowingLower_Vector64_Int16_1, + ["ShiftRightLogicalNarrowingLower.Vector64.Int32.1"] = ShiftRightLogicalNarrowingLower_Vector64_Int32_1, + ["ShiftRightLogicalNarrowingLower.Vector64.SByte.1"] = ShiftRightLogicalNarrowingLower_Vector64_SByte_1, + ["ShiftRightLogicalNarrowingLower.Vector64.UInt16.1"] = ShiftRightLogicalNarrowingLower_Vector64_UInt16_1, + ["ShiftRightLogicalNarrowingLower.Vector64.UInt32.1"] = ShiftRightLogicalNarrowingLower_Vector64_UInt32_1, + ["ShiftRightLogicalNarrowingSaturateLower.Vector64.Byte.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1, + ["ShiftRightLogicalNarrowingSaturateLower.Vector64.Int16.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1, + ["ShiftRightLogicalNarrowingSaturateLower.Vector64.Int32.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1, + ["ShiftRightLogicalNarrowingSaturateLower.Vector64.SByte.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1, + ["ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt16.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1, + ["ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt32.1"] = ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1, + ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.Byte.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_Byte_1, + ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int16.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int16_1, + ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int32.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int32_1, + ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.SByte.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_SByte_1, + ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt16.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt16_1, + ["ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt32.1"] = ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt32_1, + ["ShiftRightLogicalNarrowingUpper.Vector128.Byte.1"] = ShiftRightLogicalNarrowingUpper_Vector128_Byte_1, + ["ShiftRightLogicalNarrowingUpper.Vector128.Int16.1"] = ShiftRightLogicalNarrowingUpper_Vector128_Int16_1, + ["ShiftRightLogicalNarrowingUpper.Vector128.Int32.1"] = ShiftRightLogicalNarrowingUpper_Vector128_Int32_1, + ["ShiftRightLogicalNarrowingUpper.Vector128.SByte.1"] = ShiftRightLogicalNarrowingUpper_Vector128_SByte_1, + ["ShiftRightLogicalNarrowingUpper.Vector128.UInt16.1"] = ShiftRightLogicalNarrowingUpper_Vector128_UInt16_1, + ["ShiftRightLogicalNarrowingUpper.Vector128.UInt32.1"] = ShiftRightLogicalNarrowingUpper_Vector128_UInt32_1, + ["ShiftRightLogicalRounded.Vector64.Byte.1"] = ShiftRightLogicalRounded_Vector64_Byte_1, + ["ShiftRightLogicalRounded.Vector64.Int16.1"] = ShiftRightLogicalRounded_Vector64_Int16_1, + ["ShiftRightLogicalRounded.Vector64.Int32.1"] = ShiftRightLogicalRounded_Vector64_Int32_1, + ["ShiftRightLogicalRounded.Vector64.SByte.1"] = ShiftRightLogicalRounded_Vector64_SByte_1, + ["ShiftRightLogicalRounded.Vector64.UInt16.1"] = ShiftRightLogicalRounded_Vector64_UInt16_1, + ["ShiftRightLogicalRounded.Vector64.UInt32.1"] = ShiftRightLogicalRounded_Vector64_UInt32_1, + ["ShiftRightLogicalRounded.Vector128.Byte.1"] = ShiftRightLogicalRounded_Vector128_Byte_1, + ["ShiftRightLogicalRounded.Vector128.Int16.1"] = ShiftRightLogicalRounded_Vector128_Int16_1, + ["ShiftRightLogicalRounded.Vector128.Int32.1"] = ShiftRightLogicalRounded_Vector128_Int32_1, + ["ShiftRightLogicalRounded.Vector128.Int64.1"] = ShiftRightLogicalRounded_Vector128_Int64_1, + ["ShiftRightLogicalRounded.Vector128.SByte.1"] = ShiftRightLogicalRounded_Vector128_SByte_1, + ["ShiftRightLogicalRounded.Vector128.UInt16.1"] = ShiftRightLogicalRounded_Vector128_UInt16_1, + ["ShiftRightLogicalRounded.Vector128.UInt32.1"] = ShiftRightLogicalRounded_Vector128_UInt32_1, + ["ShiftRightLogicalRounded.Vector128.UInt64.1"] = ShiftRightLogicalRounded_Vector128_UInt64_1, + ["ShiftRightLogicalRoundedAdd.Vector64.Byte.1"] = ShiftRightLogicalRoundedAdd_Vector64_Byte_1, + ["ShiftRightLogicalRoundedAdd.Vector64.Int16.1"] = ShiftRightLogicalRoundedAdd_Vector64_Int16_1, + ["ShiftRightLogicalRoundedAdd.Vector64.Int32.1"] = ShiftRightLogicalRoundedAdd_Vector64_Int32_1, + ["ShiftRightLogicalRoundedAdd.Vector64.SByte.1"] = ShiftRightLogicalRoundedAdd_Vector64_SByte_1, + ["ShiftRightLogicalRoundedAdd.Vector64.UInt16.1"] = ShiftRightLogicalRoundedAdd_Vector64_UInt16_1, + ["ShiftRightLogicalRoundedAdd.Vector64.UInt32.1"] = ShiftRightLogicalRoundedAdd_Vector64_UInt32_1, + ["ShiftRightLogicalRoundedAdd.Vector128.Byte.1"] = ShiftRightLogicalRoundedAdd_Vector128_Byte_1, + ["ShiftRightLogicalRoundedAdd.Vector128.Int16.1"] = ShiftRightLogicalRoundedAdd_Vector128_Int16_1, + ["ShiftRightLogicalRoundedAdd.Vector128.Int32.1"] = ShiftRightLogicalRoundedAdd_Vector128_Int32_1, + ["ShiftRightLogicalRoundedAdd.Vector128.Int64.1"] = ShiftRightLogicalRoundedAdd_Vector128_Int64_1, + ["ShiftRightLogicalRoundedAdd.Vector128.SByte.1"] = ShiftRightLogicalRoundedAdd_Vector128_SByte_1, + ["ShiftRightLogicalRoundedAdd.Vector128.UInt16.1"] = ShiftRightLogicalRoundedAdd_Vector128_UInt16_1, + ["ShiftRightLogicalRoundedAdd.Vector128.UInt32.1"] = ShiftRightLogicalRoundedAdd_Vector128_UInt32_1, + ["ShiftRightLogicalRoundedAdd.Vector128.UInt64.1"] = ShiftRightLogicalRoundedAdd_Vector128_UInt64_1, + ["ShiftRightLogicalRoundedAddScalar.Vector64.Int64.1"] = ShiftRightLogicalRoundedAddScalar_Vector64_Int64_1, + ["ShiftRightLogicalRoundedAddScalar.Vector64.UInt64.1"] = ShiftRightLogicalRoundedAddScalar_Vector64_UInt64_1, + ["ShiftRightLogicalRoundedNarrowingLower.Vector64.Byte.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1, + ["ShiftRightLogicalRoundedNarrowingLower.Vector64.Int16.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1, + ["ShiftRightLogicalRoundedNarrowingLower.Vector64.Int32.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1, + ["ShiftRightLogicalRoundedNarrowingLower.Vector64.SByte.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1, + ["ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt16.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1, + ["ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt32.1"] = ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1, + ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Byte.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1, + ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int16.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int16_1, + ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int32.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int32_1, + ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.SByte.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_SByte_1, + ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt16.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1, + ["ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt32.1"] = ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1, + ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Byte.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Byte_1, + ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int16.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int16_1, + ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int32.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int32_1, + ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.SByte.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_SByte_1, + ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt16.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt16_1, + ["ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt32.1"] = ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt32_1, + ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.Byte.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_Byte_1, + ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int16.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int16_1, + ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int32.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int32_1, + ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.SByte.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_SByte_1, + ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt16.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt16_1, + ["ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt32.1"] = ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt32_1, + ["ShiftRightLogicalRoundedScalar.Vector64.Int64.1"] = ShiftRightLogicalRoundedScalar_Vector64_Int64_1, + ["ShiftRightLogicalRoundedScalar.Vector64.UInt64.1"] = ShiftRightLogicalRoundedScalar_Vector64_UInt64_1, + ["ShiftRightLogicalScalar.Vector64.Int64.1"] = ShiftRightLogicalScalar_Vector64_Int64_1, + ["ShiftRightLogicalScalar.Vector64.UInt64.1"] = ShiftRightLogicalScalar_Vector64_UInt64_1, + ["SignExtendWideningLower.Vector64.Int16"] = SignExtendWideningLower_Vector64_Int16, + ["SignExtendWideningLower.Vector64.Int32"] = SignExtendWideningLower_Vector64_Int32, + ["SignExtendWideningLower.Vector64.SByte"] = SignExtendWideningLower_Vector64_SByte, + ["SignExtendWideningUpper.Vector128.Int16"] = SignExtendWideningUpper_Vector128_Int16, + ["SignExtendWideningUpper.Vector128.Int32"] = SignExtendWideningUpper_Vector128_Int32, + ["SignExtendWideningUpper.Vector128.SByte"] = SignExtendWideningUpper_Vector128_SByte, ["SqrtScalar.Vector64.Double"] = SqrtScalar_Vector64_Double, ["SqrtScalar.Vector64.Single"] = SqrtScalar_Vector64_Single, ["Store.Vector64.Byte"] = Store_Vector64_Byte, @@ -896,6 +1217,18 @@ static Program() ["Xor.Vector128.UInt16"] = Xor_Vector128_UInt16, ["Xor.Vector128.UInt32"] = Xor_Vector128_UInt32, ["Xor.Vector128.UInt64"] = Xor_Vector128_UInt64, + ["ZeroExtendWideningLower.Vector64.Byte"] = ZeroExtendWideningLower_Vector64_Byte, + ["ZeroExtendWideningLower.Vector64.Int16"] = ZeroExtendWideningLower_Vector64_Int16, + ["ZeroExtendWideningLower.Vector64.Int32"] = ZeroExtendWideningLower_Vector64_Int32, + ["ZeroExtendWideningLower.Vector64.SByte"] = ZeroExtendWideningLower_Vector64_SByte, + ["ZeroExtendWideningLower.Vector64.UInt16"] = ZeroExtendWideningLower_Vector64_UInt16, + ["ZeroExtendWideningLower.Vector64.UInt32"] = ZeroExtendWideningLower_Vector64_UInt32, + ["ZeroExtendWideningUpper.Vector128.Byte"] = ZeroExtendWideningUpper_Vector128_Byte, + ["ZeroExtendWideningUpper.Vector128.Int16"] = ZeroExtendWideningUpper_Vector128_Int16, + ["ZeroExtendWideningUpper.Vector128.Int32"] = ZeroExtendWideningUpper_Vector128_Int32, + ["ZeroExtendWideningUpper.Vector128.SByte"] = ZeroExtendWideningUpper_Vector128_SByte, + ["ZeroExtendWideningUpper.Vector128.UInt16"] = ZeroExtendWideningUpper_Vector128_UInt16, + ["ZeroExtendWideningUpper.Vector128.UInt32"] = ZeroExtendWideningUpper_Vector128_UInt32, }; } } diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.Int16.cs new file mode 100644 index 0000000000000..004afafdffc15 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmetic_Vector128_Int16() + { + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmetic_Vector128_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int16 testClass) + { + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmetic( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmetic( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int16*)(pClsVar1)), + AdvSimd.LoadVector128((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int16(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int16(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int16*)(&test._fld1)), + AdvSimd.LoadVector128((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmetic(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmetic)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.Int32.cs new file mode 100644 index 0000000000000..bd0527517d4f8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmetic_Vector128_Int32() + { + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmetic_Vector128_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int32 testClass) + { + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmetic( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmetic( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int32*)(pClsVar1)), + AdvSimd.LoadVector128((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int32(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int32(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int32*)(&test._fld1)), + AdvSimd.LoadVector128((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmetic(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmetic)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.Int64.cs new file mode 100644 index 0000000000000..dc31a6897a276 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.Int64.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmetic_Vector128_Int64() + { + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmetic_Vector128_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int64 testClass) + { + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmetic( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmetic( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int64*)(pClsVar1)), + AdvSimd.LoadVector128((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int64(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector128_Int64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((Int64*)(&test._fld1)), + AdvSimd.LoadVector128((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmetic(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmetic)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.SByte.cs new file mode 100644 index 0000000000000..abdadf2096690 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector128.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmetic_Vector128_SByte() + { + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector128_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmetic_Vector128_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmetic_Vector128_SByte testClass) + { + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmetic_Vector128_SByte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmetic_Vector128_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmetic_Vector128_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmetic( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmetic( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((SByte*)(pClsVar1)), + AdvSimd.LoadVector128((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector128_SByte(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector128_SByte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector128((SByte*)(&test._fld1)), + AdvSimd.LoadVector128((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmetic(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmetic)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector64.Int16.cs new file mode 100644 index 0000000000000..6147ff324bc47 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector64.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmetic_Vector64_Int16() + { + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmetic_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int16 testClass) + { + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmetic( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmetic( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((Int16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int16(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((Int16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmetic(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmetic)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector64.Int32.cs new file mode 100644 index 0000000000000..cea92f720d580 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector64.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmetic_Vector64_Int32() + { + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmetic_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int32 testClass) + { + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmetic( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmetic( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((Int32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int32(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((Int32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmetic(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmetic)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector64.SByte.cs new file mode 100644 index 0000000000000..1df2baab309eb --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmetic.Vector64.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmetic_Vector64_SByte() + { + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmetic_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmetic_Vector64_SByte testClass) + { + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmetic_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmetic_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmetic_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmetic( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmetic), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmetic( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((SByte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmetic(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector64_SByte(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmetic_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmetic(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmetic( + AdvSimd.LoadVector64((SByte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmetic(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmetic)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.Int16.cs new file mode 100644 index 0000000000000..65a0afda9b07b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRounded_Vector128_Int16() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRounded_Vector128_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int16 testClass) + { + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int16*)(pClsVar1)), + AdvSimd.LoadVector128((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int16(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int16(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int16*)(&test._fld1)), + AdvSimd.LoadVector128((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRounded)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.Int32.cs new file mode 100644 index 0000000000000..d43861ceb6b58 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRounded_Vector128_Int32() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRounded_Vector128_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int32 testClass) + { + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int32*)(pClsVar1)), + AdvSimd.LoadVector128((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int32(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int32(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int32*)(&test._fld1)), + AdvSimd.LoadVector128((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRounded)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.Int64.cs new file mode 100644 index 0000000000000..eb08ad535f566 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.Int64.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRounded_Vector128_Int64() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRounded_Vector128_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int64 testClass) + { + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int64*)(pClsVar1)), + AdvSimd.LoadVector128((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int64(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_Int64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((Int64*)(&test._fld1)), + AdvSimd.LoadVector128((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRounded)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.SByte.cs new file mode 100644 index 0000000000000..36b2d0e36c32c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector128.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRounded_Vector128_SByte() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRounded_Vector128_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_SByte testClass) + { + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_SByte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((SByte*)(pClsVar1)), + AdvSimd.LoadVector128((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_SByte(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector128_SByte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector128((SByte*)(&test._fld1)), + AdvSimd.LoadVector128((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRounded)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector64.Int16.cs new file mode 100644 index 0000000000000..56e2a394bddd8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector64.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRounded_Vector64_Int16() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRounded_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int16 testClass) + { + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((Int16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int16(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((Int16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRounded)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector64.Int32.cs new file mode 100644 index 0000000000000..ecbf0dbac1d0c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector64.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRounded_Vector64_Int32() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRounded_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int32 testClass) + { + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((Int32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int32(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((Int32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRounded)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector64.SByte.cs new file mode 100644 index 0000000000000..a0a72ba9bfa88 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRounded.Vector64.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRounded_Vector64_SByte() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRounded_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_SByte testClass) + { + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((SByte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_SByte(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRounded_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRounded( + AdvSimd.LoadVector64((SByte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRounded)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.Int16.cs new file mode 100644 index 0000000000000..7e2820aa003a3 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRoundedSaturate_Vector128_Int16() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRoundedSaturate_Vector128_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int16 testClass) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int16*)(pClsVar1)), + AdvSimd.LoadVector128((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int16(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int16(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int16*)(&test._fld1)), + AdvSimd.LoadVector128((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRoundedSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.Int32.cs new file mode 100644 index 0000000000000..a70c32f1d9001 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRoundedSaturate_Vector128_Int32() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRoundedSaturate_Vector128_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int32 testClass) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int32*)(pClsVar1)), + AdvSimd.LoadVector128((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int32(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int32(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int32*)(&test._fld1)), + AdvSimd.LoadVector128((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRoundedSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.Int64.cs new file mode 100644 index 0000000000000..0ca521fe3930e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.Int64.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRoundedSaturate_Vector128_Int64() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRoundedSaturate_Vector128_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int64 testClass) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int64*)(pClsVar1)), + AdvSimd.LoadVector128((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int64(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_Int64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((Int64*)(&test._fld1)), + AdvSimd.LoadVector128((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRoundedSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.SByte.cs new file mode 100644 index 0000000000000..92663ab176402 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector128.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRoundedSaturate_Vector128_SByte() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRoundedSaturate_Vector128_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_SByte testClass) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_SByte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((SByte*)(pClsVar1)), + AdvSimd.LoadVector128((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_SByte(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector128_SByte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector128((SByte*)(&test._fld1)), + AdvSimd.LoadVector128((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRoundedSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector64.Int16.cs new file mode 100644 index 0000000000000..7854dc8a00c6c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector64.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRoundedSaturate_Vector64_Int16() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRoundedSaturate_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int16 testClass) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((Int16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int16(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((Int16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRoundedSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector64.Int32.cs new file mode 100644 index 0000000000000..d416c680f6f19 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector64.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRoundedSaturate_Vector64_Int32() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRoundedSaturate_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int32 testClass) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((Int32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int32(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((Int32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRoundedSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector64.SByte.cs new file mode 100644 index 0000000000000..ee0cf1385a182 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturate.Vector64.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRoundedSaturate_Vector64_SByte() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRoundedSaturate_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_SByte testClass) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((SByte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_SByte(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturate_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturate( + AdvSimd.LoadVector64((SByte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRoundedSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturateScalar.Vector64.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturateScalar.Vector64.Int64.cs new file mode 100644 index 0000000000000..82a478c05dc1e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedSaturateScalar.Vector64.Int64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRoundedSaturateScalar_Vector64_Int64() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRoundedSaturateScalar_Vector64_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int64 testClass) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar1)), + AdvSimd.LoadVector64((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int64(); + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedSaturateScalar_Vector64_Int64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedSaturateScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld1)), + AdvSimd.LoadVector64((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRoundedSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedScalar.Vector64.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedScalar.Vector64.Int64.cs new file mode 100644 index 0000000000000..236e5058b4d5d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticRoundedScalar.Vector64.Int64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticRoundedScalar_Vector64_Int64() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedScalar_Vector64_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticRoundedScalar_Vector64_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticRoundedScalar_Vector64_Int64 testClass) + { + var result = AdvSimd.ShiftArithmeticRoundedScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticRoundedScalar_Vector64_Int64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticRoundedScalar_Vector64_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticRoundedScalar_Vector64_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticRoundedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticRoundedScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticRoundedScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar1)), + AdvSimd.LoadVector64((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticRoundedScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticRoundedScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedScalar_Vector64_Int64(); + var result = AdvSimd.ShiftArithmeticRoundedScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticRoundedScalar_Vector64_Int64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticRoundedScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticRoundedScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld1)), + AdvSimd.LoadVector64((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftArithmeticRounded(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticRoundedScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.Int16.cs new file mode 100644 index 0000000000000..f69865da37308 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticSaturate_Vector128_Int16() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticSaturate_Vector128_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int16 testClass) + { + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int16*)(pClsVar1)), + AdvSimd.LoadVector128((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int16(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int16(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int16*)(&test._fld1)), + AdvSimd.LoadVector128((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.Int32.cs new file mode 100644 index 0000000000000..c4b65ac67dec9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticSaturate_Vector128_Int32() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticSaturate_Vector128_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int32 testClass) + { + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int32*)(pClsVar1)), + AdvSimd.LoadVector128((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int32(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int32(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int32*)(&test._fld1)), + AdvSimd.LoadVector128((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.Int64.cs new file mode 100644 index 0000000000000..fa25da4559362 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.Int64.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticSaturate_Vector128_Int64() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticSaturate_Vector128_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int64 testClass) + { + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int64*)(pClsVar1)), + AdvSimd.LoadVector128((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int64(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_Int64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((Int64*)(&test._fld1)), + AdvSimd.LoadVector128((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.SByte.cs new file mode 100644 index 0000000000000..335a55256c564 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector128.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticSaturate_Vector128_SByte() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticSaturate_Vector128_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_SByte testClass) + { + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_SByte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((SByte*)(pClsVar1)), + AdvSimd.LoadVector128((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_SByte(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector128_SByte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector128((SByte*)(&test._fld1)), + AdvSimd.LoadVector128((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector64.Int16.cs new file mode 100644 index 0000000000000..1c0120331f375 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector64.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticSaturate_Vector64_Int16() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticSaturate_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int16 testClass) + { + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((Int16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int16(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((Int16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector64.Int32.cs new file mode 100644 index 0000000000000..67b0e4dc96e61 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector64.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticSaturate_Vector64_Int32() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticSaturate_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int32 testClass) + { + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((Int32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int32(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((Int32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector64.SByte.cs new file mode 100644 index 0000000000000..89a0732b5fcc7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturate.Vector64.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticSaturate_Vector64_SByte() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticSaturate_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_SByte testClass) + { + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((SByte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_SByte(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturate_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturate( + AdvSimd.LoadVector64((SByte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturateScalar.Vector64.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturateScalar.Vector64.Int64.cs new file mode 100644 index 0000000000000..f11399812c4b8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticSaturateScalar.Vector64.Int64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticSaturateScalar_Vector64_Int64() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticSaturateScalar_Vector64_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int64 testClass) + { + var result = AdvSimd.ShiftArithmeticSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar1)), + AdvSimd.LoadVector64((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int64(); + var result = AdvSimd.ShiftArithmeticSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticSaturateScalar_Vector64_Int64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticSaturateScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld1)), + AdvSimd.LoadVector64((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticScalar.Vector64.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticScalar.Vector64.Int64.cs new file mode 100644 index 0000000000000..ee58a039ccf2b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftArithmeticScalar.Vector64.Int64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftArithmeticScalar_Vector64_Int64() + { + var test = new SimpleBinaryOpTest__ShiftArithmeticScalar_Vector64_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftArithmeticScalar_Vector64_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftArithmeticScalar_Vector64_Int64 testClass) + { + var result = AdvSimd.ShiftArithmeticScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftArithmeticScalar_Vector64_Int64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftArithmeticScalar_Vector64_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftArithmeticScalar_Vector64_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftArithmeticScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftArithmeticScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftArithmeticScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftArithmeticScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftArithmeticScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar1)), + AdvSimd.LoadVector64((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftArithmeticScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftArithmeticScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticScalar_Vector64_Int64(); + var result = AdvSimd.ShiftArithmeticScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftArithmeticScalar_Vector64_Int64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftArithmeticScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftArithmeticScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftArithmeticScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftArithmeticScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld1)), + AdvSimd.LoadVector64((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftArithmetic(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftArithmeticScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.Byte.1.cs new file mode 100644 index 0000000000000..e5876543df026 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogical_Vector128_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogical_Vector128_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogical_Vector128_Byte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogical_Vector128_Byte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogical_Vector128_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogical_Vector128_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Byte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_Byte_1(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_Byte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Byte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..0acbde2731056 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogical_Vector128_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int16_1(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.Int64.1.cs new file mode 100644 index 0000000000000..f659c72a35604 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.Int64.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogical_Vector128_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int64_1 testClass) + { + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int64_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int64_1(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_Int64_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..79af663f324f7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogical_Vector128_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogical_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogical_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogical_Vector128_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogical_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogical_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_SByte_1(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.UInt16.1.cs new file mode 100644 index 0000000000000..9dd8e89896331 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogical_Vector128_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt16_1(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.UInt32.1.cs new file mode 100644 index 0000000000000..aef06f03ac89c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogical_Vector128_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt32_1 testClass) + { + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt32_1(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.UInt64.1.cs new file mode 100644 index 0000000000000..74d56e3d66a6b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector128.UInt64.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogical_Vector128_UInt64_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt64_1 testClass) + { + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt64_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt64_1(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector128_UInt64_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector128((UInt64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..92ee7ffad1543 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogical_Vector64_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogical_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogical_Vector64_Byte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogical_Vector64_Byte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogical_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogical_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Byte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_Byte_1(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_Byte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Byte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogical)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..9fa76a108cffb --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogical_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int16_1(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogical)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..5deca2aa3ad4f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogical_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int32_1(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_Int32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogical)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..3c21bf6fe260f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogical_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogical_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogical_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogical_Vector64_SByte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogical_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogical_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_SByte_1(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_SByte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogical)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..b6307bfc7f588 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogical_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt16_1(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogical)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..d7e57acc1492c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogical.Vector64.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogical_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt32_1(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogical_Vector64_UInt32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogical( + AdvSimd.LoadVector64((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogical)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Byte.1.cs new file mode 100644 index 0000000000000..90999ea1642aa --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector128_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Byte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Byte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Byte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Byte_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Byte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Byte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..6877a73fd6d1f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector128_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int16_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..4a76316e39da5 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector128_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int32_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Int64.1.cs new file mode 100644 index 0000000000000..37dde498561c8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.Int64.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector128_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int64_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int64_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int64_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_Int64_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..9eff7dae8b86e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector128_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_SByte_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.UInt16.1.cs new file mode 100644 index 0000000000000..d0a7cceed73cc --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector128_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt16_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.UInt32.1.cs new file mode 100644 index 0000000000000..7461e8b421132 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector128_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt32_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt32_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.UInt64.1.cs new file mode 100644 index 0000000000000..b7135ce6866ff --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector128.UInt64.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector128_UInt64_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt64_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt64_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt64_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector128_UInt64_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector128((UInt64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..19f6adbc90cd7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector64_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Byte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Byte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Byte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Byte_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Byte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Byte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..1f2f914a462ea --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int16_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..9a7e8a89f35d8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int32_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_Int32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..3515faa2d8fc3 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_SByte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_SByte_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_SByte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..0a0471355a609 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt16_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..2a74644f94f7f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturate.Vector64.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturate_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturate), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturate(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt32_1(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturate_Vector64_UInt32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturate(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturate( + AdvSimd.LoadVector64((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturate)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateScalar.Vector64.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateScalar.Vector64.Int64.1.cs new file mode 100644 index 0000000000000..6794c90089219 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateScalar.Vector64.Int64.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateScalar_Vector64_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int64_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturateScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int64_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturateScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturateScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int64_1(); + var result = AdvSimd.ShiftLeftLogicalSaturateScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_Int64_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturateScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateScalar.Vector64.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateScalar.Vector64.UInt64.1.cs new file mode 100644 index 0000000000000..46ea94dcdfcc0 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateScalar.Vector64.UInt64.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturateScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturateScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturateScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1(); + var result = AdvSimd.ShiftLeftLogicalSaturateScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturateScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..6085e1bd99156 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..f9bb48efc64ec --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.Int64.1.cs new file mode 100644 index 0000000000000..53e118e13ebdb --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.Int64.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, UInt64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..ced25f2be3b85 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector128.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector128((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..0ec38fe4678cd --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..04170dcc9b793 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..f2eae9c2e7907 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsigned.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsigned( + AdvSimd.LoadVector64((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturateUnsigned)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int64.1.cs new file mode 100644 index 0000000000000..805b233f85b79 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalSaturateUnsignedScalar.Vector64.Int64.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, UInt64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalSaturateUnsignedScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalScalar.Vector64.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalScalar.Vector64.Int64.1.cs new file mode 100644 index 0000000000000..40358c81ec1d6 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalScalar.Vector64.Int64.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalScalar_Vector64_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_Int64_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_Int64_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_Int64_1(); + var result = AdvSimd.ShiftLeftLogicalScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_Int64_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogical(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalScalar.Vector64.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalScalar.Vector64.UInt64.1.cs new file mode 100644 index 0000000000000..a9c5ebabd1281 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalScalar.Vector64.UInt64.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalScalar_Vector64_UInt64_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_UInt64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_UInt64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_UInt64_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_UInt64_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_UInt64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_UInt64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_UInt64_1(); + var result = AdvSimd.ShiftLeftLogicalScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalScalar_Vector64_UInt64_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLeftLogical(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..6643b012f5c27 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalWideningLower_Vector64_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Byte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Byte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningLower), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningLower), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Byte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalWideningLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalWideningLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Byte_1(); + var result = AdvSimd.ShiftLeftLogicalWideningLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Byte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Byte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalWideningLower)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..18b90d66f0c21 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalWideningLower_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningLower), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningLower), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalWideningLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalWideningLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int16_1(); + var result = AdvSimd.ShiftLeftLogicalWideningLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalWideningLower)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..b78654de09858 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalWideningLower_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningLower), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningLower), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalWideningLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalWideningLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int32_1(); + var result = AdvSimd.ShiftLeftLogicalWideningLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_Int32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalWideningLower)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..ceaf877d20326 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalWideningLower_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_SByte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningLower), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningLower), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalWideningLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalWideningLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_SByte_1(); + var result = AdvSimd.ShiftLeftLogicalWideningLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_SByte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalWideningLower)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..9dcf79fc9bbc6 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalWideningLower_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningLower), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningLower), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalWideningLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalWideningLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt16_1(); + var result = AdvSimd.ShiftLeftLogicalWideningLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalWideningLower)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..e53f3be0c9154 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningLower.Vector64.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalWideningLower_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningLower), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningLower), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalWideningLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalWideningLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt32_1(); + var result = AdvSimd.ShiftLeftLogicalWideningLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningLower_Vector64_UInt32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningLower( + AdvSimd.LoadVector64((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalWideningLower)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.Byte.1.cs new file mode 100644 index 0000000000000..19009e19bca80 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalWideningUpper_Vector128_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Byte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Byte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningUpper), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningUpper), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Byte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Byte_1(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Byte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Byte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalWideningUpper)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..1c8ced42418e7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalWideningUpper_Vector128_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningUpper), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningUpper), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int16_1(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalWideningUpper)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..5482ea148d99f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalWideningUpper_Vector128_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningUpper), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningUpper), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int32_1(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_Int32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalWideningUpper)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..a5158ce7397da --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalWideningUpper_Vector128_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningUpper), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningUpper), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_SByte_1(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalWideningUpper)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.UInt16.1.cs new file mode 100644 index 0000000000000..ce2a730d027f9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalWideningUpper_Vector128_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt16_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningUpper), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningUpper), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt16_1(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalWideningUpper)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.UInt32.1.cs new file mode 100644 index 0000000000000..4802406e32717 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLeftLogicalWideningUpper.Vector128.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLeftLogicalWideningUpper_Vector128_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt32_1 testClass) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningUpper), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLeftLogicalWideningUpper), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt32_1(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftLeftLogicalWideningUpper_Vector128_UInt32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLeftLogicalWideningUpper(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLeftLogicalWideningUpper( + AdvSimd.LoadVector128((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLeftLogicalWideningUpper)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Byte.cs new file mode 100644 index 0000000000000..b5f1ee0ac9a93 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Byte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector128_Byte() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector128_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, SByte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector128_Byte testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector128_Byte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector128_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector128_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Byte*)(pClsVar1)), + AdvSimd.LoadVector128((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_Byte(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_Byte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Byte*)(&test._fld1)), + AdvSimd.LoadVector128((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] left, SByte[] right, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Int16.cs new file mode 100644 index 0000000000000..61e1428538a9c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector128_Int16() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector128_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector128_Int16 testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector128_Int16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector128_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector128_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int16*)(pClsVar1)), + AdvSimd.LoadVector128((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_Int16(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_Int16(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int16*)(&test._fld1)), + AdvSimd.LoadVector128((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Int32.cs new file mode 100644 index 0000000000000..c9e06a69bd944 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector128_Int32() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector128_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector128_Int32 testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector128_Int32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector128_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector128_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int32*)(pClsVar1)), + AdvSimd.LoadVector128((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_Int32(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_Int32(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int32*)(&test._fld1)), + AdvSimd.LoadVector128((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Int64.cs new file mode 100644 index 0000000000000..9279375a741a0 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.Int64.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector128_Int64() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector128_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector128_Int64 testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector128_Int64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector128_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector128_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int64*)(pClsVar1)), + AdvSimd.LoadVector128((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_Int64(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_Int64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((Int64*)(&test._fld1)), + AdvSimd.LoadVector128((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.SByte.cs new file mode 100644 index 0000000000000..9fffdc8224b94 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector128_SByte() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector128_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector128_SByte testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector128_SByte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector128_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector128_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((SByte*)(pClsVar1)), + AdvSimd.LoadVector128((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_SByte(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_SByte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((SByte*)(&test._fld1)), + AdvSimd.LoadVector128((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.UInt16.cs new file mode 100644 index 0000000000000..f9d47ca6c3e8c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.UInt16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector128_UInt16() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector128_UInt16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, Int16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector128_UInt16 testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector128_UInt16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector128_UInt16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector128_UInt16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt16*)(pClsVar1)), + AdvSimd.LoadVector128((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_UInt16(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_UInt16(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt16*)(&test._fld1)), + AdvSimd.LoadVector128((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] left, Int16[] right, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.UInt32.cs new file mode 100644 index 0000000000000..1477f27f0237e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.UInt32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector128_UInt32() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector128_UInt32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, Int32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector128_UInt32 testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector128_UInt32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector128_UInt32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector128_UInt32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt32*)(pClsVar1)), + AdvSimd.LoadVector128((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_UInt32(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_UInt32(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt32*)(&test._fld1)), + AdvSimd.LoadVector128((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] left, Int32[] right, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.UInt64.cs new file mode 100644 index 0000000000000..878e05f57d89d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector128.UInt64.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector128_UInt64() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_UInt64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector128_UInt64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, Int64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector128_UInt64 testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector128_UInt64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector128_UInt64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector128_UInt64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt64*)(pClsVar1)), + AdvSimd.LoadVector128((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_UInt64(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector128_UInt64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector128((UInt64*)(&test._fld1)), + AdvSimd.LoadVector128((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] left, Int64[] right, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.Byte.cs new file mode 100644 index 0000000000000..0d0247d2927e9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.Byte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector64_Byte() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector64_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, SByte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector64_Byte testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector64_Byte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector64_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector64_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Byte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_Byte(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_Byte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Byte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] left, SByte[] right, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.Int16.cs new file mode 100644 index 0000000000000..cf370b6685b02 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector64_Int16() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector64_Int16 testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Int16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_Int16(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Int16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.Int32.cs new file mode 100644 index 0000000000000..74e76ebb9a32b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector64_Int32() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector64_Int32 testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Int32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_Int32(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((Int32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.SByte.cs new file mode 100644 index 0000000000000..28171de391d20 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector64_SByte() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector64_SByte testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((SByte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_SByte(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((SByte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.UInt16.cs new file mode 100644 index 0000000000000..a12a7e6f2e1e9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.UInt16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector64_UInt16() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector64_UInt16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, Int16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector64_UInt16 testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector64_UInt16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector64_UInt16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector64_UInt16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((UInt16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_UInt16(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_UInt16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((UInt16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] left, Int16[] right, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.UInt32.cs new file mode 100644 index 0000000000000..da032eca83960 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogical.Vector64.UInt32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogical_Vector64_UInt32() + { + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogical_Vector64_UInt32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, Int32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogical_Vector64_UInt32 testClass) + { + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogical_Vector64_UInt32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogical_Vector64_UInt32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogical_Vector64_UInt32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogical( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogical), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogical( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((UInt32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogical(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_UInt32(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogical_Vector64_UInt32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogical(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogical( + AdvSimd.LoadVector64((UInt32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] left, Int32[] right, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogical(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogical)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Byte.cs new file mode 100644 index 0000000000000..a2b01f27e9c26 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Byte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector128_Byte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector128_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, SByte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Byte testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Byte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Byte*)(pClsVar1)), + AdvSimd.LoadVector128((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Byte(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Byte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Byte*)(&test._fld1)), + AdvSimd.LoadVector128((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] left, SByte[] right, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Int16.cs new file mode 100644 index 0000000000000..22ab626099019 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector128_Int16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector128_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int16 testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int16*)(pClsVar1)), + AdvSimd.LoadVector128((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int16(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int16(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int16*)(&test._fld1)), + AdvSimd.LoadVector128((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Int32.cs new file mode 100644 index 0000000000000..ee5505da9a894 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector128_Int32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector128_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int32 testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int32*)(pClsVar1)), + AdvSimd.LoadVector128((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int32(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int32(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int32*)(&test._fld1)), + AdvSimd.LoadVector128((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Int64.cs new file mode 100644 index 0000000000000..1993f0d372b66 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.Int64.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector128_Int64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector128_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int64 testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int64*)(pClsVar1)), + AdvSimd.LoadVector128((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int64(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_Int64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((Int64*)(&test._fld1)), + AdvSimd.LoadVector128((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.SByte.cs new file mode 100644 index 0000000000000..a345dd531ceac --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector128_SByte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector128_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_SByte testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_SByte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((SByte*)(pClsVar1)), + AdvSimd.LoadVector128((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_SByte(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_SByte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((SByte*)(&test._fld1)), + AdvSimd.LoadVector128((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.UInt16.cs new file mode 100644 index 0000000000000..78d1aeb0268a3 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.UInt16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector128_UInt16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector128_UInt16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, Int16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt16 testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt16*)(pClsVar1)), + AdvSimd.LoadVector128((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt16(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt16(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt16*)(&test._fld1)), + AdvSimd.LoadVector128((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] left, Int16[] right, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.UInt32.cs new file mode 100644 index 0000000000000..62764e33365c8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.UInt32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector128_UInt32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector128_UInt32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, Int32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt32 testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt32*)(pClsVar1)), + AdvSimd.LoadVector128((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt32(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt32(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt32*)(&test._fld1)), + AdvSimd.LoadVector128((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] left, Int32[] right, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.UInt64.cs new file mode 100644 index 0000000000000..29dfe41903e7c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector128.UInt64.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector128_UInt64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector128_UInt64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, Int64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt64 testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt64*)(pClsVar1)), + AdvSimd.LoadVector128((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt64(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector128_UInt64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector128((UInt64*)(&test._fld1)), + AdvSimd.LoadVector128((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] left, Int64[] right, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.Byte.cs new file mode 100644 index 0000000000000..6900a082bf0e5 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.Byte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector64_Byte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector64_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, SByte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Byte testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Byte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Byte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Byte(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Byte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Byte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] left, SByte[] right, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.Int16.cs new file mode 100644 index 0000000000000..69ee56fceeaa1 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector64_Int16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int16 testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Int16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int16(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Int16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.Int32.cs new file mode 100644 index 0000000000000..5e2541004b9aa --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector64_Int32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int32 testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Int32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int32(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((Int32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.SByte.cs new file mode 100644 index 0000000000000..94df562d5b2ed --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector64_SByte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_SByte testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((SByte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_SByte(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((SByte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.UInt16.cs new file mode 100644 index 0000000000000..4c192beb8bd31 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.UInt16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector64_UInt16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector64_UInt16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, Int16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt16 testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((UInt16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt16(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((UInt16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] left, Int16[] right, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.UInt32.cs new file mode 100644 index 0000000000000..69dac65171824 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRounded.Vector64.UInt32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRounded_Vector64_UInt32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRounded_Vector64_UInt32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, Int32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt32 testClass) + { + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRounded( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRounded), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRounded( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((UInt32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRounded(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt32(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRounded_Vector64_UInt32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRounded(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRounded( + AdvSimd.LoadVector64((UInt32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] left, Int32[] right, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRounded)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Byte.cs new file mode 100644 index 0000000000000..2cd0b999b78d4 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Byte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector128_Byte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector128_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, SByte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Byte testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Byte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Byte*)(pClsVar1)), + AdvSimd.LoadVector128((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Byte(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Byte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Byte*)(&test._fld1)), + AdvSimd.LoadVector128((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] left, SByte[] right, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Int16.cs new file mode 100644 index 0000000000000..f30b6ec4362a5 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector128_Int16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector128_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int16 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int16*)(pClsVar1)), + AdvSimd.LoadVector128((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int16(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int16(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int16*)(&test._fld1)), + AdvSimd.LoadVector128((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Int32.cs new file mode 100644 index 0000000000000..7e2955eeed17c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector128_Int32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector128_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int32 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int32*)(pClsVar1)), + AdvSimd.LoadVector128((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int32(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int32(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int32*)(&test._fld1)), + AdvSimd.LoadVector128((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Int64.cs new file mode 100644 index 0000000000000..6d998963744c6 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.Int64.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector128_Int64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector128_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int64 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int64*)(pClsVar1)), + AdvSimd.LoadVector128((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int64(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_Int64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((Int64*)(&test._fld1)), + AdvSimd.LoadVector128((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.SByte.cs new file mode 100644 index 0000000000000..e40d14267f656 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector128_SByte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector128_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_SByte testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_SByte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((SByte*)(pClsVar1)), + AdvSimd.LoadVector128((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_SByte(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_SByte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((SByte*)(&test._fld1)), + AdvSimd.LoadVector128((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.UInt16.cs new file mode 100644 index 0000000000000..8229fd275f561 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.UInt16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector128_UInt16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector128_UInt16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, Int16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt16 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt16*)(pClsVar1)), + AdvSimd.LoadVector128((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt16(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt16(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt16*)(&test._fld1)), + AdvSimd.LoadVector128((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] left, Int16[] right, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.UInt32.cs new file mode 100644 index 0000000000000..7521227343c5f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.UInt32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector128_UInt32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector128_UInt32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, Int32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt32 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt32*)(pClsVar1)), + AdvSimd.LoadVector128((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt32(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt32(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt32*)(&test._fld1)), + AdvSimd.LoadVector128((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] left, Int32[] right, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.UInt64.cs new file mode 100644 index 0000000000000..ec46a3264433f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector128.UInt64.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector128_UInt64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector128_UInt64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, Int64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt64 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt64*)(pClsVar1)), + AdvSimd.LoadVector128((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt64(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector128_UInt64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector128((UInt64*)(&test._fld1)), + AdvSimd.LoadVector128((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] left, Int64[] right, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.Byte.cs new file mode 100644 index 0000000000000..efb2d9b2233a0 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.Byte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector64_Byte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector64_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, SByte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Byte testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Byte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Byte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Byte(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Byte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Byte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] left, SByte[] right, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.Int16.cs new file mode 100644 index 0000000000000..200aad4b36ba9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector64_Int16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int16 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Int16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int16(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Int16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.Int32.cs new file mode 100644 index 0000000000000..6774c82376837 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector64_Int32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int32 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Int32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int32(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((Int32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.SByte.cs new file mode 100644 index 0000000000000..ea82600c3c146 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector64_SByte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_SByte testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((SByte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_SByte(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((SByte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.UInt16.cs new file mode 100644 index 0000000000000..c88b0d3b534b7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.UInt16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector64_UInt16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector64_UInt16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, Int16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt16 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((UInt16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt16(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((UInt16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] left, Int16[] right, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.UInt32.cs new file mode 100644 index 0000000000000..051dd2eb1ef1e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturate.Vector64.UInt32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturate_Vector64_UInt32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturate_Vector64_UInt32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, Int32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt32 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((UInt32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt32(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturate_Vector64_UInt32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturate( + AdvSimd.LoadVector64((UInt32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] left, Int32[] right, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturateScalar.Vector64.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturateScalar.Vector64.Int64.cs new file mode 100644 index 0000000000000..bc197aa8ba534 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturateScalar.Vector64.Int64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturateScalar_Vector64_Int64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturateScalar_Vector64_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int64 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar1)), + AdvSimd.LoadVector64((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int64(); + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_Int64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld1)), + AdvSimd.LoadVector64((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturateScalar.Vector64.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturateScalar.Vector64.UInt64.cs new file mode 100644 index 0000000000000..b4ac5ec3e07f9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedSaturateScalar.Vector64.UInt64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedSaturateScalar_Vector64_UInt64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedSaturateScalar_Vector64_UInt64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, Int64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt64 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pClsVar1)), + AdvSimd.LoadVector64((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt64(); + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedSaturateScalar_Vector64_UInt64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(&test._fld1)), + AdvSimd.LoadVector64((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] left, Int64[] right, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedScalar.Vector64.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedScalar.Vector64.Int64.cs new file mode 100644 index 0000000000000..64738a692c27d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedScalar.Vector64.Int64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedScalar_Vector64_Int64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedScalar_Vector64_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_Int64 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_Int64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar1)), + AdvSimd.LoadVector64((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_Int64(); + var result = AdvSimd.ShiftLogicalRoundedScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_Int64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld1)), + AdvSimd.LoadVector64((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalRounded(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedScalar.Vector64.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedScalar.Vector64.UInt64.cs new file mode 100644 index 0000000000000..2730747125f70 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalRoundedScalar.Vector64.UInt64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalRoundedScalar_Vector64_UInt64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_UInt64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalRoundedScalar_Vector64_UInt64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, Int64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_UInt64 testClass) + { + var result = AdvSimd.ShiftLogicalRoundedScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_UInt64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedScalar( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_UInt64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_UInt64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalRoundedScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalRoundedScalar( + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalRoundedScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalRoundedScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalRoundedScalar( + AdvSimd.LoadVector64((UInt64*)(pClsVar1)), + AdvSimd.LoadVector64((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalRoundedScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalRoundedScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_UInt64(); + var result = AdvSimd.ShiftLogicalRoundedScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalRoundedScalar_Vector64_UInt64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalRoundedScalar( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalRoundedScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalRoundedScalar( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalRoundedScalar( + AdvSimd.LoadVector64((UInt64*)(&test._fld1)), + AdvSimd.LoadVector64((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] left, Int64[] right, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalRounded(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalRoundedScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Byte.cs new file mode 100644 index 0000000000000..4ebbb7b4b57dc --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Byte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector128_Byte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector128_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, SByte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Byte testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Byte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Byte*)(pClsVar1)), + AdvSimd.LoadVector128((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Byte(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Byte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Byte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Byte*)(&test._fld1)), + AdvSimd.LoadVector128((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] left, SByte[] right, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Int16.cs new file mode 100644 index 0000000000000..d58b5729da45c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector128_Int16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector128_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int16 testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int16*)(pClsVar1)), + AdvSimd.LoadVector128((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int16(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int16(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int16*)(&test._fld1)), + AdvSimd.LoadVector128((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Int32.cs new file mode 100644 index 0000000000000..7343fdb20232d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector128_Int32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector128_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int32 testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int32*)(pClsVar1)), + AdvSimd.LoadVector128((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int32(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int32(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int32*)(&test._fld1)), + AdvSimd.LoadVector128((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Int64.cs new file mode 100644 index 0000000000000..a5e0dd7d875cb --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.Int64.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector128_Int64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector128_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int64 testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int64*)(pClsVar1)), + AdvSimd.LoadVector128((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int64(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_Int64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((Int64*)(&test._fld1)), + AdvSimd.LoadVector128((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.SByte.cs new file mode 100644 index 0000000000000..b6943048c6175 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector128_SByte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector128_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_SByte testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_SByte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((SByte*)(pClsVar1)), + AdvSimd.LoadVector128((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_SByte(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_SByte(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((SByte*)(pFld1)), + AdvSimd.LoadVector128((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((SByte*)(&test._fld1)), + AdvSimd.LoadVector128((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.UInt16.cs new file mode 100644 index 0000000000000..b3e37eea5b4f6 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.UInt16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector128_UInt16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector128_UInt16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, Int16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt16 testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt16*)(pClsVar1)), + AdvSimd.LoadVector128((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt16(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt16(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt16*)(pFld1)), + AdvSimd.LoadVector128((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt16*)(&test._fld1)), + AdvSimd.LoadVector128((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] left, Int16[] right, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.UInt32.cs new file mode 100644 index 0000000000000..1ed51fb67edc0 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.UInt32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector128_UInt32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector128_UInt32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, Int32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt32 testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt32*)(pClsVar1)), + AdvSimd.LoadVector128((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt32(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt32(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt32*)(pFld1)), + AdvSimd.LoadVector128((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt32*)(&test._fld1)), + AdvSimd.LoadVector128((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] left, Int32[] right, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.UInt64.cs new file mode 100644 index 0000000000000..1c43ef1a55eba --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector128.UInt64.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector128_UInt64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector128_UInt64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, Int64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt64 testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt64 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + fixed (Vector128* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt64*)(pClsVar1)), + AdvSimd.LoadVector128((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt64(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector128_UInt64(); + + fixed (Vector128* pFld1 = &test._fld1) + fixed (Vector128* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + fixed (Vector128* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt64*)(pFld1)), + AdvSimd.LoadVector128((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector128((UInt64*)(&test._fld1)), + AdvSimd.LoadVector128((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, Vector128 op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] left, Int64[] right, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector128, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.Byte.cs new file mode 100644 index 0000000000000..e44da8d4c8a59 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.Byte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector64_Byte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector64_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, SByte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Byte testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Byte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Byte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Byte(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Byte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Byte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Byte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] left, SByte[] right, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.Int16.cs new file mode 100644 index 0000000000000..00e63b170038c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.Int16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector64_Int16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int16 testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Int16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int16(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Int16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Int16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.Int32.cs new file mode 100644 index 0000000000000..699d531bccd70 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.Int32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector64_Int32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int32 testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Int32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int32(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Int32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((Int32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.SByte.cs new file mode 100644 index 0000000000000..0001fd5a0afdf --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.SByte.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector64_SByte() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_SByte testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((SByte*)(pClsVar1)), + AdvSimd.LoadVector64((SByte*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_SByte(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((SByte*)(pFld1)), + AdvSimd.LoadVector64((SByte*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((SByte*)(&test._fld1)), + AdvSimd.LoadVector64((SByte*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.UInt16.cs new file mode 100644 index 0000000000000..c58411177c5fb --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.UInt16.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector64_UInt16() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector64_UInt16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, Int16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt16 testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((UInt16*)(pClsVar1)), + AdvSimd.LoadVector64((Int16*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt16(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt16(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((UInt16*)(pFld1)), + AdvSimd.LoadVector64((Int16*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((UInt16*)(&test._fld1)), + AdvSimd.LoadVector64((Int16*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] left, Int16[] right, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.UInt32.cs new file mode 100644 index 0000000000000..91e08ee024806 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturate.Vector64.UInt32.cs @@ -0,0 +1,530 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturate_Vector64_UInt32() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturate_Vector64_UInt32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, Int32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt32 testClass) + { + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturate( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturate), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturate( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((UInt32*)(pClsVar1)), + AdvSimd.LoadVector64((Int32*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturate(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt32(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturate_Vector64_UInt32(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturate(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((UInt32*)(pFld1)), + AdvSimd.LoadVector64((Int32*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturate( + AdvSimd.LoadVector64((UInt32*)(&test._fld1)), + AdvSimd.LoadVector64((Int32*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] left, Int32[] right, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturate)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturateScalar.Vector64.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturateScalar.Vector64.Int64.cs new file mode 100644 index 0000000000000..4d9371ef77e55 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturateScalar.Vector64.Int64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturateScalar_Vector64_Int64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturateScalar_Vector64_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int64 testClass) + { + var result = AdvSimd.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar1)), + AdvSimd.LoadVector64((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int64(); + var result = AdvSimd.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_Int64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld1)), + AdvSimd.LoadVector64((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturateScalar.Vector64.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturateScalar.Vector64.UInt64.cs new file mode 100644 index 0000000000000..337a8d3e6c3e4 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalSaturateScalar.Vector64.UInt64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalSaturateScalar_Vector64_UInt64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalSaturateScalar_Vector64_UInt64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, Int64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt64 testClass) + { + var result = AdvSimd.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalSaturateScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalSaturateScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalSaturateScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pClsVar1)), + AdvSimd.LoadVector64((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalSaturateScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt64(); + var result = AdvSimd.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalSaturateScalar_Vector64_UInt64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalSaturateScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturateScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalSaturateScalar( + AdvSimd.LoadVector64((UInt64*)(&test._fld1)), + AdvSimd.LoadVector64((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] left, Int64[] right, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalSaturateScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalScalar.Vector64.Int64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalScalar.Vector64.Int64.cs new file mode 100644 index 0000000000000..558309f83f7d7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalScalar.Vector64.Int64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalScalar_Vector64_Int64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_Int64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalScalar_Vector64_Int64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_Int64 testClass) + { + var result = AdvSimd.ShiftLogicalScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_Int64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_Int64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_Int64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar1)), + AdvSimd.LoadVector64((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_Int64(); + var result = AdvSimd.ShiftLogicalScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_Int64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalScalar( + AdvSimd.LoadVector64((Int64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld1)), + AdvSimd.LoadVector64((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogical(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalScalar.Vector64.UInt64.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalScalar.Vector64.UInt64.cs new file mode 100644 index 0000000000000..32852fe910875 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftLogicalScalar.Vector64.UInt64.cs @@ -0,0 +1,537 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftLogicalScalar_Vector64_UInt64() + { + var test = new SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_UInt64(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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__ShiftLogicalScalar_Vector64_UInt64 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, Int64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_UInt64 testClass) + { + var result = AdvSimd.ShiftLogicalScalar(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_UInt64 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_UInt64() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_UInt64() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftLogicalScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftLogicalScalar), new Type[] { typeof(Vector64), typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftLogicalScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + fixed (Vector64* pClsVar2 = &_clsVar2) + { + var result = AdvSimd.ShiftLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(pClsVar1)), + AdvSimd.LoadVector64((Int64*)(pClsVar2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var op2 = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftLogicalScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)); + var op2 = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftLogicalScalar(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_UInt64(); + var result = AdvSimd.ShiftLogicalScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleBinaryOpTest__ShiftLogicalScalar_Vector64_UInt64(); + + fixed (Vector64* pFld1 = &test._fld1) + fixed (Vector64* pFld2 = &test._fld2) + { + var result = AdvSimd.ShiftLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftLogicalScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + fixed (Vector64* pFld2 = &_fld2) + { + var result = AdvSimd.ShiftLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(pFld1)), + AdvSimd.LoadVector64((Int64*)(pFld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(&test._fld1)), + AdvSimd.LoadVector64((Int64*)(&test._fld2)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, Vector64 op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), op2); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] left, Int64[] right, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftLogical(left[0], right[0]) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftLogicalScalar)}(Vector64, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})"); + TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..4e3319ae8f00f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmetic_Vector128_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmetic( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmetic( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmetic)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..fe035aa7fccdd --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmetic_Vector128_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmetic( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmetic( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmetic)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.Int64.1.cs new file mode 100644 index 0000000000000..26f054d9c91a2 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.Int64.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmetic_Vector128_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int64_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmetic( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmetic( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int64_1(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector128_Int64_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmetic)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..da629e612199e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector128.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmetic_Vector128_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmetic_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmetic_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmetic_Vector128_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmetic_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmetic_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmetic( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmetic( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector128_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector128((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmetic)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..a320af6aca1f4 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmetic_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmetic( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmetic( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmetic)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..dd54b73ec1fa5 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmetic_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmetic( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmetic( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector64_Int32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmetic)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..679ec212fd4a0 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmetic.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmetic_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmetic_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmetic_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmetic_Vector64_SByte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmetic_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmetic_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmetic( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmetic), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmetic( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmetic(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmetic_Vector64_SByte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmetic(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmetic( + AdvSimd.LoadVector64((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmetic)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..f6cfec500ddd5 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticAdd_Vector128_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..a649bbe23ad9f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticAdd_Vector128_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.Int64.1.cs new file mode 100644 index 0000000000000..59d05eb5e6f1a --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.Int64.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticAdd_Vector128_Int64_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int64_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_Int64_1(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] secondOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..647925c244f7e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector128.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticAdd_Vector128_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..1c3c5188783bd --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector64.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticAdd_Vector64_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..6b88a50c83c9e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector64.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticAdd_Vector64_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..a965bf1f6fcb3 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAdd.Vector64.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticAdd_Vector64_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticAdd_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAddScalar.Vector64.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAddScalar.Vector64.Int64.1.cs new file mode 100644 index 0000000000000..20967cdf7a39e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticAddScalar.Vector64.Int64.1.cs @@ -0,0 +1,423 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticAddScalar_Vector64_Int64_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticAddScalar_Vector64_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticAddScalar_Vector64_Int64_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticAddScalar_Vector64_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticAddScalar(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticAddScalar_Vector64_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticAddScalar_Vector64_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticAddScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticAddScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAddScalar), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticAddScalar), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticAddScalar( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticAddScalar(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticAddScalar(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticAddScalar_Vector64_Int64_1(); + var result = AdvSimd.ShiftRightArithmeticAddScalar(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticAddScalar(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticAddScalar(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] secondOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticAdd(firstOp[0], secondOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticAddScalar)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..2413bc6b2ba11 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..7eef60a65ab6c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateLower.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateLower.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateLower.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..f0e6ad42ea508 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateLower.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..2fb415b1ae312 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..25f65d74f4846 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..b13144c8dd51d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedLower.Vector64.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.Byte.1.cs new file mode 100644 index 0000000000000..693d0330e6986 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.Byte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_Byte_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_Byte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, Int16[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_Byte_1(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Int16[] secondOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt16.1.cs new file mode 100644 index 0000000000000..a11c4073481c4 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt16_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, Int32[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt16_1(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, Int32[] secondOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt32.1.cs new file mode 100644 index 0000000000000..12b9fe456195d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUnsignedUpper.Vector128.UInt32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt32_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, Int64[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt32_1(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, Int64[] secondOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUnsignedUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..effa7d9d61c46 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int32[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..ce6c7ed79fdd7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUpper.Vector128.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int64[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUpper.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUpper.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..0679af81a644e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticNarrowingSaturateUpper.Vector128.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticNarrowingSaturateUpper_Vector128_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, Int16[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticNarrowingSaturateUpper_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Int16[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..89555ea94254d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRounded_Vector128_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRounded)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..217904fb6db4b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRounded_Vector128_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRounded)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.Int64.1.cs new file mode 100644 index 0000000000000..e4bd6b739214b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.Int64.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRounded_Vector128_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int64_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int64_1(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_Int64_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRounded)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..d3efbc420189b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector128.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRounded_Vector128_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector128_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector128((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRounded)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..9dba14a59013a --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRounded_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRounded)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..fdd6d7d9dc639 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRounded_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_Int32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRounded)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..8b2536f5443fd --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRounded.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRounded_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_SByte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRounded_Vector64_SByte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRounded( + AdvSimd.LoadVector64((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRounded)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..f914cf3643e28 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedAdd_Vector128_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..350750d981309 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedAdd_Vector128_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.Int64.1.cs new file mode 100644 index 0000000000000..16f6b29e7c9e8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.Int64.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedAdd_Vector128_Int64_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int64_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_Int64_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] secondOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..8dd2c523ddae2 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector128.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedAdd_Vector128_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..8a5a35b900b6c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector64.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedAdd_Vector64_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..cb541c555c574 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector64.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedAdd_Vector64_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..7b56cc89de3c5 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAdd.Vector64.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedAdd_Vector64_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAdd_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAddScalar.Vector64.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAddScalar.Vector64.Int64.1.cs new file mode 100644 index 0000000000000..fab88648a9b2e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedAddScalar.Vector64.Int64.1.cs @@ -0,0 +1,423 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedAddScalar_Vector64_Int64_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAddScalar_Vector64_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedAddScalar_Vector64_Int64_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedAddScalar_Vector64_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedAddScalar(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedAddScalar_Vector64_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedAddScalar_Vector64_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAddScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAddScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAddScalar), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedAddScalar), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAddScalar( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedAddScalar(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedAddScalar(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedAddScalar_Vector64_Int64_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedAddScalar(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedAddScalar(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedAddScalar(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] secondOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticRoundedAdd(firstOp[0], secondOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedAddScalar)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..d348c65cedd45 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..50550ce9104c1 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..f2466add87772 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateLower.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..cc8565df8d209 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..d5f79e43412fe --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..67dbbf7cb4db9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower.Vector64.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.Byte.1.cs new file mode 100644 index 0000000000000..b78b53582fda7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.Byte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_Byte_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_Byte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, Int16[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_Byte_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Int16[] secondOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt16.1.cs new file mode 100644 index 0000000000000..426b85cab078b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt16_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, Int32[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt16_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, Int32[] secondOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt32.1.cs new file mode 100644 index 0000000000000..bab5e30db1bd3 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper.Vector128.UInt32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt32_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, Int64[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt32_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, Int64[] secondOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..43a8740b116b0 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int32[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..3b1ee352ffcb1 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int64[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..4e185da5d4181 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedNarrowingSaturateUpper.Vector128.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, Int16[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Int16[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedScalar.Vector64.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedScalar.Vector64.Int64.1.cs new file mode 100644 index 0000000000000..d4c91308c4484 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticRoundedScalar.Vector64.Int64.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticRoundedScalar_Vector64_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedScalar_Vector64_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticRoundedScalar_Vector64_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticRoundedScalar_Vector64_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticRoundedScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticRoundedScalar_Vector64_Int64_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticRoundedScalar_Vector64_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticRoundedScalar_Vector64_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticRoundedScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticRoundedScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticRoundedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticRoundedScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticRoundedScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedScalar_Vector64_Int64_1(); + var result = AdvSimd.ShiftRightArithmeticRoundedScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticRoundedScalar_Vector64_Int64_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticRoundedScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticRoundedScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmeticRounded(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticRoundedScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticScalar.Vector64.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticScalar.Vector64.Int64.1.cs new file mode 100644 index 0000000000000..0bad044604de1 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightArithmeticScalar.Vector64.Int64.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightArithmeticScalar_Vector64_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftRightArithmeticScalar_Vector64_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightArithmeticScalar_Vector64_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightArithmeticScalar_Vector64_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightArithmeticScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightArithmeticScalar_Vector64_Int64_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightArithmeticScalar_Vector64_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightArithmeticScalar_Vector64_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightArithmeticScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightArithmeticScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightArithmeticScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightArithmeticScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightArithmeticScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightArithmeticScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightArithmeticScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticScalar_Vector64_Int64_1(); + var result = AdvSimd.ShiftRightArithmeticScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightArithmeticScalar_Vector64_Int64_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightArithmeticScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightArithmeticScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightArithmeticScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightArithmeticScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightArithmetic(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightArithmeticScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Byte.1.cs new file mode 100644 index 0000000000000..23729809ef4ea --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector128_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector128_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector128_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector128_Byte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector128_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector128_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Byte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_Byte_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_Byte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Byte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..2f0d94b5684b4 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector128_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector128_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..4e46a2a8f38f3 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector128_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector128_Int32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_Int32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Int64.1.cs new file mode 100644 index 0000000000000..ccf01b612b3c8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.Int64.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector128_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector128_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector128_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector128_Int64_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector128_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector128_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_Int64_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_Int64_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..72d2dff64eeeb --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector128_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector128_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.UInt16.1.cs new file mode 100644 index 0000000000000..8aa45d8f47147 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector128_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt16_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.UInt32.1.cs new file mode 100644 index 0000000000000..9bf9e8fec1790 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector128_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt32_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.UInt64.1.cs new file mode 100644 index 0000000000000..446fa4cf0889a --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector128.UInt64.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector128_UInt64_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt64_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt64_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt64_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector128_UInt64_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector128((UInt64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..ade6a58e16b82 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector64_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector64_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector64_Byte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Byte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_Byte_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_Byte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Byte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..c6d9f765d8206 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector64_Int16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_Int16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..cb700766e8946 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector64_Int32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_Int32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..764ca4d3e6312 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector64_SByte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_SByte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..8fad7e0be9070 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt16_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..e979a7d7ce6e9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogical.Vector64.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogical_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogical( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogical), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogical( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogical(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt32_1(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogical_Vector64_UInt32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogical(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogical( + AdvSimd.LoadVector64((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogical)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Byte.1.cs new file mode 100644 index 0000000000000..d5acb54a342d1 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Byte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector128_Byte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Byte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static Byte[] _data2 = new Byte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Byte_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, 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(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, 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(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] secondOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..1478fae32d881 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector128_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..f0194aafc6ef8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector128_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Int64.1.cs new file mode 100644 index 0000000000000..806d40762d425 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.Int64.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector128_Int64_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int64_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_Int64_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] secondOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..f63edb600924e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector128_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.UInt16.1.cs new file mode 100644 index 0000000000000..26aa47a7e2dc7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.UInt16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector128_UInt16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static UInt16[] _data2 = new UInt16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] secondOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.UInt32.1.cs new file mode 100644 index 0000000000000..8dc3c3e367d11 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.UInt32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector128_UInt32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static UInt32[] _data2 = new UInt32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] secondOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.UInt64.1.cs new file mode 100644 index 0000000000000..96703c835b70c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector128.UInt64.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector128_UInt64_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt64_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static UInt64[] _data2 = new UInt64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector128_UInt64_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] secondOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..6ebb0db2d3e09 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.Byte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector64_Byte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static Byte[] _data2 = new Byte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Byte_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, 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(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, 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(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] secondOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..b0629b1e843d8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector64_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..bc9794e058727 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector64_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..9e0306dd55dcd --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector64_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..5e8f29029f7aa --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.UInt16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector64_UInt16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static UInt16[] _data2 = new UInt16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] secondOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..daeee69415c29 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAdd.Vector64.UInt32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAdd_Vector64_UInt32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static UInt32[] _data2 = new UInt32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAdd( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAdd_Vector64_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] secondOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAddScalar.Vector64.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAddScalar.Vector64.Int64.1.cs new file mode 100644 index 0000000000000..f626835fc6c80 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAddScalar.Vector64.Int64.1.cs @@ -0,0 +1,423 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAddScalar_Vector64_Int64_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAddScalar_Vector64_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAddScalar_Vector64_Int64_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAddScalar_Vector64_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAddScalar(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAddScalar_Vector64_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAddScalar_Vector64_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAddScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAddScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAddScalar), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAddScalar), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAddScalar( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAddScalar(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAddScalar(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAddScalar_Vector64_Int64_1(); + var result = AdvSimd.ShiftRightLogicalAddScalar(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAddScalar(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAddScalar(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] secondOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalAdd(firstOp[0], secondOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAddScalar)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAddScalar.Vector64.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAddScalar.Vector64.UInt64.1.cs new file mode 100644 index 0000000000000..d03bd9052dd66 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalAddScalar.Vector64.UInt64.1.cs @@ -0,0 +1,423 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalAddScalar_Vector64_UInt64_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalAddScalar_Vector64_UInt64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalAddScalar_Vector64_UInt64_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalAddScalar_Vector64_UInt64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalAddScalar(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static UInt64[] _data2 = new UInt64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalAddScalar_Vector64_UInt64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalAddScalar_Vector64_UInt64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalAddScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalAddScalar( + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAddScalar), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalAddScalar), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalAddScalar( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalAddScalar(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalAddScalar(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalAddScalar_Vector64_UInt64_1(); + var result = AdvSimd.ShiftRightLogicalAddScalar(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalAddScalar(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalAddScalar(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] secondOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalAdd(firstOp[0], secondOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalAddScalar)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..16fad752e05f4 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingLower_Vector64_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Byte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Byte_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Byte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..34b14eb6cd3b3 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingLower_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..852862ee7d409 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingLower_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_Int32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..57bb8893ca506 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingLower_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..4508eb9a005a6 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingLower_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..7a94c47c21f05 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingLower.Vector64.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingLower_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingLower_Vector64_UInt32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingLower( + AdvSimd.LoadVector128((UInt64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..7f5dc434b8685 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..aae58ce73f2a4 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..a8068ef4cad65 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..64e843030bc48 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..3b5795724645b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..eeb668d918b3d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateLower.Vector64.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.Byte.1.cs new file mode 100644 index 0000000000000..635790706e213 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.Byte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateUpper_Vector128_Byte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Byte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, UInt16[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static UInt16[] _data2 = new UInt16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Byte_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..d711d91384e15 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int32[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..fb3922be3813c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int64[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..c961d2f62cbcf --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateUpper_Vector128_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, Int16[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Int16[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt16.1.cs new file mode 100644 index 0000000000000..9be98e796867b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, UInt32[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static UInt32[] _data2 = new UInt32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt32.1.cs new file mode 100644 index 0000000000000..4d002a582247e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingSaturateUpper.Vector128.UInt32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, UInt64[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static UInt64[] _data2 = new UInt64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.Byte.1.cs new file mode 100644 index 0000000000000..da2d8dc456c45 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.Byte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingUpper_Vector128_Byte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Byte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, UInt16[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static UInt16[] _data2 = new UInt16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Byte_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..74e1b9423981a --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingUpper_Vector128_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int32[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..84d216eabb414 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingUpper_Vector128_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int64[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..e4733c2473bc8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingUpper_Vector128_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, Int16[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Int16[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.UInt16.1.cs new file mode 100644 index 0000000000000..96c09e59c8f87 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.UInt16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingUpper_Vector128_UInt16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_UInt16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, UInt32[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static UInt32[] _data2 = new UInt32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.UInt32.1.cs new file mode 100644 index 0000000000000..7242b26c4f1b2 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalNarrowingUpper.Vector128.UInt32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalNarrowingUpper_Vector128_UInt32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_UInt32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, UInt64[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static UInt64[] _data2 = new UInt64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalNarrowingUpper_Vector128_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalNarrowingUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Byte.1.cs new file mode 100644 index 0000000000000..a05c067ffb061 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector128_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Byte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Byte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Byte_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Byte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Byte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..31f296e8222b7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector128_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..38a7d2ce38d11 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector128_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Int64.1.cs new file mode 100644 index 0000000000000..e90d9eb023e3a --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.Int64.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector128_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int64_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int64_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_Int64_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..2634b2403d767 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector128_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.UInt16.1.cs new file mode 100644 index 0000000000000..6dae0d74e01fb --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector128_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.UInt32.1.cs new file mode 100644 index 0000000000000..c3cf5d1549f42 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector128_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.UInt64.1.cs new file mode 100644 index 0000000000000..c82471766d7cc --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector128.UInt64.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector128_UInt64_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt64_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt64_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector128_UInt64_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector128((UInt64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..c58b5475c7826 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector64_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Byte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Byte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Byte_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Byte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Byte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Byte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..2cdf79c7a1f0f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..2acebaf78c567 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_Int32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..70c35c236dc33 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_SByte_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((SByte*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_SByte_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((SByte*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((SByte*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..4dce61b5e8598 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt16_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt16_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..49a59f1782dad --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRounded.Vector64.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRounded_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt32_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRounded( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRounded), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRounded(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRounded_Vector64_UInt32_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRounded(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRounded( + AdvSimd.LoadVector64((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRounded)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Byte.1.cs new file mode 100644 index 0000000000000..5ae6329b39111 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Byte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector128_Byte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Byte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static Byte[] _data2 = new Byte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Byte_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, 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(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, 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(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] secondOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..f235a22a9c496 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector128_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..9e450700e34f0 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector128_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Int64.1.cs new file mode 100644 index 0000000000000..51c1822310817 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.Int64.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector128_Int64_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int64_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_Int64_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] secondOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..16df705fe083f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector128_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.UInt16.1.cs new file mode 100644 index 0000000000000..6a96d773637e7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.UInt16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector128_UInt16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static UInt16[] _data2 = new UInt16[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] secondOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.UInt32.1.cs new file mode 100644 index 0000000000000..89c7ff5e8a109 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.UInt32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector128_UInt32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static UInt32[] _data2 = new UInt32[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] secondOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.UInt64.1.cs new file mode 100644 index 0000000000000..1c72cd0d481e2 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector128.UInt64.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector128_UInt64_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt64_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static UInt64[] _data2 = new UInt64[Op2ElementCount]; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector128_UInt64_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] secondOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector128.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..0a86b96dcfe61 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.Byte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector64_Byte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static Byte[] _data2 = new Byte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Byte_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, 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(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, 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(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] secondOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..e576757b44c44 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector64_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..6549868f8e13e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector64_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..7d835b05b6d39 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector64_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static SByte[] _data2 = new SByte[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + SByte[] inArray2 = new SByte[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..dedaac14dda3e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.UInt16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector64_UInt16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static UInt16[] _data2 = new UInt16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] secondOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..01774f2655abc --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAdd.Vector64.UInt32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAdd_Vector64_UInt32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static UInt32[] _data2 = new UInt32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAdd), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAdd_Vector64_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAdd(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAdd(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] secondOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAdd)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAddScalar.Vector64.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAddScalar.Vector64.Int64.1.cs new file mode 100644 index 0000000000000..a959472163435 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAddScalar.Vector64.Int64.1.cs @@ -0,0 +1,423 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAddScalar_Vector64_Int64_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAddScalar_Vector64_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAddScalar_Vector64_Int64_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAddScalar_Vector64_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data1 = new Int64[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAddScalar_Vector64_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAddScalar_Vector64_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAddScalar), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAddScalar), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAddScalar_Vector64_Int64_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray1 = new Int64[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] secondOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[0], secondOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAddScalar)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAddScalar.Vector64.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAddScalar.Vector64.UInt64.1.cs new file mode 100644 index 0000000000000..5211283aa4848 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedAddScalar.Vector64.UInt64.1.cs @@ -0,0 +1,423 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedAddScalar_Vector64_UInt64_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAddScalar_Vector64_UInt64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedAddScalar_Vector64_UInt64_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector64 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedAddScalar_Vector64_UInt64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt64[] _data1 = new UInt64[Op1ElementCount]; + private static UInt64[] _data2 = new UInt64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector64 _clsVar2; + + private Vector64 _fld1; + private Vector64 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedAddScalar_Vector64_UInt64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedAddScalar_Vector64_UInt64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar( + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAddScalar), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedAddScalar), new Type[] { typeof(Vector64), typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedAddScalar_Vector64_UInt64_1(); + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedAddScalar(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector64 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray1 = new UInt64[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] secondOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalRoundedAdd(firstOp[0], secondOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedAddScalar)}(Vector64.1, Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..9d870d5e424ed --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..5f25720d78acb --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..d11de0aeaa62f --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..2548dc60a827c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..2d1123813c1f8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..d872562d59d86 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingLower.Vector64.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingLower( + AdvSimd.LoadVector128((UInt64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Byte.1.cs new file mode 100644 index 0000000000000..3d52447cf9a04 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Byte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray, Byte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int16.1.cs new file mode 100644 index 0000000000000..ee9b1741fa829 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray, Int16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int16_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int32.1.cs new file mode 100644 index 0000000000000..9baab4e0f4950 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.Int32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int32_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.SByte.1.cs new file mode 100644 index 0000000000000..c4e1483ad181d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.SByte.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_SByte_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_SByte_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray, SByte[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_SByte_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_SByte_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_SByte_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((Int16*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt16.1.cs new file mode 100644 index 0000000000000..435f4db3c6932 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt16.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray, UInt16[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt32*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt32*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt32*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt32.1.cs new file mode 100644 index 0000000000000..55728404f1147 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateLower.Vector64.UInt32.1.cs @@ -0,0 +1,500 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt32[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1 testClass) + { + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1(); + + fixed (Vector128* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower( + AdvSimd.LoadVector128((UInt64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateLower)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Byte.1.cs new file mode 100644 index 0000000000000..01298deaf16ab --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Byte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Byte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Byte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, UInt16[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static UInt16[] _data2 = new UInt16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Byte_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..e3224aaedb025 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int32[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..c8855546345e2 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int64[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..6fd123737b4c1 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, Int16[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Int16[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt16.1.cs new file mode 100644 index 0000000000000..4a500aac8380d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, UInt32[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static UInt32[] _data2 = new UInt32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt32.1.cs new file mode 100644 index 0000000000000..572bf22ff0834 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingSaturateUpper.Vector128.UInt32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, UInt64[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static UInt64[] _data2 = new UInt64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingSaturateUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.Byte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.Byte.1.cs new file mode 100644 index 0000000000000..ab9fd0abfbf3d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.Byte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingUpper_Vector128_Byte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Byte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Byte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, UInt16[] inArray2, Byte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Byte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly byte Imm = 1; + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + private static UInt16[] _data2 = new UInt16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Byte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Byte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Byte_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + UInt16[] inArray2 = new UInt16[Op2ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, UInt16[] secondOp, Byte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int16.1.cs new file mode 100644 index 0000000000000..790ad2d1fb5f7 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int32[] inArray2, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly byte Imm = 1; + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + private static Int32[] _data2 = new Int32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int16_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] inArray2 = new Int32[Op2ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int32[] secondOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int32.1.cs new file mode 100644 index 0000000000000..d1da09400aa09 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.Int32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int64[] inArray2, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly byte Imm = 1; + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + private static Int64[] _data2 = new Int64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int32_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] inArray2 = new Int64[Op2ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int64[] secondOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.SByte.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.SByte.1.cs new file mode 100644 index 0000000000000..c909836b973bf --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.SByte.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingUpper_Vector128_SByte_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_SByte_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_SByte_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, Int16[] inArray2, SByte[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_SByte_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly byte Imm = 1; + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + private static Int16[] _data2 = new Int16[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_SByte_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_SByte_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_SByte_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] inArray2 = new Int16[Op2ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Int16[] secondOp, SByte[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt16.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt16.1.cs new file mode 100644 index 0000000000000..aebf41292401d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt16.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt16_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt16_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt16_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, UInt32[] inArray2, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt16_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly byte Imm = 1; + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + private static UInt32[] _data2 = new UInt32[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt16_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt16_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt16_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt32[] inArray2 = new UInt32[Op2ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt32[] secondOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt32.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt32.1.cs new file mode 100644 index 0000000000000..17296820b88b8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedNarrowingUpper.Vector128.UInt32.1.cs @@ -0,0 +1,416 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt32_1() + { + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt32_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt32_1 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, UInt64[] inArray2, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt32_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int Op2ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly byte Imm = 1; + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + private static UInt64[] _data2 = new UInt64[Op2ElementCount]; + + private static Vector64 _clsVar1; + private static Vector128 _clsVar2; + + private Vector64 _fld1; + private Vector128 _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt32_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt32_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper), new Type[] { typeof(Vector64), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)), + AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var secondOp = AdvSimd.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt32_1(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedNarrowingUpper(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, Vector128 secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt64[] inArray2 = new UInt64[Op2ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt64[] secondOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedNarrowingUpper)}(Vector64.1, Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedScalar.Vector64.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedScalar.Vector64.Int64.1.cs new file mode 100644 index 0000000000000..927ae9381968b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedScalar.Vector64.Int64.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedScalar_Vector64_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_Int64_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_Int64_1(); + var result = AdvSimd.ShiftRightLogicalRoundedScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_Int64_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalRounded(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedScalar.Vector64.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedScalar.Vector64.UInt64.1.cs new file mode 100644 index 0000000000000..ea06b0df0464d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalRoundedScalar.Vector64.UInt64.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalRoundedScalar_Vector64_UInt64_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_UInt64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_UInt64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_UInt64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalRoundedScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_UInt64_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_UInt64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_UInt64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalRoundedScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + AdvSimd.LoadVector64((UInt64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalRoundedScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalRoundedScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_UInt64_1(); + var result = AdvSimd.ShiftRightLogicalRoundedScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalRoundedScalar_Vector64_UInt64_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalRoundedScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalRoundedScalar( + AdvSimd.LoadVector64((UInt64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogicalRounded(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalRoundedScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalScalar.Vector64.Int64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalScalar.Vector64.Int64.1.cs new file mode 100644 index 0000000000000..033371510253a --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalScalar.Vector64.Int64.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalScalar_Vector64_Int64_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_Int64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_Int64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int64[] inArray, Int64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_Int64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_Int64_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly byte Imm = 1; + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_Int64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_Int64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); } + _dataTable = new DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalScalar( + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalScalar( + AdvSimd.LoadVector64((Int64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((Int64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_Int64_1(); + var result = AdvSimd.ShiftRightLogicalScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_Int64_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalScalar( + AdvSimd.LoadVector64((Int64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalScalar( + AdvSimd.LoadVector64((Int64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogical(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalScalar.Vector64.UInt64.1.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalScalar.Vector64.UInt64.1.cs new file mode 100644 index 0000000000000..1a5d9712e937b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ShiftRightLogicalScalar.Vector64.UInt64.1.cs @@ -0,0 +1,507 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ShiftRightLogicalScalar_Vector64_UInt64_1() + { + var test = new ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_UInt64_1(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_UInt64_1 + { + private struct DataTable + { + private byte[] inArray; + private byte[] outArray; + + private GCHandle inHandle; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt64[] inArray, UInt64[] outArray, int alignment) + { + int sizeOfinArray = inArray.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArrayPtr), ref Unsafe.As(ref inArray[0]), (uint)sizeOfinArray); + } + + public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_UInt64_1 testClass) + { + var result = AdvSimd.ShiftRightLogicalScalar(_fld, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_UInt64_1 testClass) + { + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 8; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly byte Imm = 1; + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector64 _clsVar; + + private Vector64 _fld; + + private DataTable _dataTable; + + static ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_UInt64_1() + { + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_UInt64_1() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); } + _dataTable = new DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ShiftRightLogicalScalar( + Unsafe.Read>(_dataTable.inArrayPtr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ShiftRightLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ShiftRightLogicalScalar), new Type[] { typeof(Vector64), typeof(byte) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ShiftRightLogicalScalar( + _clsVar, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar = &_clsVar) + { + var result = AdvSimd.ShiftRightLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(pClsVar)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = AdvSimd.ShiftRightLogicalScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = AdvSimd.LoadVector64((UInt64*)(_dataTable.inArrayPtr)); + var result = AdvSimd.ShiftRightLogicalScalar(firstOp, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_UInt64_1(); + var result = AdvSimd.ShiftRightLogicalScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new ImmUnaryOpTest__ShiftRightLogicalScalar_Vector64_UInt64_1(); + + fixed (Vector64* pFld = &test._fld) + { + var result = AdvSimd.ShiftRightLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ShiftRightLogicalScalar(_fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld = &_fld) + { + var result = AdvSimd.ShiftRightLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(pFld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalScalar(test._fld, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ShiftRightLogicalScalar( + AdvSimd.LoadVector64((UInt64*)(&test._fld)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + if (Helpers.ShiftRightLogical(firstOp[0], Imm) != result[0]) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + if (result[i] != 0) + { + succeeded = false; + break; + } + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ShiftRightLogicalScalar)}(Vector64, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningLower.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningLower.Vector64.Int16.cs new file mode 100644 index 0000000000000..56f22324ee1d6 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningLower.Vector64.Int16.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void SignExtendWideningLower_Vector64_Int16() + { + var test = new SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int16 testClass) + { + var result = AdvSimd.SignExtendWideningLower(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((Int16*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar1; + + private Vector64 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.SignExtendWideningLower( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SignExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SignExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.SignExtendWideningLower( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((Int16*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.SignExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.SignExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int16(); + var result = AdvSimd.SignExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + { + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((Int16*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.SignExtendWideningLower(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((Int16*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.SignExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((Int16*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.SignExtendWidening(firstOp[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SignExtendWideningLower)}(Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningLower.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningLower.Vector64.Int32.cs new file mode 100644 index 0000000000000..2a4f37f3de22c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningLower.Vector64.Int32.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void SignExtendWideningLower_Vector64_Int32() + { + var test = new SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int32 testClass) + { + var result = AdvSimd.SignExtendWideningLower(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((Int32*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar1; + + private Vector64 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.SignExtendWideningLower( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SignExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SignExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.SignExtendWideningLower( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((Int32*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.SignExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.SignExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int32(); + var result = AdvSimd.SignExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__SignExtendWideningLower_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + { + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((Int32*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.SignExtendWideningLower(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((Int32*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.SignExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((Int32*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.SignExtendWidening(firstOp[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SignExtendWideningLower)}(Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningLower.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningLower.Vector64.SByte.cs new file mode 100644 index 0000000000000..6e3505931d333 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningLower.Vector64.SByte.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void SignExtendWideningLower_Vector64_SByte() + { + var test = new SimpleUnaryOpTest__SignExtendWideningLower_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__SignExtendWideningLower_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__SignExtendWideningLower_Vector64_SByte testClass) + { + var result = AdvSimd.SignExtendWideningLower(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__SignExtendWideningLower_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((SByte*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar1; + + private Vector64 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__SignExtendWideningLower_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__SignExtendWideningLower_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.SignExtendWideningLower( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SignExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SignExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.SignExtendWideningLower( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((SByte*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.SignExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.SignExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__SignExtendWideningLower_Vector64_SByte(); + var result = AdvSimd.SignExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__SignExtendWideningLower_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + { + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((SByte*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.SignExtendWideningLower(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((SByte*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.SignExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.SignExtendWideningLower( + AdvSimd.LoadVector64((SByte*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.SignExtendWidening(firstOp[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SignExtendWideningLower)}(Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningUpper.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningUpper.Vector128.Int16.cs new file mode 100644 index 0000000000000..ecfa8a20c99ba --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningUpper.Vector128.Int16.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void SignExtendWideningUpper_Vector128_Int16() + { + var test = new SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int16 testClass) + { + var result = AdvSimd.SignExtendWideningUpper(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((Int16*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar1; + + private Vector128 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.SignExtendWideningUpper( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SignExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SignExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.SignExtendWideningUpper( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((Int16*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.SignExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.SignExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int16(); + var result = AdvSimd.SignExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int16(); + + fixed (Vector128* pFld1 = &test._fld1) + { + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((Int16*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.SignExtendWideningUpper(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((Int16*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.SignExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((Int16*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.SignExtendWideningUpper(firstOp, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SignExtendWideningUpper)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningUpper.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningUpper.Vector128.Int32.cs new file mode 100644 index 0000000000000..67de15d90c51b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningUpper.Vector128.Int32.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void SignExtendWideningUpper_Vector128_Int32() + { + var test = new SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int32 testClass) + { + var result = AdvSimd.SignExtendWideningUpper(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((Int32*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar1; + + private Vector128 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.SignExtendWideningUpper( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SignExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SignExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.SignExtendWideningUpper( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((Int32*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.SignExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.SignExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int32(); + var result = AdvSimd.SignExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_Int32(); + + fixed (Vector128* pFld1 = &test._fld1) + { + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((Int32*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.SignExtendWideningUpper(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((Int32*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.SignExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((Int32*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.SignExtendWideningUpper(firstOp, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SignExtendWideningUpper)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningUpper.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningUpper.Vector128.SByte.cs new file mode 100644 index 0000000000000..7089ef21d2818 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/SignExtendWideningUpper.Vector128.SByte.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void SignExtendWideningUpper_Vector128_SByte() + { + var test = new SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_SByte testClass) + { + var result = AdvSimd.SignExtendWideningUpper(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_SByte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((SByte*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + + private static Vector128 _clsVar1; + + private Vector128 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.SignExtendWideningUpper( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SignExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.SignExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.SignExtendWideningUpper( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((SByte*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.SignExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.SignExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_SByte(); + var result = AdvSimd.SignExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__SignExtendWideningUpper_Vector128_SByte(); + + fixed (Vector128* pFld1 = &test._fld1) + { + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((SByte*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.SignExtendWideningUpper(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((SByte*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.SignExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.SignExtendWideningUpper( + AdvSimd.LoadVector128((SByte*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.SignExtendWideningUpper(firstOp, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.SignExtendWideningUpper)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.Byte.cs new file mode 100644 index 0000000000000..0519407fbbd5e --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.Byte.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ZeroExtendWideningLower_Vector64_Byte() + { + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Byte testClass) + { + var result = AdvSimd.ZeroExtendWideningLower(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Byte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Byte*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + + private static Vector64 _clsVar1; + + private Vector64 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data1, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ZeroExtendWideningLower( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ZeroExtendWideningLower( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Byte*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.ZeroExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.ZeroExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Byte(); + var result = AdvSimd.ZeroExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Byte(); + + fixed (Vector64* pFld1 = &test._fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Byte*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ZeroExtendWideningLower(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Byte*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Byte*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ZeroExtendWidening(firstOp[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ZeroExtendWideningLower)}(Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.Int16.cs new file mode 100644 index 0000000000000..3a58cbf2e89ba --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.Int16.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ZeroExtendWideningLower_Vector64_Int16() + { + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int16 testClass) + { + var result = AdvSimd.ZeroExtendWideningLower(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Int16*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + + private static Vector64 _clsVar1; + + private Vector64 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ZeroExtendWideningLower( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ZeroExtendWideningLower( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Int16*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.ZeroExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int16*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.ZeroExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int16(); + var result = AdvSimd.ZeroExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int16(); + + fixed (Vector64* pFld1 = &test._fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Int16*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ZeroExtendWideningLower(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Int16*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Int16*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ZeroExtendWidening(firstOp[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ZeroExtendWideningLower)}(Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.Int32.cs new file mode 100644 index 0000000000000..05205c7fbb449 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.Int32.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ZeroExtendWideningLower_Vector64_Int32() + { + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int32 testClass) + { + var result = AdvSimd.ZeroExtendWideningLower(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Int32*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + + private static Vector64 _clsVar1; + + private Vector64 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ZeroExtendWideningLower( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ZeroExtendWideningLower( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Int32*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.ZeroExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((Int32*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.ZeroExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int32(); + var result = AdvSimd.ZeroExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_Int32(); + + fixed (Vector64* pFld1 = &test._fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Int32*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ZeroExtendWideningLower(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Int32*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((Int32*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ZeroExtendWidening(firstOp[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ZeroExtendWideningLower)}(Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.SByte.cs new file mode 100644 index 0000000000000..9701cdda6d48c --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.SByte.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ZeroExtendWideningLower_Vector64_SByte() + { + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_SByte testClass) + { + var result = AdvSimd.ZeroExtendWideningLower(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_SByte testClass) + { + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((SByte*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + + private static Vector64 _clsVar1; + + private Vector64 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ZeroExtendWideningLower( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ZeroExtendWideningLower( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((SByte*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.ZeroExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.ZeroExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_SByte(); + var result = AdvSimd.ZeroExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_SByte(); + + fixed (Vector64* pFld1 = &test._fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((SByte*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ZeroExtendWideningLower(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((SByte*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((SByte*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ZeroExtendWidening(firstOp[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ZeroExtendWideningLower)}(Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.UInt16.cs new file mode 100644 index 0000000000000..94696f369d89d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.UInt16.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ZeroExtendWideningLower_Vector64_UInt16() + { + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt16 testClass) + { + var result = AdvSimd.ZeroExtendWideningLower(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt16 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((UInt16*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + + private static Vector64 _clsVar1; + + private Vector64 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data1, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ZeroExtendWideningLower( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ZeroExtendWideningLower( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((UInt16*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.ZeroExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt16*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.ZeroExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt16(); + var result = AdvSimd.ZeroExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt16(); + + fixed (Vector64* pFld1 = &test._fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((UInt16*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ZeroExtendWideningLower(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((UInt16*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((UInt16*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ZeroExtendWidening(firstOp[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ZeroExtendWideningLower)}(Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.UInt32.cs new file mode 100644 index 0000000000000..d2a4a895d5265 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningLower.Vector64.UInt32.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ZeroExtendWideningLower_Vector64_UInt32() + { + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector64 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt32 testClass) + { + var result = AdvSimd.ZeroExtendWideningLower(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt32 testClass) + { + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((UInt32*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + + private static Vector64 _clsVar1; + + private Vector64 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data1, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ZeroExtendWideningLower( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningLower), new Type[] { typeof(Vector64) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ZeroExtendWideningLower( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector64* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((UInt32*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.ZeroExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector64((UInt32*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.ZeroExtendWideningLower(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt32(); + var result = AdvSimd.ZeroExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningLower_Vector64_UInt32(); + + fixed (Vector64* pFld1 = &test._fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((UInt32*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ZeroExtendWideningLower(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector64* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((UInt32*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningLower(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningLower( + AdvSimd.LoadVector64((UInt32*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector64 op1, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ZeroExtendWidening(firstOp[i]) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ZeroExtendWideningLower)}(Vector64): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.Byte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.Byte.cs new file mode 100644 index 0000000000000..07f995be11a61 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.Byte.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ZeroExtendWideningUpper_Vector128_Byte() + { + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Byte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Byte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Byte[] inArray1, UInt16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Byte testClass) + { + var result = AdvSimd.ZeroExtendWideningUpper(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Byte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Byte*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static Byte[] _data1 = new Byte[Op1ElementCount]; + + private static Vector128 _clsVar1; + + private Vector128 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Byte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Byte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); } + _dataTable = new DataTable(_data1, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ZeroExtendWideningUpper( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ZeroExtendWideningUpper( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Byte*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.ZeroExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.ZeroExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Byte(); + var result = AdvSimd.ZeroExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Byte(); + + fixed (Vector128* pFld1 = &test._fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Byte*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ZeroExtendWideningUpper(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Byte*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Byte*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray1 = new Byte[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ZeroExtendWideningUpper)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.Int16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.Int16.cs new file mode 100644 index 0000000000000..1feb2f0e43608 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.Int16.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ZeroExtendWideningUpper_Vector128_Int16() + { + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int16[] inArray1, Int32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int16 testClass) + { + var result = AdvSimd.ZeroExtendWideningUpper(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Int16*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int16[] _data1 = new Int16[Op1ElementCount]; + + private static Vector128 _clsVar1; + + private Vector128 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); } + _dataTable = new DataTable(_data1, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ZeroExtendWideningUpper( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ZeroExtendWideningUpper( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Int16*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.ZeroExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int16*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.ZeroExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int16(); + var result = AdvSimd.ZeroExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int16(); + + fixed (Vector128* pFld1 = &test._fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Int16*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ZeroExtendWideningUpper(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Int16*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Int16*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray1 = new Int16[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ZeroExtendWideningUpper)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.Int32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.Int32.cs new file mode 100644 index 0000000000000..b007617f701f5 --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.Int32.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ZeroExtendWideningUpper_Vector128_Int32() + { + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(Int32[] inArray1, Int64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int32 testClass) + { + var result = AdvSimd.ZeroExtendWideningUpper(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Int32*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int32[] _data1 = new Int32[Op1ElementCount]; + + private static Vector128 _clsVar1; + + private Vector128 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); } + _dataTable = new DataTable(_data1, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ZeroExtendWideningUpper( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ZeroExtendWideningUpper( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Int32*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.ZeroExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((Int32*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.ZeroExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int32(); + var result = AdvSimd.ZeroExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_Int32(); + + fixed (Vector128* pFld1 = &test._fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Int32*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ZeroExtendWideningUpper(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Int32*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((Int32*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray1 = new Int32[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ZeroExtendWideningUpper)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.SByte.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.SByte.cs new file mode 100644 index 0000000000000..dfa0e9e90e0cc --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.SByte.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ZeroExtendWideningUpper_Vector128_SByte() + { + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_SByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_SByte + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(SByte[] inArray1, Int16[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_SByte testClass) + { + var result = AdvSimd.ZeroExtendWideningUpper(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_SByte testClass) + { + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((SByte*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static SByte[] _data1 = new SByte[Op1ElementCount]; + + private static Vector128 _clsVar1; + + private Vector128 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_SByte() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_SByte() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); } + _dataTable = new DataTable(_data1, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ZeroExtendWideningUpper( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ZeroExtendWideningUpper( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((SByte*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.ZeroExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.ZeroExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_SByte(); + var result = AdvSimd.ZeroExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_SByte(); + + fixed (Vector128* pFld1 = &test._fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((SByte*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ZeroExtendWideningUpper(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((SByte*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((SByte*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray1 = new SByte[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ZeroExtendWideningUpper)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.UInt16.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.UInt16.cs new file mode 100644 index 0000000000000..0d471011a7b7b --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.UInt16.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ZeroExtendWideningUpper_Vector128_UInt16() + { + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt16(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt16 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt16[] inArray1, UInt32[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt16 testClass) + { + var result = AdvSimd.ZeroExtendWideningUpper(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt16 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((UInt16*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt16[] _data1 = new UInt16[Op1ElementCount]; + + private static Vector128 _clsVar1; + + private Vector128 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt16() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt16() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); } + _dataTable = new DataTable(_data1, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ZeroExtendWideningUpper( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ZeroExtendWideningUpper( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((UInt16*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.ZeroExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.ZeroExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt16(); + var result = AdvSimd.ZeroExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt16(); + + fixed (Vector128* pFld1 = &test._fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((UInt16*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ZeroExtendWideningUpper(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((UInt16*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((UInt16*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray1 = new UInt16[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ZeroExtendWideningUpper)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.UInt32.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.UInt32.cs new file mode 100644 index 0000000000000..c35161443743d --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/AdvSimd/ZeroExtendWideningUpper.Vector128.UInt32.cs @@ -0,0 +1,489 @@ +// 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.Arm\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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void ZeroExtendWideningUpper_Vector128_UInt32() + { + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt32(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing a static member works, using pinning and Load + test.RunClsVarScenario_Load(); + } + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (AdvSimd.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local class works, using pinning and Load + test.RunClassLclFldScenario_Load(); + } + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a class works, using pinning and Load + test.RunClassFldScenario_Load(); + } + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing the field of a local struct works, using pinning and Load + test.RunStructLclFldScenario_Load(); + } + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + + if (AdvSimd.IsSupported) + { + // Validates passing an instance member of a struct works, using pinning and Load + test.RunStructFldScenario_Load(); + } + } + 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 SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt32 + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable(UInt32[] inArray1, UInt64[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public Vector128 _fld1; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt32 testClass) + { + var result = AdvSimd.ZeroExtendWideningUpper(_fld1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + + public void RunStructFldScenario_Load(SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt32 testClass) + { + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((UInt32*)(pFld1)) + ); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr); + } + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt32[] _data1 = new UInt32[Op1ElementCount]; + + private static Vector128 _clsVar1; + + private Vector128 _fld1; + + private DataTable _dataTable; + + static SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt32() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt32() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); } + _dataTable = new DataTable(_data1, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => AdvSimd.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = AdvSimd.ZeroExtendWideningUpper( + Unsafe.Read>(_dataTable.inArray1Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.ZeroExtendWideningUpper), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = AdvSimd.ZeroExtendWideningUpper( + _clsVar1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load)); + + fixed (Vector128* pClsVar1 = &_clsVar1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((UInt32*)(pClsVar1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _dataTable.outArrayPtr); + } + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read>(_dataTable.inArray1Ptr); + var result = AdvSimd.ZeroExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var op1 = AdvSimd.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)); + var result = AdvSimd.ZeroExtendWideningUpper(op1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt32(); + var result = AdvSimd.ZeroExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load)); + + var test = new SimpleUnaryOpTest__ZeroExtendWideningUpper_Vector128_UInt32(); + + fixed (Vector128* pFld1 = &test._fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((UInt32*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = AdvSimd.ZeroExtendWideningUpper(_fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load)); + + fixed (Vector128* pFld1 = &_fld1) + { + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((UInt32*)(pFld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _dataTable.outArrayPtr); + } + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningUpper(test._fld1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load)); + + var test = TestStruct.Create(); + var result = AdvSimd.ZeroExtendWideningUpper( + AdvSimd.LoadVector128((UInt32*)(&test._fld1)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunStructFldScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load)); + + var test = TestStruct.Create(); + test.RunStructFldScenario_Load(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult(Vector128 op1, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray1 = new UInt32[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray1, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + for (var i = 0; i < RetElementCount; i++) + { + if (Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]) + { + succeeded = false; + break; + } + } + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.ZeroExtendWideningUpper)}(Vector128): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx index 8d9c695fb0a3b..50bc84cdbb522 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/GenerateTests.csx @@ -88,7 +88,10 @@ private static readonly (string templateFileName, string outputTemplateName, Dic { ("_UnaryOpScalarTestTemplate.template", "DuplicateTest.template", new Dictionary { ["TemplateName"] = "Duplicate", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), ("_ImmUnaryOpTestTemplate.template", "ImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_ImmUnaryOpTestTemplate.template", "VecImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), ("_ImmOpTestTemplate.template", "ImmOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_ImmBinaryOpTestTemplate.template", "ImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), + ("_ImmBinaryOpTestTemplate.template", "VecImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), ("_BinaryOpTestTemplate.template", "SimpleBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), ("_TernaryOpTestTemplate.template", "VecTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), ("_UnaryOpTestTemplate.template", "SimpleUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }), @@ -104,1267 +107,1651 @@ private static readonly (string templateFileName, string outputTemplateName, Dic private static readonly (string templateFileName, Dictionary templateData)[] AdvSimdInputs = new [] { - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "(short)-TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "(sbyte)-TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "-TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Abs(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(short)-TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(sbyte)-TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "-TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Abs(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "-TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Abs(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Abs(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Add(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Add(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AddPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAddScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAddScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWidening(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWidening(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Add(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Add(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Add(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.Add(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Byte_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int16_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int16_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int32_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int32_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int64_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_SByte_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt16_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt16_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt32_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt32_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt64_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.And(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.And(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.And(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.And(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareTest(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareTest(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "DivideScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DivideScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Divide(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "DivideScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DivideScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_Byte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "8", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "result[i] != firstOp[8]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_Int16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "4", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "result[i] != firstOp[4]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_Int32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_SByte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "8", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "result[i] != firstOp[8]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_Single_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_UInt16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "4", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "result[i] != firstOp[4]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_UInt32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Byte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "8", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "result[i] != firstOp[8]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Int16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "4", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "result[i] != firstOp[4]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Int32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_SByte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "8", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "result[i] != firstOp[8]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Single_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_UInt16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "4", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "result[i] != firstOp[4]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_UInt32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Byte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_SByte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Single_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Byte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_SByte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Single_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.DoubleToInt64Bits(firstOp[ElementIndex]) != BitConverter.DoubleToInt64Bits(result)"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAdd_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAdd_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddNegatedScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAddNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddNegatedScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAddNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtract_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtract_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractNegatedScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtractNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractNegatedScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtractNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Byte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Double", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Int16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Int32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Int64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_SByte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Single", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_UInt16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_UInt32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_UInt64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Byte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Double", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Int16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Int32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Int64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_SByte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Single", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_UInt16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_UInt32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_UInt64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Max(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Max(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumber_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumber_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumber(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumber(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Min(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Min(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumber_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumber_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumber(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumber(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Negate(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Negate(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Negate(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Negate(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Not(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Not(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Not(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Not(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Or(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Or(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Or(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Or(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWideningUpper(left, right, i) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x409e8000"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedRecipEstimate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x409e8000"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedRecipEstimate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x400e8000"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedRSqrtEstimate(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x400e8000"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedRSqrtEstimate(firstOp[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStep_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStep", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPRSqrtStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStep_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPRSqrtStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStep_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPRecipStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStep_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPRecipStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "SqrtScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SqrtScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Sqrt(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "SqrtScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SqrtScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Sqrt(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Subtract(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Subtract(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Subtract(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Subtract(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Subtract(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.Subtract(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Byte_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int16_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int16_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int32_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int32_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int64_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_SByte_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt16_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt16_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt32_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt32_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt64_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Xor(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Xor(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Xor(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Xor(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "(short)-TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "(sbyte)-TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "-TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Abs(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(short)-TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "(sbyte)-TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "-TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Abs(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "-TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Abs(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Abs(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifference(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWidening(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningLowerAndAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpper(left, right, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceWideningUpperAndAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Add(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Add(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Add(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AddPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWidening_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWidening", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(firstOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, i) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAddScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningAndAddScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningAndAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWideningAndAdd(left, right, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningScalar_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWidening(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseWideningScalar_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseWideningScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddPairwiseWidening(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "AddRoundedHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturate_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Add(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Add(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Add(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.Add(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningLower_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Byte_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int16_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int16_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int32_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int32_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_Int64_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_SByte_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt16_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt16_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt32_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt32_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddWideningUpper_Vector128_UInt64_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.And(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.And(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.And(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.And(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "And_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.And(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseClear(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "BitwiseClear_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseClear", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseClear(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "BitwiseSelect_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "BitwiseSelect", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.BitwiseSelect(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThan(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThanOrEqual(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareTest(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareTest(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "DivideScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DivideScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Divide(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "DivideScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DivideScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_Byte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "8", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "result[i] != firstOp[8]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_Int16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "4", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "result[i] != firstOp[4]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_Int32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_SByte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "8", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "result[i] != firstOp[8]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_Single_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_UInt16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "4", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "result[i] != firstOp[4]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector64_V128_UInt32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Byte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "8", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "result[i] != firstOp[8]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Int16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "4", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "result[i] != firstOp[4]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Int32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_SByte_8", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "8", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "result[i] != firstOp[8]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Single_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_UInt16_4", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "4", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "result[i] != firstOp[4]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_UInt32_2", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "2", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "result[i] != firstOp[2]" }), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Byte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Int32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_SByte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_Single_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector64_UInt32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Byte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_SByte_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Single_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt16_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt32_31", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.DoubleToInt64Bits(firstOp[ElementIndex]) != BitConverter.DoubleToInt64Bits(result)"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateResult"] = "BitConverter.SingleToInt32Bits(firstOp[ElementIndex]) != BitConverter.SingleToInt32Bits(result)"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("ExtractTest.template", new Dictionary { ["TestName"] = "Extract_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Extract", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateResult"] = "firstOp[ElementIndex] != result"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingUpper_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowingUpper(left, right, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ExtractNarrowingLower_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.ExtractNarrowing(firstOp[i]) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("ExtractVectorTest.template", new Dictionary { ["TestName"] = "ExtractVector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["ValidateIterResult"] = "Helpers.ExtractVector(firstOp, secondOp, ElementIndex, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddHalving_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedAddRoundedHalving_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedAddRoundedHalving(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAdd_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAdd_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddNegatedScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAddNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAddNegatedScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAddNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAddNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtract_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtract_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractNegatedScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtractNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtractNegatedScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtractNegatedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtractNegated(firstOp[0], secondOp[0], thirdOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "FusedSubtractHalving_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Double_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_Single_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Insert(firstOp, ElementIndex, thirdOp, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("InsertTest.template", new Dictionary { ["TestName"] = "Insert_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ElementIndex"] = "1", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Insert(firstOp, ElementIndex, thirdOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingSignCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingSignBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.CountLeadingZeroBits(firstOp[i]) != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Byte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Double", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Int16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Int32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Int64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_SByte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_Single", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_UInt16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_UInt32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector64_UInt64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector64", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Byte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Double", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Int16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Int32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Int64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_SByte", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_Single", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_UInt16", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_UInt32", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("LoadUnOpTest.template", new Dictionary { ["TestName"] = "LoadVector128_UInt64", ["Isa"] = "AdvSimd", ["Method"] = "LoadVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Max(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Max(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Max(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumber_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumber_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumber(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumber(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Min(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Min(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Min(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumber_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumber_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumber(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumber(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumber(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplySubtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndAdd_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningLowerAndSubtract_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningLowerAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningAndSubtract(firstOp[i], secondOp[i], thirdOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndAdd_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndAdd(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "MultiplyWideningUpperAndSubtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyWideningUpperAndSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyWideningUpperAndSubtract(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Negate(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Negate(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Negate(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Negate(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Not(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Not(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Not(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Not(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Not_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Not", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Or(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Or(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Or(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Or(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Or_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.OrNot(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "OrNot_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "OrNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.OrNot(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiply_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiply(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.PolynomialMultiplyWideningUpper(left, right, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "PopCount_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "PopCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.BitCount(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x409e8000"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedRecipEstimate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x409e8000"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedRecipEstimate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x400e8000"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedRSqrtEstimate(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(result[i]) != 0x400e8000"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.UnsignedRSqrtEstimate(firstOp[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStep_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStep", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPRSqrtStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStep_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPRSqrtStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStep_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPRecipStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStep_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPRecipStepFused(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmetic_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmetic(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRounded_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRounded(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftArithmeticSaturate(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftArithmetic(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogical_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturate_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[i], Imm) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsigned_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsigned", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogical(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogical(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWidening(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalWideningUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftLeftLogicalWideningUpper(firstOp, Imm, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogical_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogical(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRounded_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRounded(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturate_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRounded(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRounded(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturate_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.ShiftLogicalSaturate(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogical(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.ShiftLogical(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmetic_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmetic(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAdd_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticAddScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRounded_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAdd_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedAddScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt16_1",["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper_Vector128_UInt32_1",["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRounded(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmetic(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogical_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogical(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAdd_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAddScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalAddScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRounded_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRounded", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAdd_Vector128_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[i], secondOp[i], Imm) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAddScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedAddScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedAddScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedAdd(firstOp[0], secondOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowing(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateLower_Vector64_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[i], Imm) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_Byte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_Int32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_SByte_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt16_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("VecImmBinOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingUpper_Vector128_UInt32_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingUpper(firstOp, secondOp, Imm, i) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRounded(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalScalar_Vector64_Int64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogical(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalScalar_Vector64_UInt64_1", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftRightLogical(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SignExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "SignExtendWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SignExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SignExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "SqrtScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SqrtScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Sqrt(firstOp[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "SqrtScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SqrtScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Sqrt(firstOp[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("StoreUnOpTest.template", new Dictionary { ["TestName"] = "Store_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Store", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Subtract(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Subtract(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingLower", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowing(left[i], right[i]) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "SubtractRoundedHighNarrowingUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractRoundedHighNarrowingUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingUpper(firstOp, secondOp, thirdOp, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturate_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Subtract(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Subtract(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Subtract(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.Subtract(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningLower_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Byte_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int16_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int16_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int32_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int32_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_Int64_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_SByte_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt16_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt16_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt32_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt32_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "SubtractWideningUpper_Vector128_UInt64_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.SubtractWideningUpper(left, right, i) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Xor(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Xor(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Xor(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Xor(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Xor_Vector128_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningLower_Vector64_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ZeroExtendWidening(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_Int32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_UInt16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ZeroExtendWideningUpper_Vector128_UInt32", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZeroExtendWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.ZeroExtendWideningUpper(firstOp, i) != result[i]"}) }; private static readonly (string templateFileName, Dictionary templateData)[] AdvSimd_Arm64Inputs = new [] { - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "-TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Abs(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Abs(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteDifference(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Add(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AddPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AddPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AddPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AddPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.AddPairwise(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.AddPairwise(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareTest(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareTestScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareTest(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareTestScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareTest(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareTestScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareTest(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Divide(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Int64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Double_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int64_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), - ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt64_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAdd_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtract_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Max(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumber_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumber(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxNumberAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwise_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumberPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumberPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Max(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Max(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Min(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumber_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumber(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinNumberAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwise_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumberPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumberPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Min(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Min(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtended_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtended_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtended_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Negate(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Negate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0x4013d00000000000"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimateScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != 0x4013d00000000000", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimateScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != 0x409e8000", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalExponentScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalExponentScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != 0x4030000000000000", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalExponentScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalExponentScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != 0x41800000", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateIterResult"] = " BitConverter.DoubleToInt64Bits(result[i]) != 0x4001d00000000000"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimateScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != 0x4001d00000000000", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimateScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != 0x400e8000", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStep_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPRSqrtStepFused(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStepScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPRSqrtStepFused(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStepScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPRSqrtStepFused(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStep_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPRecipStepFused(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStepScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPRecipStepFused(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStepScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPRecipStepFused(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sqrt_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Sqrt(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sqrt_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Sqrt(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sqrt_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Sqrt(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), - ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Subtract(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), - ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), - ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "-TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Abs(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Abs_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Abs(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AbsScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Abs(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareGreaterThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteCompareLessThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteCompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteCompareLessThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifference_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifference", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteDifference(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AbsoluteDifference(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AbsoluteDifferenceScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AbsoluteDifferenceScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AbsoluteDifference(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Add_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Add(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "AddAcross_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AddPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.AddPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "AddPairwise_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.AddPairwise(left, right, i) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.AddPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.AddPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.AddPairwise(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "AddPairwiseScalar_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.AddPairwise(firstOp, 0) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "AddSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "AddSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.AddSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqual_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareEqual(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareEqualScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThan_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThan(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqual_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareGreaterThanOrEqual(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareGreaterThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareGreaterThanOrEqualScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareGreaterThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareGreaterThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThan(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThan_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThan(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThan(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThan(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThan(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThanOrEqual(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqual_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareLessThanOrEqual(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareLessThanOrEqual(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.CompareLessThanOrEqual(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareLessThanOrEqualScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareLessThanOrEqualScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareLessThanOrEqual(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareTest(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "CompareTest_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTest", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.CompareTest(left[i], right[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareTestScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.CompareTest(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareTestScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.CompareTest(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "CompareTestScalar_Vector64_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "CompareTestScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.CompareTest(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Divide(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Divide_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Divide", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Divide(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Double_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_Int64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "DuplicateSelectedScalarToVector128_V128_UInt64_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateSelectedScalarToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "1", ["ValidateFirstResult"] = "result[0] != firstOp[1]", ["ValidateRemainingResults"] = "result[i] != firstOp[1]" }), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Double_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_Int64_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("DuplicateTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != data", ["ValidateRemainingResults"] = "result[i] != data"}), + ("ImmOpTest.template", new Dictionary { ["TestName"] = "DuplicateToVector128_UInt64_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "DuplicateToVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["Imm"] = "31", ["ValidateFirstResult"] = "result[0] != 31", ["ValidateRemainingResults"] = "result[i] != 31"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplyAdd_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "FusedMultiplySubtract_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Max_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Max(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxAcross_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MaxAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumber_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumber(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MaxNumberAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwise_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumberPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxNumberPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxNumberPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxNumberPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MaxPairwise_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MaxPairwise(left, right, i) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MaxPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MaxPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MaxPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Max(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MaxScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MaxScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Max(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Min_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Min(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinAcross_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.MinAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumber_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumber", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumber(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecReduceUnOpTest.template", new Dictionary { ["TestName"] = "MinNumberAcross_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberAcross", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateReduceOpResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberAcross(firstOp)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwise_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumberPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinNumberPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinNumberPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinNumberPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinNumberPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinPairwise(left, right, i)) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinPairwise(left, right, i)) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MinPairwise_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwise", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MinPairwise(left, right, i) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinPairwiseScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MinPairwise(firstOp, 0)) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "MinPairwiseScalar_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinPairwiseScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MinPairwise(firstOp, 0)) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Min(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MinScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MinScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Min(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Multiply_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtended_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtended_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtended_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(left[i], right[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.MultiplyExtended(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "MultiplyExtendedScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "MultiplyExtendedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.MultiplyExtended(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Negate(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Negate_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Negate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "NegateScalar_Vector64_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "NegateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Negate(firstOp[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimate_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0x4013d00000000000"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimateScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != 0x4013d00000000000", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalEstimateScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != 0x409e8000", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalExponentScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalExponentScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != 0x4030000000000000", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalExponentScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalExponentScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != 0x41800000", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimate_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateIterResult"] = " BitConverter.DoubleToInt64Bits(result[i]) != 0x4001d00000000000"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimateScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int64BitsToDouble(0x3fc9db3dab555868)", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != 0x4001d00000000000", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleUnOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootEstimateScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootEstimateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "BitConverter.Int32BitsToSingle(0x3e4ed9ed)", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != 0x400e8000", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStep_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPRSqrtStepFused(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStepScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPRSqrtStepFused(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalSquareRootStepScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalSquareRootStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPRSqrtStepFused(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStep_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStep", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPRecipStepFused(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStepScalar_Vector64_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FPRecipStepFused(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ReciprocalStepScalar_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReciprocalStepScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.FPRecipStepFused(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ReverseElementBits", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.ReverseElementBits(firstOp[i]) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticRoundedSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftArithmeticSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftArithmeticSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftArithmeticSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_Byte_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_Int16_15", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "15", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_Int32_31", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "31", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_SByte_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_UInt16_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "1", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int16_5", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "5", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsignedScalar_Vector64_Int32_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftLeftLogicalSaturateUnsignedScalar_Vector64_SByte_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLeftLogicalSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.ShiftLeftLogicalSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalRoundedSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalRoundedSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalRoundedSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "ShiftLogicalSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftLogicalSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.ShiftLogicalSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int16_16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateScalar_Vector64_Int32_32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateScalar_Vector64_SByte_8", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_Byte_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt16_5", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "5", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar_Vector64_UInt32_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int16_32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "16", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_Int32_64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "32", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar_Vector64_SByte_16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "8", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_Byte_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt16_1",["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "15", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar_Vector64_UInt32_1",["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "31", ["ValidateFirstResult"] = "Helpers.ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_Byte_5", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int16_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "15", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_Int32_11", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "31", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_SByte_3", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt16_5", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "15", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalNarrowingSaturateScalar_Vector64_UInt32_7", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "31", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Byte_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int16_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "5", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_Int32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_SByte_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["Imm"] = "3", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt16_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "5", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmUnOpTest.template", new Dictionary { ["TestName"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar_Vector64_UInt32_1", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["Imm"] = "7", ["ValidateFirstResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturate(firstOp[0], Imm) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sqrt_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Sqrt(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sqrt_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Sqrt(firstOp[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sqrt_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Sqrt(firstOp[i])) != BitConverter.SingleToInt32Bits(result[i])"}), + ("VecBinOpTest.template", new Dictionary { ["TestName"] = "Subtract_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Subtract(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "SubtractSaturateScalar_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractSaturateScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "Helpers.SubtractSaturate(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeEven_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[++index] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "TransposeOdd_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookup_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), + ("VecTernOpTest.template", new Dictionary { ["TestName"] = "VectorTableLookupExtension_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipEven_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "UnzipOdd_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[index + half] != right[i+1]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipHigh_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index+half] || result[i+1] != right[index+half]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector64_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Double", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Int64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_Single", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), + ("VecPairBinOpTest.template", new Dictionary { ["TestName"] = "ZipLow_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "ZipLow", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[i] != left[index] || result[i+1] != right[index]"}), }; private static readonly (string templateFileName, Dictionary templateData)[] AesInputs = new [] { - ("AesBinOpTest.template", new Dictionary { ["TestName"] = "Decrypt_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "Decrypt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["KeySize"] = "16", ["Key"] = "{0xFF, 0xDD, 0xBB, 0x99, 0x77, 0x55, 0x33, 0x11, 0xEE, 0xCC, 0xAA, 0x88, 0x66, 0x44, 0x22, 0x00}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0x7C, 0x99, 0x02, 0x7C, 0x7C, 0x7C, 0xFE, 0x86, 0xE3, 0x7C, 0x7C, 0x97, 0xC9, 0x94, 0x7C, 0x7C}"}), - ("AesBinOpTest.template", new Dictionary { ["TestName"] = "Encrypt_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "Encrypt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["KeySize"] = "16", ["Key"] = "{0xFF, 0xDD, 0xBB, 0x99, 0x77, 0x55, 0x33, 0x11, 0xEE, 0xCC, 0xAA, 0x88, 0x66, 0x44, 0x22, 0x00}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xCA, 0xCA, 0xF5, 0xC4, 0xCA, 0x93, 0xEA, 0xCA, 0x82, 0x28, 0xCA, 0xCA, 0xC1, 0xCA, 0xCA, 0x1B}"}), - ("AesUnOpTest.template", new Dictionary { ["TestName"] = "InverseMixColumns_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "InverseMixColumns", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xA0, 0x0A, 0xE4, 0x4E, 0x28, 0x82, 0x6C, 0xC6, 0x55, 0x00, 0x77, 0x22, 0x11, 0x44, 0x33, 0x66}"}), - ("AesUnOpTest.template", new Dictionary { ["TestName"] = "MixColumns_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "MixColumns", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xAB, 0x01, 0xEF, 0x45, 0x23, 0x89, 0x67, 0xCD, 0xDD, 0x88, 0xFF, 0xAA, 0x99, 0xCC, 0xBB, 0xEE}"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_Int64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[0], right[0]) != result[1]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_UInt64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[0], right[0]) != result[1]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_Int64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[1], right[1]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[1], right[1]) != result[1]"}), - ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_UInt64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[1], right[1]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[1], right[1]) != result[1]"}) + ("AesBinOpTest.template", new Dictionary { ["TestName"] = "Decrypt_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "Decrypt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["KeySize"] = "16", ["Key"] = "{0xFF, 0xDD, 0xBB, 0x99, 0x77, 0x55, 0x33, 0x11, 0xEE, 0xCC, 0xAA, 0x88, 0x66, 0x44, 0x22, 0x00}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0x7C, 0x99, 0x02, 0x7C, 0x7C, 0x7C, 0xFE, 0x86, 0xE3, 0x7C, 0x7C, 0x97, 0xC9, 0x94, 0x7C, 0x7C}"}), + ("AesBinOpTest.template", new Dictionary { ["TestName"] = "Encrypt_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "Encrypt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["KeySize"] = "16", ["Key"] = "{0xFF, 0xDD, 0xBB, 0x99, 0x77, 0x55, 0x33, 0x11, 0xEE, 0xCC, 0xAA, 0x88, 0x66, 0x44, 0x22, 0x00}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xCA, 0xCA, 0xF5, 0xC4, 0xCA, 0x93, 0xEA, 0xCA, 0x82, 0x28, 0xCA, 0xCA, 0xC1, 0xCA, 0xCA, 0x1B}"}), + ("AesUnOpTest.template", new Dictionary { ["TestName"] = "InverseMixColumns_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "InverseMixColumns", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xA0, 0x0A, 0xE4, 0x4E, 0x28, 0x82, 0x6C, 0xC6, 0x55, 0x00, 0x77, 0x22, 0x11, 0x44, 0x33, 0x66}"}), + ("AesUnOpTest.template", new Dictionary { ["TestName"] = "MixColumns_Vector128_Byte", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "MixColumns", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xAB, 0x01, 0xEF, 0x45, 0x23, 0x89, 0x67, 0xCD, 0xDD, 0x88, 0xFF, 0xAA, 0x99, 0xCC, 0xBB, 0xEE}"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_Int64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[0], right[0]) != result[1]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningLower_Vector64_UInt64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningLower", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[0], right[0]) != result[1]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_Int64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[1], right[1]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[1], right[1]) != result[1]"}), + ("SimpleBinOpTest.template", new Dictionary { ["TestName"] = "PolynomialMultiplyWideningUpper_Vector128_UInt64", ["Isa"] = "Aes", ["LoadIsa"] = "AdvSimd", ["Method"] = "PolynomialMultiplyWideningUpper", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.PolynomialMultiplyWideningLo64(left[1], right[1]) != result[0]", ["ValidateRemainingResults"] = "Helpers.PolynomialMultiplyWideningHi64(left[1], right[1]) != result[1]"}) }; private static readonly (string templateFileName, Dictionary templateData)[] ArmBaseInputs = new [] { - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Int32", ["Isa"] = "ArmBase", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 31; (((uint)data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_UInt32", ["Isa"] = "ArmBase", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 31; ((data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Int32", ["Isa"] = "ArmBase", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_UInt32", ["Isa"] = "ArmBase", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Int32", ["Isa"] = "ArmBase", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 31; (((uint)data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_UInt32", ["Isa"] = "ArmBase", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 31; ((data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Int32", ["Isa"] = "ArmBase", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_UInt32", ["Isa"] = "ArmBase", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), }; private static readonly (string templateFileName, Dictionary templateData)[] ArmBase_Arm64Inputs = new [] { - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Int32", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingSignCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 30; (((uint)data >> index) & 1) == (((uint)data >> 31) & 1); index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingSignCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 62; (((ulong)data >> index) & 1) == (((ulong)data >> 63) & 1); index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 63; (((ulong)data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_UInt64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "UInt64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 63; ((data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), - ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_UInt64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Int32", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingSignCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 30; (((uint)data >> index) & 1) == (((uint)data >> 31) & 1); index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingSignCount_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingSignCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 62; (((ulong)data >> index) & 1) == (((ulong)data >> 63) & 1); index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 63; (((ulong)data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "LeadingZeroCount_UInt64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "LeadingZeroCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "UInt64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "int expectedResult = 0; for (int index = 63; ((data >> index) & 1) == 0; index--) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_Int64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), + ("ScalarUnOpTest.template", new Dictionary { ["TestName"] = "ReverseElementBits_UInt64", ["Isa"] = "ArmBase.Arm64", ["Method"] = "ReverseElementBits", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "isUnexpectedResult = Helpers.ReverseElementBits(data) != result;" }), }; private static readonly (string templateFileName, Dictionary templateData)[] Crc32Inputs = new [] { - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_Byte", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20", ["ValidateResult"] = "uint expectedResult = 0x169330BA; isUnexpectedResult = (expectedResult != result);" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_UInt16", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x2019", ["ValidateResult"] = "uint expectedResult = 0x1E4864D0; isUnexpectedResult = (expectedResult != result);" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_UInt32", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113", ["ValidateResult"] = "uint expectedResult = 0x219D9805; isUnexpectedResult = (expectedResult != result);" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_Byte", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20", ["ValidateResult"] = "uint expectedResult = 0x8D3F2270; isUnexpectedResult = (expectedResult != result);" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_UInt16", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x2019", ["ValidateResult"] = "uint expectedResult = 0x9F50ACBD; isUnexpectedResult = (expectedResult != result);" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_UInt32", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113", ["ValidateResult"] = "uint expectedResult = 0x78F34758; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_Byte", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20", ["ValidateResult"] = "uint expectedResult = 0x169330BA; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_UInt16", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x2019", ["ValidateResult"] = "uint expectedResult = 0x1E4864D0; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_UInt32", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113", ["ValidateResult"] = "uint expectedResult = 0x219D9805; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_Byte", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20", ["ValidateResult"] = "uint expectedResult = 0x8D3F2270; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_UInt16", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x2019", ["ValidateResult"] = "uint expectedResult = 0x9F50ACBD; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_UInt32", ["Isa"] = "Crc32", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113", ["ValidateResult"] = "uint expectedResult = 0x78F34758; isUnexpectedResult = (expectedResult != result);" }), }; private static readonly (string templateFileName, Dictionary templateData)[] Crc32_Arm64Inputs = new [] { - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_UInt64", ["Isa"] = "Crc32.Arm64", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt64", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113110219UL", ["ValidateResult"] = "uint expectedResult = 0xEFAAAB74; isUnexpectedResult = (expectedResult != result);" }), - ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_UInt64", ["Isa"] = "Crc32.Arm64", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt64", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113110219UL", ["ValidateResult"] = "uint expectedResult = 0x6295C71A; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32_UInt64", ["Isa"] = "Crc32.Arm64", ["Method"] = "ComputeCrc32", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt64", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113110219UL", ["ValidateResult"] = "uint expectedResult = 0xEFAAAB74; isUnexpectedResult = (expectedResult != result);" }), + ("ScalarBinOpTest.template", new Dictionary { ["TestName"] = "ComputeCrc32C_UInt64", ["Isa"] = "Crc32.Arm64", ["Method"] = "ComputeCrc32C", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt64", ["NextValueOp1"] = "0xFFFFFFFF", ["NextValueOp2"] = "0x20191113110219UL", ["ValidateResult"] = "uint expectedResult = 0x6295C71A; isUnexpectedResult = (expectedResult != result);" }), }; private static readonly (string templateFileName, Dictionary templateData)[] Sha1Inputs = new [] { - ("SecureHashUnOpTest.template", new Dictionary { ["TestName"] = "FixedRotate_Vector64_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "FixedRotate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "0x00112233", ["ExpectedResult"] = "{0xC004488C, 0x0, 0x0, 0x0}"}), - ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "HashUpdateChoose_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdateChoose", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x27A38C6D, 0xEFEFCA67, 0xDB4E8169, 0x73C91E71}"}), - ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "HashUpdateMajority_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdateMajority", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0xEC691B1D, 0xF21410C7, 0x9B52C9F6, 0x73C91E71}"}), - ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "HashUpdateParity_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdateParity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0xDAB2AF34, 0xFF990D18, 0xCB4F938C, 0x73C91E71}"}), - ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "ScheduleUpdate0_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate0", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x8899AABB, 0x8899AABB, 0xCCDDEEFF, 0xCCDDEEFF}"}), - ("SecureHashBinOpTest.template", new Dictionary { ["TestName"] = "ScheduleUpdate1_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate1", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["ExpectedResult"] = "{0x88888888, 0x88888888, 0x88888888, 0x11335577}"}), + ("SecureHashUnOpTest.template", new Dictionary { ["TestName"] = "FixedRotate_Vector64_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "FixedRotate", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "0x00112233", ["ExpectedResult"] = "{0xC004488C, 0x0, 0x0, 0x0}"}), + ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "HashUpdateChoose_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdateChoose", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x27A38C6D, 0xEFEFCA67, 0xDB4E8169, 0x73C91E71}"}), + ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "HashUpdateMajority_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdateMajority", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0xEC691B1D, 0xF21410C7, 0x9B52C9F6, 0x73C91E71}"}), + ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "HashUpdateParity_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdateParity", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0xDAB2AF34, 0xFF990D18, 0xCB4F938C, 0x73C91E71}"}), + ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "ScheduleUpdate0_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate0", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x8899AABB, 0x8899AABB, 0xCCDDEEFF, 0xCCDDEEFF}"}), + ("SecureHashBinOpTest.template", new Dictionary { ["TestName"] = "ScheduleUpdate1_Vector128_UInt32", ["Isa"] = "Sha1", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate1", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["ExpectedResult"] = "{0x88888888, 0x88888888, 0x88888888, 0x11335577}"}), }; private static readonly (string templateFileName, Dictionary templateData)[] Sha256Inputs = new [] { - ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "HashUpdate1_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdate1", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x3D22118E, 0x987CA5FB, 0x54F4E477, 0xDFB50278}"}), - ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "HashUpdate2_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdate2", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0xFFD38634, 0x2A33F83F, 0x55A1BE45, 0x5002B4C4}"}), - ("SecureHashBinOpTest.template", new Dictionary { ["TestName"] = "ScheduleUpdate0_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate0", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["ExpectedResult"] = "{0x2E9FE839, 0x2E9FE839, 0x2E9FE839, 0xBFB0F94A}"}), - ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "ScheduleUpdate1_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate1", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x248F1BDF, 0x248F1BDF, 0xB303DDBA, 0xF74821FE}"}), + ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "HashUpdate1_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdate1", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x3D22118E, 0x987CA5FB, 0x54F4E477, 0xDFB50278}"}), + ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "HashUpdate2_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "HashUpdate2", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0xFFD38634, 0x2A33F83F, 0x55A1BE45, 0x5002B4C4}"}), + ("SecureHashBinOpTest.template", new Dictionary { ["TestName"] = "ScheduleUpdate0_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate0", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["ExpectedResult"] = "{0x2E9FE839, 0x2E9FE839, 0x2E9FE839, 0xBFB0F94A}"}), + ("SecureHashTernOpTest.template",new Dictionary { ["TestName"] = "ScheduleUpdate1_Vector128_UInt32", ["Isa"] = "Sha256", ["LoadIsa"] = "AdvSimd", ["Method"] = "ScheduleUpdate1", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "0x00112233", ["NextValueOp2"] = "0x44556677", ["NextValueOp3"] = "0x8899AABB", ["ExpectedResult"] = "{0x248F1BDF, 0x248F1BDF, 0xB303DDBA, 0xF74821FE}"}), }; private static void ProcessInputs(string groupName, (string templateFileName, Dictionary templateData)[] inputs) diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index f54f7375a35b6..9dede7c81433f 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -9,7 +9,6 @@ using System; using System.Linq; -using System.Numerics; namespace JIT.HardwareIntrinsics.Arm { @@ -1511,6 +1510,10 @@ private static sbyte HighNarrowing(short op1, bool round) public static short SubtractWideningUpper(short[] op1, sbyte[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); + public static short ZeroExtendWidening(sbyte op1) => (short)(ushort)op1; + + public static short ZeroExtendWideningUpper(sbyte[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + public static uint AbsoluteDifferenceWidening(short op1, short op2) => op1 < op2 ? (uint)(op2 - op1) : (uint)(op1 - op2); public static uint AbsoluteDifferenceWideningUpper(short[] op1, short[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); @@ -1587,6 +1590,10 @@ private static short HighNarrowing(int op1, bool round) public static int SubtractWideningUpper(int[] op1, short[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); + public static int ZeroExtendWidening(short op1) => (int)(uint)op1; + + public static int ZeroExtendWideningUpper(short[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + public static ulong AbsoluteDifferenceWidening(int op1, int op2) => op1 < op2 ? (ulong)(op2 - op1) : (ulong)(op1 - op2); public static ulong AbsoluteDifferenceWideningUpper(int[] op1, int[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); @@ -1663,6 +1670,10 @@ private static int HighNarrowing(long op1, bool round) public static long SubtractWideningUpper(long[] op1, int[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); + public static long ZeroExtendWidening(int op1) => (long)(ulong)op1; + + public static long ZeroExtendWideningUpper(int[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + public static ushort AbsoluteDifferenceWidening(byte op1, byte op2) => op1 < op2 ? (ushort)(op2 - op1) : (ushort)(op1 - op2); public static ushort AbsoluteDifferenceWideningUpper(byte[] op1, byte[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); @@ -1739,6 +1750,10 @@ private static byte HighNarrowing(ushort op1, bool round) public static ushort SubtractWideningUpper(ushort[] op1, byte[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); + public static ushort ZeroExtendWidening(byte op1) => (ushort)(ushort)op1; + + public static ushort ZeroExtendWideningUpper(byte[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + public static uint AbsoluteDifferenceWidening(ushort op1, ushort op2) => op1 < op2 ? (uint)(op2 - op1) : (uint)(op1 - op2); public static uint AbsoluteDifferenceWideningUpper(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); @@ -1815,6 +1830,10 @@ private static ushort HighNarrowing(uint op1, bool round) public static uint SubtractWideningUpper(uint[] op1, ushort[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); + public static uint ZeroExtendWidening(ushort op1) => (uint)(uint)op1; + + public static uint ZeroExtendWideningUpper(ushort[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + public static ulong AbsoluteDifferenceWidening(uint op1, uint op2) => op1 < op2 ? (ulong)(op2 - op1) : (ulong)(op1 - op2); public static ulong AbsoluteDifferenceWideningUpper(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[i + op1.Length / 2], op2[i + op2.Length / 2]); @@ -1891,294 +1910,1718 @@ private static uint HighNarrowing(ulong op1, bool round) public static ulong SubtractWideningUpper(ulong[] op1, uint[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); - private static bool SatQ(BigInteger i, out sbyte result) + public static ulong ZeroExtendWidening(uint op1) => (ulong)(ulong)op1; + + public static ulong ZeroExtendWideningUpper(uint[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + + private static bool SignedSatQ(short val, out sbyte result) { bool saturated = false; - if (i > sbyte.MaxValue) + if (val > sbyte.MaxValue) { result = sbyte.MaxValue; saturated = true; } - else if (i < sbyte.MinValue) + else if (val < sbyte.MinValue) { result = sbyte.MinValue; saturated = true; } else { - result = (sbyte)i; + result = (sbyte)val; } return saturated; } - public static sbyte AddSaturate(sbyte op1, sbyte op2) + private static bool SignedSatQ(short val, out byte result) { - sbyte result; - SatQ(new BigInteger(op1) + new BigInteger(op2), out result); - return result; + bool saturated = false; + + if (val > byte.MaxValue) + { + result = byte.MaxValue; + saturated = true; + } + else if (val < 0) + { + result = 0; + saturated = true; + } + else + { + result = (byte)val; + } + + return saturated; } - public static sbyte SubtractSaturate(sbyte op1, sbyte op2) + private static bool UnsignedSatQ(short val, out sbyte result) { - sbyte result; - SatQ(new BigInteger(op1) - new BigInteger(op2), out result); - return result; + byte res; + + bool saturated = UnsignedSatQ((ushort)val, out res); + + result = (sbyte)res; + return saturated; } - private static bool SatQ(BigInteger i, out byte result) + private static bool UnsignedSatQ(ushort val, out byte result) { bool saturated = false; - if (i > byte.MaxValue) + if (val > byte.MaxValue) { result = byte.MaxValue; saturated = true; } - else if (i < byte.MinValue) + else if (val < 0) { - result = byte.MinValue; + result = 0; saturated = true; } else { - result = (byte)i; + result = (byte)val; } return saturated; } - public static byte AddSaturate(byte op1, byte op2) + public static short ShiftLeftLogicalWidening(sbyte op1, byte op2) => UnsignedShift((short)op1, (short)op2); + + public static ushort ShiftLeftLogicalWidening(byte op1, byte op2) => UnsignedShift((ushort)op1, (short)op2); + + public static short ShiftLeftLogicalWideningUpper(sbyte[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + + public static ushort ShiftLeftLogicalWideningUpper(byte[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + + public static sbyte ShiftRightArithmeticRoundedNarrowingSaturate(short op1, byte op2) + { + sbyte result; + + SignedSatQ(SignedShift(op1, (short)(-op2), rounding: true), out result); + + return result; + } + + public static byte ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(short op1, byte op2) { byte result; - SatQ(new BigInteger(op1) + new BigInteger(op2), out result); + + SignedSatQ(SignedShift(op1, (short)(-op2), rounding: true), out result); + return result; } - public static byte SubtractSaturate(byte op1, byte op2) + public static byte ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(byte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + + public static sbyte ShiftRightArithmeticRoundedNarrowingSaturateUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightArithmeticRoundedNarrowingSaturate(op2[i - op1.Length], op3); + + public static sbyte ShiftRightArithmeticNarrowingSaturate(short op1, byte op2) + { + sbyte result; + + SignedSatQ(SignedShift(op1, (short)(-op2)), out result); + + return result; + } + + public static byte ShiftRightArithmeticNarrowingSaturateUnsigned(short op1, byte op2) + { + byte result; + + SignedSatQ(SignedShift(op1, (short)(-op2)), out result); + + return result; + } + + public static byte ShiftRightArithmeticNarrowingSaturateUnsignedUpper(byte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightArithmeticNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + + public static sbyte ShiftRightArithmeticNarrowingSaturateUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightArithmeticNarrowingSaturate(op2[i - op1.Length], op3); + + public static sbyte ShiftRightLogicalNarrowing(short op1, byte op2) => (sbyte)UnsignedShift(op1, (short)(-op2)); + + public static byte ShiftRightLogicalNarrowing(ushort op1, byte op2) => (byte)UnsignedShift(op1, (short)(-op2)); + + public static sbyte ShiftRightLogicalRoundedNarrowing(short op1, byte op2) => (sbyte)UnsignedShift(op1, (short)(-op2), rounding: true); + + public static byte ShiftRightLogicalRoundedNarrowing(ushort op1, byte op2) => (byte)UnsignedShift(op1, (short)(-op2), rounding: true); + + public static sbyte ShiftRightLogicalRoundedNarrowingUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + + public static byte ShiftRightLogicalRoundedNarrowingUpper(byte[] op1, ushort[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + + public static sbyte ShiftRightLogicalRoundedNarrowingSaturate(short op1, byte op2) + { + sbyte result; + + UnsignedSatQ(UnsignedShift(op1, (short)(-op2), rounding: true), out result); + + return result; + } + + public static byte ShiftRightLogicalRoundedNarrowingSaturate(ushort op1, byte op2) + { + byte result; + + UnsignedSatQ(UnsignedShift(op1, (short)(-op2), rounding: true), out result); + + return result; + } + + public static sbyte ShiftRightLogicalRoundedNarrowingSaturateUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + + public static byte ShiftRightLogicalRoundedNarrowingSaturateUpper(byte[] op1, ushort[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + + public static sbyte ShiftRightLogicalNarrowingUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + + public static byte ShiftRightLogicalNarrowingUpper(byte[] op1, ushort[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + + public static sbyte ShiftRightLogicalNarrowingSaturate(short op1, byte op2) + { + sbyte result; + + UnsignedSatQ(UnsignedShift(op1, (short)(-op2)), out result); + + return result; + } + + public static byte ShiftRightLogicalNarrowingSaturate(ushort op1, byte op2) { byte result; - SatQ(new BigInteger(op1) - new BigInteger(op2), out result); + + UnsignedSatQ(UnsignedShift(op1, (short)(-op2)), out result); + return result; } - private static bool SatQ(BigInteger i, out short result) + public static sbyte ShiftRightLogicalNarrowingSaturateUpper(sbyte[] op1, short[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (sbyte)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); + + public static byte ShiftRightLogicalNarrowingSaturateUpper(byte[] op1, ushort[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (byte)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); + + public static short SignExtendWidening(sbyte op1) => op1; + + public static short SignExtendWideningUpper(sbyte[] op1, int i) => SignExtendWidening(op1[i + op1.Length / 2]); + + private static bool SignedSatQ(int val, out short result) { bool saturated = false; - if (i > short.MaxValue) + if (val > short.MaxValue) { result = short.MaxValue; saturated = true; } - else if (i < short.MinValue) + else if (val < short.MinValue) { result = short.MinValue; saturated = true; } else { - result = (short)i; + result = (short)val; } return saturated; } - public static short AddSaturate(short op1, short op2) + private static bool SignedSatQ(int val, out ushort result) { - short result; - SatQ(new BigInteger(op1) + new BigInteger(op2), out result); - return result; + bool saturated = false; + + if (val > ushort.MaxValue) + { + result = ushort.MaxValue; + saturated = true; + } + else if (val < 0) + { + result = 0; + saturated = true; + } + else + { + result = (ushort)val; + } + + return saturated; } - public static short SubtractSaturate(short op1, short op2) + private static bool UnsignedSatQ(int val, out short result) { - short result; - SatQ(new BigInteger(op1) - new BigInteger(op2), out result); - return result; + ushort res; + + bool saturated = UnsignedSatQ((uint)val, out res); + + result = (short)res; + return saturated; } - private static bool SatQ(BigInteger i, out ushort result) + private static bool UnsignedSatQ(uint val, out ushort result) { bool saturated = false; - if (i > ushort.MaxValue) + if (val > ushort.MaxValue) { result = ushort.MaxValue; saturated = true; } - else if (i < ushort.MinValue) + else if (val < 0) { - result = ushort.MinValue; + result = 0; saturated = true; } else { - result = (ushort)i; + result = (ushort)val; } return saturated; } - public static ushort AddSaturate(ushort op1, ushort op2) + public static int ShiftLeftLogicalWidening(short op1, byte op2) => UnsignedShift((int)op1, (int)op2); + + public static uint ShiftLeftLogicalWidening(ushort op1, byte op2) => UnsignedShift((uint)op1, (int)op2); + + public static int ShiftLeftLogicalWideningUpper(short[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + + public static uint ShiftLeftLogicalWideningUpper(ushort[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + + public static short ShiftRightArithmeticRoundedNarrowingSaturate(int op1, byte op2) + { + short result; + + SignedSatQ(SignedShift(op1, (int)(-op2), rounding: true), out result); + + return result; + } + + public static ushort ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(int op1, byte op2) { ushort result; - SatQ(new BigInteger(op1) + new BigInteger(op2), out result); + + SignedSatQ(SignedShift(op1, (int)(-op2), rounding: true), out result); + return result; } - public static ushort SubtractSaturate(ushort op1, ushort op2) + public static ushort ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(ushort[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + + public static short ShiftRightArithmeticRoundedNarrowingSaturateUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightArithmeticRoundedNarrowingSaturate(op2[i - op1.Length], op3); + + public static short ShiftRightArithmeticNarrowingSaturate(int op1, byte op2) + { + short result; + + SignedSatQ(SignedShift(op1, (int)(-op2)), out result); + + return result; + } + + public static ushort ShiftRightArithmeticNarrowingSaturateUnsigned(int op1, byte op2) { ushort result; - SatQ(new BigInteger(op1) - new BigInteger(op2), out result); + + SignedSatQ(SignedShift(op1, (int)(-op2)), out result); + return result; } - private static bool SatQ(BigInteger i, out int result) + public static ushort ShiftRightArithmeticNarrowingSaturateUnsignedUpper(ushort[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightArithmeticNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + + public static short ShiftRightArithmeticNarrowingSaturateUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightArithmeticNarrowingSaturate(op2[i - op1.Length], op3); + + public static short ShiftRightLogicalNarrowing(int op1, byte op2) => (short)UnsignedShift(op1, (int)(-op2)); + + public static ushort ShiftRightLogicalNarrowing(uint op1, byte op2) => (ushort)UnsignedShift(op1, (int)(-op2)); + + public static short ShiftRightLogicalRoundedNarrowing(int op1, byte op2) => (short)UnsignedShift(op1, (int)(-op2), rounding: true); + + public static ushort ShiftRightLogicalRoundedNarrowing(uint op1, byte op2) => (ushort)UnsignedShift(op1, (int)(-op2), rounding: true); + + public static short ShiftRightLogicalRoundedNarrowingUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + + public static ushort ShiftRightLogicalRoundedNarrowingUpper(ushort[] op1, uint[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + + public static short ShiftRightLogicalRoundedNarrowingSaturate(int op1, byte op2) { - bool saturated = false; + short result; - if (i > int.MaxValue) - { - result = int.MaxValue; - saturated = true; - } - else if (i < int.MinValue) - { - result = int.MinValue; - saturated = true; - } - else - { - result = (int)i; - } + UnsignedSatQ(UnsignedShift(op1, (int)(-op2), rounding: true), out result); - return saturated; + return result; } - public static int AddSaturate(int op1, int op2) + public static ushort ShiftRightLogicalRoundedNarrowingSaturate(uint op1, byte op2) { - int result; - SatQ(new BigInteger(op1) + new BigInteger(op2), out result); + ushort result; + + UnsignedSatQ(UnsignedShift(op1, (int)(-op2), rounding: true), out result); + return result; } - public static int SubtractSaturate(int op1, int op2) + public static short ShiftRightLogicalRoundedNarrowingSaturateUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + + public static ushort ShiftRightLogicalRoundedNarrowingSaturateUpper(ushort[] op1, uint[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + + public static short ShiftRightLogicalNarrowingUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + + public static ushort ShiftRightLogicalNarrowingUpper(ushort[] op1, uint[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + + public static short ShiftRightLogicalNarrowingSaturate(int op1, byte op2) { - int result; - SatQ(new BigInteger(op1) - new BigInteger(op2), out result); + short result; + + UnsignedSatQ(UnsignedShift(op1, (int)(-op2)), out result); + + return result; + } + + public static ushort ShiftRightLogicalNarrowingSaturate(uint op1, byte op2) + { + ushort result; + + UnsignedSatQ(UnsignedShift(op1, (int)(-op2)), out result); + return result; } - private static bool SatQ(BigInteger i, out uint result) + public static short ShiftRightLogicalNarrowingSaturateUpper(short[] op1, int[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (short)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); + + public static ushort ShiftRightLogicalNarrowingSaturateUpper(ushort[] op1, uint[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (ushort)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); + + public static int SignExtendWidening(short op1) => op1; + + public static int SignExtendWideningUpper(short[] op1, int i) => SignExtendWidening(op1[i + op1.Length / 2]); + + private static bool SignedSatQ(long val, out int result) { bool saturated = false; - if (i > uint.MaxValue) + if (val > int.MaxValue) { - result = uint.MaxValue; + result = int.MaxValue; saturated = true; } - else if (i < uint.MinValue) + else if (val < int.MinValue) { - result = uint.MinValue; + result = int.MinValue; saturated = true; } else { - result = (uint)i; + result = (int)val; } return saturated; } - public static uint AddSaturate(uint op1, uint op2) - { - uint result; - SatQ(new BigInteger(op1) + new BigInteger(op2), out result); - return result; - } - - public static uint SubtractSaturate(uint op1, uint op2) - { - uint result; - SatQ(new BigInteger(op1) - new BigInteger(op2), out result); - return result; - } - - private static bool SatQ(BigInteger i, out long result) + private static bool SignedSatQ(long val, out uint result) { bool saturated = false; - if (i > long.MaxValue) + if (val > uint.MaxValue) { - result = long.MaxValue; + result = uint.MaxValue; saturated = true; } - else if (i < long.MinValue) + else if (val < 0) { - result = long.MinValue; + result = 0; saturated = true; } else { - result = (long)i; + result = (uint)val; } return saturated; } - public static long AddSaturate(long op1, long op2) + private static bool UnsignedSatQ(long val, out int result) { - long result; - SatQ(new BigInteger(op1) + new BigInteger(op2), out result); - return result; - } + uint res; - public static long SubtractSaturate(long op1, long op2) - { - long result; - SatQ(new BigInteger(op1) - new BigInteger(op2), out result); - return result; + bool saturated = UnsignedSatQ((ulong)val, out res); + + result = (int)res; + return saturated; } - private static bool SatQ(BigInteger i, out ulong result) + private static bool UnsignedSatQ(ulong val, out uint result) { bool saturated = false; - if (i > ulong.MaxValue) + if (val > uint.MaxValue) { - result = ulong.MaxValue; + result = uint.MaxValue; saturated = true; } - else if (i < ulong.MinValue) + else if (val < 0) { - result = ulong.MinValue; + result = 0; saturated = true; } else { - result = (ulong)i; + result = (uint)val; } return saturated; } - public static ulong AddSaturate(ulong op1, ulong op2) + public static long ShiftLeftLogicalWidening(int op1, byte op2) => UnsignedShift((long)op1, (long)op2); + + public static ulong ShiftLeftLogicalWidening(uint op1, byte op2) => UnsignedShift((ulong)op1, (long)op2); + + public static long ShiftLeftLogicalWideningUpper(int[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + + public static ulong ShiftLeftLogicalWideningUpper(uint[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + + public static int ShiftRightArithmeticRoundedNarrowingSaturate(long op1, byte op2) { - ulong result; - SatQ(new BigInteger(op1) + new BigInteger(op2), out result); + int result; + + SignedSatQ(SignedShift(op1, (long)(-op2), rounding: true), out result); + return result; } - public static ulong SubtractSaturate(ulong op1, ulong op2) + public static uint ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(long op1, byte op2) + { + uint result; + + SignedSatQ(SignedShift(op1, (long)(-op2), rounding: true), out result); + + return result; + } + + public static uint ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(uint[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + + public static int ShiftRightArithmeticRoundedNarrowingSaturateUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightArithmeticRoundedNarrowingSaturate(op2[i - op1.Length], op3); + + public static int ShiftRightArithmeticNarrowingSaturate(long op1, byte op2) { - ulong result; - SatQ(new BigInteger(op1) - new BigInteger(op2), out result); + int result; + + SignedSatQ(SignedShift(op1, (long)(-op2)), out result); + return result; } + public static uint ShiftRightArithmeticNarrowingSaturateUnsigned(long op1, byte op2) + { + uint result; + + SignedSatQ(SignedShift(op1, (long)(-op2)), out result); + + return result; + } + + public static uint ShiftRightArithmeticNarrowingSaturateUnsignedUpper(uint[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightArithmeticNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + + public static int ShiftRightArithmeticNarrowingSaturateUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightArithmeticNarrowingSaturate(op2[i - op1.Length], op3); + + public static int ShiftRightLogicalNarrowing(long op1, byte op2) => (int)UnsignedShift(op1, (long)(-op2)); + + public static uint ShiftRightLogicalNarrowing(ulong op1, byte op2) => (uint)UnsignedShift(op1, (long)(-op2)); + + public static int ShiftRightLogicalRoundedNarrowing(long op1, byte op2) => (int)UnsignedShift(op1, (long)(-op2), rounding: true); + + public static uint ShiftRightLogicalRoundedNarrowing(ulong op1, byte op2) => (uint)UnsignedShift(op1, (long)(-op2), rounding: true); + + public static int ShiftRightLogicalRoundedNarrowingUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + + public static uint ShiftRightLogicalRoundedNarrowingUpper(uint[] op1, ulong[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + + public static int ShiftRightLogicalRoundedNarrowingSaturate(long op1, byte op2) + { + int result; + + UnsignedSatQ(UnsignedShift(op1, (long)(-op2), rounding: true), out result); + + return result; + } + + public static uint ShiftRightLogicalRoundedNarrowingSaturate(ulong op1, byte op2) + { + uint result; + + UnsignedSatQ(UnsignedShift(op1, (long)(-op2), rounding: true), out result); + + return result; + } + + public static int ShiftRightLogicalRoundedNarrowingSaturateUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + + public static uint ShiftRightLogicalRoundedNarrowingSaturateUpper(uint[] op1, ulong[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + + public static int ShiftRightLogicalNarrowingUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + + public static uint ShiftRightLogicalNarrowingUpper(uint[] op1, ulong[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + + public static int ShiftRightLogicalNarrowingSaturate(long op1, byte op2) + { + int result; + + UnsignedSatQ(UnsignedShift(op1, (long)(-op2)), out result); + + return result; + } + + public static uint ShiftRightLogicalNarrowingSaturate(ulong op1, byte op2) + { + uint result; + + UnsignedSatQ(UnsignedShift(op1, (long)(-op2)), out result); + + return result; + } + + public static int ShiftRightLogicalNarrowingSaturateUpper(int[] op1, long[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (int)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); + + public static uint ShiftRightLogicalNarrowingSaturateUpper(uint[] op1, ulong[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (uint)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); + + public static long SignExtendWidening(int op1) => op1; + + public static long SignExtendWideningUpper(int[] op1, int i) => SignExtendWidening(op1[i + op1.Length / 2]); + + public static sbyte ShiftArithmetic(sbyte op1, sbyte op2) => SignedShift(op1, op2); + + public static sbyte ShiftArithmeticRounded(sbyte op1, sbyte op2) => SignedShift(op1, op2, rounding: true); + + public static sbyte ShiftArithmeticSaturate(sbyte op1, sbyte op2) => SignedShift(op1, op2, saturating: true); + + public static sbyte ShiftArithmeticRoundedSaturate(sbyte op1, sbyte op2) => SignedShift(op1, op2, rounding: true, saturating: true); + + private static sbyte SignedShift(sbyte op1, sbyte op2, bool rounding = false, bool saturating = false) + { + int shift = (sbyte)(op2 & 0xFF); + + sbyte rndCns = 0; + + if (rounding) + { + bool ovf; + + (rndCns, ovf) = ShiftOvf((sbyte)1, -shift-1); + + if (ovf) + { + return 0; + } + } + + sbyte result; + + bool addOvf; + + (result, addOvf) = AddOvf(op1, rndCns); + + if (addOvf) + { + result = (sbyte)ShiftOvf((byte)result, shift).val; + } + else + { + bool shiftOvf; + + (result, shiftOvf) = ShiftOvf(result, shift); + + if (saturating) + { + if (shiftOvf) + { + result = sbyte.MaxValue; + } + } + } + + return result; + } + + public static sbyte ShiftLeftLogical(sbyte op1, byte op2) => UnsignedShift(op1, (sbyte)op2); + + public static byte ShiftLeftLogical(byte op1, byte op2) => UnsignedShift(op1, (sbyte)op2); + + public static sbyte ShiftLeftLogicalSaturate(sbyte op1, byte op2) => SignedShift(op1, (sbyte)op2, saturating: true); + + public static byte ShiftLeftLogicalSaturate(byte op1, byte op2) => UnsignedShift(op1, (sbyte)op2, saturating: true); + + public static byte ShiftLeftLogicalSaturateUnsigned(sbyte op1, byte op2) => (byte)UnsignedShift(op1, (sbyte)op2, saturating: true); + + public static sbyte ShiftLogical(sbyte op1, sbyte op2) => UnsignedShift(op1, op2); + + public static byte ShiftLogical(byte op1, sbyte op2) => UnsignedShift(op1, op2); + + public static byte ShiftLogicalRounded(byte op1, sbyte op2) => UnsignedShift(op1, op2, rounding: true); + + public static sbyte ShiftLogicalRounded(sbyte op1, sbyte op2) => UnsignedShift(op1, op2, rounding: true); + + public static byte ShiftLogicalRoundedSaturate(byte op1, sbyte op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); + + public static sbyte ShiftLogicalRoundedSaturate(sbyte op1, sbyte op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); + + public static sbyte ShiftLogicalSaturate(sbyte op1, sbyte op2) => UnsignedShift(op1, op2, saturating: true); + + public static byte ShiftLogicalSaturate(byte op1, sbyte op2) => UnsignedShift(op1, op2, saturating: true); + + public static sbyte ShiftRightArithmetic(sbyte op1, byte op2) => SignedShift(op1, (sbyte)(-op2)); + + public static sbyte ShiftRightArithmeticAdd(sbyte op1, sbyte op2, byte op3) => (sbyte)(op1 + ShiftRightArithmetic(op2, op3)); + + public static sbyte ShiftRightArithmeticRounded(sbyte op1, byte op2) => SignedShift(op1, (sbyte)(-op2), rounding: true); + + public static sbyte ShiftRightArithmeticRoundedAdd(sbyte op1, sbyte op2, byte op3) => (sbyte)(op1 + ShiftRightArithmeticRounded(op2, op3)); + + public static sbyte ShiftRightLogical(sbyte op1, byte op2) => UnsignedShift(op1, (sbyte)(-op2)); + + public static byte ShiftRightLogical(byte op1, byte op2) => UnsignedShift(op1, (sbyte)(-op2)); + + public static sbyte ShiftRightLogicalAdd(sbyte op1, sbyte op2, byte op3) => (sbyte)(op1 + ShiftRightLogical(op2, op3)); + + public static byte ShiftRightLogicalAdd(byte op1, byte op2, byte op3) => (byte)(op1 + ShiftRightLogical(op2, op3)); + + public static sbyte ShiftRightLogicalRounded(sbyte op1, byte op2) => UnsignedShift(op1, (sbyte)(-op2), rounding: true); + + public static byte ShiftRightLogicalRounded(byte op1, byte op2) => UnsignedShift(op1, (sbyte)(-op2), rounding: true); + + public static sbyte ShiftRightLogicalRoundedAdd(sbyte op1, sbyte op2, byte op3) => (sbyte)(op1 + ShiftRightLogicalRounded(op2, op3)); + + public static byte ShiftRightLogicalRoundedAdd(byte op1, byte op2, byte op3) => (byte)(op1 + ShiftRightLogicalRounded(op2, op3)); + + private static byte UnsignedShift(byte op1, sbyte op2, bool rounding = false, bool saturating = false) + { + int shift = (sbyte)(op2 & 0xFF); + + byte rndCns = 0; + + if (rounding) + { + bool ovf; + + (rndCns, ovf) = ShiftOvf((byte)1, -shift-1); + + if (ovf) + { + return 0; + } + } + + (byte result, bool addOvf) = AddOvf(op1, rndCns); + + bool shiftOvf; + + (result, shiftOvf) = ShiftOvf(result, shift); + + if (addOvf) + { + byte shiftedCarry = ShiftOvf((byte)1, 8 * sizeof(byte) + shift).val; + result = (byte)(result | shiftedCarry); + } + + if (saturating) + { + if (shiftOvf) + { + result = byte.MaxValue; + } + } + + return result; + } + + private static sbyte UnsignedShift(sbyte op1, sbyte op2, bool rounding = false, bool saturating = false) => (sbyte)UnsignedShift((byte)op1, op2, rounding, saturating); + + private static (sbyte val, bool ovf) AddOvf(sbyte op1, sbyte op2) + { + sbyte result = (sbyte)(op1 + op2); + + bool ovf = false; + + if ((op1 > 0) && (op2 > 0)) + { + ovf = (result < 0); + } + else if ((op1 < 0) && (op2 < 0)) + { + ovf = (result > 0); + } + + return (result, ovf); + } + + private static (byte val, bool ovf) AddOvf(byte op1, byte op2) + { + byte result = (byte)(op1 + op2); + + bool ovf = (result < op1); + + return (result, ovf); + } + + private static (sbyte val, bool ovf) SubtractOvf(sbyte op1, sbyte op2) + { + sbyte result = (sbyte)(op1 - op2); + + bool ovf = false; + + if ((op1 > 0) && (op2 < 0)) + { + ovf = (result < 0); + } + else if ((op1 < 0) && (op2 > 0)) + { + ovf = (result > 0); + } + + return (result, ovf); + } + + private static (byte val, bool ovf) SubtractOvf(byte op1, byte op2) + { + byte result = (byte)(op1 - op2); + + bool ovf = (op1 < op2); + + return (result, ovf); + } + + public static sbyte AddSaturate(sbyte op1, sbyte op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? (result > 0 ? sbyte.MinValue : sbyte.MaxValue) : result; + } + + public static byte AddSaturate(byte op1, byte op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? byte.MaxValue : result; + } + + public static sbyte SubtractSaturate(sbyte op1, sbyte op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? (result > 0 ? sbyte.MinValue : sbyte.MaxValue) : result; + } + + public static byte SubtractSaturate(byte op1, byte op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? byte.MinValue : result; + } + + public static short ShiftArithmetic(short op1, short op2) => SignedShift(op1, op2); + + public static short ShiftArithmeticRounded(short op1, short op2) => SignedShift(op1, op2, rounding: true); + + public static short ShiftArithmeticSaturate(short op1, short op2) => SignedShift(op1, op2, saturating: true); + + public static short ShiftArithmeticRoundedSaturate(short op1, short op2) => SignedShift(op1, op2, rounding: true, saturating: true); + + private static short SignedShift(short op1, short op2, bool rounding = false, bool saturating = false) + { + int shift = (sbyte)(op2 & 0xFF); + + short rndCns = 0; + + if (rounding) + { + bool ovf; + + (rndCns, ovf) = ShiftOvf((short)1, -shift-1); + + if (ovf) + { + return 0; + } + } + + short result; + + bool addOvf; + + (result, addOvf) = AddOvf(op1, rndCns); + + if (addOvf) + { + result = (short)ShiftOvf((ushort)result, shift).val; + } + else + { + bool shiftOvf; + + (result, shiftOvf) = ShiftOvf(result, shift); + + if (saturating) + { + if (shiftOvf) + { + result = short.MaxValue; + } + } + } + + return result; + } + + public static short ShiftLeftLogical(short op1, byte op2) => UnsignedShift(op1, (short)op2); + + public static ushort ShiftLeftLogical(ushort op1, byte op2) => UnsignedShift(op1, (short)op2); + + public static short ShiftLeftLogicalSaturate(short op1, byte op2) => SignedShift(op1, (short)op2, saturating: true); + + public static ushort ShiftLeftLogicalSaturate(ushort op1, byte op2) => UnsignedShift(op1, (short)op2, saturating: true); + + public static ushort ShiftLeftLogicalSaturateUnsigned(short op1, byte op2) => (ushort)UnsignedShift(op1, (short)op2, saturating: true); + + public static short ShiftLogical(short op1, short op2) => UnsignedShift(op1, op2); + + public static ushort ShiftLogical(ushort op1, short op2) => UnsignedShift(op1, op2); + + public static ushort ShiftLogicalRounded(ushort op1, short op2) => UnsignedShift(op1, op2, rounding: true); + + public static short ShiftLogicalRounded(short op1, short op2) => UnsignedShift(op1, op2, rounding: true); + + public static ushort ShiftLogicalRoundedSaturate(ushort op1, short op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); + + public static short ShiftLogicalRoundedSaturate(short op1, short op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); + + public static short ShiftLogicalSaturate(short op1, short op2) => UnsignedShift(op1, op2, saturating: true); + + public static ushort ShiftLogicalSaturate(ushort op1, short op2) => UnsignedShift(op1, op2, saturating: true); + + public static short ShiftRightArithmetic(short op1, byte op2) => SignedShift(op1, (short)(-op2)); + + public static short ShiftRightArithmeticAdd(short op1, short op2, byte op3) => (short)(op1 + ShiftRightArithmetic(op2, op3)); + + public static short ShiftRightArithmeticRounded(short op1, byte op2) => SignedShift(op1, (short)(-op2), rounding: true); + + public static short ShiftRightArithmeticRoundedAdd(short op1, short op2, byte op3) => (short)(op1 + ShiftRightArithmeticRounded(op2, op3)); + + public static short ShiftRightLogical(short op1, byte op2) => UnsignedShift(op1, (short)(-op2)); + + public static ushort ShiftRightLogical(ushort op1, byte op2) => UnsignedShift(op1, (short)(-op2)); + + public static short ShiftRightLogicalAdd(short op1, short op2, byte op3) => (short)(op1 + ShiftRightLogical(op2, op3)); + + public static ushort ShiftRightLogicalAdd(ushort op1, ushort op2, byte op3) => (ushort)(op1 + ShiftRightLogical(op2, op3)); + + public static short ShiftRightLogicalRounded(short op1, byte op2) => UnsignedShift(op1, (short)(-op2), rounding: true); + + public static ushort ShiftRightLogicalRounded(ushort op1, byte op2) => UnsignedShift(op1, (short)(-op2), rounding: true); + + public static short ShiftRightLogicalRoundedAdd(short op1, short op2, byte op3) => (short)(op1 + ShiftRightLogicalRounded(op2, op3)); + + public static ushort ShiftRightLogicalRoundedAdd(ushort op1, ushort op2, byte op3) => (ushort)(op1 + ShiftRightLogicalRounded(op2, op3)); + + private static ushort UnsignedShift(ushort op1, short op2, bool rounding = false, bool saturating = false) + { + int shift = (sbyte)(op2 & 0xFF); + + ushort rndCns = 0; + + if (rounding) + { + bool ovf; + + (rndCns, ovf) = ShiftOvf((ushort)1, -shift-1); + + if (ovf) + { + return 0; + } + } + + (ushort result, bool addOvf) = AddOvf(op1, rndCns); + + bool shiftOvf; + + (result, shiftOvf) = ShiftOvf(result, shift); + + if (addOvf) + { + ushort shiftedCarry = ShiftOvf((ushort)1, 8 * sizeof(ushort) + shift).val; + result = (ushort)(result | shiftedCarry); + } + + if (saturating) + { + if (shiftOvf) + { + result = ushort.MaxValue; + } + } + + return result; + } + + private static short UnsignedShift(short op1, short op2, bool rounding = false, bool saturating = false) => (short)UnsignedShift((ushort)op1, op2, rounding, saturating); + + private static (short val, bool ovf) AddOvf(short op1, short op2) + { + short result = (short)(op1 + op2); + + bool ovf = false; + + if ((op1 > 0) && (op2 > 0)) + { + ovf = (result < 0); + } + else if ((op1 < 0) && (op2 < 0)) + { + ovf = (result > 0); + } + + return (result, ovf); + } + + private static (ushort val, bool ovf) AddOvf(ushort op1, ushort op2) + { + ushort result = (ushort)(op1 + op2); + + bool ovf = (result < op1); + + return (result, ovf); + } + + private static (short val, bool ovf) SubtractOvf(short op1, short op2) + { + short result = (short)(op1 - op2); + + bool ovf = false; + + if ((op1 > 0) && (op2 < 0)) + { + ovf = (result < 0); + } + else if ((op1 < 0) && (op2 > 0)) + { + ovf = (result > 0); + } + + return (result, ovf); + } + + private static (ushort val, bool ovf) SubtractOvf(ushort op1, ushort op2) + { + ushort result = (ushort)(op1 - op2); + + bool ovf = (op1 < op2); + + return (result, ovf); + } + + public static short AddSaturate(short op1, short op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? (result > 0 ? short.MinValue : short.MaxValue) : result; + } + + public static ushort AddSaturate(ushort op1, ushort op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? ushort.MaxValue : result; + } + + public static short SubtractSaturate(short op1, short op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? (result > 0 ? short.MinValue : short.MaxValue) : result; + } + + public static ushort SubtractSaturate(ushort op1, ushort op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? ushort.MinValue : result; + } + + public static int ShiftArithmetic(int op1, int op2) => SignedShift(op1, op2); + + public static int ShiftArithmeticRounded(int op1, int op2) => SignedShift(op1, op2, rounding: true); + + public static int ShiftArithmeticSaturate(int op1, int op2) => SignedShift(op1, op2, saturating: true); + + public static int ShiftArithmeticRoundedSaturate(int op1, int op2) => SignedShift(op1, op2, rounding: true, saturating: true); + + private static int SignedShift(int op1, int op2, bool rounding = false, bool saturating = false) + { + int shift = (sbyte)(op2 & 0xFF); + + int rndCns = 0; + + if (rounding) + { + bool ovf; + + (rndCns, ovf) = ShiftOvf((int)1, -shift-1); + + if (ovf) + { + return 0; + } + } + + int result; + + bool addOvf; + + (result, addOvf) = AddOvf(op1, rndCns); + + if (addOvf) + { + result = (int)ShiftOvf((uint)result, shift).val; + } + else + { + bool shiftOvf; + + (result, shiftOvf) = ShiftOvf(result, shift); + + if (saturating) + { + if (shiftOvf) + { + result = int.MaxValue; + } + } + } + + return result; + } + + public static int ShiftLeftLogical(int op1, byte op2) => UnsignedShift(op1, (int)op2); + + public static uint ShiftLeftLogical(uint op1, byte op2) => UnsignedShift(op1, (int)op2); + + public static int ShiftLeftLogicalSaturate(int op1, byte op2) => SignedShift(op1, (int)op2, saturating: true); + + public static uint ShiftLeftLogicalSaturate(uint op1, byte op2) => UnsignedShift(op1, (int)op2, saturating: true); + + public static uint ShiftLeftLogicalSaturateUnsigned(int op1, byte op2) => (uint)UnsignedShift(op1, (int)op2, saturating: true); + + public static int ShiftLogical(int op1, int op2) => UnsignedShift(op1, op2); + + public static uint ShiftLogical(uint op1, int op2) => UnsignedShift(op1, op2); + + public static uint ShiftLogicalRounded(uint op1, int op2) => UnsignedShift(op1, op2, rounding: true); + + public static int ShiftLogicalRounded(int op1, int op2) => UnsignedShift(op1, op2, rounding: true); + + public static uint ShiftLogicalRoundedSaturate(uint op1, int op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); + + public static int ShiftLogicalRoundedSaturate(int op1, int op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); + + public static int ShiftLogicalSaturate(int op1, int op2) => UnsignedShift(op1, op2, saturating: true); + + public static uint ShiftLogicalSaturate(uint op1, int op2) => UnsignedShift(op1, op2, saturating: true); + + public static int ShiftRightArithmetic(int op1, byte op2) => SignedShift(op1, (int)(-op2)); + + public static int ShiftRightArithmeticAdd(int op1, int op2, byte op3) => (int)(op1 + ShiftRightArithmetic(op2, op3)); + + public static int ShiftRightArithmeticRounded(int op1, byte op2) => SignedShift(op1, (int)(-op2), rounding: true); + + public static int ShiftRightArithmeticRoundedAdd(int op1, int op2, byte op3) => (int)(op1 + ShiftRightArithmeticRounded(op2, op3)); + + public static int ShiftRightLogical(int op1, byte op2) => UnsignedShift(op1, (int)(-op2)); + + public static uint ShiftRightLogical(uint op1, byte op2) => UnsignedShift(op1, (int)(-op2)); + + public static int ShiftRightLogicalAdd(int op1, int op2, byte op3) => (int)(op1 + ShiftRightLogical(op2, op3)); + + public static uint ShiftRightLogicalAdd(uint op1, uint op2, byte op3) => (uint)(op1 + ShiftRightLogical(op2, op3)); + + public static int ShiftRightLogicalRounded(int op1, byte op2) => UnsignedShift(op1, (int)(-op2), rounding: true); + + public static uint ShiftRightLogicalRounded(uint op1, byte op2) => UnsignedShift(op1, (int)(-op2), rounding: true); + + public static int ShiftRightLogicalRoundedAdd(int op1, int op2, byte op3) => (int)(op1 + ShiftRightLogicalRounded(op2, op3)); + + public static uint ShiftRightLogicalRoundedAdd(uint op1, uint op2, byte op3) => (uint)(op1 + ShiftRightLogicalRounded(op2, op3)); + + private static uint UnsignedShift(uint op1, int op2, bool rounding = false, bool saturating = false) + { + int shift = (sbyte)(op2 & 0xFF); + + uint rndCns = 0; + + if (rounding) + { + bool ovf; + + (rndCns, ovf) = ShiftOvf((uint)1, -shift-1); + + if (ovf) + { + return 0; + } + } + + (uint result, bool addOvf) = AddOvf(op1, rndCns); + + bool shiftOvf; + + (result, shiftOvf) = ShiftOvf(result, shift); + + if (addOvf) + { + uint shiftedCarry = ShiftOvf((uint)1, 8 * sizeof(uint) + shift).val; + result = (uint)(result | shiftedCarry); + } + + if (saturating) + { + if (shiftOvf) + { + result = uint.MaxValue; + } + } + + return result; + } + + private static int UnsignedShift(int op1, int op2, bool rounding = false, bool saturating = false) => (int)UnsignedShift((uint)op1, op2, rounding, saturating); + + private static (int val, bool ovf) AddOvf(int op1, int op2) + { + int result = (int)(op1 + op2); + + bool ovf = false; + + if ((op1 > 0) && (op2 > 0)) + { + ovf = (result < 0); + } + else if ((op1 < 0) && (op2 < 0)) + { + ovf = (result > 0); + } + + return (result, ovf); + } + + private static (uint val, bool ovf) AddOvf(uint op1, uint op2) + { + uint result = (uint)(op1 + op2); + + bool ovf = (result < op1); + + return (result, ovf); + } + + private static (int val, bool ovf) SubtractOvf(int op1, int op2) + { + int result = (int)(op1 - op2); + + bool ovf = false; + + if ((op1 > 0) && (op2 < 0)) + { + ovf = (result < 0); + } + else if ((op1 < 0) && (op2 > 0)) + { + ovf = (result > 0); + } + + return (result, ovf); + } + + private static (uint val, bool ovf) SubtractOvf(uint op1, uint op2) + { + uint result = (uint)(op1 - op2); + + bool ovf = (op1 < op2); + + return (result, ovf); + } + + public static int AddSaturate(int op1, int op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? (result > 0 ? int.MinValue : int.MaxValue) : result; + } + + public static uint AddSaturate(uint op1, uint op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? uint.MaxValue : result; + } + + public static int SubtractSaturate(int op1, int op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? (result > 0 ? int.MinValue : int.MaxValue) : result; + } + + public static uint SubtractSaturate(uint op1, uint op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? uint.MinValue : result; + } + + public static long ShiftArithmetic(long op1, long op2) => SignedShift(op1, op2); + + public static long ShiftArithmeticRounded(long op1, long op2) => SignedShift(op1, op2, rounding: true); + + public static long ShiftArithmeticSaturate(long op1, long op2) => SignedShift(op1, op2, saturating: true); + + public static long ShiftArithmeticRoundedSaturate(long op1, long op2) => SignedShift(op1, op2, rounding: true, saturating: true); + + private static long SignedShift(long op1, long op2, bool rounding = false, bool saturating = false) + { + int shift = (sbyte)(op2 & 0xFF); + + long rndCns = 0; + + if (rounding) + { + bool ovf; + + (rndCns, ovf) = ShiftOvf((long)1, -shift-1); + + if (ovf) + { + return 0; + } + } + + long result; + + bool addOvf; + + (result, addOvf) = AddOvf(op1, rndCns); + + if (addOvf) + { + result = (long)ShiftOvf((ulong)result, shift).val; + } + else + { + bool shiftOvf; + + (result, shiftOvf) = ShiftOvf(result, shift); + + if (saturating) + { + if (shiftOvf) + { + result = long.MaxValue; + } + } + } + + return result; + } + + public static long ShiftLeftLogical(long op1, byte op2) => UnsignedShift(op1, (long)op2); + + public static ulong ShiftLeftLogical(ulong op1, byte op2) => UnsignedShift(op1, (long)op2); + + public static long ShiftLeftLogicalSaturate(long op1, byte op2) => SignedShift(op1, (long)op2, saturating: true); + + public static ulong ShiftLeftLogicalSaturate(ulong op1, byte op2) => UnsignedShift(op1, (long)op2, saturating: true); + + public static ulong ShiftLeftLogicalSaturateUnsigned(long op1, byte op2) => (ulong)UnsignedShift(op1, (long)op2, saturating: true); + + public static long ShiftLogical(long op1, long op2) => UnsignedShift(op1, op2); + + public static ulong ShiftLogical(ulong op1, long op2) => UnsignedShift(op1, op2); + + public static ulong ShiftLogicalRounded(ulong op1, long op2) => UnsignedShift(op1, op2, rounding: true); + + public static long ShiftLogicalRounded(long op1, long op2) => UnsignedShift(op1, op2, rounding: true); + + public static ulong ShiftLogicalRoundedSaturate(ulong op1, long op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); + + public static long ShiftLogicalRoundedSaturate(long op1, long op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); + + public static long ShiftLogicalSaturate(long op1, long op2) => UnsignedShift(op1, op2, saturating: true); + + public static ulong ShiftLogicalSaturate(ulong op1, long op2) => UnsignedShift(op1, op2, saturating: true); + + public static long ShiftRightArithmetic(long op1, byte op2) => SignedShift(op1, (long)(-op2)); + + public static long ShiftRightArithmeticAdd(long op1, long op2, byte op3) => (long)(op1 + ShiftRightArithmetic(op2, op3)); + + public static long ShiftRightArithmeticRounded(long op1, byte op2) => SignedShift(op1, (long)(-op2), rounding: true); + + public static long ShiftRightArithmeticRoundedAdd(long op1, long op2, byte op3) => (long)(op1 + ShiftRightArithmeticRounded(op2, op3)); + + public static long ShiftRightLogical(long op1, byte op2) => UnsignedShift(op1, (long)(-op2)); + + public static ulong ShiftRightLogical(ulong op1, byte op2) => UnsignedShift(op1, (long)(-op2)); + + public static long ShiftRightLogicalAdd(long op1, long op2, byte op3) => (long)(op1 + ShiftRightLogical(op2, op3)); + + public static ulong ShiftRightLogicalAdd(ulong op1, ulong op2, byte op3) => (ulong)(op1 + ShiftRightLogical(op2, op3)); + + public static long ShiftRightLogicalRounded(long op1, byte op2) => UnsignedShift(op1, (long)(-op2), rounding: true); + + public static ulong ShiftRightLogicalRounded(ulong op1, byte op2) => UnsignedShift(op1, (long)(-op2), rounding: true); + + public static long ShiftRightLogicalRoundedAdd(long op1, long op2, byte op3) => (long)(op1 + ShiftRightLogicalRounded(op2, op3)); + + public static ulong ShiftRightLogicalRoundedAdd(ulong op1, ulong op2, byte op3) => (ulong)(op1 + ShiftRightLogicalRounded(op2, op3)); + + private static ulong UnsignedShift(ulong op1, long op2, bool rounding = false, bool saturating = false) + { + int shift = (sbyte)(op2 & 0xFF); + + ulong rndCns = 0; + + if (rounding) + { + bool ovf; + + (rndCns, ovf) = ShiftOvf((ulong)1, -shift-1); + + if (ovf) + { + return 0; + } + } + + (ulong result, bool addOvf) = AddOvf(op1, rndCns); + + bool shiftOvf; + + (result, shiftOvf) = ShiftOvf(result, shift); + + if (addOvf) + { + ulong shiftedCarry = ShiftOvf((ulong)1, 8 * sizeof(ulong) + shift).val; + result = (ulong)(result | shiftedCarry); + } + + if (saturating) + { + if (shiftOvf) + { + result = ulong.MaxValue; + } + } + + return result; + } + + private static long UnsignedShift(long op1, long op2, bool rounding = false, bool saturating = false) => (long)UnsignedShift((ulong)op1, op2, rounding, saturating); + + private static (long val, bool ovf) AddOvf(long op1, long op2) + { + long result = (long)(op1 + op2); + + bool ovf = false; + + if ((op1 > 0) && (op2 > 0)) + { + ovf = (result < 0); + } + else if ((op1 < 0) && (op2 < 0)) + { + ovf = (result > 0); + } + + return (result, ovf); + } + + private static (ulong val, bool ovf) AddOvf(ulong op1, ulong op2) + { + ulong result = (ulong)(op1 + op2); + + bool ovf = (result < op1); + + return (result, ovf); + } + + private static (long val, bool ovf) SubtractOvf(long op1, long op2) + { + long result = (long)(op1 - op2); + + bool ovf = false; + + if ((op1 > 0) && (op2 < 0)) + { + ovf = (result < 0); + } + else if ((op1 < 0) && (op2 > 0)) + { + ovf = (result > 0); + } + + return (result, ovf); + } + + private static (ulong val, bool ovf) SubtractOvf(ulong op1, ulong op2) + { + ulong result = (ulong)(op1 - op2); + + bool ovf = (op1 < op2); + + return (result, ovf); + } + + public static long AddSaturate(long op1, long op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? (result > 0 ? long.MinValue : long.MaxValue) : result; + } + + public static ulong AddSaturate(ulong op1, ulong op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? ulong.MaxValue : result; + } + + public static long SubtractSaturate(long op1, long op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? (result > 0 ? long.MinValue : long.MaxValue) : result; + } + + public static ulong SubtractSaturate(ulong op1, ulong op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? ulong.MinValue : result; + } + + + private static (sbyte val, bool ovf) ShiftOvf(sbyte value, int shift) + { + sbyte result = value; + + bool ovf = false; + sbyte msb = 1; + msb = (sbyte)(msb << (8 * sizeof(sbyte) - 1)); + + for (int i = 0; i < shift; i++) + { + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } + + for (int i = 0; i > shift; i--) + { + result >>= 1; + } + + if ((value > 0) && (result < 0)) + { + ovf = true; + } + + return (result, ovf); + } + + + + private static (byte val, bool ovf) ShiftOvf(byte value, int shift) + { + byte result = value; + + bool ovf = false; + byte msb = 1; + msb = (byte)(msb << (8 * sizeof(byte) - 1)); + + for (int i = 0; i < shift; i++) + { + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } + + for (int i = 0; i > shift; i--) + { + result >>= 1; + } + + if ((value > 0) && (result < 0)) + { + ovf = true; + } + + return (result, ovf); + } + + + + private static (short val, bool ovf) ShiftOvf(short value, int shift) + { + short result = value; + + bool ovf = false; + short msb = 1; + msb = (short)(msb << (8 * sizeof(short) - 1)); + + for (int i = 0; i < shift; i++) + { + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } + + for (int i = 0; i > shift; i--) + { + result >>= 1; + } + + if ((value > 0) && (result < 0)) + { + ovf = true; + } + + return (result, ovf); + } + + + + private static (ushort val, bool ovf) ShiftOvf(ushort value, int shift) + { + ushort result = value; + + bool ovf = false; + ushort msb = 1; + msb = (ushort)(msb << (8 * sizeof(ushort) - 1)); + + for (int i = 0; i < shift; i++) + { + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } + + for (int i = 0; i > shift; i--) + { + result >>= 1; + } + + if ((value > 0) && (result < 0)) + { + ovf = true; + } + + return (result, ovf); + } + + + + private static (int val, bool ovf) ShiftOvf(int value, int shift) + { + int result = value; + + bool ovf = false; + int msb = 1; + msb = (int)(msb << (8 * sizeof(int) - 1)); + + for (int i = 0; i < shift; i++) + { + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } + + for (int i = 0; i > shift; i--) + { + result >>= 1; + } + + if ((value > 0) && (result < 0)) + { + ovf = true; + } + + return (result, ovf); + } + + + + private static (uint val, bool ovf) ShiftOvf(uint value, int shift) + { + uint result = value; + + bool ovf = false; + uint msb = 1; + msb = (uint)(msb << (8 * sizeof(uint) - 1)); + + for (int i = 0; i < shift; i++) + { + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } + + for (int i = 0; i > shift; i--) + { + result >>= 1; + } + + if ((value > 0) && (result < 0)) + { + ovf = true; + } + + return (result, ovf); + } + + + + private static (long val, bool ovf) ShiftOvf(long value, int shift) + { + long result = value; + + bool ovf = false; + long msb = 1; + msb = (long)(msb << (8 * sizeof(long) - 1)); + + for (int i = 0; i < shift; i++) + { + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } + + for (int i = 0; i > shift; i--) + { + result >>= 1; + } + + if ((value > 0) && (result < 0)) + { + ovf = true; + } + + return (result, ovf); + } + + + + private static (ulong val, bool ovf) ShiftOvf(ulong value, int shift) + { + ulong result = value; + + bool ovf = false; + ulong msb = 1; + msb = (ulong)(msb << (8 * sizeof(ulong) - 1)); + + for (int i = 0; i < shift; i++) + { + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } + + for (int i = 0; i > shift; i--) + { + result >>= 1; + } + + if ((value > 0) && (result < 0)) + { + ovf = true; + } + + return (result, ovf); + } + + public static float AbsoluteDifference(float op1, float op2) => MathF.Abs(op1 - op2); public static float FusedMultiplyAdd(float op1, float op2, float op3) => MathF.FusedMultiplyAdd(op2, op3, op1); diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt index cc62c0a9a42aa..9c50cda89e592 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/Helpers.tt @@ -11,7 +11,6 @@ using System; using System.Linq; -using System.Numerics; namespace JIT.HardwareIntrinsics.Arm { @@ -409,48 +408,479 @@ namespace JIT.HardwareIntrinsics.Arm public static <#= type.wide #> SubtractWideningUpper(<#= type.wide #>[] op1, <#= type.name #>[] op2, int i) => SubtractWidening(op1[i], op2[i + op2.Length / 2]); + public static <#= type.wide #> ZeroExtendWidening(<#= type.name #> op1) => (<#= type.wide #>)(<#= type.wideUnsigned #>)op1; + + public static <#= type.wide #> ZeroExtendWideningUpper(<#= type.name #>[] op1, int i) => ZeroExtendWidening(op1[i + op1.Length / 2]); + <# } - foreach (string typeName in new string[] { "sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong" }) + foreach (var type in new[] { (name: "sbyte", unsigned: "byte", wide: "short", wideUnsigned: "ushort"), + (name: "short", unsigned: "ushort", wide: "int", wideUnsigned: "uint"), + (name: "int", unsigned: "uint", wide: "long", wideUnsigned: "ulong") }) { #> - private static bool SatQ(BigInteger i, out <#= typeName #> result) + private static bool SignedSatQ(<#= type.wide #> val, out <#= type.name #> result) + { + bool saturated = false; + + if (val > <#= type.name #>.MaxValue) + { + result = <#= type.name #>.MaxValue; + saturated = true; + } + else if (val < <#= type.name #>.MinValue) + { + result = <#= type.name #>.MinValue; + saturated = true; + } + else + { + result = (<#= type.name #>)val; + } + + return saturated; + } + + private static bool SignedSatQ(<#= type.wide #> val, out <#= type.unsigned #> result) + { + bool saturated = false; + + if (val > <#= type.unsigned #>.MaxValue) + { + result = <#= type.unsigned #>.MaxValue; + saturated = true; + } + else if (val < 0) + { + result = 0; + saturated = true; + } + else + { + result = (<#= type.unsigned #>)val; + } + + return saturated; + } + + private static bool UnsignedSatQ(<#= type.wide #> val, out <#= type.name #> result) + { + <#= type.unsigned #> res; + + bool saturated = UnsignedSatQ((<#= type.wideUnsigned #>)val, out res); + + result = (<#= type.name #>)res; + return saturated; + } + + private static bool UnsignedSatQ(<#= type.wideUnsigned #> val, out <#= type.unsigned #> result) { bool saturated = false; - if (i > <#= typeName #>.MaxValue) + if (val > <#= type.unsigned #>.MaxValue) { - result = <#= typeName #>.MaxValue; + result = <#= type.unsigned #>.MaxValue; saturated = true; } - else if (i < <#= typeName #>.MinValue) + else if (val < 0) { - result = <#= typeName #>.MinValue; + result = 0; saturated = true; } else { - result = (<#= typeName #>)i; + result = (<#= type.unsigned #>)val; } return saturated; } - public static <#= typeName #> AddSaturate(<#= typeName #> op1, <#= typeName #> op2) + public static <#= type.wide #> ShiftLeftLogicalWidening(<#= type.name #> op1, byte op2) => UnsignedShift((<#= type.wide #>)op1, (<#= type.wide #>)op2); + + public static <#= type.wideUnsigned #> ShiftLeftLogicalWidening(<#= type.unsigned #> op1, byte op2) => UnsignedShift((<#= type.wideUnsigned #>)op1, (<#= type.wide #>)op2); + + public static <#= type.wide #> ShiftLeftLogicalWideningUpper(<#= type.name #>[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + + public static <#= type.wideUnsigned #> ShiftLeftLogicalWideningUpper(<#= type.unsigned #>[] op1, byte op2, int i) => ShiftLeftLogicalWidening(op1[i + op1.Length / 2], op2); + + public static <#= type.name #> ShiftRightArithmeticRoundedNarrowingSaturate(<#= type.wide #> op1, byte op2) + { + <#= type.name #> result; + + SignedSatQ(SignedShift(op1, (<#= type.wide #>)(-op2), rounding: true), out result); + + return result; + } + + public static <#= type.unsigned #> ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(<#= type.wide #> op1, byte op2) + { + <#= type.unsigned #> result; + + SignedSatQ(SignedShift(op1, (<#= type.wide #>)(-op2), rounding: true), out result); + + return result; + } + + public static <#= type.unsigned #> ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(<#= type.unsigned #>[] op1, <#= type.wide #>[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (<#= type.unsigned #>)ShiftRightArithmeticRoundedNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + + public static <#= type.name #> ShiftRightArithmeticRoundedNarrowingSaturateUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (<#= type.name #>)ShiftRightArithmeticRoundedNarrowingSaturate(op2[i - op1.Length], op3); + + public static <#= type.name #> ShiftRightArithmeticNarrowingSaturate(<#= type.wide #> op1, byte op2) { - <#= typeName #> result; - SatQ(new BigInteger(op1) + new BigInteger(op2), out result); + <#= type.name #> result; + + SignedSatQ(SignedShift(op1, (<#= type.wide #>)(-op2)), out result); + + return result; + } + + public static <#= type.unsigned #> ShiftRightArithmeticNarrowingSaturateUnsigned(<#= type.wide #> op1, byte op2) + { + <#= type.unsigned #> result; + + SignedSatQ(SignedShift(op1, (<#= type.wide #>)(-op2)), out result); + + return result; + } + + public static <#= type.unsigned #> ShiftRightArithmeticNarrowingSaturateUnsignedUpper(<#= type.unsigned #>[] op1, <#= type.wide #>[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (<#= type.unsigned #>)ShiftRightArithmeticNarrowingSaturateUnsigned(op2[i - op1.Length], op3); + + public static <#= type.name #> ShiftRightArithmeticNarrowingSaturateUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (<#= type.name #>)ShiftRightArithmeticNarrowingSaturate(op2[i - op1.Length], op3); + + public static <#= type.name #> ShiftRightLogicalNarrowing(<#= type.wide #> op1, byte op2) => (<#= type.name #>)UnsignedShift(op1, (<#= type.wide #>)(-op2)); + + public static <#= type.unsigned #> ShiftRightLogicalNarrowing(<#= type.wideUnsigned #> op1, byte op2) => (<#= type.unsigned #>)UnsignedShift(op1, (<#= type.wide #>)(-op2)); + + public static <#= type.name #> ShiftRightLogicalRoundedNarrowing(<#= type.wide #> op1, byte op2) => (<#= type.name #>)UnsignedShift(op1, (<#= type.wide #>)(-op2), rounding: true); + + public static <#= type.unsigned #> ShiftRightLogicalRoundedNarrowing(<#= type.wideUnsigned #> op1, byte op2) => (<#= type.unsigned #>)UnsignedShift(op1, (<#= type.wide #>)(-op2), rounding: true); + + public static <#= type.name #> ShiftRightLogicalRoundedNarrowingUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (<#= type.name #>)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + + public static <#= type.unsigned #> ShiftRightLogicalRoundedNarrowingUpper(<#= type.unsigned #>[] op1, <#= type.wideUnsigned #>[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (<#= type.unsigned #>)ShiftRightLogicalRoundedNarrowing(op2[i - op1.Length], op3); + + public static <#= type.name #> ShiftRightLogicalRoundedNarrowingSaturate(<#= type.wide #> op1, byte op2) + { + <#= type.name #> result; + + UnsignedSatQ(UnsignedShift(op1, (<#= type.wide #>)(-op2), rounding: true), out result); + + return result; + } + + public static <#= type.unsigned #> ShiftRightLogicalRoundedNarrowingSaturate(<#= type.wideUnsigned #> op1, byte op2) + { + <#= type.unsigned #> result; + + UnsignedSatQ(UnsignedShift(op1, (<#= type.wide #>)(-op2), rounding: true), out result); + + return result; + } + + public static <#= type.name #> ShiftRightLogicalRoundedNarrowingSaturateUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (<#= type.name #>)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + + public static <#= type.unsigned #> ShiftRightLogicalRoundedNarrowingSaturateUpper(<#= type.unsigned #>[] op1, <#= type.wideUnsigned #>[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (<#= type.unsigned #>)ShiftRightLogicalRoundedNarrowingSaturate(op2[i - op1.Length], op3); + + public static <#= type.name #> ShiftRightLogicalNarrowingUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (<#= type.name #>)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + + public static <#= type.unsigned #> ShiftRightLogicalNarrowingUpper(<#= type.unsigned #>[] op1, <#= type.wideUnsigned #>[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (<#= type.unsigned #>)ShiftRightLogicalNarrowing(op2[i - op1.Length], op3); + + public static <#= type.name #> ShiftRightLogicalNarrowingSaturate(<#= type.wide #> op1, byte op2) + { + <#= type.name #> result; + + UnsignedSatQ(UnsignedShift(op1, (<#= type.wide #>)(-op2)), out result); + + return result; + } + + public static <#= type.unsigned #> ShiftRightLogicalNarrowingSaturate(<#= type.wideUnsigned #> op1, byte op2) + { + <#= type.unsigned #> result; + + UnsignedSatQ(UnsignedShift(op1, (<#= type.wide #>)(-op2)), out result); + + return result; + } + + public static <#= type.name #> ShiftRightLogicalNarrowingSaturateUpper(<#= type.name #>[] op1, <#= type.wide #>[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (<#= type.name #>)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); + + public static <#= type.unsigned #> ShiftRightLogicalNarrowingSaturateUpper(<#= type.unsigned #>[] op1, <#= type.wideUnsigned #>[] op2, byte op3, int i) => i < op1.Length ? op1[i] : (<#= type.unsigned #>)ShiftRightLogicalNarrowingSaturate(op2[i - op1.Length], op3); + + public static <#= type.wide #> SignExtendWidening(<#= type.name #> op1) => op1; + + public static <#= type.wide #> SignExtendWideningUpper(<#= type.name #>[] op1, int i) => SignExtendWidening(op1[i + op1.Length / 2]); + +<# + } + + foreach (var type in new[] { (name: "sbyte", unsigned: "byte"), + (name: "short", unsigned: "ushort"), + (name: "int", unsigned: "uint"), + (name: "long", unsigned: "ulong") }) + { +#> + public static <#= type.name #> ShiftArithmetic(<#= type.name #> op1, <#= type.name #> op2) => SignedShift(op1, op2); + + public static <#= type.name #> ShiftArithmeticRounded(<#= type.name #> op1, <#= type.name #> op2) => SignedShift(op1, op2, rounding: true); + + public static <#= type.name #> ShiftArithmeticSaturate(<#= type.name #> op1, <#= type.name #> op2) => SignedShift(op1, op2, saturating: true); + + public static <#= type.name #> ShiftArithmeticRoundedSaturate(<#= type.name #> op1, <#= type.name #> op2) => SignedShift(op1, op2, rounding: true, saturating: true); + + private static <#= type.name #> SignedShift(<#= type.name #> op1, <#= type.name #> op2, bool rounding = false, bool saturating = false) + { + int shift = (sbyte)(op2 & 0xFF); + + <#= type.name #> rndCns = 0; + + if (rounding) + { + bool ovf; + + (rndCns, ovf) = ShiftOvf((<#= type.name #>)1, -shift-1); + + if (ovf) + { + return 0; + } + } + + <#= type.name #> result; + + bool addOvf; + + (result, addOvf) = AddOvf(op1, rndCns); + + if (addOvf) + { + result = (<#= type.name #>)ShiftOvf((<#= type.unsigned #>)result, shift).val; + } + else + { + bool shiftOvf; + + (result, shiftOvf) = ShiftOvf(result, shift); + + if (saturating) + { + if (shiftOvf) + { + result = <#= type.name #>.MaxValue; + } + } + } + return result; } - public static <#= typeName #> SubtractSaturate(<#= typeName #> op1, <#= typeName #> op2) + public static <#= type.name #> ShiftLeftLogical(<#= type.name #> op1, byte op2) => UnsignedShift(op1, (<#= type.name #>)op2); + + public static <#= type.unsigned #> ShiftLeftLogical(<#= type.unsigned #> op1, byte op2) => UnsignedShift(op1, (<#= type.name #>)op2); + + public static <#= type.name #> ShiftLeftLogicalSaturate(<#= type.name #> op1, byte op2) => SignedShift(op1, (<#= type.name #>)op2, saturating: true); + + public static <#= type.unsigned #> ShiftLeftLogicalSaturate(<#= type.unsigned #> op1, byte op2) => UnsignedShift(op1, (<#= type.name #>)op2, saturating: true); + + public static <#= type.unsigned #> ShiftLeftLogicalSaturateUnsigned(<#= type.name #> op1, byte op2) => (<#= type.unsigned #>)UnsignedShift(op1, (<#= type.name #>)op2, saturating: true); + + public static <#= type.name #> ShiftLogical(<#= type.name #> op1, <#= type.name #> op2) => UnsignedShift(op1, op2); + + public static <#= type.unsigned #> ShiftLogical(<#= type.unsigned #> op1, <#= type.name #> op2) => UnsignedShift(op1, op2); + + public static <#= type.unsigned #> ShiftLogicalRounded(<#= type.unsigned #> op1, <#= type.name #> op2) => UnsignedShift(op1, op2, rounding: true); + + public static <#= type.name #> ShiftLogicalRounded(<#= type.name #> op1, <#= type.name #> op2) => UnsignedShift(op1, op2, rounding: true); + + public static <#= type.unsigned #> ShiftLogicalRoundedSaturate(<#= type.unsigned #> op1, <#= type.name #> op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); + + public static <#= type.name #> ShiftLogicalRoundedSaturate(<#= type.name #> op1, <#= type.name #> op2) => UnsignedShift(op1, op2, rounding: true, saturating: true); + + public static <#= type.name #> ShiftLogicalSaturate(<#= type.name #> op1, <#= type.name #> op2) => UnsignedShift(op1, op2, saturating: true); + + public static <#= type.unsigned #> ShiftLogicalSaturate(<#= type.unsigned #> op1, <#= type.name #> op2) => UnsignedShift(op1, op2, saturating: true); + + public static <#= type.name #> ShiftRightArithmetic(<#= type.name #> op1, byte op2) => SignedShift(op1, (<#= type.name #>)(-op2)); + + public static <#= type.name #> ShiftRightArithmeticAdd(<#= type.name #> op1, <#= type.name #> op2, byte op3) => (<#= type.name #>)(op1 + ShiftRightArithmetic(op2, op3)); + + public static <#= type.name #> ShiftRightArithmeticRounded(<#= type.name #> op1, byte op2) => SignedShift(op1, (<#= type.name #>)(-op2), rounding: true); + + public static <#= type.name #> ShiftRightArithmeticRoundedAdd(<#= type.name #> op1, <#= type.name #> op2, byte op3) => (<#= type.name #>)(op1 + ShiftRightArithmeticRounded(op2, op3)); + + public static <#= type.name #> ShiftRightLogical(<#= type.name #> op1, byte op2) => UnsignedShift(op1, (<#= type.name #>)(-op2)); + + public static <#= type.unsigned #> ShiftRightLogical(<#= type.unsigned #> op1, byte op2) => UnsignedShift(op1, (<#= type.name #>)(-op2)); + + public static <#= type.name #> ShiftRightLogicalAdd(<#= type.name #> op1, <#= type.name #> op2, byte op3) => (<#= type.name #>)(op1 + ShiftRightLogical(op2, op3)); + + public static <#= type.unsigned #> ShiftRightLogicalAdd(<#= type.unsigned #> op1, <#= type.unsigned #> op2, byte op3) => (<#= type.unsigned #>)(op1 + ShiftRightLogical(op2, op3)); + + public static <#= type.name #> ShiftRightLogicalRounded(<#= type.name #> op1, byte op2) => UnsignedShift(op1, (<#= type.name #>)(-op2), rounding: true); + + public static <#= type.unsigned #> ShiftRightLogicalRounded(<#= type.unsigned #> op1, byte op2) => UnsignedShift(op1, (<#= type.name #>)(-op2), rounding: true); + + public static <#= type.name #> ShiftRightLogicalRoundedAdd(<#= type.name #> op1, <#= type.name #> op2, byte op3) => (<#= type.name #>)(op1 + ShiftRightLogicalRounded(op2, op3)); + + public static <#= type.unsigned #> ShiftRightLogicalRoundedAdd(<#= type.unsigned #> op1, <#= type.unsigned #> op2, byte op3) => (<#= type.unsigned #>)(op1 + ShiftRightLogicalRounded(op2, op3)); + + private static <#= type.unsigned #> UnsignedShift(<#= type.unsigned #> op1, <#= type.name #> op2, bool rounding = false, bool saturating = false) { - <#= typeName #> result; - SatQ(new BigInteger(op1) - new BigInteger(op2), out result); + int shift = (sbyte)(op2 & 0xFF); + + <#= type.unsigned #> rndCns = 0; + + if (rounding) + { + bool ovf; + + (rndCns, ovf) = ShiftOvf((<#= type.unsigned #>)1, -shift-1); + + if (ovf) + { + return 0; + } + } + + (<#= type.unsigned #> result, bool addOvf) = AddOvf(op1, rndCns); + + bool shiftOvf; + + (result, shiftOvf) = ShiftOvf(result, shift); + + if (addOvf) + { + <#= type.unsigned #> shiftedCarry = ShiftOvf((<#= type.unsigned #>)1, 8 * sizeof(<#= type.unsigned #>) + shift).val; + result = (<#= type.unsigned #>)(result | shiftedCarry); + } + + if (saturating) + { + if (shiftOvf) + { + result = <#= type.unsigned #>.MaxValue; + } + } + return result; } + private static <#= type.name #> UnsignedShift(<#= type.name #> op1, <#= type.name #> op2, bool rounding = false, bool saturating = false) => (<#= type.name #>)UnsignedShift((<#= type.unsigned #>)op1, op2, rounding, saturating); + + private static (<#= type.name #> val, bool ovf) AddOvf(<#= type.name #> op1, <#= type.name #> op2) + { + <#= type.name #> result = (<#= type.name #>)(op1 + op2); + + bool ovf = false; + + if ((op1 > 0) && (op2 > 0)) + { + ovf = (result < 0); + } + else if ((op1 < 0) && (op2 < 0)) + { + ovf = (result > 0); + } + + return (result, ovf); + } + + private static (<#= type.unsigned #> val, bool ovf) AddOvf(<#= type.unsigned #> op1, <#= type.unsigned #> op2) + { + <#= type.unsigned #> result = (<#= type.unsigned #>)(op1 + op2); + + bool ovf = (result < op1); + + return (result, ovf); + } + + private static (<#= type.name #> val, bool ovf) SubtractOvf(<#= type.name #> op1, <#= type.name #> op2) + { + <#= type.name #> result = (<#= type.name #>)(op1 - op2); + + bool ovf = false; + + if ((op1 > 0) && (op2 < 0)) + { + ovf = (result < 0); + } + else if ((op1 < 0) && (op2 > 0)) + { + ovf = (result > 0); + } + + return (result, ovf); + } + + private static (<#= type.unsigned #> val, bool ovf) SubtractOvf(<#= type.unsigned #> op1, <#= type.unsigned #> op2) + { + <#= type.unsigned #> result = (<#= type.unsigned #>)(op1 - op2); + + bool ovf = (op1 < op2); + + return (result, ovf); + } + + public static <#= type.name #> AddSaturate(<#= type.name #> op1, <#= type.name #> op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? (result > 0 ? <#= type.name #>.MinValue : <#= type.name #>.MaxValue) : result; + } + + public static <#= type.unsigned #> AddSaturate(<#= type.unsigned #> op1, <#= type.unsigned #> op2) + { + var (result, ovf) = AddOvf(op1, op2); + return ovf ? <#= type.unsigned #>.MaxValue : result; + } + + public static <#= type.name #> SubtractSaturate(<#= type.name #> op1, <#= type.name #> op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? (result > 0 ? <#= type.name #>.MinValue : <#= type.name #>.MaxValue) : result; + } + + public static <#= type.unsigned #> SubtractSaturate(<#= type.unsigned #> op1, <#= type.unsigned #> op2) + { + var (result, ovf) = SubtractOvf(op1, op2); + return ovf ? <#= type.unsigned #>.MinValue : result; + } + +<# + } + + foreach (string typeName in new string[] { "sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong" }) + { +#> + + private static (<#= typeName #> val, bool ovf) ShiftOvf(<#= typeName #> value, int shift) + { + <#= typeName #> result = value; + + bool ovf = false; + <#= typeName #> msb = 1; + msb = (<#= typeName #>)(msb << (8 * sizeof(<#= typeName #>) - 1)); + + for (int i = 0; i < shift; i++) + { + ovf = ovf || ((result & msb) != 0); + result <<= 1; + } + + for (int i = 0; i > shift; i--) + { + result >>= 1; + } + + if ((value > 0) && (result < 0)) + { + ovf = true; + } + + return (result, ovf); + } + + <# } diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmBinaryOpTestTemplate.template b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmBinaryOpTestTemplate.template new file mode 100644 index 0000000000000..be123b5522add --- /dev/null +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmBinaryOpTestTemplate.template @@ -0,0 +1,409 @@ +// 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.Arm; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + private static void {TestName}() + { + var test = new ImmBinaryOpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + 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 ImmBinaryOpTest__{TestName} + { + private struct DataTable + { + private byte[] inArray1; + private byte[] inArray2; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle inHandle2; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({Op1BaseType}[] inArray1, {Op2BaseType}[] inArray2, {RetBaseType}[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException("Invalid value of alignment"); + } + + this.inArray1 = new byte[alignment * 2]; + this.inArray2 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + inHandle2.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld1; + public {Op2VectorType}<{Op2BaseType}> _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmBinaryOpTest__{TestName} testClass) + { + var result = {Isa}.{Method}(_fld1, _fld2, {Imm}); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + private static readonly byte Imm = {Imm}; + + private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount]; + + private static {Op1VectorType}<{Op1BaseType}> _clsVar1; + private static {Op2VectorType}<{Op2BaseType}> _clsVar2; + + private {Op1VectorType}<{Op1BaseType}> _fld1; + private {Op2VectorType}<{Op2BaseType}> _fld2; + + private DataTable _dataTable; + + static ImmBinaryOpTest__{TestName}() + { + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _clsVar2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + } + + public ImmBinaryOpTest__{TestName}() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + _dataTable = new DataTable(_data1, _data2, new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + (byte){Imm} + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof(byte) }) + .Invoke(null, new object[] { + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)), + (byte){Imm} + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = {Isa}.{Method}( + _clsVar1, + _clsVar2, + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); + var secondOp = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); + var result = {Isa}.{Method}(firstOp, secondOp, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)); + var secondOp = {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)); + var result = {Isa}.{Method}(firstOp, secondOp, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, secondOp, _dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmBinaryOpTest__{TestName}(); + var result = {Isa}.{Method}(test._fld1, test._fld2, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld1, _fld2, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld1, test._fld2, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult({Op1VectorType}<{Op1BaseType}> firstOp, {Op2VectorType}<{Op2BaseType}> secondOp, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), firstOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), secondOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult(void* firstOp, void* secondOp, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(secondOp), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, inArray2, outArray, method); + } + + private void ValidateResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {RetBaseType}[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + {TemplateValidationLogic} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>.{Imm}, {Op2VectorType}<{Op2BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +} diff --git a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmUnaryOpTestTemplate.template b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmUnaryOpTestTemplate.template index df6ea9bf70435..a670c6e795d26 100644 --- a/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmUnaryOpTestTemplate.template +++ b/src/coreclr/tests/src/JIT/HardwareIntrinsics/Arm/Shared/_ImmUnaryOpTestTemplate.template @@ -198,6 +198,7 @@ namespace JIT.HardwareIntrinsics.Arm private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + private static readonly byte Imm = {Imm}; private static {Op1BaseType}[] _data = new {Op1BaseType}[Op1ElementCount]; diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs index 8f988f065faa8..080c7b1f5d1fb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs @@ -1200,6 +1200,312 @@ public new abstract class Arm64 : ArmBase.Arm64 /// public static Vector64 ReciprocalStepScalar(Vector64 left, Vector64 right) { throw new PlatformNotSupportedException(); } + /// + /// int16_t vqrshlh_s16 (int16_t a, int16_t b) + /// A64: SQRSHL Hd, Hn, Hm + /// + public static Vector64 ShiftArithmeticRoundedSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// int32_t vqrshls_s32 (int32_t a, int32_t b) + /// A64: SQRSHL Sd, Sn, Sm + /// + public static Vector64 ShiftArithmeticRoundedSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// int8_t vqrshlb_s8 (int8_t a, int8_t b) + /// A64: SQRSHL Bd, Bn, Bm + /// + public static Vector64 ShiftArithmeticRoundedSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// int16_t vqshlh_s16 (int16_t a, int16_t b) + /// A64: SQSHL Hd, Hn, Hm + /// + public static Vector64 ShiftArithmeticSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// int32_t vqshls_s32 (int32_t a, int32_t b) + /// A64: SQSHL Sd, Sn, Sm + /// + public static Vector64 ShiftArithmeticSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// int8_t vqshlb_s8 (int8_t a, int8_t b) + /// A64: SQSHL Bd, Bn, Bm + /// + public static Vector64 ShiftArithmeticSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8_t vqshlb_n_u8 (uint8_t a, const int n) + /// A64: UQSHL Bd, Bn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16_t vqshlh_n_s16 (int16_t a, const int n) + /// A64: SQSHL Hd, Hn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32_t vqshls_n_s32 (int32_t a, const int n) + /// A64: SQSHL Sd, Sn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8_t vqshlb_n_s8 (int8_t a, const int n) + /// A64: SQSHL Bd, Bn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t vqshlh_n_u16 (uint16_t a, const int n) + /// A64: UQSHL Hd, Hn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t vqshls_n_u32 (uint32_t a, const int n) + /// A64: UQSHL Sd, Sn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t vqshluh_n_s16 (int16_t a, const int n) + /// A64: SQSHLU Hd, Hn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsignedScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t vqshlus_n_s32 (int32_t a, const int n) + /// A64: SQSHLU Sd, Sn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsignedScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8_t vqshlub_n_s8 (int8_t a, const int n) + /// A64: SQSHLU Bd, Bn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsignedScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8_t vqrshlb_u8 (uint8_t a, int8_t b) + /// A64: UQRSHL Bd, Bn, Bm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t vqrshlh_u16 (uint16_t a, int16_t b) + /// A64: UQRSHL Hd, Hn, Hm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t vqrshls_u32 (uint32_t a, int32_t b) + /// A64: UQRSHL Sd, Sn, Sm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8_t vqrshlb_u8 (uint8_t a, int8_t b) + /// A64: UQRSHL Bd, Bn, Bm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t vqrshlh_u16 (uint16_t a, int16_t b) + /// A64: UQRSHL Hd, Hn, Hm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t vqrshls_u32 (uint32_t a, int32_t b) + /// A64: UQRSHL Sd, Sn, Sm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8_t vqshlb_u8 (uint8_t a, int8_t b) + /// A64: UQSHL Bd, Bn, Bm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t vqshlh_u16 (uint16_t a, int16_t b) + /// A64: UQSHL Hd, Hn, Hm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t vqshls_u32 (uint32_t a, int32_t b) + /// A64: UQSHL Sd, Sn, Sm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8_t vqshlb_u8 (uint8_t a, int8_t b) + /// A64: UQSHL Bd, Bn, Bm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t vqshlh_u16 (uint16_t a, int16_t b) + /// A64: UQSHL Hd, Hn, Hm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t vqshls_u32 (uint32_t a, int32_t b) + /// A64: UQSHL Sd, Sn, Sm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// int16_t vqshrns_n_s32 (int32_t a, const int n) + /// A64: SQSHRN Hd, Sn, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32_t vqshrnd_n_s64 (int64_t a, const int n) + /// A64: SQSHRN Sd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8_t vqshrnh_n_s16 (int16_t a, const int n) + /// A64: SQSHRN Bd, Hn, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8_t vqshrunh_n_s16 (int16_t a, const int n) + /// A64: SQSHRUN Bd, Hn, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t vqshruns_n_s32 (int32_t a, const int n) + /// A64: SQSHRUN Hd, Sn, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t vqshrund_n_s64 (int64_t a, const int n) + /// A64: SQSHRUN Sd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16_t vqrshrns_n_s32 (int32_t a, const int n) + /// A64: SQRSHRN Hd, Sn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32_t vqrshrnd_n_s64 (int64_t a, const int n) + /// A64: SQRSHRN Sd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8_t vqrshrnh_n_s16 (int16_t a, const int n) + /// A64: SQRSHRN Bd, Hn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8_t vqrshrunh_n_s16 (int16_t a, const int n) + /// A64: SQRSHRUN Bd, Hn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t vqrshruns_n_s32 (int32_t a, const int n) + /// A64: SQRSHRUN Hd, Sn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t vqrshrund_n_s64 (int64_t a, const int n) + /// A64: SQRSHRUN Sd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8_t vqshrnh_n_u16 (uint16_t a, const int n) + /// A64: UQSHRN Bd, Hn, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t vqshrns_n_u32 (uint32_t a, const int n) + /// A64: UQSHRN Hd, Sn, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t vqshrnd_n_u64 (uint64_t a, const int n) + /// A64: UQSHRN Sd, Dn, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8_t vqshrnh_n_u16 (uint16_t a, const int n) + /// A64: UQSHRN Bd, Hn, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t vqshrns_n_u32 (uint32_t a, const int n) + /// A64: UQSHRN Hd, Sn, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t vqshrnd_n_u64 (uint64_t a, const int n) + /// A64: UQSHRN Sd, Dn, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8_t vqrshrnh_n_u16 (uint16_t a, const int n) + /// A64: UQRSHRN Bd, Hn, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t vqrshrns_n_u32 (uint32_t a, const int n) + /// A64: UQRSHRN Hd, Sn, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t vqrshrnd_n_u64 (uint64_t a, const int n) + /// A64: UQRSHRN Sd, Dn, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8_t vqrshrnh_n_u16 (uint16_t a, const int n) + /// A64: UQRSHRN Bd, Hn, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16_t vqrshrns_n_u32 (uint32_t a, const int n) + /// A64: UQRSHRN Hd, Sn, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32_t vqrshrnd_n_u64 (uint64_t a, const int n) + /// A64: UQRSHRN Sd, Dn, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + /// /// float32x2_t vsqrt_f32 (float32x2_t a) /// A64: FSQRT Vd.2S, Vn.2S @@ -7135,184 +7441,2431 @@ public new abstract class Arm64 : ArmBase.Arm64 public static Vector128 ReciprocalStep(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } /// - /// float64x1_t vsqrt_f64 (float64x1_t a) - /// A32: VSQRT.F64 Dd, Dm - /// A64: FSQRT Dd, Dn + /// int16x4_t vshl_s16 (int16x4_t a, int16x4_t b) + /// A32: VSHL.S16 Dd, Dn, Dm + /// A64: SSHL Vd.4H, Vn.4H, Vm.4H /// - public static Vector64 SqrtScalar(Vector64 value) { throw new PlatformNotSupportedException(); } + public static Vector64 ShiftArithmetic(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } /// - /// float32_t vsqrts_f32 (float32_t a) - /// A32: VSQRT.F32 Sd, Sm - /// A64: FSQRT Sd, Sn - /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// int32x2_t vshl_s32 (int32x2_t a, int32x2_t b) + /// A32: VSHL.S32 Dd, Dn, Dm + /// A64: SSHL Vd.2S, Vn.2S, Vm.2S /// - public static Vector64 SqrtScalar(Vector64 value) { throw new PlatformNotSupportedException(); } + public static Vector64 ShiftArithmetic(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1_u8 (uint8_t * ptr, uint8x8_t val) - /// A32: VST1.8 { Dd }, [Rn] - /// A64: ST1 { Vt.8B }, [Xn] + /// int8x8_t vshl_s8 (int8x8_t a, int8x8_t b) + /// A32: VSHL.S8 Dd, Dn, Dm + /// A64: SSHL Vd.8B, Vn.8B, Vm.8B /// - public static unsafe void Store(byte* address, Vector64 source) { throw new PlatformNotSupportedException(); } + public static Vector64 ShiftArithmetic(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1_f64 (float64_t * ptr, float64x1_t val) - /// A32: VST1.64 { Dd }, [Rn] - /// A64: ST1 { Vt.1D }, [Xn] + /// int16x8_t vshlq_s16 (int16x8_t a, int16x8_t b) + /// A32: VSHL.S16 Qd, Qn, Qm + /// A64: SSHL Vd.8H, Vn.8H, Vm.8H /// - public static unsafe void Store(double* address, Vector64 source) { throw new PlatformNotSupportedException(); } + public static Vector128 ShiftArithmetic(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1_s16 (int16_t * ptr, int16x4_t val) - /// A32: VST1.16 { Dd }, [Rn] - /// A64: ST1 {Vt.4H }, [Xn] + /// int32x4_t vshlq_s32 (int32x4_t a, int32x4_t b) + /// A32: VSHL.S32 Qd, Qn, Qm + /// A64: SSHL Vd.4S, Vn.4S, Vm.4S /// - public static unsafe void Store(short* address, Vector64 source) { throw new PlatformNotSupportedException(); } + public static Vector128 ShiftArithmetic(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1_s32 (int32_t * ptr, int32x2_t val) - /// A32: VST1.32 { Dd }, [Rn] - /// A64: ST1 { Vt.2S }, [Xn] + /// int64x2_t vshlq_s64 (int64x2_t a, int64x2_t b) + /// A32: VSHL.S64 Qd, Qn, Qm + /// A64: SSHL Vd.2D, Vn.2D, Vm.2D /// - public static unsafe void Store(int* address, Vector64 source) { throw new PlatformNotSupportedException(); } + public static Vector128 ShiftArithmetic(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1_s64 (int64_t * ptr, int64x1_t val) - /// A32: VST1.64 { Dd }, [Rn] - /// A64: ST1 { Vt.1D }, [Xn] + /// int8x16_t vshlq_s8 (int8x16_t a, int8x16_t b) + /// A32: VSHL.S8 Qd, Qn, Qm + /// A64: SSHL Vd.16B, Vn.16B, Vm.16B /// - public static unsafe void Store(long* address, Vector64 source) { throw new PlatformNotSupportedException(); } + public static Vector128 ShiftArithmetic(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1_s8 (int8_t * ptr, int8x8_t val) - /// A32: VST1.8 { Dd }, [Rn] - /// A64: ST1 { Vt.8B }, [Xn] + /// int16x4_t vrshl_s16 (int16x4_t a, int16x4_t b) + /// A32: VRSHL.S16 Dd, Dn, Dm + /// A64: SRSHL Vd.4H, Vn.4H, Vm.4H /// - public static unsafe void Store(sbyte* address, Vector64 source) { throw new PlatformNotSupportedException(); } + public static Vector64 ShiftArithmeticRounded(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1_f32 (float32_t * ptr, float32x2_t val) - /// A32: VST1.32 { Dd }, [Rn] - /// A64: ST1 { Vt.2S }, [Xn] + /// int32x2_t vrshl_s32 (int32x2_t a, int32x2_t b) + /// A32: VRSHL.S32 Dd, Dn, Dm + /// A64: SRSHL Vd.2S, Vn.2S, Vm.2S /// - public static unsafe void Store(float* address, Vector64 source) { throw new PlatformNotSupportedException(); } + public static Vector64 ShiftArithmeticRounded(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1_u16 (uint16_t * ptr, uint16x4_t val) - /// A32: VST1.16 { Dd }, [Rn] - /// A64: ST1 { Vt.4H }, [Xn] + /// int8x8_t vrshl_s8 (int8x8_t a, int8x8_t b) + /// A32: VRSHL.S8 Dd, Dn, Dm + /// A64: SRSHL Vd.8B, Vn.8B, Vm.8B /// - public static unsafe void Store(ushort* address, Vector64 source) { throw new PlatformNotSupportedException(); } + public static Vector64 ShiftArithmeticRounded(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1_u32 (uint32_t * ptr, uint32x2_t val) - /// A32: VST1.32 { Dd }, [Rn] - /// A64: ST1 { Vt.2S }, [Xn] + /// int16x8_t vrshlq_s16 (int16x8_t a, int16x8_t b) + /// A32: VRSHL.S16 Qd, Qn, Qm + /// A64: SRSHL Vd.8H, Vn.8H, Vm.8H /// - public static unsafe void Store(uint* address, Vector64 source) { throw new PlatformNotSupportedException(); } + public static Vector128 ShiftArithmeticRounded(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1_u64 (uint64_t * ptr, uint64x1_t val) - /// A32: VST1.64 { Dd }, [Rn] - /// A64: ST1 { Vt.1D }, [Xn] + /// int32x4_t vrshlq_s32 (int32x4_t a, int32x4_t b) + /// A32: VRSHL.S32 Qd, Qn, Qm + /// A64: SRSHL Vd.4S, Vn.4S, Vm.4S /// - public static unsafe void Store(ulong* address, Vector64 source) { throw new PlatformNotSupportedException(); } + public static Vector128 ShiftArithmeticRounded(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1q_u8 (uint8_t * ptr, uint8x16_t val) - /// A32: VST1.8 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.16B }, [Xn] + /// int64x2_t vrshlq_s64 (int64x2_t a, int64x2_t b) + /// A32: VRSHL.S64 Qd, Qn, Qm + /// A64: SRSHL Vd.2D, Vn.2D, Vm.2D /// - public static unsafe void Store(byte* address, Vector128 source) { throw new PlatformNotSupportedException(); } + public static Vector128 ShiftArithmeticRounded(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1q_f64 (float64_t * ptr, float64x2_t val) - /// A32: VST1.64 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.2D }, [Xn] + /// int8x16_t vrshlq_s8 (int8x16_t a, int8x16_t b) + /// A32: VRSHL.S8 Qd, Qn, Qm + /// A64: SRSHL Vd.16B, Vn.16B, Vm.16B /// - public static unsafe void Store(double* address, Vector128 source) { throw new PlatformNotSupportedException(); } + public static Vector128 ShiftArithmeticRounded(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1q_s16 (int16_t * ptr, int16x8_t val) - /// A32: VST1.16 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.8H }, [Xn] + /// int16x4_t vqrshl_s16 (int16x4_t a, int16x4_t b) + /// A32: VQRSHL.S16 Dd, Dn, Dm + /// A64: SQRSHL Vd.4H, Vn.4H, Vm.4H /// - public static unsafe void Store(short* address, Vector128 source) { throw new PlatformNotSupportedException(); } + public static Vector64 ShiftArithmeticRoundedSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1q_s32 (int32_t * ptr, int32x4_t val) - /// A32: VST1.32 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.4S }, [Xn] + /// int32x2_t vqrshl_s32 (int32x2_t a, int32x2_t b) + /// A32: VQRSHL.S32 Dd, Dn, Dm + /// A64: SQRSHL Vd.2S, Vn.2S, Vm.2S /// - public static unsafe void Store(int* address, Vector128 source) { throw new PlatformNotSupportedException(); } + public static Vector64 ShiftArithmeticRoundedSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1q_s64 (int64_t * ptr, int64x2_t val) - /// A32: VST1.64 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.2D }, [Xn] + /// int8x8_t vqrshl_s8 (int8x8_t a, int8x8_t b) + /// A32: VQRSHL.S8 Dd, Dn, Dm + /// A64: SQRSHL Vd.8B, Vn.8B, Vm.8B /// - public static unsafe void Store(long* address, Vector128 source) { throw new PlatformNotSupportedException(); } + public static Vector64 ShiftArithmeticRoundedSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1q_s8 (int8_t * ptr, int8x16_t val) - /// A32: VST1.8 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.16B }, [Xn] + /// int16x8_t vqrshlq_s16 (int16x8_t a, int16x8_t b) + /// A32: VQRSHL.S16 Qd, Qn, Qm + /// A64: SQRSHL Vd.8H, Vn.8H, Vm.8H /// - public static unsafe void Store(sbyte* address, Vector128 source) { throw new PlatformNotSupportedException(); } + public static Vector128 ShiftArithmeticRoundedSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1q_f32 (float32_t * ptr, float32x4_t val) - /// A32: VST1.32 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.4S }, [Xn] + /// int32x4_t vqrshlq_s32 (int32x4_t a, int32x4_t b) + /// A32: VQRSHL.S32 Qd, Qn, Qm + /// A64: SQRSHL Vd.4S, Vn.4S, Vm.4S /// - public static unsafe void Store(float* address, Vector128 source) { throw new PlatformNotSupportedException(); } + public static Vector128 ShiftArithmeticRoundedSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1q_u16 (uint16_t * ptr, uint16x8_t val) - /// A32: VST1.16 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.8H }, [Xn] + /// int64x2_t vqrshlq_s64 (int64x2_t a, int64x2_t b) + /// A32: VQRSHL.S64 Qd, Qn, Qm + /// A64: SQRSHL Vd.2D, Vn.2D, Vm.2D /// - public static unsafe void Store(ushort* address, Vector128 source) { throw new PlatformNotSupportedException(); } + public static Vector128 ShiftArithmeticRoundedSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1q_u32 (uint32_t * ptr, uint32x4_t val) - /// A32: VST1.32 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.4S }, [Xn] + /// int8x16_t vqrshlq_s8 (int8x16_t a, int8x16_t b) + /// A32: VQRSHL.S8 Qd, Qn, Qm + /// A64: SQRSHL Vd.16B, Vn.16B, Vm.16B /// - public static unsafe void Store(uint* address, Vector128 source) { throw new PlatformNotSupportedException(); } + public static Vector128 ShiftArithmeticRoundedSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } /// - /// void vst1q_u64 (uint64_t * ptr, uint64x2_t val) - /// A32: VST1.64 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.2D }, [Xn] + /// int64x1_t vqrshl_s64 (int64x1_t a, int64x1_t b) + /// A32: VQRSHL.S64 Dd, Dn, Dm + /// A64: SQRSHL Dd, Dn, Dm /// - public static unsafe void Store(ulong* address, Vector128 source) { throw new PlatformNotSupportedException(); } + public static Vector64 ShiftArithmeticRoundedSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } /// - /// uint8x8_t vsub_u8 (uint8x8_t a, uint8x8_t b) - /// A32: VSUB.I8 Dd, Dn, Dm - /// A64: SUB Vd.8B, Vn.8B, Vm.8B + /// int64x1_t vrshl_s64 (int64x1_t a, int64x1_t b) + /// A32: VRSHL.S64 Dd, Dn, Dm + /// A64: SRSHL Dd, Dn, Dm /// - public static Vector64 Subtract(Vector64 left, Vector64 right) { throw new PlatformNotSupportedException(); } + public static Vector64 ShiftArithmeticRoundedScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } /// - /// int16x4_t vsub_s16 (int16x4_t a, int16x4_t b) - /// A32: VSUB.I16 Dd, Dn, Dm - /// A64: SUB Vd.4H, Vn.4H, Vm.4H + /// int16x4_t vqshl_s16 (int16x4_t a, int16x4_t b) + /// A32: VQSHL.S16 Dd, Dn, Dm + /// A64: SQSHL Vd.4H, Vn.4H, Vm.4H /// - public static Vector64 Subtract(Vector64 left, Vector64 right) { throw new PlatformNotSupportedException(); } + public static Vector64 ShiftArithmeticSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } /// - /// int32x2_t vsub_s32 (int32x2_t a, int32x2_t b) - /// A32: VSUB.I32 Dd, Dn, Dm - /// A64: SUB Vd.2S, Vn.2S, Vm.2S + /// int32x2_t vqshl_s32 (int32x2_t a, int32x2_t b) + /// A32: VQSHL.S32 Dd, Dn, Dm + /// A64: SQSHL Vd.2S, Vn.2S, Vm.2S /// - public static Vector64 Subtract(Vector64 left, Vector64 right) { throw new PlatformNotSupportedException(); } + public static Vector64 ShiftArithmeticSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } /// - /// int8x8_t vsub_s8 (int8x8_t a, int8x8_t b) - /// A32: VSUB.I8 Dd, Dn, Dm + /// int8x8_t vqshl_s8 (int8x8_t a, int8x8_t b) + /// A32: VQSHL.S8 Dd, Dn, Dm + /// A64: SQSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftArithmeticSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vqshlq_s16 (int16x8_t a, int16x8_t b) + /// A32: VQSHL.S16 Qd, Qn, Qm + /// A64: SQSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftArithmeticSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vqshlq_s32 (int32x4_t a, int32x4_t b) + /// A32: VQSHL.S32 Qd, Qn, Qm + /// A64: SQSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftArithmeticSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x2_t vqshlq_s64 (int64x2_t a, int64x2_t b) + /// A32: VQSHL.S64 Qd, Qn, Qm + /// A64: SQSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftArithmeticSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vqshlq_s8 (int8x16_t a, int8x16_t b) + /// A32: VQSHL.S8 Qd, Qn, Qm + /// A64: SQSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftArithmeticSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x1_t vqshl_s64 (int64x1_t a, int64x1_t b) + /// A32: VQSHL.S64 Dd, Dn, Dm + /// A64: SQSHL Dd, Dn, Dm + /// + public static Vector64 ShiftArithmeticSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x1_t vshl_s64 (int64x1_t a, int64x1_t b) + /// A32: VSHL.S64 Dd, Dn, Dm + /// A64: SSHL Dd, Dn, Dm + /// + public static Vector64 ShiftArithmeticScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vshl_n_u8 (uint8x8_t a, const int n) + /// A32: VSHL.I8 Dd, Dm, #n + /// A64: SHL Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftLeftLogical(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vshl_n_s16 (int16x4_t a, const int n) + /// A32: VSHL.I16 Dd, Dm, #n + /// A64: SHL Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftLeftLogical(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vshl_n_s32 (int32x2_t a, const int n) + /// A32: VSHL.I32 Dd, Dm, #n + /// A64: SHL Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftLeftLogical(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vshl_n_s8 (int8x8_t a, const int n) + /// A32: VSHL.I8 Dd, Dm, #n + /// A64: SHL Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftLeftLogical(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vshl_n_u16 (uint16x4_t a, const int n) + /// A32: VSHL.I16 Dd, Dm, #n + /// A64: SHL Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftLeftLogical(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vshl_n_u32 (uint32x2_t a, const int n) + /// A32: VSHL.I32 Dd, Dm, #n + /// A64: SHL Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftLeftLogical(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vshlq_n_u8 (uint8x16_t a, const int n) + /// A32: VSHL.I8 Qd, Qm, #n + /// A64: SHL Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vshlq_n_s16 (int16x8_t a, const int n) + /// A32: VSHL.I16 Qd, Qm, #n + /// A64: SHL Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x2_t vshlq_n_s64 (int64x2_t a, const int n) + /// A32: VSHL.I64 Qd, Qm, #n + /// A64: SHL Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vshlq_n_s8 (int8x16_t a, const int n) + /// A32: VSHL.I8 Qd, Qm, #n + /// A64: SHL Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vshlq_n_u16 (uint16x8_t a, const int n) + /// A32: VSHL.I16 Qd, Qm, #n + /// A64: SHL Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vshlq_n_u32 (uint32x4_t a, const int n) + /// A32: VSHL.I32 Qd, Qm, #n + /// A64: SHL Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vshlq_n_u64 (uint64x2_t a, const int n) + /// A32: VSHL.I64 Qd, Qm, #n + /// A64: SHL Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vqshl_n_u8 (uint8x8_t a, const int n) + /// A32: VQSHL.U8 Dd, Dm, #n + /// A64: UQSHL Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftLeftLogicalSaturate(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vqshl_n_s16 (int16x4_t a, const int n) + /// A32: VQSHL.S16 Dd, Dm, #n + /// A64: SQSHL Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftLeftLogicalSaturate(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vqshl_n_s32 (int32x2_t a, const int n) + /// A32: VQSHL.S32 Dd, Dm, #n + /// A64: SQSHL Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftLeftLogicalSaturate(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vqshl_n_s8 (int8x8_t a, const int n) + /// A32: VQSHL.S8 Dd, Dm, #n + /// A64: SQSHL Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftLeftLogicalSaturate(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vqshl_n_u16 (uint16x4_t a, const int n) + /// A32: VQSHL.U16 Dd, Dm, #n + /// A64: UQSHL Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftLeftLogicalSaturate(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vqshl_n_u32 (uint32x2_t a, const int n) + /// A32: VQSHL.U32 Dd, Dm, #n + /// A64: UQSHL Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftLeftLogicalSaturate(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vqshlq_n_u8 (uint8x16_t a, const int n) + /// A32: VQSHL.U8 Qd, Qm, #n + /// A64: UQSHL Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vqshlq_n_s16 (int16x8_t a, const int n) + /// A32: VQSHL.S16 Qd, Qm, #n + /// A64: SQSHL Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vqshlq_n_s32 (int32x4_t a, const int n) + /// A32: VQSHL.S32 Qd, Qm, #n + /// A64: SQSHL Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x2_t vqshlq_n_s64 (int64x2_t a, const int n) + /// A32: VQSHL.S64 Qd, Qm, #n + /// A64: SQSHL Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vqshlq_n_s8 (int8x16_t a, const int n) + /// A32: VQSHL.S8 Qd, Qm, #n + /// A64: SQSHL Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vqshlq_n_u16 (uint16x8_t a, const int n) + /// A32: VQSHL.U16 Qd, Qm, #n + /// A64: UQSHL Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vqshlq_n_u32 (uint32x4_t a, const int n) + /// A32: VQSHL.U32 Qd, Qm, #n + /// A64: UQSHL Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vqshlq_n_u64 (uint64x2_t a, const int n) + /// A32: VQSHL.U64 Qd, Qm, #n + /// A64: UQSHL Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x1_t vqshl_n_s64 (int64x1_t a, const int n) + /// A32: VQSHL.S64 Dd, Dm, #n + /// A64: SQSHL Dd, Dn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vqshl_n_u64 (uint64x1_t a, const int n) + /// A32: VQSHL.U64 Dd, Dm, #n + /// A64: UQSHL Dd, Dn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vqshlu_n_s16 (int16x4_t a, const int n) + /// A32: VQSHLU.S16 Dd, Dm, #n + /// A64: SQSHLU Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsigned(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vqshlu_n_s32 (int32x2_t a, const int n) + /// A32: VQSHLU.S32 Dd, Dm, #n + /// A64: SQSHLU Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsigned(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vqshlu_n_s8 (int8x8_t a, const int n) + /// A32: VQSHLU.S8 Dd, Dm, #n + /// A64: SQSHLU Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsigned(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vqshluq_n_s16 (int16x8_t a, const int n) + /// A32: VQSHLU.S16 Qd, Qm, #n + /// A64: SQSHLU Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogicalSaturateUnsigned(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vqshluq_n_s32 (int32x4_t a, const int n) + /// A32: VQSHLU.S32 Qd, Qm, #n + /// A64: SQSHLU Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftLeftLogicalSaturateUnsigned(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vqshluq_n_s64 (int64x2_t a, const int n) + /// A32: VQSHLU.S64 Qd, Qm, #n + /// A64: SQSHLU Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftLeftLogicalSaturateUnsigned(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vqshluq_n_s8 (int8x16_t a, const int n) + /// A32: VQSHLU.S8 Qd, Qm, #n + /// A64: SQSHLU Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogicalSaturateUnsigned(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vqshlu_n_s64 (int64x1_t a, const int n) + /// A32: VQSHLU.S64 Dd, Dm, #n + /// A64: SQSHLU Dd, Dn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsignedScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x1_t vshl_n_s64 (int64x1_t a, const int n) + /// A32: VSHL.I64 Dd, Dm, #n + /// A64: SHL Dd, Dn, #n + /// + public static Vector64 ShiftLeftLogicalScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vshl_n_u64 (uint64x1_t a, const int n) + /// A32: VSHL.I64 Dd, Dm, #n + /// A64: SHL Dd, Dn, #n + /// + public static Vector64 ShiftLeftLogicalScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vshll_n_u8 (uint8x8_t a, const int n) + /// A32: VSHLL.U8 Qd, Dm, #n + /// A64: USHLL Vd.8H, Vn.8B, #n + /// + public static Vector128 ShiftLeftLogicalWideningLower(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vshll_n_s16 (int16x4_t a, const int n) + /// A32: VSHLL.S16 Qd, Dm, #n + /// A64: SSHLL Vd.4S, Vn.4H, #n + /// + public static Vector128 ShiftLeftLogicalWideningLower(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x2_t vshll_n_s32 (int32x2_t a, const int n) + /// A32: VSHLL.S32 Qd, Dm, #n + /// A64: SSHLL Vd.2D, Vn.2S, #n + /// + public static Vector128 ShiftLeftLogicalWideningLower(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vshll_n_s8 (int8x8_t a, const int n) + /// A32: VSHLL.S8 Qd, Dm, #n + /// A64: SSHLL Vd.8H, Vn.8B, #n + /// + public static Vector128 ShiftLeftLogicalWideningLower(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vshll_n_u16 (uint16x4_t a, const int n) + /// A32: VSHLL.U16 Qd, Dm, #n + /// A64: USHLL Vd.4S, Vn.4H, #n + /// + public static Vector128 ShiftLeftLogicalWideningLower(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vshll_n_u32 (uint32x2_t a, const int n) + /// A32: VSHLL.U32 Qd, Dm, #n + /// A64: USHLL Vd.2D, Vn.2S, #n + /// + public static Vector128 ShiftLeftLogicalWideningLower(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vshll_high_n_u8 (uint8x16_t a, const int n) + /// A32: VSHLL.U8 Qd, Dm+1, #n + /// A64: USHLL2 Vd.8H, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogicalWideningUpper(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vshll_high_n_s16 (int16x8_t a, const int n) + /// A32: VSHLL.S16 Qd, Dm+1, #n + /// A64: SSHLL2 Vd.4S, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogicalWideningUpper(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x2_t vshll_high_n_s32 (int32x4_t a, const int n) + /// A32: VSHLL.S32 Qd, Dm+1, #n + /// A64: SSHLL2 Vd.2D, Vn.4S, #n + /// + public static Vector128 ShiftLeftLogicalWideningUpper(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vshll_high_n_s8 (int8x16_t a, const int n) + /// A32: VSHLL.S8 Qd, Dm+1, #n + /// A64: SSHLL2 Vd.8H, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogicalWideningUpper(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vshll_high_n_u16 (uint16x8_t a, const int n) + /// A32: VSHLL.U16 Qd, Dm+1, #n + /// A64: USHLL2 Vd.4S, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogicalWideningUpper(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vshll_high_n_u32 (uint32x4_t a, const int n) + /// A32: VSHLL.U32 Qd, Dm+1, #n + /// A64: USHLL2 Vd.2D, Vn.4S, #n + /// + public static Vector128 ShiftLeftLogicalWideningUpper(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VSHL.U8 Dd, Dn, Dm + /// A64: USHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogical(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VSHL.U16 Dd, Dn, Dm + /// A64: USHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogical(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VSHL.U32 Dd, Dn, Dm + /// A64: USHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogical(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VSHL.U8 Dd, Dn, Dm + /// A64: USHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogical(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VSHL.U16 Dd, Dn, Dm + /// A64: USHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogical(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VSHL.U32 Dd, Dn, Dm + /// A64: USHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogical(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VSHL.U8 Qd, Qn, Qm + /// A64: USHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VSHL.U16 Qd, Qn, Qm + /// A64: USHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VSHL.U32 Qd, Qn, Qm + /// A64: USHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VSHL.U64 Qd, Qn, Qm + /// A64: USHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VSHL.U8 Qd, Qn, Qm + /// A64: USHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VSHL.U16 Qd, Qn, Qm + /// A64: USHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VSHL.U32 Qd, Qn, Qm + /// A64: USHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VSHL.U64 Qd, Qn, Qm + /// A64: USHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vrshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VRSHL.U8 Dd, Dn, Dm + /// A64: URSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogicalRounded(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vrshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VRSHL.U16 Dd, Dn, Dm + /// A64: URSHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogicalRounded(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vrshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VRSHL.U32 Dd, Dn, Dm + /// A64: URSHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogicalRounded(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vrshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VRSHL.U8 Dd, Dn, Dm + /// A64: URSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogicalRounded(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vrshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VRSHL.U16 Dd, Dn, Dm + /// A64: URSHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogicalRounded(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vrshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VRSHL.U32 Dd, Dn, Dm + /// A64: URSHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogicalRounded(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vrshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VRSHL.U8 Qd, Qn, Qm + /// A64: URSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vrshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VRSHL.U16 Qd, Qn, Qm + /// A64: URSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vrshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VRSHL.U32 Qd, Qn, Qm + /// A64: URSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vrshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VRSHL.U64 Qd, Qn, Qm + /// A64: URSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vrshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VRSHL.U8 Qd, Qn, Qm + /// A64: URSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vrshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VRSHL.U16 Qd, Qn, Qm + /// A64: URSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vrshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VRSHL.U32 Qd, Qn, Qm + /// A64: URSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vrshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VRSHL.U64 Qd, Qn, Qm + /// A64: URSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vqrshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VQRSHL.U8 Dd, Dn, Dm + /// A64: UQRSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogicalRoundedSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vqrshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VQRSHL.U16 Dd, Dn, Dm + /// A64: UQRSHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogicalRoundedSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vqrshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VQRSHL.U32 Dd, Dn, Dm + /// A64: UQRSHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogicalRoundedSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vqrshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VQRSHL.U8 Dd, Dn, Dm + /// A64: UQRSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogicalRoundedSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vqrshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VQRSHL.U16 Dd, Dn, Dm + /// A64: UQRSHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogicalRoundedSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vqrshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VQRSHL.U32 Dd, Dn, Dm + /// A64: UQRSHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogicalRoundedSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vqrshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VQRSHL.U8 Qd, Qn, Qm + /// A64: UQRSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vqrshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VQRSHL.U16 Qd, Qn, Qm + /// A64: UQRSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vqrshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VQRSHL.U32 Qd, Qn, Qm + /// A64: UQRSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vqrshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VQRSHL.U64 Qd, Qn, Qm + /// A64: UQRSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vqrshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VQRSHL.U8 Qd, Qn, Qm + /// A64: UQRSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vqrshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VQRSHL.U16 Qd, Qn, Qm + /// A64: UQRSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vqrshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VQRSHL.U32 Qd, Qn, Qm + /// A64: UQRSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vqrshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VQRSHL.U64 Qd, Qn, Qm + /// A64: UQRSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vqrshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VQRSHL.U64 Dd, Dn, Dm + /// A64: UQRSHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vqrshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VQRSHL.U64 Dd, Dn, Dm + /// A64: UQRSHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vrshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VRSHL.U64 Dd, Dn, Dm + /// A64: URSHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalRoundedScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vrshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VRSHL.U64 Dd, Dn, Dm + /// A64: URSHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalRoundedScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vqshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VQSHL.U8 Dd, Dn, Dm + /// A64: UQSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogicalSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vqshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VQSHL.U16 Dd, Dn, Dm + /// A64: UQSHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogicalSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vqshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VQSHL.U32 Dd, Dn, Dm + /// A64: UQSHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogicalSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vqshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VQSHL.U8 Dd, Dn, Dm + /// A64: UQSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogicalSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vqshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VQSHL.U16 Dd, Dn, Dm + /// A64: UQSHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogicalSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vqshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VQSHL.U32 Dd, Dn, Dm + /// A64: UQSHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogicalSaturate(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vqshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VQSHL.U8 Qd, Qn, Qm + /// A64: UQSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vqshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VQSHL.U16 Qd, Qn, Qm + /// A64: UQSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vqshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VQSHL.U32 Qd, Qn, Qm + /// A64: UQSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vqshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VQSHL.U64 Qd, Qn, Qm + /// A64: UQSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vqshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VQSHL.U8 Qd, Qn, Qm + /// A64: UQSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vqshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VQSHL.U16 Qd, Qn, Qm + /// A64: UQSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vqshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VQSHL.U32 Qd, Qn, Qm + /// A64: UQSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vqshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VQSHL.U64 Qd, Qn, Qm + /// A64: UQSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vqshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VQSHL.U64 Dd, Dn, Dm + /// A64: UQSHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vqshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VQSHL.U64 Dd, Dn, Dm + /// A64: UQSHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VSHL.U64 Dd, Dn, Dm + /// A64: USHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VSHL.U64 Dd, Dn, Dm + /// A64: USHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalScalar(Vector64 value, Vector64 count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vshr_n_s16 (int16x4_t a, const int n) + /// A32: VSHR.S16 Dd, Dm, #n + /// A64: SSHR Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightArithmetic(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vshr_n_s32 (int32x2_t a, const int n) + /// A32: VSHR.S32 Dd, Dm, #n + /// A64: SSHR Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightArithmetic(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vshr_n_s8 (int8x8_t a, const int n) + /// A32: VSHR.S8 Dd, Dm, #n + /// A64: SSHR Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightArithmetic(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vshrq_n_s16 (int16x8_t a, const int n) + /// A32: VSHR.S16 Qd, Qm, #n + /// A64: SSHR Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmetic(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vshrq_n_s32 (int32x4_t a, const int n) + /// A32: VSHR.S32 Qd, Qm, #n + /// A64: SSHR Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmetic(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x2_t vshrq_n_s64 (int64x2_t a, const int n) + /// A32: VSHR.S64 Qd, Qm, #n + /// A64: SSHR Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmetic(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vshrq_n_s8 (int8x16_t a, const int n) + /// A32: VSHR.S8 Qd, Qm, #n + /// A64: SSHR Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightArithmetic(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vsra_n_s16 (int16x4_t a, int16x4_t b, const int n) + /// A32: VSRA.S16 Dd, Dm, #n + /// A64: SSRA Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightArithmeticAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vsra_n_s32 (int32x2_t a, int32x2_t b, const int n) + /// A32: VSRA.S32 Dd, Dm, #n + /// A64: SSRA Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightArithmeticAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vsra_n_s8 (int8x8_t a, int8x8_t b, const int n) + /// A32: VSRA.S8 Dd, Dm, #n + /// A64: SSRA Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightArithmeticAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vsraq_n_s16 (int16x8_t a, int16x8_t b, const int n) + /// A32: VSRA.S16 Qd, Qm, #n + /// A64: SSRA Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vsraq_n_s32 (int32x4_t a, int32x4_t b, const int n) + /// A32: VSRA.S32 Qd, Qm, #n + /// A64: SSRA Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x2_t vsraq_n_s64 (int64x2_t a, int64x2_t b, const int n) + /// A32: VSRA.S64 Qd, Qm, #n + /// A64: SSRA Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vsraq_n_s8 (int8x16_t a, int8x16_t b, const int n) + /// A32: VSRA.S8 Qd, Qm, #n + /// A64: SSRA Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightArithmeticAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x1_t vsra_n_s64 (int64x1_t a, int64x1_t b, const int n) + /// A32: VSRA.S64 Dd, Dm, #n + /// A64: SSRA Dd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticAddScalar(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vqshrn_n_s32 (int32x4_t a, const int n) + /// A32: VQSHRN.S32 Dd, Qm, #n + /// A64: SQSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vqshrn_n_s64 (int64x2_t a, const int n) + /// A32: VQSHRN.S64 Dd, Qm, #n + /// A64: SQSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vqshrn_n_s16 (int16x8_t a, const int n) + /// A32: VQSHRN.S16 Dd, Qm, #n + /// A64: SQSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vqshrun_n_s16 (int16x8_t a, const int n) + /// A32: VQSHRUN.S16 Dd, Qm, #n + /// A64: SQSHRUN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vqshrun_n_s32 (int32x4_t a, const int n) + /// A32: VQSHRUN.S32 Dd, Qm, #n + /// A64: SQSHRUN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vqshrun_n_s64 (int64x2_t a, const int n) + /// A32: VQSHRUN.S64 Dd, Qm, #n + /// A64: SQSHRUN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vqshrun_high_n_s16 (uint8x8_t r, int16x8_t a, const int n) + /// A32: VQSHRUN.S16 Dd+1, Dn, #n + /// A64: SQSHRUN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticNarrowingSaturateUnsignedUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vqshrun_high_n_s32 (uint16x4_t r, int32x4_t a, const int n) + /// A32: VQSHRUN.S32 Dd+1, Dn, #n + /// A64: SQSHRUN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticNarrowingSaturateUnsignedUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vqshrun_high_n_s64 (uint32x2_t r, int64x2_t a, const int n) + /// A32: VQSHRUN.S64 Dd+1, Dn, #n + /// A64: SQSHRUN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticNarrowingSaturateUnsignedUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vqshrn_high_n_s32 (int16x4_t r, int32x4_t a, const int n) + /// A32: VQSHRN.S32 Dd+1, Qm, #n + /// A64: SQSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vqshrn_high_n_s64 (int32x2_t r, int64x2_t a, const int n) + /// A32: VQSHRN.S64 Dd+1, Qm, #n + /// A64: SQSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vqshrn_high_n_s16 (int8x8_t r, int16x8_t a, const int n) + /// A32: VQSHRN.S16 Dd+1, Qm, #n + /// A64: SQSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vrshr_n_s16 (int16x4_t a, const int n) + /// A32: VRSHR.S16 Dd, Dm, #n + /// A64: SRSHR Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightArithmeticRounded(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vrshr_n_s32 (int32x2_t a, const int n) + /// A32: VRSHR.S32 Dd, Dm, #n + /// A64: SRSHR Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightArithmeticRounded(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vrshr_n_s8 (int8x8_t a, const int n) + /// A32: VRSHR.S8 Dd, Dm, #n + /// A64: SRSHR Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightArithmeticRounded(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vrshrq_n_s16 (int16x8_t a, const int n) + /// A32: VRSHR.S16 Qd, Qm, #n + /// A64: SRSHR Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticRounded(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vrshrq_n_s32 (int32x4_t a, const int n) + /// A32: VRSHR.S32 Qd, Qm, #n + /// A64: SRSHR Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticRounded(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x2_t vrshrq_n_s64 (int64x2_t a, const int n) + /// A32: VRSHR.S64 Qd, Qm, #n + /// A64: SRSHR Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticRounded(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vrshrq_n_s8 (int8x16_t a, const int n) + /// A32: VRSHR.S8 Qd, Qm, #n + /// A64: SRSHR Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightArithmeticRounded(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vrsra_n_s16 (int16x4_t a, int16x4_t b, const int n) + /// A32: VRSRA.S16 Dd, Dm, #n + /// A64: SRSRA Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightArithmeticRoundedAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vrsra_n_s32 (int32x2_t a, int32x2_t b, const int n) + /// A32: VRSRA.S32 Dd, Dm, #n + /// A64: SRSRA Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightArithmeticRoundedAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vrsra_n_s8 (int8x8_t a, int8x8_t b, const int n) + /// A32: VRSRA.S8 Dd, Dm, #n + /// A64: SRSRA Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightArithmeticRoundedAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vrsraq_n_s16 (int16x8_t a, int16x8_t b, const int n) + /// A32: VRSRA.S16 Qd, Qm, #n + /// A64: SRSRA Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticRoundedAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vrsraq_n_s32 (int32x4_t a, int32x4_t b, const int n) + /// A32: VRSRA.S32 Qd, Qm, #n + /// A64: SRSRA Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticRoundedAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x2_t vrsraq_n_s64 (int64x2_t a, int64x2_t b, const int n) + /// A32: VRSRA.S64 Qd, Qm, #n + /// A64: SRSRA Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticRoundedAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vrsraq_n_s8 (int8x16_t a, int8x16_t b, const int n) + /// A32: VRSRA.S8 Qd, Qm, #n + /// A64: SRSRA Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightArithmeticRoundedAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x1_t vrsra_n_s64 (int64x1_t a, int64x1_t b, const int n) + /// A32: VRSRA.S64 Dd, Dm, #n + /// A64: SRSRA Dd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedAddScalar(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vqrshrn_n_s32 (int32x4_t a, const int n) + /// A32: VQRSHRN.S32 Dd, Qm, #n + /// A64: SQRSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vqrshrn_n_s64 (int64x2_t a, const int n) + /// A32: VQRSHRN.S64 Dd, Qm, #n + /// A64: SQRSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vqrshrn_n_s16 (int16x8_t a, const int n) + /// A32: VQRSHRN.S16 Dd, Qm, #n + /// A64: SQRSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vqrshrun_n_s16 (int16x8_t a, const int n) + /// A32: VQRSHRUN.S16 Dd, Qm, #n + /// A64: SQRSHRUN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vqrshrun_n_s32 (int32x4_t a, const int n) + /// A32: VQRSHRUN.S32 Dd, Qm, #n + /// A64: SQRSHRUN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vqrshrun_n_s64 (int64x2_t a, const int n) + /// A32: VQRSHRUN.S64 Dd, Qm, #n + /// A64: SQRSHRUN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vqrshrun_high_n_s16 (uint8x8_t r, int16x8_t a, const int n) + /// A32: VQRSHRUN.S16 Dd+1, Dn, #n + /// A64: SQRSHRUN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vqrshrun_high_n_s32 (uint16x4_t r, int32x4_t a, const int n) + /// A32: VQRSHRUN.S32 Dd+1, Dn, #n + /// A64: SQRSHRUN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vqrshrun_high_n_s64 (uint32x2_t r, int64x2_t a, const int n) + /// A32: VQRSHRUN.S64 Dd+1, Dn, #n + /// A64: SQRSHRUN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vqrshrn_high_n_s32 (int16x4_t r, int32x4_t a, const int n) + /// A32: VQRSHRN.S32 Dd+1, Dn, #n + /// A64: SQRSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vqrshrn_high_n_s64 (int32x2_t r, int64x2_t a, const int n) + /// A32: VQRSHRN.S64 Dd+1, Dn, #n + /// A64: SQRSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vqrshrn_high_n_s16 (int8x8_t r, int16x8_t a, const int n) + /// A32: VQRSHRN.S16 Dd+1, Dn, #n + /// A64: SQRSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x1_t vrshr_n_s64 (int64x1_t a, const int n) + /// A32: VRSHR.S64 Dd, Dm, #n + /// A64: SRSHR Dd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int64x1_t vshr_n_s64 (int64x1_t a, const int n) + /// A32: VSHR.S64 Dd, Dm, #n + /// A64: SSHR Dd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vshr_n_u8 (uint8x8_t a, const int n) + /// A32: VSHR.U8 Dd, Dm, #n + /// A64: USHR Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogical(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vshr_n_u16 (uint16x4_t a, const int n) + /// A32: VSHR.U16 Dd, Dm, #n + /// A64: USHR Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogical(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vshr_n_u32 (uint32x2_t a, const int n) + /// A32: VSHR.U32 Dd, Dm, #n + /// A64: USHR Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogical(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vshr_n_u8 (uint8x8_t a, const int n) + /// A32: VSHR.U8 Dd, Dm, #n + /// A64: USHR Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogical(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vshr_n_u16 (uint16x4_t a, const int n) + /// A32: VSHR.U16 Dd, Dm, #n + /// A64: USHR Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogical(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vshr_n_u32 (uint32x2_t a, const int n) + /// A32: VSHR.U32 Dd, Dm, #n + /// A64: USHR Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogical(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vshrq_n_u8 (uint8x16_t a, const int n) + /// A32: VSHR.U8 Qd, Qm, #n + /// A64: USHR Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vshrq_n_u16 (uint16x8_t a, const int n) + /// A32: VSHR.U16 Qd, Qm, #n + /// A64: USHR Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vshrq_n_u32 (uint32x4_t a, const int n) + /// A32: VSHR.U32 Qd, Qm, #n + /// A64: USHR Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vshrq_n_u64 (uint64x2_t a, const int n) + /// A32: VSHR.U64 Qd, Qm, #n + /// A64: USHR Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vshrq_n_u8 (uint8x16_t a, const int n) + /// A32: VSHR.U8 Qd, Qm, #n + /// A64: USHR Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vshrq_n_u16 (uint16x8_t a, const int n) + /// A32: VSHR.U16 Qd, Qm, #n + /// A64: USHR Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vshrq_n_u32 (uint32x4_t a, const int n) + /// A32: VSHR.U32 Qd, Qm, #n + /// A64: USHR Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vshrq_n_u64 (uint64x2_t a, const int n) + /// A32: VSHR.U64 Qd, Qm, #n + /// A64: USHR Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vsra_n_u8 (uint8x8_t a, uint8x8_t b, const int n) + /// A32: VSRA.U8 Dd, Dm, #n + /// A64: USRA Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogicalAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vsra_n_u16 (uint16x4_t a, uint16x4_t b, const int n) + /// A32: VSRA.U16 Dd, Dm, #n + /// A64: USRA Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogicalAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vsra_n_u32 (uint32x2_t a, uint32x2_t b, const int n) + /// A32: VSRA.U32 Dd, Dm, #n + /// A64: USRA Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogicalAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vsra_n_u8 (uint8x8_t a, uint8x8_t b, const int n) + /// A32: VSRA.U8 Dd, Dm, #n + /// A64: USRA Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogicalAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vsra_n_u16 (uint16x4_t a, uint16x4_t b, const int n) + /// A32: VSRA.U16 Dd, Dm, #n + /// A64: USRA Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogicalAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vsra_n_u32 (uint32x2_t a, uint32x2_t b, const int n) + /// A32: VSRA.U32 Dd, Dm, #n + /// A64: USRA Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogicalAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vsraq_n_u8 (uint8x16_t a, uint8x16_t b, const int n) + /// A32: VSRA.U8 Qd, Qm, #n + /// A64: USRA Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vsraq_n_u16 (uint16x8_t a, uint16x8_t b, const int n) + /// A32: VSRA.U16 Qd, Qm, #n + /// A64: USRA Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vsraq_n_u32 (uint32x4_t a, uint32x4_t b, const int n) + /// A32: VSRA.U32 Qd, Qm, #n + /// A64: USRA Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vsraq_n_u64 (uint64x2_t a, uint64x2_t b, const int n) + /// A32: VSRA.U64 Qd, Qm, #n + /// A64: USRA Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vsraq_n_u8 (uint8x16_t a, uint8x16_t b, const int n) + /// A32: VSRA.U8 Qd, Qm, #n + /// A64: USRA Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vsraq_n_u16 (uint16x8_t a, uint16x8_t b, const int n) + /// A32: VSRA.U16 Qd, Qm, #n + /// A64: USRA Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vsraq_n_u32 (uint32x4_t a, uint32x4_t b, const int n) + /// A32: VSRA.U32 Qd, Qm, #n + /// A64: USRA Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vsraq_n_u64 (uint64x2_t a, uint64x2_t b, const int n) + /// A32: VSRA.U64 Qd, Qm, #n + /// A64: USRA Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vsra_n_u64 (uint64x1_t a, uint64x1_t b, const int n) + /// A32: VSRA.U64 Dd, Dm, #n + /// A64: USRA Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalAddScalar(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vsra_n_u64 (uint64x1_t a, uint64x1_t b, const int n) + /// A32: VSRA.U64 Dd, Dm, #n + /// A64: USRA Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalAddScalar(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vshrn_n_u16 (uint16x8_t a, const int n) + /// A32: VSHRN.I16 Dd, Qm, #n + /// A64: SHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalNarrowingLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vshrn_n_s32 (int32x4_t a, const int n) + /// A32: VSHRN.I32 Dd, Qm, #n + /// A64: SHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalNarrowingLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vshrn_n_s64 (int64x2_t a, const int n) + /// A32: VSHRN.I64 Dd, Qm, #n + /// A64: SHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalNarrowingLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vshrn_n_s16 (int16x8_t a, const int n) + /// A32: VSHRN.I16 Dd, Qm, #n + /// A64: SHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalNarrowingLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vshrn_n_u32 (uint32x4_t a, const int n) + /// A32: VSHRN.I32 Dd, Qm, #n + /// A64: SHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalNarrowingLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vshrn_n_u64 (uint64x2_t a, const int n) + /// A32: VSHRN.I64 Dd, Qm, #n + /// A64: SHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalNarrowingLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vqshrn_n_u16 (uint16x8_t a, const int n) + /// A32: VQSHRN.U16 Dd, Qm, #n + /// A64: UQSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vqshrn_n_u32 (uint32x4_t a, const int n) + /// A32: VQSHRN.U32 Dd, Qm, #n + /// A64: UQSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vqshrn_n_u64 (uint64x2_t a, const int n) + /// A32: VQSHRN.U64 Dd, Qm, #n + /// A64: UQSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vqshrn_n_u16 (uint16x8_t a, const int n) + /// A32: VQSHRN.U16 Dd, Qm, #n + /// A64: UQSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vqshrn_n_u32 (uint32x4_t a, const int n) + /// A32: VQSHRN.U32 Dd, Qm, #n + /// A64: UQSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vqshrn_n_u64 (uint64x2_t a, const int n) + /// A32: VQSHRN.U64 Dd, Qm, #n + /// A64: UQSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vqshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n) + /// A32: VQSHRN.U16 Dd+1, Qm, #n + /// A64: UQSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vqshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n) + /// A32: VQSHRN.U32 Dd+1, Qm, #n + /// A64: UQSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vqshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n) + /// A32: VQSHRN.U64 Dd+1, Qm, #n + /// A64: UQSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vqshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n) + /// A32: VQSHRN.U16 Dd+1, Qm, #n + /// A64: UQSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vqshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n) + /// A32: VQSHRN.U32 Dd+1, Qm, #n + /// A64: UQSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vqshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n) + /// A32: VQSHRN.U64 Dd+1, Qm, #n + /// A64: UQSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n) + /// A32: VSHRN.I16 Dd+1, Qm, #n + /// A64: SHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalNarrowingUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vshrn_high_n_s32 (int16x4_t r, int32x4_t a, const int n) + /// A32: VSHRN.I32 Dd+1, Qm, #n + /// A64: SHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalNarrowingUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vshrn_high_n_s64 (int32x2_t r, int64x2_t a, const int n) + /// A32: VSHRN.I64 Dd+1, Qm, #n + /// A64: SHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalNarrowingUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vshrn_high_n_s16 (int8x8_t r, int16x8_t a, const int n) + /// A32: VSHRN.I16 Dd+1, Qm, #n + /// A64: SHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalNarrowingUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n) + /// A32: VSHRN.I32 Dd+1, Qm, #n + /// A64: SHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalNarrowingUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n) + /// A32: VSHRN.I64 Dd+1, Qm, #n + /// A64: SHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalNarrowingUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vrshr_n_u8 (uint8x8_t a, const int n) + /// A32: VRSHR.U8 Dd, Dm, #n + /// A64: URSHR Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogicalRounded(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vrshr_n_u16 (uint16x4_t a, const int n) + /// A32: VRSHR.U16 Dd, Dm, #n + /// A64: URSHR Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogicalRounded(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vrshr_n_u32 (uint32x2_t a, const int n) + /// A32: VRSHR.U32 Dd, Dm, #n + /// A64: URSHR Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogicalRounded(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vrshr_n_u8 (uint8x8_t a, const int n) + /// A32: VRSHR.U8 Dd, Dm, #n + /// A64: URSHR Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogicalRounded(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vrshr_n_u16 (uint16x4_t a, const int n) + /// A32: VRSHR.U16 Dd, Dm, #n + /// A64: URSHR Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogicalRounded(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vrshr_n_u32 (uint32x2_t a, const int n) + /// A32: VRSHR.U32 Dd, Dm, #n + /// A64: URSHR Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogicalRounded(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vrshrq_n_u8 (uint8x16_t a, const int n) + /// A32: VRSHR.U8 Qd, Qm, #n + /// A64: URSHR Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vrshrq_n_u16 (uint16x8_t a, const int n) + /// A32: VRSHR.U16 Qd, Qm, #n + /// A64: URSHR Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vrshrq_n_u32 (uint32x4_t a, const int n) + /// A32: VRSHR.U32 Qd, Qm, #n + /// A64: URSHR Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vrshrq_n_u64 (uint64x2_t a, const int n) + /// A32: VRSHR.U64 Qd, Qm, #n + /// A64: URSHR Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vrshrq_n_u8 (uint8x16_t a, const int n) + /// A32: VRSHR.U8 Qd, Qm, #n + /// A64: URSHR Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vrshrq_n_u16 (uint16x8_t a, const int n) + /// A32: VRSHR.U16 Qd, Qm, #n + /// A64: URSHR Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vrshrq_n_u32 (uint32x4_t a, const int n) + /// A32: VRSHR.U32 Qd, Qm, #n + /// A64: URSHR Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vrshrq_n_u64 (uint64x2_t a, const int n) + /// A32: VRSHR.U64 Qd, Qm, #n + /// A64: URSHR Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vrsra_n_u8 (uint8x8_t a, uint8x8_t b, const int n) + /// A32: VRSRA.U8 Dd, Dm, #n + /// A64: URSRA Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogicalRoundedAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vrsra_n_u16 (uint16x4_t a, uint16x4_t b, const int n) + /// A32: VRSRA.U16 Dd, Dm, #n + /// A64: URSRA Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogicalRoundedAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vrsra_n_u32 (uint32x2_t a, uint32x2_t b, const int n) + /// A32: VRSRA.U32 Dd, Dm, #n + /// A64: URSRA Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogicalRoundedAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vrsra_n_u8 (uint8x8_t a, uint8x8_t b, const int n) + /// A32: VRSRA.U8 Dd, Dm, #n + /// A64: URSRA Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogicalRoundedAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vrsra_n_u16 (uint16x4_t a, uint16x4_t b, const int n) + /// A32: VRSRA.U16 Dd, Dm, #n + /// A64: URSRA Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogicalRoundedAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vrsra_n_u32 (uint32x2_t a, uint32x2_t b, const int n) + /// A32: VRSRA.U32 Dd, Dm, #n + /// A64: URSRA Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogicalRoundedAdd(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vrsraq_n_u8 (uint8x16_t a, uint8x16_t b, const int n) + /// A32: VRSRA.U8 Qd, Qm, #n + /// A64: URSRA Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vrsraq_n_u16 (uint16x8_t a, uint16x8_t b, const int n) + /// A32: VRSRA.U16 Qd, Qm, #n + /// A64: URSRA Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vrsraq_n_u32 (uint32x4_t a, uint32x4_t b, const int n) + /// A32: VRSRA.U32 Qd, Qm, #n + /// A64: URSRA Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vrsraq_n_u64 (uint64x2_t a, uint64x2_t b, const int n) + /// A32: VRSRA.U64 Qd, Qm, #n + /// A64: URSRA Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vrsraq_n_u8 (uint8x16_t a, uint8x16_t b, const int n) + /// A32: VRSRA.U8 Qd, Qm, #n + /// A64: URSRA Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vrsraq_n_u16 (uint16x8_t a, uint16x8_t b, const int n) + /// A32: VRSRA.U16 Qd, Qm, #n + /// A64: URSRA Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vrsraq_n_u32 (uint32x4_t a, uint32x4_t b, const int n) + /// A32: VRSRA.U32 Qd, Qm, #n + /// A64: URSRA Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vrsraq_n_u64 (uint64x2_t a, uint64x2_t b, const int n) + /// A32: VRSRA.U64 Qd, Qm, #n + /// A64: URSRA Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vrsra_n_u64 (uint64x1_t a, uint64x1_t b, const int n) + /// A32: VRSRA.U64 Dd, Dm, #n + /// A64: URSRA Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalRoundedAddScalar(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vrsra_n_u64 (uint64x1_t a, uint64x1_t b, const int n) + /// A32: VRSRA.U64 Dd, Dm, #n + /// A64: URSRA Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalRoundedAddScalar(Vector64 addend, Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vrshrn_n_u16 (uint16x8_t a, const int n) + /// A32: VRSHRN.I16 Dd, Qm, #n + /// A64: RSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vrshrn_n_s32 (int32x4_t a, const int n) + /// A32: VRSHRN.I32 Dd, Qm, #n + /// A64: RSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vrshrn_n_s64 (int64x2_t a, const int n) + /// A32: VRSHRN.I64 Dd, Qm, #n + /// A64: RSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vrshrn_n_s16 (int16x8_t a, const int n) + /// A32: VRSHRN.I16 Dd, Qm, #n + /// A64: RSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vrshrn_n_u32 (uint32x4_t a, const int n) + /// A32: VRSHRN.I32 Dd, Qm, #n + /// A64: RSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vrshrn_n_u64 (uint64x2_t a, const int n) + /// A32: VRSHRN.I64 Dd, Qm, #n + /// A64: RSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vqrshrn_n_u16 (uint16x8_t a, const int n) + /// A32: VQRSHRN.U16 Dd, Qm, #n + /// A64: UQRSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vqrshrn_n_u32 (uint32x4_t a, const int n) + /// A32: VQRSHRN.U32 Dd, Qm, #n + /// A64: UQRSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vqrshrn_n_u64 (uint64x2_t a, const int n) + /// A32: VQRSHRN.U64 Dd, Qm, #n + /// A64: UQRSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vqrshrn_n_u16 (uint16x8_t a, const int n) + /// A32: VQRSHRN.U16 Dd, Qm, #n + /// A64: UQRSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x4_t vqrshrn_n_u32 (uint32x4_t a, const int n) + /// A32: VQRSHRN.U32 Dd, Qm, #n + /// A64: UQRSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x2_t vqrshrn_n_u64 (uint64x2_t a, const int n) + /// A32: VQRSHRN.U64 Dd, Qm, #n + /// A64: UQRSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vqrshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n) + /// A32: VQRSHRN.U16 Dd+1, Dn, #n + /// A64: UQRSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vqrshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n) + /// A32: VQRSHRN.U32 Dd+1, Dn, #n + /// A64: UQRSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vqrshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n) + /// A32: VQRSHRN.U64 Dd+1, Dn, #n + /// A64: UQRSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vqrshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n) + /// A32: VQRSHRN.U16 Dd+1, Dn, #n + /// A64: UQRSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vqrshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n) + /// A32: VQRSHRN.U32 Dd+1, Dn, #n + /// A64: UQRSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vqrshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n) + /// A32: VQRSHRN.U64 Dd+1, Dn, #n + /// A64: UQRSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x16_t vrshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n) + /// A32: VRSHRN.I16 Dd+1, Qm, #n + /// A64: RSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vrshrn_high_n_s32 (int16x4_t r, int32x4_t a, const int n) + /// A32: VRSHRN.I32 Dd+1, Qm, #n + /// A64: RSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vrshrn_high_n_s64 (int32x2_t r, int64x2_t a, const int n) + /// A32: VRSHRN.I64 Dd+1, Qm, #n + /// A64: RSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int8x16_t vrshrn_high_n_s16 (int8x8_t r, int16x8_t a, const int n) + /// A32: VRSHRN.I16 Dd+1, Qm, #n + /// A64: RSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vrshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n) + /// A32: VRSHRN.I32 Dd+1, Qm, #n + /// A64: RSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vrshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n) + /// A32: VRSHRN.I64 Dd+1, Qm, #n + /// A64: RSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingUpper(Vector64 lower, Vector128 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vrshr_n_u64 (uint64x1_t a, const int n) + /// A32: VRSHR.U64 Dd, Dm, #n + /// A64: URSHR Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalRoundedScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vrshr_n_u64 (uint64x1_t a, const int n) + /// A32: VRSHR.U64 Dd, Dm, #n + /// A64: URSHR Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalRoundedScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vshr_n_u64 (uint64x1_t a, const int n) + /// A32: VSHR.U64 Dd, Dm, #n + /// A64: USHR Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x1_t vshr_n_u64 (uint64x1_t a, const int n) + /// A32: VSHR.U64 Dd, Dm, #n + /// A64: USHR Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalScalar(Vector64 value, byte count) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vmovl_s16 (int16x4_t a) + /// A32: VMOVL.S16 Qd, Dm + /// A64: SXTL Vd.4S, Vn.4H + /// + public static Vector128 SignExtendWideningLower(Vector64 value) { throw new PlatformNotSupportedException(); } + + /// + /// int64x2_t vmovl_s32 (int32x2_t a) + /// A32: VMOVL.S32 Qd, Dm + /// A64: SXTL Vd.2D, Vn.2S + /// + public static Vector128 SignExtendWideningLower(Vector64 value) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vmovl_s8 (int8x8_t a) + /// A32: VMOVL.S8 Qd, Dm + /// A64: SXTL Vd.8H, Vn.8B + /// + public static Vector128 SignExtendWideningLower(Vector64 value) { throw new PlatformNotSupportedException(); } + + /// + /// int32x4_t vmovl_high_s16 (int16x8_t a) + /// A32: VMOVL.S16 Qd, Dm+1 + /// A64: SXTL2 Vd.4S, Vn.8H + /// + public static Vector128 SignExtendWideningUpper(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// int64x2_t vmovl_high_s32 (int32x4_t a) + /// A32: VMOVL.S32 Qd, Dm+1 + /// A64: SXTL2 Vd.2D, Vn.4S + /// + public static Vector128 SignExtendWideningUpper(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// int16x8_t vmovl_high_s8 (int8x16_t a) + /// A32: VMOVL.S8 Qd, Dm+1 + /// A64: SXTL2 Vd.8H, Vn.16B + /// + public static Vector128 SignExtendWideningUpper(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// float64x1_t vsqrt_f64 (float64x1_t a) + /// A32: VSQRT.F64 Dd, Dm + /// A64: FSQRT Dd, Dn + /// + public static Vector64 SqrtScalar(Vector64 value) { throw new PlatformNotSupportedException(); } + + /// + /// float32_t vsqrts_f32 (float32_t a) + /// A32: VSQRT.F32 Sd, Sm + /// A64: FSQRT Sd, Sn + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector64 SqrtScalar(Vector64 value) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1_u8 (uint8_t * ptr, uint8x8_t val) + /// A32: VST1.8 { Dd }, [Rn] + /// A64: ST1 { Vt.8B }, [Xn] + /// + public static unsafe void Store(byte* address, Vector64 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1_f64 (float64_t * ptr, float64x1_t val) + /// A32: VST1.64 { Dd }, [Rn] + /// A64: ST1 { Vt.1D }, [Xn] + /// + public static unsafe void Store(double* address, Vector64 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1_s16 (int16_t * ptr, int16x4_t val) + /// A32: VST1.16 { Dd }, [Rn] + /// A64: ST1 {Vt.4H }, [Xn] + /// + public static unsafe void Store(short* address, Vector64 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1_s32 (int32_t * ptr, int32x2_t val) + /// A32: VST1.32 { Dd }, [Rn] + /// A64: ST1 { Vt.2S }, [Xn] + /// + public static unsafe void Store(int* address, Vector64 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1_s64 (int64_t * ptr, int64x1_t val) + /// A32: VST1.64 { Dd }, [Rn] + /// A64: ST1 { Vt.1D }, [Xn] + /// + public static unsafe void Store(long* address, Vector64 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1_s8 (int8_t * ptr, int8x8_t val) + /// A32: VST1.8 { Dd }, [Rn] + /// A64: ST1 { Vt.8B }, [Xn] + /// + public static unsafe void Store(sbyte* address, Vector64 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1_f32 (float32_t * ptr, float32x2_t val) + /// A32: VST1.32 { Dd }, [Rn] + /// A64: ST1 { Vt.2S }, [Xn] + /// + public static unsafe void Store(float* address, Vector64 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1_u16 (uint16_t * ptr, uint16x4_t val) + /// A32: VST1.16 { Dd }, [Rn] + /// A64: ST1 { Vt.4H }, [Xn] + /// + public static unsafe void Store(ushort* address, Vector64 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1_u32 (uint32_t * ptr, uint32x2_t val) + /// A32: VST1.32 { Dd }, [Rn] + /// A64: ST1 { Vt.2S }, [Xn] + /// + public static unsafe void Store(uint* address, Vector64 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1_u64 (uint64_t * ptr, uint64x1_t val) + /// A32: VST1.64 { Dd }, [Rn] + /// A64: ST1 { Vt.1D }, [Xn] + /// + public static unsafe void Store(ulong* address, Vector64 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1q_u8 (uint8_t * ptr, uint8x16_t val) + /// A32: VST1.8 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.16B }, [Xn] + /// + public static unsafe void Store(byte* address, Vector128 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1q_f64 (float64_t * ptr, float64x2_t val) + /// A32: VST1.64 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.2D }, [Xn] + /// + public static unsafe void Store(double* address, Vector128 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1q_s16 (int16_t * ptr, int16x8_t val) + /// A32: VST1.16 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.8H }, [Xn] + /// + public static unsafe void Store(short* address, Vector128 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1q_s32 (int32_t * ptr, int32x4_t val) + /// A32: VST1.32 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.4S }, [Xn] + /// + public static unsafe void Store(int* address, Vector128 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1q_s64 (int64_t * ptr, int64x2_t val) + /// A32: VST1.64 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.2D }, [Xn] + /// + public static unsafe void Store(long* address, Vector128 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1q_s8 (int8_t * ptr, int8x16_t val) + /// A32: VST1.8 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.16B }, [Xn] + /// + public static unsafe void Store(sbyte* address, Vector128 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1q_f32 (float32_t * ptr, float32x4_t val) + /// A32: VST1.32 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.4S }, [Xn] + /// + public static unsafe void Store(float* address, Vector128 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1q_u16 (uint16_t * ptr, uint16x8_t val) + /// A32: VST1.16 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.8H }, [Xn] + /// + public static unsafe void Store(ushort* address, Vector128 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1q_u32 (uint32_t * ptr, uint32x4_t val) + /// A32: VST1.32 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.4S }, [Xn] + /// + public static unsafe void Store(uint* address, Vector128 source) { throw new PlatformNotSupportedException(); } + + /// + /// void vst1q_u64 (uint64_t * ptr, uint64x2_t val) + /// A32: VST1.64 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.2D }, [Xn] + /// + public static unsafe void Store(ulong* address, Vector128 source) { throw new PlatformNotSupportedException(); } + + /// + /// uint8x8_t vsub_u8 (uint8x8_t a, uint8x8_t b) + /// A32: VSUB.I8 Dd, Dn, Dm + /// A64: SUB Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 Subtract(Vector64 left, Vector64 right) { throw new PlatformNotSupportedException(); } + + /// + /// int16x4_t vsub_s16 (int16x4_t a, int16x4_t b) + /// A32: VSUB.I16 Dd, Dn, Dm + /// A64: SUB Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 Subtract(Vector64 left, Vector64 right) { throw new PlatformNotSupportedException(); } + + /// + /// int32x2_t vsub_s32 (int32x2_t a, int32x2_t b) + /// A32: VSUB.I32 Dd, Dn, Dm + /// A64: SUB Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 Subtract(Vector64 left, Vector64 right) { throw new PlatformNotSupportedException(); } + + /// + /// int8x8_t vsub_s8 (int8x8_t a, int8x8_t b) + /// A32: VSUB.I8 Dd, Dn, Dm /// A64: SUB Vd.8B, Vn.8B, Vm.8B /// public static Vector64 Subtract(Vector64 left, Vector64 right) { throw new PlatformNotSupportedException(); } @@ -8049,5 +10602,89 @@ public new abstract class Arm64 : ArmBase.Arm64 /// A64: EOR Vd.16B, Vn.16B, Vm.16B /// public static Vector128 Xor(Vector128 left, Vector128 right) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vmovl_u8 (uint8x8_t a) + /// A32: VMOVL.U8 Qd, Dm + /// A64: UXTL Vd.8H, Vn.8B + /// + public static Vector128 ZeroExtendWideningLower(Vector64 value) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vmovl_u16 (uint16x4_t a) + /// A32: VMOVL.U16 Qd, Dm + /// A64: UXTL Vd.4S, Vn.4H + /// + public static Vector128 ZeroExtendWideningLower(Vector64 value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vmovl_u32 (uint32x2_t a) + /// A32: VMOVL.U32 Qd, Dm + /// A64: UXTL Vd.2D, Vn.2S + /// + public static Vector128 ZeroExtendWideningLower(Vector64 value) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vmovl_u8 (uint8x8_t a) + /// A32: VMOVL.U8 Qd, Dm + /// A64: UXTL Vd.8H, Vn.8B + /// + public static Vector128 ZeroExtendWideningLower(Vector64 value) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vmovl_u16 (uint16x4_t a) + /// A32: VMOVL.U16 Qd, Dm + /// A64: UXTL Vd.4S, Vn.4H + /// + public static Vector128 ZeroExtendWideningLower(Vector64 value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vmovl_u32 (uint32x2_t a) + /// A32: VMOVL.U32 Qd, Dm + /// A64: UXTL Vd.2D, Vn.2S + /// + public static Vector128 ZeroExtendWideningLower(Vector64 value) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vmovl_high_u8 (uint8x16_t a) + /// A32: VMOVL.U8 Qd, Dm+1 + /// A64: UXTL2 Vd.8H, Vn.16B + /// + public static Vector128 ZeroExtendWideningUpper(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vmovl_high_u16 (uint16x8_t a) + /// A32: VMOVL.U16 Qd, Dm+1 + /// A64: UXTL2 Vd.4S, Vn.8H + /// + public static Vector128 ZeroExtendWideningUpper(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vmovl_high_u32 (uint32x4_t a) + /// A32: VMOVL.U32 Qd, Dm+1 + /// A64: UXTL2 Vd.2D, Vn.4S + /// + public static Vector128 ZeroExtendWideningUpper(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// uint16x8_t vmovl_high_u8 (uint8x16_t a) + /// A32: VMOVL.U8 Qd, Dm+1 + /// A64: UXTL2 Vd.8H, Vn.16B + /// + public static Vector128 ZeroExtendWideningUpper(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// uint32x4_t vmovl_high_u16 (uint16x8_t a) + /// A32: VMOVL.U16 Qd, Dm+1 + /// A64: UXTL2 Vd.4S, Vn.8H + /// + public static Vector128 ZeroExtendWideningUpper(Vector128 value) { throw new PlatformNotSupportedException(); } + + /// + /// uint64x2_t vmovl_high_u32 (uint32x4_t a) + /// A32: VMOVL.U32 Qd, Dm+1 + /// A64: UXTL2 Vd.2D, Vn.4S + /// + public static Vector128 ZeroExtendWideningUpper(Vector128 value) { throw new PlatformNotSupportedException(); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs index 27b265a963bd0..72233956e1829 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.cs @@ -1202,6 +1202,312 @@ public new abstract class Arm64 : ArmBase.Arm64 /// public static Vector64 ReciprocalStepScalar(Vector64 left, Vector64 right) => ReciprocalStepScalar(left, right); + /// + /// int16_t vqrshlh_s16 (int16_t a, int16_t b) + /// A64: SQRSHL Hd, Hn, Hm + /// + public static Vector64 ShiftArithmeticRoundedSaturateScalar(Vector64 value, Vector64 count) => ShiftArithmeticRoundedSaturateScalar(value, count); + + /// + /// int32_t vqrshls_s32 (int32_t a, int32_t b) + /// A64: SQRSHL Sd, Sn, Sm + /// + public static Vector64 ShiftArithmeticRoundedSaturateScalar(Vector64 value, Vector64 count) => ShiftArithmeticRoundedSaturateScalar(value, count); + + /// + /// int8_t vqrshlb_s8 (int8_t a, int8_t b) + /// A64: SQRSHL Bd, Bn, Bm + /// + public static Vector64 ShiftArithmeticRoundedSaturateScalar(Vector64 value, Vector64 count) => ShiftArithmeticRoundedSaturateScalar(value, count); + + /// + /// int16_t vqshlh_s16 (int16_t a, int16_t b) + /// A64: SQSHL Hd, Hn, Hm + /// + public static Vector64 ShiftArithmeticSaturateScalar(Vector64 value, Vector64 count) => ShiftArithmeticSaturateScalar(value, count); + + /// + /// int32_t vqshls_s32 (int32_t a, int32_t b) + /// A64: SQSHL Sd, Sn, Sm + /// + public static Vector64 ShiftArithmeticSaturateScalar(Vector64 value, Vector64 count) => ShiftArithmeticSaturateScalar(value, count); + + /// + /// int8_t vqshlb_s8 (int8_t a, int8_t b) + /// A64: SQSHL Bd, Bn, Bm + /// + public static Vector64 ShiftArithmeticSaturateScalar(Vector64 value, Vector64 count) => ShiftArithmeticSaturateScalar(value, count); + + /// + /// uint8_t vqshlb_n_u8 (uint8_t a, const int n) + /// A64: UQSHL Bd, Bn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) => ShiftLeftLogicalSaturateScalar(value, count); + + /// + /// int16_t vqshlh_n_s16 (int16_t a, const int n) + /// A64: SQSHL Hd, Hn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) => ShiftLeftLogicalSaturateScalar(value, count); + + /// + /// int32_t vqshls_n_s32 (int32_t a, const int n) + /// A64: SQSHL Sd, Sn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) => ShiftLeftLogicalSaturateScalar(value, count); + + /// + /// int8_t vqshlb_n_s8 (int8_t a, const int n) + /// A64: SQSHL Bd, Bn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) => ShiftLeftLogicalSaturateScalar(value, count); + + /// + /// uint16_t vqshlh_n_u16 (uint16_t a, const int n) + /// A64: UQSHL Hd, Hn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) => ShiftLeftLogicalSaturateScalar(value, count); + + /// + /// uint32_t vqshls_n_u32 (uint32_t a, const int n) + /// A64: UQSHL Sd, Sn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) => ShiftLeftLogicalSaturateScalar(value, count); + + /// + /// uint16_t vqshluh_n_s16 (int16_t a, const int n) + /// A64: SQSHLU Hd, Hn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsignedScalar(Vector64 value, byte count) => ShiftLeftLogicalSaturateUnsignedScalar(value, count); + + /// + /// uint32_t vqshlus_n_s32 (int32_t a, const int n) + /// A64: SQSHLU Sd, Sn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsignedScalar(Vector64 value, byte count) => ShiftLeftLogicalSaturateUnsignedScalar(value, count); + + /// + /// uint8_t vqshlub_n_s8 (int8_t a, const int n) + /// A64: SQSHLU Bd, Bn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsignedScalar(Vector64 value, byte count) => ShiftLeftLogicalSaturateUnsignedScalar(value, count); + + /// + /// uint8_t vqrshlb_u8 (uint8_t a, int8_t b) + /// A64: UQRSHL Bd, Bn, Bm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturateScalar(value, count); + + /// + /// uint16_t vqrshlh_u16 (uint16_t a, int16_t b) + /// A64: UQRSHL Hd, Hn, Hm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturateScalar(value, count); + + /// + /// uint32_t vqrshls_u32 (uint32_t a, int32_t b) + /// A64: UQRSHL Sd, Sn, Sm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturateScalar(value, count); + + /// + /// uint8_t vqrshlb_u8 (uint8_t a, int8_t b) + /// A64: UQRSHL Bd, Bn, Bm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturateScalar(value, count); + + /// + /// uint16_t vqrshlh_u16 (uint16_t a, int16_t b) + /// A64: UQRSHL Hd, Hn, Hm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturateScalar(value, count); + + /// + /// uint32_t vqrshls_u32 (uint32_t a, int32_t b) + /// A64: UQRSHL Sd, Sn, Sm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturateScalar(value, count); + + /// + /// uint8_t vqshlb_u8 (uint8_t a, int8_t b) + /// A64: UQSHL Bd, Bn, Bm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalSaturateScalar(value, count); + + /// + /// uint16_t vqshlh_u16 (uint16_t a, int16_t b) + /// A64: UQSHL Hd, Hn, Hm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalSaturateScalar(value, count); + + /// + /// uint32_t vqshls_u32 (uint32_t a, int32_t b) + /// A64: UQSHL Sd, Sn, Sm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalSaturateScalar(value, count); + + /// + /// uint8_t vqshlb_u8 (uint8_t a, int8_t b) + /// A64: UQSHL Bd, Bn, Bm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalSaturateScalar(value, count); + + /// + /// uint16_t vqshlh_u16 (uint16_t a, int16_t b) + /// A64: UQSHL Hd, Hn, Hm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalSaturateScalar(value, count); + + /// + /// uint32_t vqshls_u32 (uint32_t a, int32_t b) + /// A64: UQSHL Sd, Sn, Sm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalSaturateScalar(value, count); + + /// + /// int16_t vqshrns_n_s32 (int32_t a, const int n) + /// A64: SQSHRN Hd, Sn, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightArithmeticNarrowingSaturateScalar(value, count); + + /// + /// int32_t vqshrnd_n_s64 (int64_t a, const int n) + /// A64: SQSHRN Sd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightArithmeticNarrowingSaturateScalar(value, count); + + /// + /// int8_t vqshrnh_n_s16 (int16_t a, const int n) + /// A64: SQSHRN Bd, Hn, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightArithmeticNarrowingSaturateScalar(value, count); + + /// + /// uint8_t vqshrunh_n_s16 (int16_t a, const int n) + /// A64: SQSHRUN Bd, Hn, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedScalar(Vector64 value, byte count) => ShiftRightArithmeticNarrowingSaturateUnsignedScalar(value, count); + + /// + /// uint16_t vqshruns_n_s32 (int32_t a, const int n) + /// A64: SQSHRUN Hd, Sn, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedScalar(Vector64 value, byte count) => ShiftRightArithmeticNarrowingSaturateUnsignedScalar(value, count); + + /// + /// uint32_t vqshrund_n_s64 (int64_t a, const int n) + /// A64: SQSHRUN Sd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedScalar(Vector64 value, byte count) => ShiftRightArithmeticNarrowingSaturateUnsignedScalar(value, count); + + /// + /// int16_t vqrshrns_n_s32 (int32_t a, const int n) + /// A64: SQRSHRN Hd, Sn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateScalar(value, count); + + /// + /// int32_t vqrshrnd_n_s64 (int64_t a, const int n) + /// A64: SQRSHRN Sd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateScalar(value, count); + + /// + /// int8_t vqrshrnh_n_s16 (int16_t a, const int n) + /// A64: SQRSHRN Bd, Hn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateScalar(value, count); + + /// + /// uint8_t vqrshrunh_n_s16 (int16_t a, const int n) + /// A64: SQRSHRUN Bd, Hn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(Vector64 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(value, count); + + /// + /// uint16_t vqrshruns_n_s32 (int32_t a, const int n) + /// A64: SQRSHRUN Hd, Sn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(Vector64 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(value, count); + + /// + /// uint32_t vqrshrund_n_s64 (int64_t a, const int n) + /// A64: SQRSHRUN Sd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(Vector64 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(value, count); + + /// + /// uint8_t vqshrnh_n_u16 (uint16_t a, const int n) + /// A64: UQSHRN Bd, Hn, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightLogicalNarrowingSaturateScalar(value, count); + + /// + /// uint16_t vqshrns_n_u32 (uint32_t a, const int n) + /// A64: UQSHRN Hd, Sn, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightLogicalNarrowingSaturateScalar(value, count); + + /// + /// uint32_t vqshrnd_n_u64 (uint64_t a, const int n) + /// A64: UQSHRN Sd, Dn, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightLogicalNarrowingSaturateScalar(value, count); + + /// + /// uint8_t vqshrnh_n_u16 (uint16_t a, const int n) + /// A64: UQSHRN Bd, Hn, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightLogicalNarrowingSaturateScalar(value, count); + + /// + /// uint16_t vqshrns_n_u32 (uint32_t a, const int n) + /// A64: UQSHRN Hd, Sn, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightLogicalNarrowingSaturateScalar(value, count); + + /// + /// uint32_t vqshrnd_n_u64 (uint64_t a, const int n) + /// A64: UQSHRN Sd, Dn, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightLogicalNarrowingSaturateScalar(value, count); + + /// + /// uint8_t vqrshrnh_n_u16 (uint16_t a, const int n) + /// A64: UQRSHRN Bd, Hn, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateScalar(value, count); + + /// + /// uint16_t vqrshrns_n_u32 (uint32_t a, const int n) + /// A64: UQRSHRN Hd, Sn, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateScalar(value, count); + + /// + /// uint32_t vqrshrnd_n_u64 (uint64_t a, const int n) + /// A64: UQRSHRN Sd, Dn, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateScalar(value, count); + + /// + /// uint8_t vqrshrnh_n_u16 (uint16_t a, const int n) + /// A64: UQRSHRN Bd, Hn, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateScalar(value, count); + + /// + /// uint16_t vqrshrns_n_u32 (uint32_t a, const int n) + /// A64: UQRSHRN Hd, Sn, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateScalar(value, count); + + /// + /// uint32_t vqrshrnd_n_u64 (uint64_t a, const int n) + /// A64: UQRSHRN Sd, Dn, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(Vector64 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateScalar(value, count); + /// /// float32x2_t vsqrt_f32 (float32x2_t a) /// A64: FSQRT Vd.2S, Vn.2S @@ -7137,184 +7443,2431 @@ public new abstract class Arm64 : ArmBase.Arm64 public static Vector128 ReciprocalStep(Vector128 left, Vector128 right) => ReciprocalStep(left, right); /// - /// float64x1_t vsqrt_f64 (float64x1_t a) - /// A32: VSQRT.F64 Dd, Dm - /// A64: FSQRT Dd, Dn + /// int16x4_t vshl_s16 (int16x4_t a, int16x4_t b) + /// A32: VSHL.S16 Dd, Dn, Dm + /// A64: SSHL Vd.4H, Vn.4H, Vm.4H /// - public static Vector64 SqrtScalar(Vector64 value) => SqrtScalar(value); + public static Vector64 ShiftArithmetic(Vector64 value, Vector64 count) => ShiftArithmetic(value, count); /// - /// float32_t vsqrts_f32 (float32_t a) - /// A32: VSQRT.F32 Sd, Sm - /// A64: FSQRT Sd, Sn - /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// int32x2_t vshl_s32 (int32x2_t a, int32x2_t b) + /// A32: VSHL.S32 Dd, Dn, Dm + /// A64: SSHL Vd.2S, Vn.2S, Vm.2S /// - public static Vector64 SqrtScalar(Vector64 value) => SqrtScalar(value); + public static Vector64 ShiftArithmetic(Vector64 value, Vector64 count) => ShiftArithmetic(value, count); /// - /// void vst1_u8 (uint8_t * ptr, uint8x8_t val) - /// A32: VST1.8 { Dd }, [Rn] - /// A64: ST1 { Vt.8B }, [Xn] + /// int8x8_t vshl_s8 (int8x8_t a, int8x8_t b) + /// A32: VSHL.S8 Dd, Dn, Dm + /// A64: SSHL Vd.8B, Vn.8B, Vm.8B /// - public static unsafe void Store(byte* address, Vector64 source) => Store(address, source); + public static Vector64 ShiftArithmetic(Vector64 value, Vector64 count) => ShiftArithmetic(value, count); /// - /// void vst1_f64 (float64_t * ptr, float64x1_t val) - /// A32: VST1.64 { Dd }, [Rn] - /// A64: ST1 { Vt.1D }, [Xn] + /// int16x8_t vshlq_s16 (int16x8_t a, int16x8_t b) + /// A32: VSHL.S16 Qd, Qn, Qm + /// A64: SSHL Vd.8H, Vn.8H, Vm.8H /// - public static unsafe void Store(double* address, Vector64 source) => Store(address, source); + public static Vector128 ShiftArithmetic(Vector128 value, Vector128 count) => ShiftArithmetic(value, count); /// - /// void vst1_s16 (int16_t * ptr, int16x4_t val) - /// A32: VST1.16 { Dd }, [Rn] - /// A64: ST1 {Vt.4H }, [Xn] + /// int32x4_t vshlq_s32 (int32x4_t a, int32x4_t b) + /// A32: VSHL.S32 Qd, Qn, Qm + /// A64: SSHL Vd.4S, Vn.4S, Vm.4S /// - public static unsafe void Store(short* address, Vector64 source) => Store(address, source); + public static Vector128 ShiftArithmetic(Vector128 value, Vector128 count) => ShiftArithmetic(value, count); /// - /// void vst1_s32 (int32_t * ptr, int32x2_t val) - /// A32: VST1.32 { Dd }, [Rn] - /// A64: ST1 { Vt.2S }, [Xn] + /// int64x2_t vshlq_s64 (int64x2_t a, int64x2_t b) + /// A32: VSHL.S64 Qd, Qn, Qm + /// A64: SSHL Vd.2D, Vn.2D, Vm.2D /// - public static unsafe void Store(int* address, Vector64 source) => Store(address, source); + public static Vector128 ShiftArithmetic(Vector128 value, Vector128 count) => ShiftArithmetic(value, count); /// - /// void vst1_s64 (int64_t * ptr, int64x1_t val) - /// A32: VST1.64 { Dd }, [Rn] - /// A64: ST1 { Vt.1D }, [Xn] + /// int8x16_t vshlq_s8 (int8x16_t a, int8x16_t b) + /// A32: VSHL.S8 Qd, Qn, Qm + /// A64: SSHL Vd.16B, Vn.16B, Vm.16B /// - public static unsafe void Store(long* address, Vector64 source) => Store(address, source); + public static Vector128 ShiftArithmetic(Vector128 value, Vector128 count) => ShiftArithmetic(value, count); /// - /// void vst1_s8 (int8_t * ptr, int8x8_t val) - /// A32: VST1.8 { Dd }, [Rn] - /// A64: ST1 { Vt.8B }, [Xn] + /// int16x4_t vrshl_s16 (int16x4_t a, int16x4_t b) + /// A32: VRSHL.S16 Dd, Dn, Dm + /// A64: SRSHL Vd.4H, Vn.4H, Vm.4H /// - public static unsafe void Store(sbyte* address, Vector64 source) => Store(address, source); + public static Vector64 ShiftArithmeticRounded(Vector64 value, Vector64 count) => ShiftArithmeticRounded(value, count); /// - /// void vst1_f32 (float32_t * ptr, float32x2_t val) - /// A32: VST1.32 { Dd }, [Rn] - /// A64: ST1 { Vt.2S }, [Xn] + /// int32x2_t vrshl_s32 (int32x2_t a, int32x2_t b) + /// A32: VRSHL.S32 Dd, Dn, Dm + /// A64: SRSHL Vd.2S, Vn.2S, Vm.2S /// - public static unsafe void Store(float* address, Vector64 source) => Store(address, source); + public static Vector64 ShiftArithmeticRounded(Vector64 value, Vector64 count) => ShiftArithmeticRounded(value, count); /// - /// void vst1_u16 (uint16_t * ptr, uint16x4_t val) - /// A32: VST1.16 { Dd }, [Rn] - /// A64: ST1 { Vt.4H }, [Xn] + /// int8x8_t vrshl_s8 (int8x8_t a, int8x8_t b) + /// A32: VRSHL.S8 Dd, Dn, Dm + /// A64: SRSHL Vd.8B, Vn.8B, Vm.8B /// - public static unsafe void Store(ushort* address, Vector64 source) => Store(address, source); + public static Vector64 ShiftArithmeticRounded(Vector64 value, Vector64 count) => ShiftArithmeticRounded(value, count); /// - /// void vst1_u32 (uint32_t * ptr, uint32x2_t val) - /// A32: VST1.32 { Dd }, [Rn] - /// A64: ST1 { Vt.2S }, [Xn] + /// int16x8_t vrshlq_s16 (int16x8_t a, int16x8_t b) + /// A32: VRSHL.S16 Qd, Qn, Qm + /// A64: SRSHL Vd.8H, Vn.8H, Vm.8H /// - public static unsafe void Store(uint* address, Vector64 source) => Store(address, source); + public static Vector128 ShiftArithmeticRounded(Vector128 value, Vector128 count) => ShiftArithmeticRounded(value, count); /// - /// void vst1_u64 (uint64_t * ptr, uint64x1_t val) - /// A32: VST1.64 { Dd }, [Rn] - /// A64: ST1 { Vt.1D }, [Xn] + /// int32x4_t vrshlq_s32 (int32x4_t a, int32x4_t b) + /// A32: VRSHL.S32 Qd, Qn, Qm + /// A64: SRSHL Vd.4S, Vn.4S, Vm.4S /// - public static unsafe void Store(ulong* address, Vector64 source) => Store(address, source); + public static Vector128 ShiftArithmeticRounded(Vector128 value, Vector128 count) => ShiftArithmeticRounded(value, count); /// - /// void vst1q_u8 (uint8_t * ptr, uint8x16_t val) - /// A32: VST1.8 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.16B }, [Xn] + /// int64x2_t vrshlq_s64 (int64x2_t a, int64x2_t b) + /// A32: VRSHL.S64 Qd, Qn, Qm + /// A64: SRSHL Vd.2D, Vn.2D, Vm.2D /// - public static unsafe void Store(byte* address, Vector128 source) => Store(address, source); + public static Vector128 ShiftArithmeticRounded(Vector128 value, Vector128 count) => ShiftArithmeticRounded(value, count); /// - /// void vst1q_f64 (float64_t * ptr, float64x2_t val) - /// A32: VST1.64 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.2D }, [Xn] + /// int8x16_t vrshlq_s8 (int8x16_t a, int8x16_t b) + /// A32: VRSHL.S8 Qd, Qn, Qm + /// A64: SRSHL Vd.16B, Vn.16B, Vm.16B /// - public static unsafe void Store(double* address, Vector128 source) => Store(address, source); + public static Vector128 ShiftArithmeticRounded(Vector128 value, Vector128 count) => ShiftArithmeticRounded(value, count); /// - /// void vst1q_s16 (int16_t * ptr, int16x8_t val) - /// A32: VST1.16 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.8H }, [Xn] + /// int16x4_t vqrshl_s16 (int16x4_t a, int16x4_t b) + /// A32: VQRSHL.S16 Dd, Dn, Dm + /// A64: SQRSHL Vd.4H, Vn.4H, Vm.4H /// - public static unsafe void Store(short* address, Vector128 source) => Store(address, source); + public static Vector64 ShiftArithmeticRoundedSaturate(Vector64 value, Vector64 count) => ShiftArithmeticRoundedSaturate(value, count); /// - /// void vst1q_s32 (int32_t * ptr, int32x4_t val) - /// A32: VST1.32 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.4S }, [Xn] + /// int32x2_t vqrshl_s32 (int32x2_t a, int32x2_t b) + /// A32: VQRSHL.S32 Dd, Dn, Dm + /// A64: SQRSHL Vd.2S, Vn.2S, Vm.2S /// - public static unsafe void Store(int* address, Vector128 source) => Store(address, source); + public static Vector64 ShiftArithmeticRoundedSaturate(Vector64 value, Vector64 count) => ShiftArithmeticRoundedSaturate(value, count); /// - /// void vst1q_s64 (int64_t * ptr, int64x2_t val) - /// A32: VST1.64 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.2D }, [Xn] + /// int8x8_t vqrshl_s8 (int8x8_t a, int8x8_t b) + /// A32: VQRSHL.S8 Dd, Dn, Dm + /// A64: SQRSHL Vd.8B, Vn.8B, Vm.8B /// - public static unsafe void Store(long* address, Vector128 source) => Store(address, source); + public static Vector64 ShiftArithmeticRoundedSaturate(Vector64 value, Vector64 count) => ShiftArithmeticRoundedSaturate(value, count); /// - /// void vst1q_s8 (int8_t * ptr, int8x16_t val) - /// A32: VST1.8 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.16B }, [Xn] + /// int16x8_t vqrshlq_s16 (int16x8_t a, int16x8_t b) + /// A32: VQRSHL.S16 Qd, Qn, Qm + /// A64: SQRSHL Vd.8H, Vn.8H, Vm.8H /// - public static unsafe void Store(sbyte* address, Vector128 source) => Store(address, source); + public static Vector128 ShiftArithmeticRoundedSaturate(Vector128 value, Vector128 count) => ShiftArithmeticRoundedSaturate(value, count); /// - /// void vst1q_f32 (float32_t * ptr, float32x4_t val) - /// A32: VST1.32 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.4S }, [Xn] + /// int32x4_t vqrshlq_s32 (int32x4_t a, int32x4_t b) + /// A32: VQRSHL.S32 Qd, Qn, Qm + /// A64: SQRSHL Vd.4S, Vn.4S, Vm.4S /// - public static unsafe void Store(float* address, Vector128 source) => Store(address, source); + public static Vector128 ShiftArithmeticRoundedSaturate(Vector128 value, Vector128 count) => ShiftArithmeticRoundedSaturate(value, count); /// - /// void vst1q_u16 (uint16_t * ptr, uint16x8_t val) - /// A32: VST1.16 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.8H }, [Xn] + /// int64x2_t vqrshlq_s64 (int64x2_t a, int64x2_t b) + /// A32: VQRSHL.S64 Qd, Qn, Qm + /// A64: SQRSHL Vd.2D, Vn.2D, Vm.2D /// - public static unsafe void Store(ushort* address, Vector128 source) => Store(address, source); + public static Vector128 ShiftArithmeticRoundedSaturate(Vector128 value, Vector128 count) => ShiftArithmeticRoundedSaturate(value, count); /// - /// void vst1q_u32 (uint32_t * ptr, uint32x4_t val) - /// A32: VST1.32 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.4S }, [Xn] + /// int8x16_t vqrshlq_s8 (int8x16_t a, int8x16_t b) + /// A32: VQRSHL.S8 Qd, Qn, Qm + /// A64: SQRSHL Vd.16B, Vn.16B, Vm.16B /// - public static unsafe void Store(uint* address, Vector128 source) => Store(address, source); + public static Vector128 ShiftArithmeticRoundedSaturate(Vector128 value, Vector128 count) => ShiftArithmeticRoundedSaturate(value, count); /// - /// void vst1q_u64 (uint64_t * ptr, uint64x2_t val) - /// A32: VST1.64 { Dd, Dd+1 }, [Rn] - /// A64: ST1 { Vt.2D }, [Xn] + /// int64x1_t vqrshl_s64 (int64x1_t a, int64x1_t b) + /// A32: VQRSHL.S64 Dd, Dn, Dm + /// A64: SQRSHL Dd, Dn, Dm /// - public static unsafe void Store(ulong* address, Vector128 source) => Store(address, source); + public static Vector64 ShiftArithmeticRoundedSaturateScalar(Vector64 value, Vector64 count) => ShiftArithmeticRoundedSaturateScalar(value, count); /// - /// uint8x8_t vsub_u8 (uint8x8_t a, uint8x8_t b) - /// A32: VSUB.I8 Dd, Dn, Dm - /// A64: SUB Vd.8B, Vn.8B, Vm.8B + /// int64x1_t vrshl_s64 (int64x1_t a, int64x1_t b) + /// A32: VRSHL.S64 Dd, Dn, Dm + /// A64: SRSHL Dd, Dn, Dm /// - public static Vector64 Subtract(Vector64 left, Vector64 right) => Subtract(left, right); + public static Vector64 ShiftArithmeticRoundedScalar(Vector64 value, Vector64 count) => ShiftArithmeticRoundedScalar(value, count); /// - /// int16x4_t vsub_s16 (int16x4_t a, int16x4_t b) - /// A32: VSUB.I16 Dd, Dn, Dm - /// A64: SUB Vd.4H, Vn.4H, Vm.4H + /// int16x4_t vqshl_s16 (int16x4_t a, int16x4_t b) + /// A32: VQSHL.S16 Dd, Dn, Dm + /// A64: SQSHL Vd.4H, Vn.4H, Vm.4H /// - public static Vector64 Subtract(Vector64 left, Vector64 right) => Subtract(left, right); + public static Vector64 ShiftArithmeticSaturate(Vector64 value, Vector64 count) => ShiftArithmeticSaturate(value, count); /// - /// int32x2_t vsub_s32 (int32x2_t a, int32x2_t b) - /// A32: VSUB.I32 Dd, Dn, Dm - /// A64: SUB Vd.2S, Vn.2S, Vm.2S + /// int32x2_t vqshl_s32 (int32x2_t a, int32x2_t b) + /// A32: VQSHL.S32 Dd, Dn, Dm + /// A64: SQSHL Vd.2S, Vn.2S, Vm.2S /// - public static Vector64 Subtract(Vector64 left, Vector64 right) => Subtract(left, right); + public static Vector64 ShiftArithmeticSaturate(Vector64 value, Vector64 count) => ShiftArithmeticSaturate(value, count); /// - /// int8x8_t vsub_s8 (int8x8_t a, int8x8_t b) - /// A32: VSUB.I8 Dd, Dn, Dm + /// int8x8_t vqshl_s8 (int8x8_t a, int8x8_t b) + /// A32: VQSHL.S8 Dd, Dn, Dm + /// A64: SQSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftArithmeticSaturate(Vector64 value, Vector64 count) => ShiftArithmeticSaturate(value, count); + + /// + /// int16x8_t vqshlq_s16 (int16x8_t a, int16x8_t b) + /// A32: VQSHL.S16 Qd, Qn, Qm + /// A64: SQSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftArithmeticSaturate(Vector128 value, Vector128 count) => ShiftArithmeticSaturate(value, count); + + /// + /// int32x4_t vqshlq_s32 (int32x4_t a, int32x4_t b) + /// A32: VQSHL.S32 Qd, Qn, Qm + /// A64: SQSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftArithmeticSaturate(Vector128 value, Vector128 count) => ShiftArithmeticSaturate(value, count); + + /// + /// int64x2_t vqshlq_s64 (int64x2_t a, int64x2_t b) + /// A32: VQSHL.S64 Qd, Qn, Qm + /// A64: SQSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftArithmeticSaturate(Vector128 value, Vector128 count) => ShiftArithmeticSaturate(value, count); + + /// + /// int8x16_t vqshlq_s8 (int8x16_t a, int8x16_t b) + /// A32: VQSHL.S8 Qd, Qn, Qm + /// A64: SQSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftArithmeticSaturate(Vector128 value, Vector128 count) => ShiftArithmeticSaturate(value, count); + + /// + /// int64x1_t vqshl_s64 (int64x1_t a, int64x1_t b) + /// A32: VQSHL.S64 Dd, Dn, Dm + /// A64: SQSHL Dd, Dn, Dm + /// + public static Vector64 ShiftArithmeticSaturateScalar(Vector64 value, Vector64 count) => ShiftArithmeticSaturateScalar(value, count); + + /// + /// int64x1_t vshl_s64 (int64x1_t a, int64x1_t b) + /// A32: VSHL.S64 Dd, Dn, Dm + /// A64: SSHL Dd, Dn, Dm + /// + public static Vector64 ShiftArithmeticScalar(Vector64 value, Vector64 count) => ShiftArithmeticScalar(value, count); + + /// + /// uint8x8_t vshl_n_u8 (uint8x8_t a, const int n) + /// A32: VSHL.I8 Dd, Dm, #n + /// A64: SHL Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftLeftLogical(Vector64 value, byte count) => ShiftLeftLogical(value, count); + + /// + /// int16x4_t vshl_n_s16 (int16x4_t a, const int n) + /// A32: VSHL.I16 Dd, Dm, #n + /// A64: SHL Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftLeftLogical(Vector64 value, byte count) => ShiftLeftLogical(value, count); + + /// + /// int32x2_t vshl_n_s32 (int32x2_t a, const int n) + /// A32: VSHL.I32 Dd, Dm, #n + /// A64: SHL Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftLeftLogical(Vector64 value, byte count) => ShiftLeftLogical(value, count); + + /// + /// int8x8_t vshl_n_s8 (int8x8_t a, const int n) + /// A32: VSHL.I8 Dd, Dm, #n + /// A64: SHL Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftLeftLogical(Vector64 value, byte count) => ShiftLeftLogical(value, count); + + /// + /// uint16x4_t vshl_n_u16 (uint16x4_t a, const int n) + /// A32: VSHL.I16 Dd, Dm, #n + /// A64: SHL Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftLeftLogical(Vector64 value, byte count) => ShiftLeftLogical(value, count); + + /// + /// uint32x2_t vshl_n_u32 (uint32x2_t a, const int n) + /// A32: VSHL.I32 Dd, Dm, #n + /// A64: SHL Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftLeftLogical(Vector64 value, byte count) => ShiftLeftLogical(value, count); + + /// + /// uint8x16_t vshlq_n_u8 (uint8x16_t a, const int n) + /// A32: VSHL.I8 Qd, Qm, #n + /// A64: SHL Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) => ShiftLeftLogical(value, count); + + /// + /// int16x8_t vshlq_n_s16 (int16x8_t a, const int n) + /// A32: VSHL.I16 Qd, Qm, #n + /// A64: SHL Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) => ShiftLeftLogical(value, count); + + /// + /// int64x2_t vshlq_n_s64 (int64x2_t a, const int n) + /// A32: VSHL.I64 Qd, Qm, #n + /// A64: SHL Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) => ShiftLeftLogical(value, count); + + /// + /// int8x16_t vshlq_n_s8 (int8x16_t a, const int n) + /// A32: VSHL.I8 Qd, Qm, #n + /// A64: SHL Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) => ShiftLeftLogical(value, count); + + /// + /// uint16x8_t vshlq_n_u16 (uint16x8_t a, const int n) + /// A32: VSHL.I16 Qd, Qm, #n + /// A64: SHL Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) => ShiftLeftLogical(value, count); + + /// + /// uint32x4_t vshlq_n_u32 (uint32x4_t a, const int n) + /// A32: VSHL.I32 Qd, Qm, #n + /// A64: SHL Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) => ShiftLeftLogical(value, count); + + /// + /// uint64x2_t vshlq_n_u64 (uint64x2_t a, const int n) + /// A32: VSHL.I64 Qd, Qm, #n + /// A64: SHL Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftLeftLogical(Vector128 value, byte count) => ShiftLeftLogical(value, count); + + /// + /// uint8x8_t vqshl_n_u8 (uint8x8_t a, const int n) + /// A32: VQSHL.U8 Dd, Dm, #n + /// A64: UQSHL Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftLeftLogicalSaturate(Vector64 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// int16x4_t vqshl_n_s16 (int16x4_t a, const int n) + /// A32: VQSHL.S16 Dd, Dm, #n + /// A64: SQSHL Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftLeftLogicalSaturate(Vector64 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// int32x2_t vqshl_n_s32 (int32x2_t a, const int n) + /// A32: VQSHL.S32 Dd, Dm, #n + /// A64: SQSHL Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftLeftLogicalSaturate(Vector64 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// int8x8_t vqshl_n_s8 (int8x8_t a, const int n) + /// A32: VQSHL.S8 Dd, Dm, #n + /// A64: SQSHL Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftLeftLogicalSaturate(Vector64 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// uint16x4_t vqshl_n_u16 (uint16x4_t a, const int n) + /// A32: VQSHL.U16 Dd, Dm, #n + /// A64: UQSHL Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftLeftLogicalSaturate(Vector64 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// uint32x2_t vqshl_n_u32 (uint32x2_t a, const int n) + /// A32: VQSHL.U32 Dd, Dm, #n + /// A64: UQSHL Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftLeftLogicalSaturate(Vector64 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// uint8x16_t vqshlq_n_u8 (uint8x16_t a, const int n) + /// A32: VQSHL.U8 Qd, Qm, #n + /// A64: UQSHL Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// int16x8_t vqshlq_n_s16 (int16x8_t a, const int n) + /// A32: VQSHL.S16 Qd, Qm, #n + /// A64: SQSHL Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// int32x4_t vqshlq_n_s32 (int32x4_t a, const int n) + /// A32: VQSHL.S32 Qd, Qm, #n + /// A64: SQSHL Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// int64x2_t vqshlq_n_s64 (int64x2_t a, const int n) + /// A32: VQSHL.S64 Qd, Qm, #n + /// A64: SQSHL Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// int8x16_t vqshlq_n_s8 (int8x16_t a, const int n) + /// A32: VQSHL.S8 Qd, Qm, #n + /// A64: SQSHL Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// uint16x8_t vqshlq_n_u16 (uint16x8_t a, const int n) + /// A32: VQSHL.U16 Qd, Qm, #n + /// A64: UQSHL Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// uint32x4_t vqshlq_n_u32 (uint32x4_t a, const int n) + /// A32: VQSHL.U32 Qd, Qm, #n + /// A64: UQSHL Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// uint64x2_t vqshlq_n_u64 (uint64x2_t a, const int n) + /// A32: VQSHL.U64 Qd, Qm, #n + /// A64: UQSHL Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftLeftLogicalSaturate(Vector128 value, byte count) => ShiftLeftLogicalSaturate(value, count); + + /// + /// int64x1_t vqshl_n_s64 (int64x1_t a, const int n) + /// A32: VQSHL.S64 Dd, Dm, #n + /// A64: SQSHL Dd, Dn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) => ShiftLeftLogicalSaturateScalar(value, count); + + /// + /// uint64x1_t vqshl_n_u64 (uint64x1_t a, const int n) + /// A32: VQSHL.U64 Dd, Dm, #n + /// A64: UQSHL Dd, Dn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateScalar(Vector64 value, byte count) => ShiftLeftLogicalSaturateScalar(value, count); + + /// + /// uint16x4_t vqshlu_n_s16 (int16x4_t a, const int n) + /// A32: VQSHLU.S16 Dd, Dm, #n + /// A64: SQSHLU Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsigned(Vector64 value, byte count) => ShiftLeftLogicalSaturateUnsigned(value, count); + + /// + /// uint32x2_t vqshlu_n_s32 (int32x2_t a, const int n) + /// A32: VQSHLU.S32 Dd, Dm, #n + /// A64: SQSHLU Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsigned(Vector64 value, byte count) => ShiftLeftLogicalSaturateUnsigned(value, count); + + /// + /// uint8x8_t vqshlu_n_s8 (int8x8_t a, const int n) + /// A32: VQSHLU.S8 Dd, Dm, #n + /// A64: SQSHLU Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsigned(Vector64 value, byte count) => ShiftLeftLogicalSaturateUnsigned(value, count); + + /// + /// uint16x8_t vqshluq_n_s16 (int16x8_t a, const int n) + /// A32: VQSHLU.S16 Qd, Qm, #n + /// A64: SQSHLU Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogicalSaturateUnsigned(Vector128 value, byte count) => ShiftLeftLogicalSaturateUnsigned(value, count); + + /// + /// uint32x4_t vqshluq_n_s32 (int32x4_t a, const int n) + /// A32: VQSHLU.S32 Qd, Qm, #n + /// A64: SQSHLU Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftLeftLogicalSaturateUnsigned(Vector128 value, byte count) => ShiftLeftLogicalSaturateUnsigned(value, count); + + /// + /// uint64x2_t vqshluq_n_s64 (int64x2_t a, const int n) + /// A32: VQSHLU.S64 Qd, Qm, #n + /// A64: SQSHLU Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftLeftLogicalSaturateUnsigned(Vector128 value, byte count) => ShiftLeftLogicalSaturateUnsigned(value, count); + + /// + /// uint8x16_t vqshluq_n_s8 (int8x16_t a, const int n) + /// A32: VQSHLU.S8 Qd, Qm, #n + /// A64: SQSHLU Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogicalSaturateUnsigned(Vector128 value, byte count) => ShiftLeftLogicalSaturateUnsigned(value, count); + + /// + /// uint64x1_t vqshlu_n_s64 (int64x1_t a, const int n) + /// A32: VQSHLU.S64 Dd, Dm, #n + /// A64: SQSHLU Dd, Dn, #n + /// + public static Vector64 ShiftLeftLogicalSaturateUnsignedScalar(Vector64 value, byte count) => ShiftLeftLogicalSaturateUnsignedScalar(value, count); + + /// + /// int64x1_t vshl_n_s64 (int64x1_t a, const int n) + /// A32: VSHL.I64 Dd, Dm, #n + /// A64: SHL Dd, Dn, #n + /// + public static Vector64 ShiftLeftLogicalScalar(Vector64 value, byte count) => ShiftLeftLogicalScalar(value, count); + + /// + /// uint64x1_t vshl_n_u64 (uint64x1_t a, const int n) + /// A32: VSHL.I64 Dd, Dm, #n + /// A64: SHL Dd, Dn, #n + /// + public static Vector64 ShiftLeftLogicalScalar(Vector64 value, byte count) => ShiftLeftLogicalScalar(value, count); + + /// + /// uint16x8_t vshll_n_u8 (uint8x8_t a, const int n) + /// A32: VSHLL.U8 Qd, Dm, #n + /// A64: USHLL Vd.8H, Vn.8B, #n + /// + public static Vector128 ShiftLeftLogicalWideningLower(Vector64 value, byte count) => ShiftLeftLogicalWideningLower(value, count); + + /// + /// int32x4_t vshll_n_s16 (int16x4_t a, const int n) + /// A32: VSHLL.S16 Qd, Dm, #n + /// A64: SSHLL Vd.4S, Vn.4H, #n + /// + public static Vector128 ShiftLeftLogicalWideningLower(Vector64 value, byte count) => ShiftLeftLogicalWideningLower(value, count); + + /// + /// int64x2_t vshll_n_s32 (int32x2_t a, const int n) + /// A32: VSHLL.S32 Qd, Dm, #n + /// A64: SSHLL Vd.2D, Vn.2S, #n + /// + public static Vector128 ShiftLeftLogicalWideningLower(Vector64 value, byte count) => ShiftLeftLogicalWideningLower(value, count); + + /// + /// int16x8_t vshll_n_s8 (int8x8_t a, const int n) + /// A32: VSHLL.S8 Qd, Dm, #n + /// A64: SSHLL Vd.8H, Vn.8B, #n + /// + public static Vector128 ShiftLeftLogicalWideningLower(Vector64 value, byte count) => ShiftLeftLogicalWideningLower(value, count); + + /// + /// uint32x4_t vshll_n_u16 (uint16x4_t a, const int n) + /// A32: VSHLL.U16 Qd, Dm, #n + /// A64: USHLL Vd.4S, Vn.4H, #n + /// + public static Vector128 ShiftLeftLogicalWideningLower(Vector64 value, byte count) => ShiftLeftLogicalWideningLower(value, count); + + /// + /// uint64x2_t vshll_n_u32 (uint32x2_t a, const int n) + /// A32: VSHLL.U32 Qd, Dm, #n + /// A64: USHLL Vd.2D, Vn.2S, #n + /// + public static Vector128 ShiftLeftLogicalWideningLower(Vector64 value, byte count) => ShiftLeftLogicalWideningLower(value, count); + + /// + /// uint16x8_t vshll_high_n_u8 (uint8x16_t a, const int n) + /// A32: VSHLL.U8 Qd, Dm+1, #n + /// A64: USHLL2 Vd.8H, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogicalWideningUpper(Vector128 value, byte count) => ShiftLeftLogicalWideningUpper(value, count); + + /// + /// int32x4_t vshll_high_n_s16 (int16x8_t a, const int n) + /// A32: VSHLL.S16 Qd, Dm+1, #n + /// A64: SSHLL2 Vd.4S, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogicalWideningUpper(Vector128 value, byte count) => ShiftLeftLogicalWideningUpper(value, count); + + /// + /// int64x2_t vshll_high_n_s32 (int32x4_t a, const int n) + /// A32: VSHLL.S32 Qd, Dm+1, #n + /// A64: SSHLL2 Vd.2D, Vn.4S, #n + /// + public static Vector128 ShiftLeftLogicalWideningUpper(Vector128 value, byte count) => ShiftLeftLogicalWideningUpper(value, count); + + /// + /// int16x8_t vshll_high_n_s8 (int8x16_t a, const int n) + /// A32: VSHLL.S8 Qd, Dm+1, #n + /// A64: SSHLL2 Vd.8H, Vn.16B, #n + /// + public static Vector128 ShiftLeftLogicalWideningUpper(Vector128 value, byte count) => ShiftLeftLogicalWideningUpper(value, count); + + /// + /// uint32x4_t vshll_high_n_u16 (uint16x8_t a, const int n) + /// A32: VSHLL.U16 Qd, Dm+1, #n + /// A64: USHLL2 Vd.4S, Vn.8H, #n + /// + public static Vector128 ShiftLeftLogicalWideningUpper(Vector128 value, byte count) => ShiftLeftLogicalWideningUpper(value, count); + + /// + /// uint64x2_t vshll_high_n_u32 (uint32x4_t a, const int n) + /// A32: VSHLL.U32 Qd, Dm+1, #n + /// A64: USHLL2 Vd.2D, Vn.4S, #n + /// + public static Vector128 ShiftLeftLogicalWideningUpper(Vector128 value, byte count) => ShiftLeftLogicalWideningUpper(value, count); + + /// + /// uint8x8_t vshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VSHL.U8 Dd, Dn, Dm + /// A64: USHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogical(Vector64 value, Vector64 count) => ShiftLogical(value, count); + + /// + /// uint16x4_t vshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VSHL.U16 Dd, Dn, Dm + /// A64: USHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogical(Vector64 value, Vector64 count) => ShiftLogical(value, count); + + /// + /// uint32x2_t vshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VSHL.U32 Dd, Dn, Dm + /// A64: USHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogical(Vector64 value, Vector64 count) => ShiftLogical(value, count); + + /// + /// uint8x8_t vshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VSHL.U8 Dd, Dn, Dm + /// A64: USHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogical(Vector64 value, Vector64 count) => ShiftLogical(value, count); + + /// + /// uint16x4_t vshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VSHL.U16 Dd, Dn, Dm + /// A64: USHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogical(Vector64 value, Vector64 count) => ShiftLogical(value, count); + + /// + /// uint32x2_t vshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VSHL.U32 Dd, Dn, Dm + /// A64: USHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogical(Vector64 value, Vector64 count) => ShiftLogical(value, count); + + /// + /// uint8x16_t vshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VSHL.U8 Qd, Qn, Qm + /// A64: USHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) => ShiftLogical(value, count); + + /// + /// uint16x8_t vshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VSHL.U16 Qd, Qn, Qm + /// A64: USHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) => ShiftLogical(value, count); + + /// + /// uint32x4_t vshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VSHL.U32 Qd, Qn, Qm + /// A64: USHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) => ShiftLogical(value, count); + + /// + /// uint64x2_t vshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VSHL.U64 Qd, Qn, Qm + /// A64: USHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) => ShiftLogical(value, count); + + /// + /// uint8x16_t vshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VSHL.U8 Qd, Qn, Qm + /// A64: USHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) => ShiftLogical(value, count); + + /// + /// uint16x8_t vshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VSHL.U16 Qd, Qn, Qm + /// A64: USHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) => ShiftLogical(value, count); + + /// + /// uint32x4_t vshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VSHL.U32 Qd, Qn, Qm + /// A64: USHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) => ShiftLogical(value, count); + + /// + /// uint64x2_t vshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VSHL.U64 Qd, Qn, Qm + /// A64: USHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogical(Vector128 value, Vector128 count) => ShiftLogical(value, count); + + /// + /// uint8x8_t vrshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VRSHL.U8 Dd, Dn, Dm + /// A64: URSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogicalRounded(Vector64 value, Vector64 count) => ShiftLogicalRounded(value, count); + + /// + /// uint16x4_t vrshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VRSHL.U16 Dd, Dn, Dm + /// A64: URSHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogicalRounded(Vector64 value, Vector64 count) => ShiftLogicalRounded(value, count); + + /// + /// uint32x2_t vrshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VRSHL.U32 Dd, Dn, Dm + /// A64: URSHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogicalRounded(Vector64 value, Vector64 count) => ShiftLogicalRounded(value, count); + + /// + /// uint8x8_t vrshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VRSHL.U8 Dd, Dn, Dm + /// A64: URSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogicalRounded(Vector64 value, Vector64 count) => ShiftLogicalRounded(value, count); + + /// + /// uint16x4_t vrshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VRSHL.U16 Dd, Dn, Dm + /// A64: URSHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogicalRounded(Vector64 value, Vector64 count) => ShiftLogicalRounded(value, count); + + /// + /// uint32x2_t vrshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VRSHL.U32 Dd, Dn, Dm + /// A64: URSHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogicalRounded(Vector64 value, Vector64 count) => ShiftLogicalRounded(value, count); + + /// + /// uint8x16_t vrshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VRSHL.U8 Qd, Qn, Qm + /// A64: URSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) => ShiftLogicalRounded(value, count); + + /// + /// uint16x8_t vrshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VRSHL.U16 Qd, Qn, Qm + /// A64: URSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) => ShiftLogicalRounded(value, count); + + /// + /// uint32x4_t vrshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VRSHL.U32 Qd, Qn, Qm + /// A64: URSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) => ShiftLogicalRounded(value, count); + + /// + /// uint64x2_t vrshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VRSHL.U64 Qd, Qn, Qm + /// A64: URSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) => ShiftLogicalRounded(value, count); + + /// + /// uint8x16_t vrshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VRSHL.U8 Qd, Qn, Qm + /// A64: URSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) => ShiftLogicalRounded(value, count); + + /// + /// uint16x8_t vrshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VRSHL.U16 Qd, Qn, Qm + /// A64: URSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) => ShiftLogicalRounded(value, count); + + /// + /// uint32x4_t vrshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VRSHL.U32 Qd, Qn, Qm + /// A64: URSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) => ShiftLogicalRounded(value, count); + + /// + /// uint64x2_t vrshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VRSHL.U64 Qd, Qn, Qm + /// A64: URSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogicalRounded(Vector128 value, Vector128 count) => ShiftLogicalRounded(value, count); + + /// + /// uint8x8_t vqrshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VQRSHL.U8 Dd, Dn, Dm + /// A64: UQRSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogicalRoundedSaturate(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint16x4_t vqrshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VQRSHL.U16 Dd, Dn, Dm + /// A64: UQRSHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogicalRoundedSaturate(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint32x2_t vqrshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VQRSHL.U32 Dd, Dn, Dm + /// A64: UQRSHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogicalRoundedSaturate(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint8x8_t vqrshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VQRSHL.U8 Dd, Dn, Dm + /// A64: UQRSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogicalRoundedSaturate(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint16x4_t vqrshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VQRSHL.U16 Dd, Dn, Dm + /// A64: UQRSHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogicalRoundedSaturate(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint32x2_t vqrshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VQRSHL.U32 Dd, Dn, Dm + /// A64: UQRSHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogicalRoundedSaturate(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint8x16_t vqrshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VQRSHL.U8 Qd, Qn, Qm + /// A64: UQRSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint16x8_t vqrshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VQRSHL.U16 Qd, Qn, Qm + /// A64: UQRSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint32x4_t vqrshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VQRSHL.U32 Qd, Qn, Qm + /// A64: UQRSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint64x2_t vqrshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VQRSHL.U64 Qd, Qn, Qm + /// A64: UQRSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint8x16_t vqrshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VQRSHL.U8 Qd, Qn, Qm + /// A64: UQRSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint16x8_t vqrshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VQRSHL.U16 Qd, Qn, Qm + /// A64: UQRSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint32x4_t vqrshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VQRSHL.U32 Qd, Qn, Qm + /// A64: UQRSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint64x2_t vqrshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VQRSHL.U64 Qd, Qn, Qm + /// A64: UQRSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogicalRoundedSaturate(Vector128 value, Vector128 count) => ShiftLogicalRoundedSaturate(value, count); + + /// + /// uint64x1_t vqrshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VQRSHL.U64 Dd, Dn, Dm + /// A64: UQRSHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturateScalar(value, count); + + /// + /// uint64x1_t vqrshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VQRSHL.U64 Dd, Dn, Dm + /// A64: UQRSHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalRoundedSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalRoundedSaturateScalar(value, count); + + /// + /// uint64x1_t vrshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VRSHL.U64 Dd, Dn, Dm + /// A64: URSHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalRoundedScalar(Vector64 value, Vector64 count) => ShiftLogicalRoundedScalar(value, count); + + /// + /// uint64x1_t vrshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VRSHL.U64 Dd, Dn, Dm + /// A64: URSHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalRoundedScalar(Vector64 value, Vector64 count) => ShiftLogicalRoundedScalar(value, count); + + /// + /// uint8x8_t vqshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VQSHL.U8 Dd, Dn, Dm + /// A64: UQSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogicalSaturate(Vector64 value, Vector64 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint16x4_t vqshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VQSHL.U16 Dd, Dn, Dm + /// A64: UQSHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogicalSaturate(Vector64 value, Vector64 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint32x2_t vqshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VQSHL.U32 Dd, Dn, Dm + /// A64: UQSHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogicalSaturate(Vector64 value, Vector64 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint8x8_t vqshl_u8 (uint8x8_t a, int8x8_t b) + /// A32: VQSHL.U8 Dd, Dn, Dm + /// A64: UQSHL Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 ShiftLogicalSaturate(Vector64 value, Vector64 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint16x4_t vqshl_u16 (uint16x4_t a, int16x4_t b) + /// A32: VQSHL.U16 Dd, Dn, Dm + /// A64: UQSHL Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 ShiftLogicalSaturate(Vector64 value, Vector64 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint32x2_t vqshl_u32 (uint32x2_t a, int32x2_t b) + /// A32: VQSHL.U32 Dd, Dn, Dm + /// A64: UQSHL Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 ShiftLogicalSaturate(Vector64 value, Vector64 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint8x16_t vqshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VQSHL.U8 Qd, Qn, Qm + /// A64: UQSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint16x8_t vqshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VQSHL.U16 Qd, Qn, Qm + /// A64: UQSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint32x4_t vqshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VQSHL.U32 Qd, Qn, Qm + /// A64: UQSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint64x2_t vqshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VQSHL.U64 Qd, Qn, Qm + /// A64: UQSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint8x16_t vqshlq_u8 (uint8x16_t a, int8x16_t b) + /// A32: VQSHL.U8 Qd, Qn, Qm + /// A64: UQSHL Vd.16B, Vn.16B, Vm.16B + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint16x8_t vqshlq_u16 (uint16x8_t a, int16x8_t b) + /// A32: VQSHL.U16 Qd, Qn, Qm + /// A64: UQSHL Vd.8H, Vn.8H, Vm.8H + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint32x4_t vqshlq_u32 (uint32x4_t a, int32x4_t b) + /// A32: VQSHL.U32 Qd, Qn, Qm + /// A64: UQSHL Vd.4S, Vn.4S, Vm.4S + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint64x2_t vqshlq_u64 (uint64x2_t a, int64x2_t b) + /// A32: VQSHL.U64 Qd, Qn, Qm + /// A64: UQSHL Vd.2D, Vn.2D, Vm.2D + /// + public static Vector128 ShiftLogicalSaturate(Vector128 value, Vector128 count) => ShiftLogicalSaturate(value, count); + + /// + /// uint64x1_t vqshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VQSHL.U64 Dd, Dn, Dm + /// A64: UQSHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalSaturateScalar(value, count); + + /// + /// uint64x1_t vqshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VQSHL.U64 Dd, Dn, Dm + /// A64: UQSHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalSaturateScalar(Vector64 value, Vector64 count) => ShiftLogicalSaturateScalar(value, count); + + /// + /// uint64x1_t vshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VSHL.U64 Dd, Dn, Dm + /// A64: USHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalScalar(Vector64 value, Vector64 count) => ShiftLogicalScalar(value, count); + + /// + /// uint64x1_t vshl_u64 (uint64x1_t a, int64x1_t b) + /// A32: VSHL.U64 Dd, Dn, Dm + /// A64: USHL Dd, Dn, Dm + /// + public static Vector64 ShiftLogicalScalar(Vector64 value, Vector64 count) => ShiftLogicalScalar(value, count); + + /// + /// int16x4_t vshr_n_s16 (int16x4_t a, const int n) + /// A32: VSHR.S16 Dd, Dm, #n + /// A64: SSHR Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightArithmetic(Vector64 value, byte count) => ShiftRightArithmetic(value, count); + + /// + /// int32x2_t vshr_n_s32 (int32x2_t a, const int n) + /// A32: VSHR.S32 Dd, Dm, #n + /// A64: SSHR Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightArithmetic(Vector64 value, byte count) => ShiftRightArithmetic(value, count); + + /// + /// int8x8_t vshr_n_s8 (int8x8_t a, const int n) + /// A32: VSHR.S8 Dd, Dm, #n + /// A64: SSHR Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightArithmetic(Vector64 value, byte count) => ShiftRightArithmetic(value, count); + + /// + /// int16x8_t vshrq_n_s16 (int16x8_t a, const int n) + /// A32: VSHR.S16 Qd, Qm, #n + /// A64: SSHR Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmetic(Vector128 value, byte count) => ShiftRightArithmetic(value, count); + + /// + /// int32x4_t vshrq_n_s32 (int32x4_t a, const int n) + /// A32: VSHR.S32 Qd, Qm, #n + /// A64: SSHR Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmetic(Vector128 value, byte count) => ShiftRightArithmetic(value, count); + + /// + /// int64x2_t vshrq_n_s64 (int64x2_t a, const int n) + /// A32: VSHR.S64 Qd, Qm, #n + /// A64: SSHR Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmetic(Vector128 value, byte count) => ShiftRightArithmetic(value, count); + + /// + /// int8x16_t vshrq_n_s8 (int8x16_t a, const int n) + /// A32: VSHR.S8 Qd, Qm, #n + /// A64: SSHR Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightArithmetic(Vector128 value, byte count) => ShiftRightArithmetic(value, count); + + /// + /// int16x4_t vsra_n_s16 (int16x4_t a, int16x4_t b, const int n) + /// A32: VSRA.S16 Dd, Dm, #n + /// A64: SSRA Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightArithmeticAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightArithmeticAdd(addend, value, count); + + /// + /// int32x2_t vsra_n_s32 (int32x2_t a, int32x2_t b, const int n) + /// A32: VSRA.S32 Dd, Dm, #n + /// A64: SSRA Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightArithmeticAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightArithmeticAdd(addend, value, count); + + /// + /// int8x8_t vsra_n_s8 (int8x8_t a, int8x8_t b, const int n) + /// A32: VSRA.S8 Dd, Dm, #n + /// A64: SSRA Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightArithmeticAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightArithmeticAdd(addend, value, count); + + /// + /// int16x8_t vsraq_n_s16 (int16x8_t a, int16x8_t b, const int n) + /// A32: VSRA.S16 Qd, Qm, #n + /// A64: SSRA Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightArithmeticAdd(addend, value, count); + + /// + /// int32x4_t vsraq_n_s32 (int32x4_t a, int32x4_t b, const int n) + /// A32: VSRA.S32 Qd, Qm, #n + /// A64: SSRA Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightArithmeticAdd(addend, value, count); + + /// + /// int64x2_t vsraq_n_s64 (int64x2_t a, int64x2_t b, const int n) + /// A32: VSRA.S64 Qd, Qm, #n + /// A64: SSRA Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightArithmeticAdd(addend, value, count); + + /// + /// int8x16_t vsraq_n_s8 (int8x16_t a, int8x16_t b, const int n) + /// A32: VSRA.S8 Qd, Qm, #n + /// A64: SSRA Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightArithmeticAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightArithmeticAdd(addend, value, count); + + /// + /// int64x1_t vsra_n_s64 (int64x1_t a, int64x1_t b, const int n) + /// A32: VSRA.S64 Dd, Dm, #n + /// A64: SSRA Dd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticAddScalar(Vector64 addend, Vector64 value, byte count) => ShiftRightArithmeticAddScalar(addend, value, count); + + /// + /// int16x4_t vqshrn_n_s32 (int32x4_t a, const int n) + /// A32: VQSHRN.S32 Dd, Qm, #n + /// A64: SQSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightArithmeticNarrowingSaturateLower(value, count); + + /// + /// int32x2_t vqshrn_n_s64 (int64x2_t a, const int n) + /// A32: VQSHRN.S64 Dd, Qm, #n + /// A64: SQSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightArithmeticNarrowingSaturateLower(value, count); + + /// + /// int8x8_t vqshrn_n_s16 (int16x8_t a, const int n) + /// A32: VQSHRN.S16 Dd, Qm, #n + /// A64: SQSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightArithmeticNarrowingSaturateLower(value, count); + + /// + /// uint8x8_t vqshrun_n_s16 (int16x8_t a, const int n) + /// A32: VQSHRUN.S16 Dd, Qm, #n + /// A64: SQSHRUN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedLower(Vector128 value, byte count) => ShiftRightArithmeticNarrowingSaturateUnsignedLower(value, count); + + /// + /// uint16x4_t vqshrun_n_s32 (int32x4_t a, const int n) + /// A32: VQSHRUN.S32 Dd, Qm, #n + /// A64: SQSHRUN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedLower(Vector128 value, byte count) => ShiftRightArithmeticNarrowingSaturateUnsignedLower(value, count); + + /// + /// uint32x2_t vqshrun_n_s64 (int64x2_t a, const int n) + /// A32: VQSHRUN.S64 Dd, Qm, #n + /// A64: SQSHRUN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedLower(Vector128 value, byte count) => ShiftRightArithmeticNarrowingSaturateUnsignedLower(value, count); + + /// + /// uint8x16_t vqshrun_high_n_s16 (uint8x8_t r, int16x8_t a, const int n) + /// A32: VQSHRUN.S16 Dd+1, Dn, #n + /// A64: SQSHRUN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticNarrowingSaturateUnsignedUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightArithmeticNarrowingSaturateUnsignedUpper(lower, value, count); + + /// + /// uint16x8_t vqshrun_high_n_s32 (uint16x4_t r, int32x4_t a, const int n) + /// A32: VQSHRUN.S32 Dd+1, Dn, #n + /// A64: SQSHRUN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticNarrowingSaturateUnsignedUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightArithmeticNarrowingSaturateUnsignedUpper(lower, value, count); + + /// + /// uint32x4_t vqshrun_high_n_s64 (uint32x2_t r, int64x2_t a, const int n) + /// A32: VQSHRUN.S64 Dd+1, Dn, #n + /// A64: SQSHRUN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticNarrowingSaturateUnsignedUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightArithmeticNarrowingSaturateUnsignedUpper(lower, value, count); + + /// + /// int16x8_t vqshrn_high_n_s32 (int16x4_t r, int32x4_t a, const int n) + /// A32: VQSHRN.S32 Dd+1, Qm, #n + /// A64: SQSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightArithmeticNarrowingSaturateUpper(lower, value, count); + + /// + /// int32x4_t vqshrn_high_n_s64 (int32x2_t r, int64x2_t a, const int n) + /// A32: VQSHRN.S64 Dd+1, Qm, #n + /// A64: SQSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightArithmeticNarrowingSaturateUpper(lower, value, count); + + /// + /// int8x16_t vqshrn_high_n_s16 (int8x8_t r, int16x8_t a, const int n) + /// A32: VQSHRN.S16 Dd+1, Qm, #n + /// A64: SQSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightArithmeticNarrowingSaturateUpper(lower, value, count); + + /// + /// int16x4_t vrshr_n_s16 (int16x4_t a, const int n) + /// A32: VRSHR.S16 Dd, Dm, #n + /// A64: SRSHR Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightArithmeticRounded(Vector64 value, byte count) => ShiftRightArithmeticRounded(value, count); + + /// + /// int32x2_t vrshr_n_s32 (int32x2_t a, const int n) + /// A32: VRSHR.S32 Dd, Dm, #n + /// A64: SRSHR Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightArithmeticRounded(Vector64 value, byte count) => ShiftRightArithmeticRounded(value, count); + + /// + /// int8x8_t vrshr_n_s8 (int8x8_t a, const int n) + /// A32: VRSHR.S8 Dd, Dm, #n + /// A64: SRSHR Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightArithmeticRounded(Vector64 value, byte count) => ShiftRightArithmeticRounded(value, count); + + /// + /// int16x8_t vrshrq_n_s16 (int16x8_t a, const int n) + /// A32: VRSHR.S16 Qd, Qm, #n + /// A64: SRSHR Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticRounded(Vector128 value, byte count) => ShiftRightArithmeticRounded(value, count); + + /// + /// int32x4_t vrshrq_n_s32 (int32x4_t a, const int n) + /// A32: VRSHR.S32 Qd, Qm, #n + /// A64: SRSHR Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticRounded(Vector128 value, byte count) => ShiftRightArithmeticRounded(value, count); + + /// + /// int64x2_t vrshrq_n_s64 (int64x2_t a, const int n) + /// A32: VRSHR.S64 Qd, Qm, #n + /// A64: SRSHR Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticRounded(Vector128 value, byte count) => ShiftRightArithmeticRounded(value, count); + + /// + /// int8x16_t vrshrq_n_s8 (int8x16_t a, const int n) + /// A32: VRSHR.S8 Qd, Qm, #n + /// A64: SRSHR Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightArithmeticRounded(Vector128 value, byte count) => ShiftRightArithmeticRounded(value, count); + + /// + /// int16x4_t vrsra_n_s16 (int16x4_t a, int16x4_t b, const int n) + /// A32: VRSRA.S16 Dd, Dm, #n + /// A64: SRSRA Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightArithmeticRoundedAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightArithmeticRoundedAdd(addend, value, count); + + /// + /// int32x2_t vrsra_n_s32 (int32x2_t a, int32x2_t b, const int n) + /// A32: VRSRA.S32 Dd, Dm, #n + /// A64: SRSRA Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightArithmeticRoundedAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightArithmeticRoundedAdd(addend, value, count); + + /// + /// int8x8_t vrsra_n_s8 (int8x8_t a, int8x8_t b, const int n) + /// A32: VRSRA.S8 Dd, Dm, #n + /// A64: SRSRA Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightArithmeticRoundedAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightArithmeticRoundedAdd(addend, value, count); + + /// + /// int16x8_t vrsraq_n_s16 (int16x8_t a, int16x8_t b, const int n) + /// A32: VRSRA.S16 Qd, Qm, #n + /// A64: SRSRA Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticRoundedAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightArithmeticRoundedAdd(addend, value, count); + + /// + /// int32x4_t vrsraq_n_s32 (int32x4_t a, int32x4_t b, const int n) + /// A32: VRSRA.S32 Qd, Qm, #n + /// A64: SRSRA Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticRoundedAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightArithmeticRoundedAdd(addend, value, count); + + /// + /// int64x2_t vrsraq_n_s64 (int64x2_t a, int64x2_t b, const int n) + /// A32: VRSRA.S64 Qd, Qm, #n + /// A64: SRSRA Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticRoundedAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightArithmeticRoundedAdd(addend, value, count); + + /// + /// int8x16_t vrsraq_n_s8 (int8x16_t a, int8x16_t b, const int n) + /// A32: VRSRA.S8 Qd, Qm, #n + /// A64: SRSRA Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightArithmeticRoundedAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightArithmeticRoundedAdd(addend, value, count); + + /// + /// int64x1_t vrsra_n_s64 (int64x1_t a, int64x1_t b, const int n) + /// A32: VRSRA.S64 Dd, Dm, #n + /// A64: SRSRA Dd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedAddScalar(Vector64 addend, Vector64 value, byte count) => ShiftRightArithmeticRoundedAddScalar(addend, value, count); + + /// + /// int16x4_t vqrshrn_n_s32 (int32x4_t a, const int n) + /// A32: VQRSHRN.S32 Dd, Qm, #n + /// A64: SQRSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateLower(value, count); + + /// + /// int32x2_t vqrshrn_n_s64 (int64x2_t a, const int n) + /// A32: VQRSHRN.S64 Dd, Qm, #n + /// A64: SQRSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateLower(value, count); + + /// + /// int8x8_t vqrshrn_n_s16 (int16x8_t a, const int n) + /// A32: VQRSHRN.S16 Dd, Qm, #n + /// A64: SQRSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateLower(value, count); + + /// + /// uint8x8_t vqrshrun_n_s16 (int16x8_t a, const int n) + /// A32: VQRSHRUN.S16 Dd, Qm, #n + /// A64: SQRSHRUN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(Vector128 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(value, count); + + /// + /// uint16x4_t vqrshrun_n_s32 (int32x4_t a, const int n) + /// A32: VQRSHRUN.S32 Dd, Qm, #n + /// A64: SQRSHRUN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(Vector128 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(value, count); + + /// + /// uint32x2_t vqrshrun_n_s64 (int64x2_t a, const int n) + /// A32: VQRSHRUN.S64 Dd, Qm, #n + /// A64: SQRSHRUN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(Vector128 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(value, count); + + /// + /// uint8x16_t vqrshrun_high_n_s16 (uint8x8_t r, int16x8_t a, const int n) + /// A32: VQRSHRUN.S16 Dd+1, Dn, #n + /// A64: SQRSHRUN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(lower, value, count); + + /// + /// uint16x8_t vqrshrun_high_n_s32 (uint16x4_t r, int32x4_t a, const int n) + /// A32: VQRSHRUN.S32 Dd+1, Dn, #n + /// A64: SQRSHRUN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(lower, value, count); + + /// + /// uint32x4_t vqrshrun_high_n_s64 (uint32x2_t r, int64x2_t a, const int n) + /// A32: VQRSHRUN.S64 Dd+1, Dn, #n + /// A64: SQRSHRUN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(lower, value, count); + + /// + /// int16x8_t vqrshrn_high_n_s32 (int16x4_t r, int32x4_t a, const int n) + /// A32: VQRSHRN.S32 Dd+1, Dn, #n + /// A64: SQRSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateUpper(lower, value, count); + + /// + /// int32x4_t vqrshrn_high_n_s64 (int32x2_t r, int64x2_t a, const int n) + /// A32: VQRSHRN.S64 Dd+1, Dn, #n + /// A64: SQRSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateUpper(lower, value, count); + + /// + /// int8x16_t vqrshrn_high_n_s16 (int8x8_t r, int16x8_t a, const int n) + /// A32: VQRSHRN.S16 Dd+1, Dn, #n + /// A64: SQRSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightArithmeticRoundedNarrowingSaturateUpper(lower, value, count); + + /// + /// int64x1_t vrshr_n_s64 (int64x1_t a, const int n) + /// A32: VRSHR.S64 Dd, Dm, #n + /// A64: SRSHR Dd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticRoundedScalar(Vector64 value, byte count) => ShiftRightArithmeticRoundedScalar(value, count); + + /// + /// int64x1_t vshr_n_s64 (int64x1_t a, const int n) + /// A32: VSHR.S64 Dd, Dm, #n + /// A64: SSHR Dd, Dn, #n + /// + public static Vector64 ShiftRightArithmeticScalar(Vector64 value, byte count) => ShiftRightArithmeticScalar(value, count); + + /// + /// uint8x8_t vshr_n_u8 (uint8x8_t a, const int n) + /// A32: VSHR.U8 Dd, Dm, #n + /// A64: USHR Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogical(Vector64 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint16x4_t vshr_n_u16 (uint16x4_t a, const int n) + /// A32: VSHR.U16 Dd, Dm, #n + /// A64: USHR Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogical(Vector64 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint32x2_t vshr_n_u32 (uint32x2_t a, const int n) + /// A32: VSHR.U32 Dd, Dm, #n + /// A64: USHR Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogical(Vector64 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint8x8_t vshr_n_u8 (uint8x8_t a, const int n) + /// A32: VSHR.U8 Dd, Dm, #n + /// A64: USHR Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogical(Vector64 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint16x4_t vshr_n_u16 (uint16x4_t a, const int n) + /// A32: VSHR.U16 Dd, Dm, #n + /// A64: USHR Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogical(Vector64 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint32x2_t vshr_n_u32 (uint32x2_t a, const int n) + /// A32: VSHR.U32 Dd, Dm, #n + /// A64: USHR Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogical(Vector64 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint8x16_t vshrq_n_u8 (uint8x16_t a, const int n) + /// A32: VSHR.U8 Qd, Qm, #n + /// A64: USHR Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint16x8_t vshrq_n_u16 (uint16x8_t a, const int n) + /// A32: VSHR.U16 Qd, Qm, #n + /// A64: USHR Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint32x4_t vshrq_n_u32 (uint32x4_t a, const int n) + /// A32: VSHR.U32 Qd, Qm, #n + /// A64: USHR Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint64x2_t vshrq_n_u64 (uint64x2_t a, const int n) + /// A32: VSHR.U64 Qd, Qm, #n + /// A64: USHR Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint8x16_t vshrq_n_u8 (uint8x16_t a, const int n) + /// A32: VSHR.U8 Qd, Qm, #n + /// A64: USHR Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint16x8_t vshrq_n_u16 (uint16x8_t a, const int n) + /// A32: VSHR.U16 Qd, Qm, #n + /// A64: USHR Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint32x4_t vshrq_n_u32 (uint32x4_t a, const int n) + /// A32: VSHR.U32 Qd, Qm, #n + /// A64: USHR Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint64x2_t vshrq_n_u64 (uint64x2_t a, const int n) + /// A32: VSHR.U64 Qd, Qm, #n + /// A64: USHR Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogical(Vector128 value, byte count) => ShiftRightLogical(value, count); + + /// + /// uint8x8_t vsra_n_u8 (uint8x8_t a, uint8x8_t b, const int n) + /// A32: VSRA.U8 Dd, Dm, #n + /// A64: USRA Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogicalAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint16x4_t vsra_n_u16 (uint16x4_t a, uint16x4_t b, const int n) + /// A32: VSRA.U16 Dd, Dm, #n + /// A64: USRA Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogicalAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint32x2_t vsra_n_u32 (uint32x2_t a, uint32x2_t b, const int n) + /// A32: VSRA.U32 Dd, Dm, #n + /// A64: USRA Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogicalAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint8x8_t vsra_n_u8 (uint8x8_t a, uint8x8_t b, const int n) + /// A32: VSRA.U8 Dd, Dm, #n + /// A64: USRA Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogicalAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint16x4_t vsra_n_u16 (uint16x4_t a, uint16x4_t b, const int n) + /// A32: VSRA.U16 Dd, Dm, #n + /// A64: USRA Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogicalAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint32x2_t vsra_n_u32 (uint32x2_t a, uint32x2_t b, const int n) + /// A32: VSRA.U32 Dd, Dm, #n + /// A64: USRA Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogicalAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint8x16_t vsraq_n_u8 (uint8x16_t a, uint8x16_t b, const int n) + /// A32: VSRA.U8 Qd, Qm, #n + /// A64: USRA Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint16x8_t vsraq_n_u16 (uint16x8_t a, uint16x8_t b, const int n) + /// A32: VSRA.U16 Qd, Qm, #n + /// A64: USRA Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint32x4_t vsraq_n_u32 (uint32x4_t a, uint32x4_t b, const int n) + /// A32: VSRA.U32 Qd, Qm, #n + /// A64: USRA Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint64x2_t vsraq_n_u64 (uint64x2_t a, uint64x2_t b, const int n) + /// A32: VSRA.U64 Qd, Qm, #n + /// A64: USRA Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint8x16_t vsraq_n_u8 (uint8x16_t a, uint8x16_t b, const int n) + /// A32: VSRA.U8 Qd, Qm, #n + /// A64: USRA Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint16x8_t vsraq_n_u16 (uint16x8_t a, uint16x8_t b, const int n) + /// A32: VSRA.U16 Qd, Qm, #n + /// A64: USRA Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint32x4_t vsraq_n_u32 (uint32x4_t a, uint32x4_t b, const int n) + /// A32: VSRA.U32 Qd, Qm, #n + /// A64: USRA Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint64x2_t vsraq_n_u64 (uint64x2_t a, uint64x2_t b, const int n) + /// A32: VSRA.U64 Qd, Qm, #n + /// A64: USRA Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalAdd(addend, value, count); + + /// + /// uint64x1_t vsra_n_u64 (uint64x1_t a, uint64x1_t b, const int n) + /// A32: VSRA.U64 Dd, Dm, #n + /// A64: USRA Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalAddScalar(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalAddScalar(addend, value, count); + + /// + /// uint64x1_t vsra_n_u64 (uint64x1_t a, uint64x1_t b, const int n) + /// A32: VSRA.U64 Dd, Dm, #n + /// A64: USRA Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalAddScalar(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalAddScalar(addend, value, count); + + /// + /// uint8x8_t vshrn_n_u16 (uint16x8_t a, const int n) + /// A32: VSHRN.I16 Dd, Qm, #n + /// A64: SHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalNarrowingLower(Vector128 value, byte count) => ShiftRightLogicalNarrowingLower(value, count); + + /// + /// int16x4_t vshrn_n_s32 (int32x4_t a, const int n) + /// A32: VSHRN.I32 Dd, Qm, #n + /// A64: SHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalNarrowingLower(Vector128 value, byte count) => ShiftRightLogicalNarrowingLower(value, count); + + /// + /// int32x2_t vshrn_n_s64 (int64x2_t a, const int n) + /// A32: VSHRN.I64 Dd, Qm, #n + /// A64: SHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalNarrowingLower(Vector128 value, byte count) => ShiftRightLogicalNarrowingLower(value, count); + + /// + /// int8x8_t vshrn_n_s16 (int16x8_t a, const int n) + /// A32: VSHRN.I16 Dd, Qm, #n + /// A64: SHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalNarrowingLower(Vector128 value, byte count) => ShiftRightLogicalNarrowingLower(value, count); + + /// + /// uint16x4_t vshrn_n_u32 (uint32x4_t a, const int n) + /// A32: VSHRN.I32 Dd, Qm, #n + /// A64: SHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalNarrowingLower(Vector128 value, byte count) => ShiftRightLogicalNarrowingLower(value, count); + + /// + /// uint32x2_t vshrn_n_u64 (uint64x2_t a, const int n) + /// A32: VSHRN.I64 Dd, Qm, #n + /// A64: SHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalNarrowingLower(Vector128 value, byte count) => ShiftRightLogicalNarrowingLower(value, count); + + /// + /// uint8x8_t vqshrn_n_u16 (uint16x8_t a, const int n) + /// A32: VQSHRN.U16 Dd, Qm, #n + /// A64: UQSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightLogicalNarrowingSaturateLower(value, count); + + /// + /// uint16x4_t vqshrn_n_u32 (uint32x4_t a, const int n) + /// A32: VQSHRN.U32 Dd, Qm, #n + /// A64: UQSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightLogicalNarrowingSaturateLower(value, count); + + /// + /// uint32x2_t vqshrn_n_u64 (uint64x2_t a, const int n) + /// A32: VQSHRN.U64 Dd, Qm, #n + /// A64: UQSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightLogicalNarrowingSaturateLower(value, count); + + /// + /// uint8x8_t vqshrn_n_u16 (uint16x8_t a, const int n) + /// A32: VQSHRN.U16 Dd, Qm, #n + /// A64: UQSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightLogicalNarrowingSaturateLower(value, count); + + /// + /// uint16x4_t vqshrn_n_u32 (uint32x4_t a, const int n) + /// A32: VQSHRN.U32 Dd, Qm, #n + /// A64: UQSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightLogicalNarrowingSaturateLower(value, count); + + /// + /// uint32x2_t vqshrn_n_u64 (uint64x2_t a, const int n) + /// A32: VQSHRN.U64 Dd, Qm, #n + /// A64: UQSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightLogicalNarrowingSaturateLower(value, count); + + /// + /// uint8x16_t vqshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n) + /// A32: VQSHRN.U16 Dd+1, Qm, #n + /// A64: UQSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalNarrowingSaturateUpper(lower, value, count); + + /// + /// uint16x8_t vqshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n) + /// A32: VQSHRN.U32 Dd+1, Qm, #n + /// A64: UQSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalNarrowingSaturateUpper(lower, value, count); + + /// + /// uint32x4_t vqshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n) + /// A32: VQSHRN.U64 Dd+1, Qm, #n + /// A64: UQSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalNarrowingSaturateUpper(lower, value, count); + + /// + /// uint8x16_t vqshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n) + /// A32: VQSHRN.U16 Dd+1, Qm, #n + /// A64: UQSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalNarrowingSaturateUpper(lower, value, count); + + /// + /// uint16x8_t vqshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n) + /// A32: VQSHRN.U32 Dd+1, Qm, #n + /// A64: UQSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalNarrowingSaturateUpper(lower, value, count); + + /// + /// uint32x4_t vqshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n) + /// A32: VQSHRN.U64 Dd+1, Qm, #n + /// A64: UQSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalNarrowingSaturateUpper(lower, value, count); + + /// + /// uint8x16_t vshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n) + /// A32: VSHRN.I16 Dd+1, Qm, #n + /// A64: SHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalNarrowingUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalNarrowingUpper(lower, value, count); + + /// + /// int16x8_t vshrn_high_n_s32 (int16x4_t r, int32x4_t a, const int n) + /// A32: VSHRN.I32 Dd+1, Qm, #n + /// A64: SHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalNarrowingUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalNarrowingUpper(lower, value, count); + + /// + /// int32x4_t vshrn_high_n_s64 (int32x2_t r, int64x2_t a, const int n) + /// A32: VSHRN.I64 Dd+1, Qm, #n + /// A64: SHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalNarrowingUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalNarrowingUpper(lower, value, count); + + /// + /// int8x16_t vshrn_high_n_s16 (int8x8_t r, int16x8_t a, const int n) + /// A32: VSHRN.I16 Dd+1, Qm, #n + /// A64: SHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalNarrowingUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalNarrowingUpper(lower, value, count); + + /// + /// uint16x8_t vshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n) + /// A32: VSHRN.I32 Dd+1, Qm, #n + /// A64: SHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalNarrowingUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalNarrowingUpper(lower, value, count); + + /// + /// uint32x4_t vshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n) + /// A32: VSHRN.I64 Dd+1, Qm, #n + /// A64: SHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalNarrowingUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalNarrowingUpper(lower, value, count); + + /// + /// uint8x8_t vrshr_n_u8 (uint8x8_t a, const int n) + /// A32: VRSHR.U8 Dd, Dm, #n + /// A64: URSHR Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogicalRounded(Vector64 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint16x4_t vrshr_n_u16 (uint16x4_t a, const int n) + /// A32: VRSHR.U16 Dd, Dm, #n + /// A64: URSHR Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogicalRounded(Vector64 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint32x2_t vrshr_n_u32 (uint32x2_t a, const int n) + /// A32: VRSHR.U32 Dd, Dm, #n + /// A64: URSHR Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogicalRounded(Vector64 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint8x8_t vrshr_n_u8 (uint8x8_t a, const int n) + /// A32: VRSHR.U8 Dd, Dm, #n + /// A64: URSHR Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogicalRounded(Vector64 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint16x4_t vrshr_n_u16 (uint16x4_t a, const int n) + /// A32: VRSHR.U16 Dd, Dm, #n + /// A64: URSHR Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogicalRounded(Vector64 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint32x2_t vrshr_n_u32 (uint32x2_t a, const int n) + /// A32: VRSHR.U32 Dd, Dm, #n + /// A64: URSHR Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogicalRounded(Vector64 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint8x16_t vrshrq_n_u8 (uint8x16_t a, const int n) + /// A32: VRSHR.U8 Qd, Qm, #n + /// A64: URSHR Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint16x8_t vrshrq_n_u16 (uint16x8_t a, const int n) + /// A32: VRSHR.U16 Qd, Qm, #n + /// A64: URSHR Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint32x4_t vrshrq_n_u32 (uint32x4_t a, const int n) + /// A32: VRSHR.U32 Qd, Qm, #n + /// A64: URSHR Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint64x2_t vrshrq_n_u64 (uint64x2_t a, const int n) + /// A32: VRSHR.U64 Qd, Qm, #n + /// A64: URSHR Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint8x16_t vrshrq_n_u8 (uint8x16_t a, const int n) + /// A32: VRSHR.U8 Qd, Qm, #n + /// A64: URSHR Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint16x8_t vrshrq_n_u16 (uint16x8_t a, const int n) + /// A32: VRSHR.U16 Qd, Qm, #n + /// A64: URSHR Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint32x4_t vrshrq_n_u32 (uint32x4_t a, const int n) + /// A32: VRSHR.U32 Qd, Qm, #n + /// A64: URSHR Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint64x2_t vrshrq_n_u64 (uint64x2_t a, const int n) + /// A32: VRSHR.U64 Qd, Qm, #n + /// A64: URSHR Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRounded(Vector128 value, byte count) => ShiftRightLogicalRounded(value, count); + + /// + /// uint8x8_t vrsra_n_u8 (uint8x8_t a, uint8x8_t b, const int n) + /// A32: VRSRA.U8 Dd, Dm, #n + /// A64: URSRA Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogicalRoundedAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint16x4_t vrsra_n_u16 (uint16x4_t a, uint16x4_t b, const int n) + /// A32: VRSRA.U16 Dd, Dm, #n + /// A64: URSRA Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogicalRoundedAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint32x2_t vrsra_n_u32 (uint32x2_t a, uint32x2_t b, const int n) + /// A32: VRSRA.U32 Dd, Dm, #n + /// A64: URSRA Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogicalRoundedAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint8x8_t vrsra_n_u8 (uint8x8_t a, uint8x8_t b, const int n) + /// A32: VRSRA.U8 Dd, Dm, #n + /// A64: URSRA Vd.8B, Vn.8B, #n + /// + public static Vector64 ShiftRightLogicalRoundedAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint16x4_t vrsra_n_u16 (uint16x4_t a, uint16x4_t b, const int n) + /// A32: VRSRA.U16 Dd, Dm, #n + /// A64: URSRA Vd.4H, Vn.4H, #n + /// + public static Vector64 ShiftRightLogicalRoundedAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint32x2_t vrsra_n_u32 (uint32x2_t a, uint32x2_t b, const int n) + /// A32: VRSRA.U32 Dd, Dm, #n + /// A64: URSRA Vd.2S, Vn.2S, #n + /// + public static Vector64 ShiftRightLogicalRoundedAdd(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint8x16_t vrsraq_n_u8 (uint8x16_t a, uint8x16_t b, const int n) + /// A32: VRSRA.U8 Qd, Qm, #n + /// A64: URSRA Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint16x8_t vrsraq_n_u16 (uint16x8_t a, uint16x8_t b, const int n) + /// A32: VRSRA.U16 Qd, Qm, #n + /// A64: URSRA Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint32x4_t vrsraq_n_u32 (uint32x4_t a, uint32x4_t b, const int n) + /// A32: VRSRA.U32 Qd, Qm, #n + /// A64: URSRA Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint64x2_t vrsraq_n_u64 (uint64x2_t a, uint64x2_t b, const int n) + /// A32: VRSRA.U64 Qd, Qm, #n + /// A64: URSRA Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint8x16_t vrsraq_n_u8 (uint8x16_t a, uint8x16_t b, const int n) + /// A32: VRSRA.U8 Qd, Qm, #n + /// A64: URSRA Vd.16B, Vn.16B, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint16x8_t vrsraq_n_u16 (uint16x8_t a, uint16x8_t b, const int n) + /// A32: VRSRA.U16 Qd, Qm, #n + /// A64: URSRA Vd.8H, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint32x4_t vrsraq_n_u32 (uint32x4_t a, uint32x4_t b, const int n) + /// A32: VRSRA.U32 Qd, Qm, #n + /// A64: URSRA Vd.4S, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint64x2_t vrsraq_n_u64 (uint64x2_t a, uint64x2_t b, const int n) + /// A32: VRSRA.U64 Qd, Qm, #n + /// A64: URSRA Vd.2D, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRoundedAdd(Vector128 addend, Vector128 value, byte count) => ShiftRightLogicalRoundedAdd(addend, value, count); + + /// + /// uint64x1_t vrsra_n_u64 (uint64x1_t a, uint64x1_t b, const int n) + /// A32: VRSRA.U64 Dd, Dm, #n + /// A64: URSRA Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalRoundedAddScalar(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalRoundedAddScalar(addend, value, count); + + /// + /// uint64x1_t vrsra_n_u64 (uint64x1_t a, uint64x1_t b, const int n) + /// A32: VRSRA.U64 Dd, Dm, #n + /// A64: URSRA Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalRoundedAddScalar(Vector64 addend, Vector64 value, byte count) => ShiftRightLogicalRoundedAddScalar(addend, value, count); + + /// + /// uint8x8_t vrshrn_n_u16 (uint16x8_t a, const int n) + /// A32: VRSHRN.I16 Dd, Qm, #n + /// A64: RSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingLower(Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingLower(value, count); + + /// + /// int16x4_t vrshrn_n_s32 (int32x4_t a, const int n) + /// A32: VRSHRN.I32 Dd, Qm, #n + /// A64: RSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingLower(Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingLower(value, count); + + /// + /// int32x2_t vrshrn_n_s64 (int64x2_t a, const int n) + /// A32: VRSHRN.I64 Dd, Qm, #n + /// A64: RSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingLower(Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingLower(value, count); + + /// + /// int8x8_t vrshrn_n_s16 (int16x8_t a, const int n) + /// A32: VRSHRN.I16 Dd, Qm, #n + /// A64: RSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingLower(Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingLower(value, count); + + /// + /// uint16x4_t vrshrn_n_u32 (uint32x4_t a, const int n) + /// A32: VRSHRN.I32 Dd, Qm, #n + /// A64: RSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingLower(Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingLower(value, count); + + /// + /// uint32x2_t vrshrn_n_u64 (uint64x2_t a, const int n) + /// A32: VRSHRN.I64 Dd, Qm, #n + /// A64: RSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingLower(Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingLower(value, count); + + /// + /// uint8x8_t vqrshrn_n_u16 (uint16x8_t a, const int n) + /// A32: VQRSHRN.U16 Dd, Qm, #n + /// A64: UQRSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateLower(value, count); + + /// + /// uint16x4_t vqrshrn_n_u32 (uint32x4_t a, const int n) + /// A32: VQRSHRN.U32 Dd, Qm, #n + /// A64: UQRSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateLower(value, count); + + /// + /// uint32x2_t vqrshrn_n_u64 (uint64x2_t a, const int n) + /// A32: VQRSHRN.U64 Dd, Qm, #n + /// A64: UQRSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateLower(value, count); + + /// + /// uint8x8_t vqrshrn_n_u16 (uint16x8_t a, const int n) + /// A32: VQRSHRN.U16 Dd, Qm, #n + /// A64: UQRSHRN Vd.8B, Vn.8H, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateLower(value, count); + + /// + /// uint16x4_t vqrshrn_n_u32 (uint32x4_t a, const int n) + /// A32: VQRSHRN.U32 Dd, Qm, #n + /// A64: UQRSHRN Vd.4H, Vn.4S, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateLower(value, count); + + /// + /// uint32x2_t vqrshrn_n_u64 (uint64x2_t a, const int n) + /// A32: VQRSHRN.U64 Dd, Qm, #n + /// A64: UQRSHRN Vd.2S, Vn.2D, #n + /// + public static Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateLower(value, count); + + /// + /// uint8x16_t vqrshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n) + /// A32: VQRSHRN.U16 Dd+1, Dn, #n + /// A64: UQRSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateUpper(lower, value, count); + + /// + /// uint16x8_t vqrshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n) + /// A32: VQRSHRN.U32 Dd+1, Dn, #n + /// A64: UQRSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateUpper(lower, value, count); + + /// + /// uint32x4_t vqrshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n) + /// A32: VQRSHRN.U64 Dd+1, Dn, #n + /// A64: UQRSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateUpper(lower, value, count); + + /// + /// uint8x16_t vqrshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n) + /// A32: VQRSHRN.U16 Dd+1, Dn, #n + /// A64: UQRSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateUpper(lower, value, count); + + /// + /// uint16x8_t vqrshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n) + /// A32: VQRSHRN.U32 Dd+1, Dn, #n + /// A64: UQRSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateUpper(lower, value, count); + + /// + /// uint32x4_t vqrshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n) + /// A32: VQRSHRN.U64 Dd+1, Dn, #n + /// A64: UQRSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingSaturateUpper(lower, value, count); + + /// + /// uint8x16_t vrshrn_high_n_u16 (uint8x8_t r, uint16x8_t a, const int n) + /// A32: VRSHRN.I16 Dd+1, Qm, #n + /// A64: RSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingUpper(lower, value, count); + + /// + /// int16x8_t vrshrn_high_n_s32 (int16x4_t r, int32x4_t a, const int n) + /// A32: VRSHRN.I32 Dd+1, Qm, #n + /// A64: RSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingUpper(lower, value, count); + + /// + /// int32x4_t vrshrn_high_n_s64 (int32x2_t r, int64x2_t a, const int n) + /// A32: VRSHRN.I64 Dd+1, Qm, #n + /// A64: RSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingUpper(lower, value, count); + + /// + /// int8x16_t vrshrn_high_n_s16 (int8x8_t r, int16x8_t a, const int n) + /// A32: VRSHRN.I16 Dd+1, Qm, #n + /// A64: RSHRN2 Vd.16B, Vn.8H, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingUpper(lower, value, count); + + /// + /// uint16x8_t vrshrn_high_n_u32 (uint16x4_t r, uint32x4_t a, const int n) + /// A32: VRSHRN.I32 Dd+1, Qm, #n + /// A64: RSHRN2 Vd.8H, Vn.4S, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingUpper(lower, value, count); + + /// + /// uint32x4_t vrshrn_high_n_u64 (uint32x2_t r, uint64x2_t a, const int n) + /// A32: VRSHRN.I64 Dd+1, Qm, #n + /// A64: RSHRN2 Vd.4S, Vn.2D, #n + /// + public static Vector128 ShiftRightLogicalRoundedNarrowingUpper(Vector64 lower, Vector128 value, byte count) => ShiftRightLogicalRoundedNarrowingUpper(lower, value, count); + + /// + /// uint64x1_t vrshr_n_u64 (uint64x1_t a, const int n) + /// A32: VRSHR.U64 Dd, Dm, #n + /// A64: URSHR Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalRoundedScalar(Vector64 value, byte count) => ShiftRightLogicalRoundedScalar(value, count); + + /// + /// uint64x1_t vrshr_n_u64 (uint64x1_t a, const int n) + /// A32: VRSHR.U64 Dd, Dm, #n + /// A64: URSHR Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalRoundedScalar(Vector64 value, byte count) => ShiftRightLogicalRoundedScalar(value, count); + + /// + /// uint64x1_t vshr_n_u64 (uint64x1_t a, const int n) + /// A32: VSHR.U64 Dd, Dm, #n + /// A64: USHR Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalScalar(Vector64 value, byte count) => ShiftRightLogicalScalar(value, count); + + /// + /// uint64x1_t vshr_n_u64 (uint64x1_t a, const int n) + /// A32: VSHR.U64 Dd, Dm, #n + /// A64: USHR Dd, Dn, #n + /// + public static Vector64 ShiftRightLogicalScalar(Vector64 value, byte count) => ShiftRightLogicalScalar(value, count); + + /// + /// int32x4_t vmovl_s16 (int16x4_t a) + /// A32: VMOVL.S16 Qd, Dm + /// A64: SXTL Vd.4S, Vn.4H + /// + public static Vector128 SignExtendWideningLower(Vector64 value) => SignExtendWideningLower(value); + + /// + /// int64x2_t vmovl_s32 (int32x2_t a) + /// A32: VMOVL.S32 Qd, Dm + /// A64: SXTL Vd.2D, Vn.2S + /// + public static Vector128 SignExtendWideningLower(Vector64 value) => SignExtendWideningLower(value); + + /// + /// int16x8_t vmovl_s8 (int8x8_t a) + /// A32: VMOVL.S8 Qd, Dm + /// A64: SXTL Vd.8H, Vn.8B + /// + public static Vector128 SignExtendWideningLower(Vector64 value) => SignExtendWideningLower(value); + + /// + /// int32x4_t vmovl_high_s16 (int16x8_t a) + /// A32: VMOVL.S16 Qd, Dm+1 + /// A64: SXTL2 Vd.4S, Vn.8H + /// + public static Vector128 SignExtendWideningUpper(Vector128 value) => SignExtendWideningUpper(value); + + /// + /// int64x2_t vmovl_high_s32 (int32x4_t a) + /// A32: VMOVL.S32 Qd, Dm+1 + /// A64: SXTL2 Vd.2D, Vn.4S + /// + public static Vector128 SignExtendWideningUpper(Vector128 value) => SignExtendWideningUpper(value); + + /// + /// int16x8_t vmovl_high_s8 (int8x16_t a) + /// A32: VMOVL.S8 Qd, Dm+1 + /// A64: SXTL2 Vd.8H, Vn.16B + /// + public static Vector128 SignExtendWideningUpper(Vector128 value) => SignExtendWideningUpper(value); + + /// + /// float64x1_t vsqrt_f64 (float64x1_t a) + /// A32: VSQRT.F64 Dd, Dm + /// A64: FSQRT Dd, Dn + /// + public static Vector64 SqrtScalar(Vector64 value) => SqrtScalar(value); + + /// + /// float32_t vsqrts_f32 (float32_t a) + /// A32: VSQRT.F32 Sd, Sm + /// A64: FSQRT Sd, Sn + /// The above native signature does not exist. We provide this additional overload for consistency with the other scalar APIs. + /// + public static Vector64 SqrtScalar(Vector64 value) => SqrtScalar(value); + + /// + /// void vst1_u8 (uint8_t * ptr, uint8x8_t val) + /// A32: VST1.8 { Dd }, [Rn] + /// A64: ST1 { Vt.8B }, [Xn] + /// + public static unsafe void Store(byte* address, Vector64 source) => Store(address, source); + + /// + /// void vst1_f64 (float64_t * ptr, float64x1_t val) + /// A32: VST1.64 { Dd }, [Rn] + /// A64: ST1 { Vt.1D }, [Xn] + /// + public static unsafe void Store(double* address, Vector64 source) => Store(address, source); + + /// + /// void vst1_s16 (int16_t * ptr, int16x4_t val) + /// A32: VST1.16 { Dd }, [Rn] + /// A64: ST1 {Vt.4H }, [Xn] + /// + public static unsafe void Store(short* address, Vector64 source) => Store(address, source); + + /// + /// void vst1_s32 (int32_t * ptr, int32x2_t val) + /// A32: VST1.32 { Dd }, [Rn] + /// A64: ST1 { Vt.2S }, [Xn] + /// + public static unsafe void Store(int* address, Vector64 source) => Store(address, source); + + /// + /// void vst1_s64 (int64_t * ptr, int64x1_t val) + /// A32: VST1.64 { Dd }, [Rn] + /// A64: ST1 { Vt.1D }, [Xn] + /// + public static unsafe void Store(long* address, Vector64 source) => Store(address, source); + + /// + /// void vst1_s8 (int8_t * ptr, int8x8_t val) + /// A32: VST1.8 { Dd }, [Rn] + /// A64: ST1 { Vt.8B }, [Xn] + /// + public static unsafe void Store(sbyte* address, Vector64 source) => Store(address, source); + + /// + /// void vst1_f32 (float32_t * ptr, float32x2_t val) + /// A32: VST1.32 { Dd }, [Rn] + /// A64: ST1 { Vt.2S }, [Xn] + /// + public static unsafe void Store(float* address, Vector64 source) => Store(address, source); + + /// + /// void vst1_u16 (uint16_t * ptr, uint16x4_t val) + /// A32: VST1.16 { Dd }, [Rn] + /// A64: ST1 { Vt.4H }, [Xn] + /// + public static unsafe void Store(ushort* address, Vector64 source) => Store(address, source); + + /// + /// void vst1_u32 (uint32_t * ptr, uint32x2_t val) + /// A32: VST1.32 { Dd }, [Rn] + /// A64: ST1 { Vt.2S }, [Xn] + /// + public static unsafe void Store(uint* address, Vector64 source) => Store(address, source); + + /// + /// void vst1_u64 (uint64_t * ptr, uint64x1_t val) + /// A32: VST1.64 { Dd }, [Rn] + /// A64: ST1 { Vt.1D }, [Xn] + /// + public static unsafe void Store(ulong* address, Vector64 source) => Store(address, source); + + /// + /// void vst1q_u8 (uint8_t * ptr, uint8x16_t val) + /// A32: VST1.8 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.16B }, [Xn] + /// + public static unsafe void Store(byte* address, Vector128 source) => Store(address, source); + + /// + /// void vst1q_f64 (float64_t * ptr, float64x2_t val) + /// A32: VST1.64 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.2D }, [Xn] + /// + public static unsafe void Store(double* address, Vector128 source) => Store(address, source); + + /// + /// void vst1q_s16 (int16_t * ptr, int16x8_t val) + /// A32: VST1.16 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.8H }, [Xn] + /// + public static unsafe void Store(short* address, Vector128 source) => Store(address, source); + + /// + /// void vst1q_s32 (int32_t * ptr, int32x4_t val) + /// A32: VST1.32 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.4S }, [Xn] + /// + public static unsafe void Store(int* address, Vector128 source) => Store(address, source); + + /// + /// void vst1q_s64 (int64_t * ptr, int64x2_t val) + /// A32: VST1.64 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.2D }, [Xn] + /// + public static unsafe void Store(long* address, Vector128 source) => Store(address, source); + + /// + /// void vst1q_s8 (int8_t * ptr, int8x16_t val) + /// A32: VST1.8 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.16B }, [Xn] + /// + public static unsafe void Store(sbyte* address, Vector128 source) => Store(address, source); + + /// + /// void vst1q_f32 (float32_t * ptr, float32x4_t val) + /// A32: VST1.32 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.4S }, [Xn] + /// + public static unsafe void Store(float* address, Vector128 source) => Store(address, source); + + /// + /// void vst1q_u16 (uint16_t * ptr, uint16x8_t val) + /// A32: VST1.16 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.8H }, [Xn] + /// + public static unsafe void Store(ushort* address, Vector128 source) => Store(address, source); + + /// + /// void vst1q_u32 (uint32_t * ptr, uint32x4_t val) + /// A32: VST1.32 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.4S }, [Xn] + /// + public static unsafe void Store(uint* address, Vector128 source) => Store(address, source); + + /// + /// void vst1q_u64 (uint64_t * ptr, uint64x2_t val) + /// A32: VST1.64 { Dd, Dd+1 }, [Rn] + /// A64: ST1 { Vt.2D }, [Xn] + /// + public static unsafe void Store(ulong* address, Vector128 source) => Store(address, source); + + /// + /// uint8x8_t vsub_u8 (uint8x8_t a, uint8x8_t b) + /// A32: VSUB.I8 Dd, Dn, Dm + /// A64: SUB Vd.8B, Vn.8B, Vm.8B + /// + public static Vector64 Subtract(Vector64 left, Vector64 right) => Subtract(left, right); + + /// + /// int16x4_t vsub_s16 (int16x4_t a, int16x4_t b) + /// A32: VSUB.I16 Dd, Dn, Dm + /// A64: SUB Vd.4H, Vn.4H, Vm.4H + /// + public static Vector64 Subtract(Vector64 left, Vector64 right) => Subtract(left, right); + + /// + /// int32x2_t vsub_s32 (int32x2_t a, int32x2_t b) + /// A32: VSUB.I32 Dd, Dn, Dm + /// A64: SUB Vd.2S, Vn.2S, Vm.2S + /// + public static Vector64 Subtract(Vector64 left, Vector64 right) => Subtract(left, right); + + /// + /// int8x8_t vsub_s8 (int8x8_t a, int8x8_t b) + /// A32: VSUB.I8 Dd, Dn, Dm /// A64: SUB Vd.8B, Vn.8B, Vm.8B /// public static Vector64 Subtract(Vector64 left, Vector64 right) => Subtract(left, right); @@ -8051,5 +10604,89 @@ public new abstract class Arm64 : ArmBase.Arm64 /// A64: EOR Vd.16B, Vn.16B, Vm.16B /// public static Vector128 Xor(Vector128 left, Vector128 right) => Xor(left, right); + + /// + /// uint16x8_t vmovl_u8 (uint8x8_t a) + /// A32: VMOVL.U8 Qd, Dm + /// A64: UXTL Vd.8H, Vn.8B + /// + public static Vector128 ZeroExtendWideningLower(Vector64 value) => ZeroExtendWideningLower(value); + + /// + /// uint32x4_t vmovl_u16 (uint16x4_t a) + /// A32: VMOVL.U16 Qd, Dm + /// A64: UXTL Vd.4S, Vn.4H + /// + public static Vector128 ZeroExtendWideningLower(Vector64 value) => ZeroExtendWideningLower(value); + + /// + /// uint64x2_t vmovl_u32 (uint32x2_t a) + /// A32: VMOVL.U32 Qd, Dm + /// A64: UXTL Vd.2D, Vn.2S + /// + public static Vector128 ZeroExtendWideningLower(Vector64 value) => ZeroExtendWideningLower(value); + + /// + /// uint16x8_t vmovl_u8 (uint8x8_t a) + /// A32: VMOVL.U8 Qd, Dm + /// A64: UXTL Vd.8H, Vn.8B + /// + public static Vector128 ZeroExtendWideningLower(Vector64 value) => ZeroExtendWideningLower(value); + + /// + /// uint32x4_t vmovl_u16 (uint16x4_t a) + /// A32: VMOVL.U16 Qd, Dm + /// A64: UXTL Vd.4S, Vn.4H + /// + public static Vector128 ZeroExtendWideningLower(Vector64 value) => ZeroExtendWideningLower(value); + + /// + /// uint64x2_t vmovl_u32 (uint32x2_t a) + /// A32: VMOVL.U32 Qd, Dm + /// A64: UXTL Vd.2D, Vn.2S + /// + public static Vector128 ZeroExtendWideningLower(Vector64 value) => ZeroExtendWideningLower(value); + + /// + /// uint16x8_t vmovl_high_u8 (uint8x16_t a) + /// A32: VMOVL.U8 Qd, Dm+1 + /// A64: UXTL2 Vd.8H, Vn.16B + /// + public static Vector128 ZeroExtendWideningUpper(Vector128 value) => ZeroExtendWideningUpper(value); + + /// + /// uint32x4_t vmovl_high_u16 (uint16x8_t a) + /// A32: VMOVL.U16 Qd, Dm+1 + /// A64: UXTL2 Vd.4S, Vn.8H + /// + public static Vector128 ZeroExtendWideningUpper(Vector128 value) => ZeroExtendWideningUpper(value); + + /// + /// uint64x2_t vmovl_high_u32 (uint32x4_t a) + /// A32: VMOVL.U32 Qd, Dm+1 + /// A64: UXTL2 Vd.2D, Vn.4S + /// + public static Vector128 ZeroExtendWideningUpper(Vector128 value) => ZeroExtendWideningUpper(value); + + /// + /// uint16x8_t vmovl_high_u8 (uint8x16_t a) + /// A32: VMOVL.U8 Qd, Dm+1 + /// A64: UXTL2 Vd.8H, Vn.16B + /// + public static Vector128 ZeroExtendWideningUpper(Vector128 value) => ZeroExtendWideningUpper(value); + + /// + /// uint32x4_t vmovl_high_u16 (uint16x8_t a) + /// A32: VMOVL.U16 Qd, Dm+1 + /// A64: UXTL2 Vd.4S, Vn.8H + /// + public static Vector128 ZeroExtendWideningUpper(Vector128 value) => ZeroExtendWideningUpper(value); + + /// + /// uint64x2_t vmovl_high_u32 (uint32x4_t a) + /// A32: VMOVL.U32 Qd, Dm+1 + /// A64: UXTL2 Vd.2D, Vn.4S + /// + public static Vector128 ZeroExtendWideningUpper(Vector128 value) => ZeroExtendWideningUpper(value); } } diff --git a/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs b/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs index d404129038d17..68ce7894c11b7 100644 --- a/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs +++ b/src/libraries/System.Runtime.Intrinsics.Experimental/ref/System.Runtime.Intrinsics.Experimental.cs @@ -752,6 +752,327 @@ public abstract partial class AdvSimd : System.Runtime.Intrinsics.Arm.ArmBase public static System.Runtime.Intrinsics.Vector64 ReciprocalSquareRootStep(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 ReciprocalStep(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 ReciprocalStep(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmetic(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmetic(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmetic(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmetic(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmetic(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmetic(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmetic(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmeticRounded(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmeticRounded(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmeticRounded(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmeticRounded(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticRounded(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticRounded(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticRounded(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmeticRoundedSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmeticRoundedSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmeticRoundedSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmeticRoundedSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticRoundedSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticRoundedSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticRoundedSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticRoundedSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticRoundedScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmeticSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmeticSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmeticSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftArithmeticSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogical(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogical(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogical(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogical(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogical(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogical(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturate(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalSaturateUnsigned(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalSaturateUnsigned(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalSaturateUnsigned(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalSaturateUnsigned(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateUnsigned(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateUnsigned(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateUnsigned(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateUnsignedScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalWideningLower(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalWideningLower(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalWideningLower(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalWideningLower(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalWideningLower(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalWideningLower(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalWideningUpper(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalWideningUpper(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalWideningUpper(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalWideningUpper(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalWideningUpper(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLeftLogicalWideningUpper(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogical(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogical(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogical(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogical(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogical(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogical(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogical(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogical(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogical(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogical(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogical(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogical(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogical(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogical(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRounded(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturate(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticAddScalar(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticNarrowingSaturateUnsignedUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticNarrowingSaturateUnsignedUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticNarrowingSaturateUnsignedUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRounded(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRounded(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRounded(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRounded(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRounded(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRounded(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRounded(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRoundedAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRoundedAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRoundedAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRoundedAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedAddScalar(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticRoundedNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogical(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogical(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogical(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogical(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogical(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogical(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogical(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalAddScalar(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalAddScalar(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRounded(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector128 addend, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedAdd(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedAddScalar(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedAddScalar(System.Runtime.Intrinsics.Vector64 addend, System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingSaturateLower(System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedNarrowingSaturateUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalRoundedNarrowingUpper(System.Runtime.Intrinsics.Vector64 lower, System.Runtime.Intrinsics.Vector128 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SignExtendWideningLower(System.Runtime.Intrinsics.Vector64 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SignExtendWideningLower(System.Runtime.Intrinsics.Vector64 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SignExtendWideningLower(System.Runtime.Intrinsics.Vector64 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SignExtendWideningUpper(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SignExtendWideningUpper(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SignExtendWideningUpper(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector64 SqrtScalar(System.Runtime.Intrinsics.Vector64 value) { throw null; } public static System.Runtime.Intrinsics.Vector64 SqrtScalar(System.Runtime.Intrinsics.Vector64 value) { throw null; } public unsafe static void Store(byte* address, System.Runtime.Intrinsics.Vector128 source) { } @@ -882,6 +1203,18 @@ public abstract partial class AdvSimd : System.Runtime.Intrinsics.Arm.ArmBase public static System.Runtime.Intrinsics.Vector64 Xor(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Xor(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Xor(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ZeroExtendWideningLower(System.Runtime.Intrinsics.Vector64 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ZeroExtendWideningLower(System.Runtime.Intrinsics.Vector64 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ZeroExtendWideningLower(System.Runtime.Intrinsics.Vector64 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ZeroExtendWideningLower(System.Runtime.Intrinsics.Vector64 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ZeroExtendWideningLower(System.Runtime.Intrinsics.Vector64 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ZeroExtendWideningLower(System.Runtime.Intrinsics.Vector64 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ZeroExtendWideningUpper(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ZeroExtendWideningUpper(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ZeroExtendWideningUpper(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ZeroExtendWideningUpper(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ZeroExtendWideningUpper(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 ZeroExtendWideningUpper(System.Runtime.Intrinsics.Vector128 value) { throw null; } public new abstract partial class Arm64 : System.Runtime.Intrinsics.Arm.ArmBase.Arm64 { internal Arm64() { } @@ -1076,6 +1409,57 @@ public new abstract partial class Arm64 : System.Runtime.Intrinsics.Arm.ArmBase. public static System.Runtime.Intrinsics.Vector128 ReverseElementBits(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector64 ReverseElementBits(System.Runtime.Intrinsics.Vector64 value) { throw null; } public static System.Runtime.Intrinsics.Vector64 ReverseElementBits(System.Runtime.Intrinsics.Vector64 value) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticRoundedSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticRoundedSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticRoundedSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftArithmeticSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateUnsignedScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateUnsignedScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLeftLogicalSaturateUnsignedScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalRoundedSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftLogicalSaturateScalar(System.Runtime.Intrinsics.Vector64 value, System.Runtime.Intrinsics.Vector64 count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticNarrowingSaturateUnsignedScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightArithmeticRoundedNarrowingSaturateUnsignedScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector64 ShiftRightLogicalRoundedNarrowingSaturateScalar(System.Runtime.Intrinsics.Vector64 value, byte count) { throw null; } public static System.Runtime.Intrinsics.Vector128 Sqrt(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector128 Sqrt(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector64 Sqrt(System.Runtime.Intrinsics.Vector64 value) { throw null; } From 70ac9ae4c6972f603139f5d6b76198e35205163a Mon Sep 17 00:00:00 2001 From: SRV Date: Sat, 23 May 2020 06:48:53 +0300 Subject: [PATCH 359/420] BigMul with 64-bit operands (#35975) * Unsigned 128-bit BigMul * Signed 128-bit BigMul * Added explanation of alg and reference to it * Removed else branch Co-authored-by: Adeel Mujahid --- .../System.Private.CoreLib/src/System/Math.cs | 47 +++++++++++++++++++ .../tests/System/Math.cs | 30 ++++++++++++ .../System.Runtime/ref/System.Runtime.cs | 3 ++ 3 files changed, 80 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.cs b/src/libraries/System.Private.CoreLib/src/System/Math.cs index 9e90ad9ca1176..9e80f5560fcba 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.cs @@ -18,6 +18,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics.X86; using System.Runtime.Versioning; namespace System @@ -113,6 +114,52 @@ public static long BigMul(int a, int b) return ((long)a) * b; } + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe ulong BigMul(ulong a, ulong b, out ulong low) + { + if (Bmi2.X64.IsSupported) + { + ulong tmp; + ulong high = Bmi2.X64.MultiplyNoFlags(a, b, &tmp); + low = tmp; + return high; + } + + return SoftwareFallback(a, b, out low); + + static ulong SoftwareFallback(ulong a, ulong b, out ulong low) + { + // It's adoption of algorithm for multiplication + // of 32-bit unsigned integers described + // in Hacker's Delight by Henry S. Warren, Jr. (ISBN 0-201-91465-4), Chapter 8 + // Basically, it's an optimized version of FOIL method applied to + // low and high dwords of each operand + const ulong lowBitsMask = 0xFFFFFFFFU; + + ulong al = a & lowBitsMask; + ulong ah = a >> 32; + ulong bl = b & lowBitsMask; + ulong bh = b >> 32; + + ulong mull = al * bl; + ulong t = ah * bl + (mull >> 32); + ulong tl = t & lowBitsMask; + + tl += al * bh; + low = tl << 32 | mull & lowBitsMask; + + return ah * bh + (t >> 32) + (tl >> 32); + } + } + + public static long BigMul(long a, long b, out long low) + { + ulong high = BigMul((ulong)a, (ulong)b, out ulong ulow); + low = (long)ulow; + return (long)high - ((a >> 63) & b) - ((b >> 63) & a); + } + public static double BitDecrement(double x) { long bits = BitConverter.DoubleToInt64Bits(x); diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Math.cs b/src/libraries/System.Runtime.Extensions/tests/System/Math.cs index 7614d2b31555e..f3c3bc0777b15 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Math.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Math.cs @@ -1749,6 +1749,36 @@ public static void BigMul() Assert.Equal(0L, Math.BigMul(0, 0)); } + [Theory] + [InlineData(0U, 0U, "00000000000000000000000000000000")] + [InlineData(0U, 1U, "00000000000000000000000000000000")] + [InlineData(1U, 0U, "00000000000000000000000000000000")] + [InlineData(2U, 3U, "00000000000000000000000000000006")] + [InlineData(ulong.MaxValue, 2, "0000000000000001FFFFFFFFFFFFFFFE")] + [InlineData(ulong.MaxValue, 1, "0000000000000000FFFFFFFFFFFFFFFF")] + [InlineData(ulong.MaxValue, ulong.MaxValue, "FFFFFFFFFFFFFFFE0000000000000001")] + [InlineData(ulong.MaxValue, 3, "0000000000000002FFFFFFFFFFFFFFFD")] + public static void BigMul128_Unsigned(ulong a, ulong b, string result) + { + ulong high = Math.BigMul(a, b, out ulong low); + Assert.Equal(result, high.ToString("X16") + low.ToString("X16")); + } + + [Theory] + [InlineData(0L, 0L, "00000000000000000000000000000000")] + [InlineData(0L, 1L, "00000000000000000000000000000000")] + [InlineData(1L, 0L, "00000000000000000000000000000000")] + [InlineData(2L, 3L, "00000000000000000000000000000006")] + [InlineData(3L, -2L, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA")] + [InlineData(-1L, -1L, "00000000000000000000000000000001")] + [InlineData(-1L, long.MinValue, "00000000000000008000000000000000")] + [InlineData(1L, long.MinValue, "FFFFFFFFFFFFFFFF8000000000000000")] + public static void BigMul128_Signed(long a, long b, string result) + { + long high = Math.BigMul(a, b, out long low); + Assert.Equal(result, high.ToString("X16") + low.ToString("X16")); + } + [Theory] [InlineData(1073741, 2147483647, 2000, 1647)] [InlineData(6, 13952, 2000, 1952)] diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index f84784e75b1d4..2aac15f3deca6 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -2548,6 +2548,9 @@ public static partial class Math public static double Atan2(double y, double x) { throw null; } public static double Atanh(double d) { throw null; } public static long BigMul(int a, int b) { throw null; } + [System.CLSCompliantAttribute(false)] + public static ulong BigMul(ulong a, ulong b, out ulong low) { throw null; } + public static long BigMul(long a, long b, out long low) { throw null; } public static double BitDecrement(double x) { throw null; } public static double BitIncrement(double x) { throw null; } public static double Cbrt(double d) { throw null; } From ba728d9fa0ad756bf39e2ed9e5411f871ccec16d Mon Sep 17 00:00:00 2001 From: Clinton Ingram Date: Fri, 22 May 2020 20:50:01 -0700 Subject: [PATCH 360/420] Optimize BitOperations uses in CoreLib (#35650) * make Log2 branch-free * convert LeadingZeroCount uses to Log2 * switch Bmi1.TrailingZeroCount calls to BitOperations --- .../Text/FormattingHelpers.CountDigits.cs | 3 +- .../src/System/Buffers/Utilities.cs | 9 +++- .../src/System/Numerics/BitOperations.cs | 23 ++++------- .../src/System/SpanHelpers.Byte.cs | 26 +----------- .../src/System/SpanHelpers.Char.cs | 26 +----------- .../src/System/Text/ASCIIUtility.Helpers.cs | 41 ++++--------------- .../src/System/Text/ASCIIUtility.cs | 12 +++--- .../Text/Unicode/Utf8Utility.Validation.cs | 5 +-- 8 files changed, 37 insertions(+), 108 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs index 8235339820dfe..eb339b89576d6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs @@ -104,7 +104,8 @@ public static int CountDigits(uint value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountHexDigits(ulong value) { - return (64 - BitOperations.LeadingZeroCount(value | 1) + 3) >> 2; + // The number of hex digits is log16(value) + 1, or log2(value) / 4 + 1 + return (BitOperations.Log2(value) >> 2) + 1; } // Counts the number of trailing '0' digits in a decimal number. diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Utilities.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Utilities.cs index 7e1caa039b36c..9fe7233e16486 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Utilities.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Utilities.cs @@ -14,8 +14,13 @@ internal static class Utilities internal static int SelectBucketIndex(int bufferSize) { Debug.Assert(bufferSize >= 0); - uint bits = ((uint)bufferSize - 1) >> 4; - return 32 - BitOperations.LeadingZeroCount(bits); + + // Buffers are bucketed so that a request between 2^(n-1) + 1 and 2^n is given a buffer of 2^n + // Bucket index is log2(bufferSize - 1) with the exception that buffers between 1 and 16 bytes + // are combined, and the index is slid down by 3 to compensate. + // Zero is a valid bufferSize, and it is assigned the highest bucket index so that zero-length + // buffers are not retained by the pool. The pool will return the Array.Empty singleton for these. + return BitOperations.Log2((uint)bufferSize - 1 | 15) - 3; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs index 0847f377e0c98..28b341633de4e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/BitOperations.cs @@ -123,21 +123,18 @@ public static int LeadingZeroCount(ulong value) /// /// Returns the integer (floor) log of the specified value, base 2. - /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. + /// Note that by convention, input value 0 returns 0 since log(0) is undefined. /// /// The value. [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static int Log2(uint value) { - // Enforce conventional contract 0->0 (Log(0) is undefined) - if (value == 0) - { - return 0; - } + // The 0->0 contract is fulfilled by setting the LSB to 1. + // Log(1) is 0, and setting the LSB for values > 1 does not change the log2 result. + value |= 1; // value lzcnt actual expected - // ..0000 32 0 0 (by convention, guard clause) // ..0001 31 31-31 0 // ..0010 30 31-30 1 // 0010.. 2 31-2 29 @@ -153,8 +150,8 @@ public static int Log2(uint value) return 31 ^ ArmBase.LeadingZeroCount(value); } - // BSR returns the answer we're looking for directly. - // However BSR is much slower than LZCNT on AMD processors, so we leave it as a fallback only. + // BSR returns the log2 result directly. However BSR is slower than LZCNT + // on AMD processors, so we leave it as a fallback only. if (X86Base.IsSupported) { return (int)X86Base.BitScanReverse(value); @@ -166,18 +163,14 @@ public static int Log2(uint value) /// /// Returns the integer (floor) log of the specified value, base 2. - /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. + /// Note that by convention, input value 0 returns 0 since log(0) is undefined. /// /// The value. [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static int Log2(ulong value) { - // Enforce conventional contract 0->0 (Log(0) is undefined) - if (value == 0) - { - return 0; - } + value |= 1; if (Lzcnt.X64.IsSupported) { diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs index c396bb06fe653..5132148ae5832 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs @@ -1733,33 +1733,11 @@ private static int LocateLastFoundByte(Vector match) [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int LocateFirstFoundByte(ulong match) - { - if (Bmi1.X64.IsSupported) - { - return (int)(Bmi1.X64.TrailingZeroCount(match) >> 3); - } - else - { - // Flag least significant power of two bit - ulong powerOfTwoFlag = match ^ (match - 1); - // Shift all powers of two into the high byte and extract - return (int)((powerOfTwoFlag * XorPowerOfTwoToHighByte) >> 57); - } - } + => BitOperations.TrailingZeroCount(match) >> 3; [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int LocateLastFoundByte(ulong match) - { - return 7 - (BitOperations.LeadingZeroCount(match) >> 3); - } - - private const ulong XorPowerOfTwoToHighByte = (0x07ul | - 0x06ul << 8 | - 0x05ul << 16 | - 0x04ul << 24 | - 0x03ul << 32 | - 0x02ul << 40 | - 0x01ul << 48) + 1; + => BitOperations.Log2(match) >> 3; [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ushort LoadUShort(ref byte start) diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs index b3234e4aa77a1..02f0ba9920724 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs @@ -975,27 +975,7 @@ private static int LocateFirstFoundChar(Vector match) [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int LocateFirstFoundChar(ulong match) - { - // TODO: Arm variants - if (Bmi1.X64.IsSupported) - { - return (int)(Bmi1.X64.TrailingZeroCount(match) >> 4); - } - else - { - unchecked - { - // Flag least significant power of two bit - ulong powerOfTwoFlag = match ^ (match - 1); - // Shift all powers of two into the high byte and extract - return (int)((powerOfTwoFlag * XorPowerOfTwoToHighChar) >> 49); - } - } - } - - private const ulong XorPowerOfTwoToHighChar = (0x03ul | - 0x02ul << 16 | - 0x01ul << 32) + 1; + => BitOperations.TrailingZeroCount(match) >> 4; // Vector sub-search adapted from https://github.com/aspnet/KestrelHttpServer/pull/1138 [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1020,9 +1000,7 @@ private static int LocateLastFoundChar(Vector match) [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int LocateLastFoundChar(ulong match) - { - return 3 - (BitOperations.LeadingZeroCount(match) >> 4); - } + => BitOperations.Log2(match) >> 4; [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector LoadVector(ref char start, nint offset) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.Helpers.cs b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.Helpers.cs index 731d52ab822cc..71f984bbd4cfd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.Helpers.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.Helpers.cs @@ -44,44 +44,19 @@ internal static uint CountNumberOfLeadingAsciiBytesFromUInt32WithSomeNonAsciiDat { Debug.Assert(!AllBytesInUInt32AreAscii(value), "Caller shouldn't provide an all-ASCII value."); - // Use BMI1 directly rather than going through BitOperations. We only see a perf gain here - // if we're able to emit a real tzcnt instruction; the software fallback used by BitOperations - // is too slow for our purposes since we can provide our own faster, specialized software fallback. - - if (Bmi1.IsSupported) - { - Debug.Assert(BitConverter.IsLittleEndian); - return Bmi1.TrailingZeroCount(value & UInt32HighBitsOnlyMask) >> 3; - } - - // Couldn't emit tzcnt, use specialized software fallback. - // The 'allBytesUpToNowAreAscii' DWORD uses bit twiddling to hold a 1 or a 0 depending - // on whether all processed bytes were ASCII. Then we accumulate all of the - // results to calculate how many consecutive ASCII bytes are present. - - value = ~value; - if (BitConverter.IsLittleEndian) { - // Read first byte - value >>= 7; - uint allBytesUpToNowAreAscii = value & 1; - uint numAsciiBytes = allBytesUpToNowAreAscii; - - // Read second byte - value >>= 8; - allBytesUpToNowAreAscii &= value; - numAsciiBytes += allBytesUpToNowAreAscii; - - // Read third byte - value >>= 8; - allBytesUpToNowAreAscii &= value; - numAsciiBytes += allBytesUpToNowAreAscii; - - return numAsciiBytes; + return (uint)BitOperations.TrailingZeroCount(value & UInt32HighBitsOnlyMask) >> 3; } else { + // Couldn't use tzcnt, use specialized software fallback. + // The 'allBytesUpToNowAreAscii' DWORD uses bit twiddling to hold a 1 or a 0 depending + // on whether all processed bytes were ASCII. Then we accumulate all of the + // results to calculate how many consecutive ASCII bytes are present. + + value = ~value; + // BinaryPrimitives.ReverseEndianness is only implemented as an intrinsic on // little-endian platforms, so using it in this big-endian path would be too // expensive. Instead we'll just change how we perform the shifts. diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs index 31de76bfd0c9a..57492533d199a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs @@ -388,7 +388,7 @@ private static unsafe nuint GetIndexOfFirstNonAsciiByte_Sse2(byte* pBuffer, nuin if ((bufferLength & 8) != 0) { - if (Bmi1.X64.IsSupported) + if (UIntPtr.Size == sizeof(ulong)) { // If we can use 64-bit tzcnt to count the number of leading ASCII bytes, prefer it. @@ -396,10 +396,10 @@ private static unsafe nuint GetIndexOfFirstNonAsciiByte_Sse2(byte* pBuffer, nuin if (!AllBytesInUInt64AreAscii(candidateUInt64)) { // Clear everything but the high bit of each byte, then tzcnt. - // Remember the / 8 at the end to convert bit count to byte count. + // Remember to divide by 8 at the end to convert bit count to byte count. candidateUInt64 &= UInt64HighBitsOnlyMask; - pBuffer += (nuint)(Bmi1.X64.TrailingZeroCount(candidateUInt64) / 8); + pBuffer += (nuint)(BitOperations.TrailingZeroCount(candidateUInt64) >> 3); goto Finish; } } @@ -914,7 +914,7 @@ private static unsafe nuint GetIndexOfFirstNonAsciiChar_Sse2(char* pBuffer, nuin if ((bufferLength & 4) != 0) { - if (Bmi1.X64.IsSupported) + if (UIntPtr.Size == sizeof(ulong)) { // If we can use 64-bit tzcnt to count the number of leading ASCII chars, prefer it. @@ -922,12 +922,12 @@ private static unsafe nuint GetIndexOfFirstNonAsciiChar_Sse2(char* pBuffer, nuin if (!AllCharsInUInt64AreAscii(candidateUInt64)) { // Clear the low 7 bits (the ASCII bits) of each char, then tzcnt. - // Remember the / 8 at the end to convert bit count to byte count, + // Remember to divide by 8 at the end to convert bit count to byte count, // then the & ~1 at the end to treat a match in the high byte of // any char the same as a match in the low byte of that same char. candidateUInt64 &= 0xFF80FF80_FF80FF80ul; - pBuffer = (char*)((byte*)pBuffer + ((nuint)(Bmi1.X64.TrailingZeroCount(candidateUInt64) / 8) & ~(nuint)1)); + pBuffer = (char*)((byte*)pBuffer + ((nuint)(BitOperations.TrailingZeroCount(candidateUInt64) >> 3) & ~(nuint)1)); goto Finish; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Validation.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Validation.cs index 636829e289c26..a4a1932987fe3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Validation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Validation.cs @@ -122,7 +122,7 @@ internal static unsafe partial class Utf8Utility do { - if (Sse2.IsSupported && Bmi1.IsSupported) + if (Sse2.IsSupported) { // pInputBuffer is 32-bit aligned but not necessary 128-bit aligned, so we're // going to perform an unaligned load. We don't necessarily care about aligning @@ -158,7 +158,6 @@ internal static unsafe partial class Utf8Utility Debug.Assert(BitConverter.IsLittleEndian); Debug.Assert(Sse2.IsSupported); - Debug.Assert(Bmi1.IsSupported); // The 'mask' value will have a 0 bit for each ASCII byte we saw and a 1 bit // for each non-ASCII byte we saw. We can count the number of ASCII bytes, @@ -167,7 +166,7 @@ internal static unsafe partial class Utf8Utility Debug.Assert(mask != 0); - pInputBuffer += Bmi1.TrailingZeroCount(mask); + pInputBuffer += BitOperations.TrailingZeroCount(mask); if (pInputBuffer > pFinalPosWhereCanReadDWordFromInputBuffer) { goto ProcessRemainingBytesSlow; From 1ed54765d8f8c2eef40be91bbc9094eb9b0b38b5 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Sat, 23 May 2020 00:17:37 -0400 Subject: [PATCH 361/420] [jit] Return the compiled method and an unbox trampoline from ldvirtftn when calling ldvirtftn on a valuetype method. (#36736) Fixes https://github.com/dotnet/runtime/issues/34379. Co-authored-by: vargaz --- src/mono/mono/metadata/class-internals.h | 3 - src/mono/mono/metadata/icall.c | 2 +- src/mono/mono/metadata/marshal.c | 2 +- src/mono/mono/metadata/object-internals.h | 10 +-- src/mono/mono/metadata/object.c | 86 ++--------------------- src/mono/mono/mini/aot-runtime.c | 27 ++++++- src/mono/mono/mini/interp/interp.c | 2 +- src/mono/mono/mini/jit-icalls.c | 25 ++++++- src/mono/mono/mini/mini-arm64.c | 10 +++ src/mono/mono/mini/mini-runtime.c | 53 ++++++++++++-- src/mono/mono/mini/mini-wasm.c | 8 +++ src/mono/mono/mini/mini.h | 9 ++- 12 files changed, 135 insertions(+), 102 deletions(-) diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index d503e3e5c0b07..f00ea0345beeb 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -828,9 +828,6 @@ mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext * gpointer mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, gboolean check_token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error); -gpointer -mono_runtime_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper, MonoError *error); - gpointer mono_runtime_create_delegate_trampoline (MonoClass *klass); diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index 18c2c1e826711..0fa8444117d9a 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -7310,7 +7310,7 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionTypeHandle ref_ return_val_if_nok (error, NULL_HANDLE); } - mono_delegate_ctor_with_method (delegate, target, NULL, method, error); + mono_delegate_ctor (delegate, target, NULL, method, error); return_val_if_nok (error, NULL_HANDLE); return delegate; } diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index 6223aca76475e..30b6b55b506ba 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -512,7 +512,7 @@ mono_ftnptr_to_delegate_impl (MonoClass *klass, gpointer ftn, MonoError *error) gpointer compiled_ptr = mono_compile_method_checked (wrapper, error); goto_if_nok (error, leave); - mono_delegate_ctor_with_method (MONO_HANDLE_CAST (MonoObject, d), this_obj, compiled_ptr, wrapper, error); + mono_delegate_ctor (MONO_HANDLE_CAST (MonoObject, d), this_obj, compiled_ptr, wrapper, error); goto_if_nok (error, leave); } diff --git a/src/mono/mono/metadata/object-internals.h b/src/mono/mono/metadata/object-internals.h index 9f7ef48a5ea82..ee34045d181ad 100644 --- a/src/mono/mono/metadata/object-internals.h +++ b/src/mono/mono/metadata/object-internals.h @@ -820,10 +820,9 @@ typedef struct { void (*set_cast_details) (MonoClass *from, MonoClass *to); void (*debug_log) (int level, MonoString *category, MonoString *message); gboolean (*debug_log_is_enabled) (void); - void (*init_delegate) (MonoDelegateHandle delegate, MonoError *error); + void (*init_delegate) (MonoDelegateHandle delegate, MonoObjectHandle target, gpointer addr, MonoMethod *method, MonoError *error); MonoObject* (*runtime_invoke) (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError *error); void* (*compile_method) (MonoMethod *method, MonoError *error); - gpointer (*create_jump_trampoline) (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper, MonoError *error); gpointer (*create_jit_trampoline) (MonoDomain *domain, MonoMethod *method, MonoError *error); /* used to free a dynamic method */ void (*free_method) (MonoDomain *domain, MonoMethod *method); @@ -881,11 +880,8 @@ mono_method_call_message_new (MonoMethod *method, gpointer *params, MonoMethod * void mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoArray *out_args, MonoError *error); -gboolean -mono_delegate_ctor_with_method (MonoObjectHandle this_obj, MonoObjectHandle target, gpointer addr, MonoMethod *method, MonoError *error); - -gboolean -mono_delegate_ctor (MonoObjectHandle this_obj, MonoObjectHandle target, gpointer addr, MonoError *error); +void +mono_delegate_ctor (MonoObjectHandle this_obj, MonoObjectHandle target, gpointer addr, MonoMethod *method, MonoError *error); MonoMethod * mono_get_delegate_invoke_checked (MonoClass *klass, MonoError *error); diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index 952b2be7c1cc0..c9bacf3ad2aa6 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -802,18 +802,6 @@ mono_compile_method_checked (MonoMethod *method, MonoError *error) return res; } -gpointer -mono_runtime_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper, MonoError *error) -{ - gpointer res; - - MONO_REQ_GC_NEUTRAL_MODE; - - error_init (error); - res = callbacks.create_jump_trampoline (domain, method, add_sync_wrapper, error); - return res; -} - gpointer mono_runtime_create_delegate_trampoline (MonoClass *klass) { @@ -8714,7 +8702,7 @@ mono_print_unhandled_exception (MonoObject *exc) } /** - * mono_delegate_ctor_with_method: + * mono_delegate_ctor: * \param this pointer to an uninitialized delegate object * \param target target object * \param addr pointer to native code @@ -8724,82 +8712,22 @@ mono_print_unhandled_exception (MonoObject *exc) * associated with \p addr. This is useful when sharing generic code. * In that case \p addr will most probably not be associated with the * correct instantiation of the method. - * On failure returns FALSE and sets \p error. + * If \method is NULL, it is looked up using \addr in the JIT info tables. */ -gboolean -mono_delegate_ctor_with_method (MonoObjectHandle this_obj, MonoObjectHandle target, gpointer addr, MonoMethod *method, MonoError *error) +void +mono_delegate_ctor (MonoObjectHandle this_obj, MonoObjectHandle target, gpointer addr, MonoMethod *method, MonoError *error) { MONO_REQ_GC_UNSAFE_MODE; - error_init (error); MonoDelegateHandle delegate = MONO_HANDLE_CAST (MonoDelegate, this_obj); - g_assert (!MONO_HANDLE_IS_NULL (this_obj)); + UnlockedIncrement (&mono_stats.delegate_creations); MonoClass *klass = mono_handle_class (this_obj); g_assert (mono_class_has_parent (klass, mono_defaults.multicastdelegate_class)); - if (method) - MONO_HANDLE_SETVAL (delegate, method, MonoMethod*, method); - - UnlockedIncrement (&mono_stats.delegate_creations); - - if (addr) - MONO_HANDLE_SETVAL (delegate, method_ptr, gpointer, addr); - -#ifndef DISABLE_REMOTING - if (!MONO_HANDLE_IS_NULL (target) && mono_class_is_transparent_proxy (mono_handle_class (target))) { - if (callbacks.interp_get_remoting_invoke) { - MONO_HANDLE_SETVAL (delegate, interp_method, gpointer, callbacks.interp_get_remoting_invoke (method, addr, error)); - } else { - g_assert (method); - method = mono_marshal_get_remoting_invoke (method, error); - return_val_if_nok (error, FALSE); - MONO_HANDLE_SETVAL (delegate, method_ptr, gpointer, mono_compile_method_checked (method, error)); - } - return_val_if_nok (error, FALSE); - } -#endif - - MONO_HANDLE_SET (delegate, target, target); - MONO_HANDLE_SETVAL (delegate, invoke_impl, gpointer, callbacks.create_delegate_trampoline (MONO_HANDLE_DOMAIN (delegate), mono_handle_class (delegate))); - g_assert (callbacks.init_delegate); - callbacks.init_delegate (delegate, error); - return_val_if_nok (error, FALSE); - return TRUE; -} - -/** - * mono_delegate_ctor: - * \param this pointer to an uninitialized delegate object - * \param target target object - * \param addr pointer to native code - * \param error set on error. - * This is used to initialize a delegate. - * On failure returns FALSE and sets \p error. - */ -gboolean -mono_delegate_ctor (MonoObjectHandle this_obj, MonoObjectHandle target, gpointer addr, MonoError *error) -{ - MONO_REQ_GC_UNSAFE_MODE; - - error_init (error); - MonoDomain *domain = mono_domain_get (); - MonoJitInfo *ji; - MonoMethod *method = NULL; - - g_assert (addr); - - ji = mono_jit_info_table_find (domain, mono_get_addr_from_ftnptr (addr)); - /* Shared code */ - if (!ji && domain != mono_get_root_domain ()) - ji = mono_jit_info_table_find (mono_get_root_domain (), mono_get_addr_from_ftnptr (addr)); - if (ji) { - method = mono_jit_info_get_method (ji); - g_assert (!mono_class_is_gtd (method->klass)); - } - - return mono_delegate_ctor_with_method (this_obj, target, addr, method, error); + /* Done by the EE */ + callbacks.init_delegate (delegate, target, addr, method, error); } /** diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index cd7ff7bc4c8fb..df3f5b614779c 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -148,6 +148,8 @@ struct MonoAotModule { guint32 *unbox_trampolines_end; guint32 *unbox_trampoline_addresses; guint8 *unwind_info; + /* Maps method index -> unbox tramp */ + gpointer *unbox_tramp_per_method; /* Points to the mono EH data created by LLVM */ guint8 *mono_eh_frame; @@ -6050,6 +6052,16 @@ mono_aot_get_unbox_trampoline (MonoMethod *method, gpointer addr) return mono_aot_get_unbox_arbitrary_trampoline (addr); } + if (!amodule->unbox_tramp_per_method) { + gpointer arr = g_new0 (gpointer, amodule->info.nmethods); + mono_memory_barrier (); + gpointer old_arr = mono_atomic_cas_ptr ((volatile gpointer*)&amodule->unbox_tramp_per_method, arr, NULL); + if (old_arr) + g_free (arr); + } + if (amodule->unbox_tramp_per_method [method_index]) + return amodule->unbox_tramp_per_method [method_index]; + if (amodule->info.llvm_unbox_tramp_indexes) { int unbox_tramp_idx; @@ -6068,6 +6080,10 @@ mono_aot_get_unbox_trampoline (MonoMethod *method, gpointer addr) g_assert (unbox_tramp_idx < amodule->info.llvm_unbox_tramp_num); code = ((gpointer*)(amodule->info.llvm_unbox_trampolines))[unbox_tramp_idx]; g_assert (code); + + mono_memory_barrier (); + amodule->unbox_tramp_per_method [method_index] = code; + return code; } @@ -6075,8 +6091,12 @@ mono_aot_get_unbox_trampoline (MonoMethod *method, gpointer addr) gpointer (*get_tramp) (int) = (gpointer (*)(int))amodule->info.llvm_get_unbox_tramp; code = get_tramp (method_index); - if (code) + if (code) { + mono_memory_barrier (); + amodule->unbox_tramp_per_method [method_index] = code; + return code; + } } ut = amodule->unbox_trampolines; @@ -6113,9 +6133,14 @@ mono_aot_get_unbox_trampoline (MonoMethod *method, gpointer addr) return FALSE; } + tinfo->method = method; tinfo->code_size = *(guint32*)symbol_addr; + tinfo->unwind_ops = mono_arch_get_cie_program (); mono_aot_tramp_info_register (tinfo, NULL); + mono_memory_barrier (); + amodule->unbox_tramp_per_method [method_index] = code; + /* The caller expects an ftnptr */ return mono_create_ftnptr (mono_domain_get (), code); } diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 6fb7279b7a0ff..62c06d10bc099 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -1658,7 +1658,7 @@ interp_delegate_ctor (MonoObjectHandle this_obj, MonoObjectHandle target, gpoint MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoDelegate, this_obj), interp_method, gpointer, imethod); - mono_delegate_ctor (this_obj, target, entry, error); + mono_delegate_ctor (this_obj, target, entry, imethod->method, error); } /* diff --git a/src/mono/mono/mini/jit-icalls.c b/src/mono/mono/mini/jit-icalls.c index 6a833649fb02b..b50d3163996a8 100644 --- a/src/mono/mono/mini/jit-icalls.c +++ b/src/mono/mono/mini/jit-icalls.c @@ -67,6 +67,7 @@ ldvirtfn_internal (MonoObject *obj, MonoMethod *method, gboolean gshared) { ERROR_DECL (error); MonoMethod *res; + gpointer addr; if (obj == NULL) { mono_error_set_null_reference (error); @@ -93,8 +94,28 @@ ldvirtfn_internal (MonoObject *obj, MonoMethod *method, gboolean gshared) } /* An rgctx wrapper is added by the trampolines no need to do it here */ + gboolean need_unbox = m_class_is_valuetype (res->klass) && !m_class_is_valuetype (method->klass); + if (need_unbox) { + /* + * We can't return a jump trampoline here, because the trampoline code + * can't determine whenever to add an unbox trampoline (ldvirtftn) or + * not (ldftn). So compile the method here. + */ + addr = mono_compile_method_checked (res, error); + if (!is_ok (error)) { + mono_error_set_pending_exception (error); + return NULL; + } + + if (mono_llvm_only && mono_method_needs_static_rgctx_invoke (res, FALSE)) + // FIXME: + g_assert_not_reached (); - return mono_ldftn (res); + addr = mini_add_method_trampoline (res, addr, mono_method_needs_static_rgctx_invoke (res, FALSE), TRUE); + } else { + addr = mono_ldftn (res); + } + return addr; } void* @@ -1463,7 +1484,7 @@ ves_icall_mono_delegate_ctor (MonoObject *this_obj_raw, MonoObject *target_raw, mono_error_set_pending_exception (error); goto leave; } - mono_delegate_ctor (this_obj, target, addr, error); + mono_delegate_ctor (this_obj, target, addr, NULL, error); mono_error_set_pending_exception (error); leave: diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 8a8a5b070637b..7907193b5e0ff 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -1035,6 +1035,16 @@ mono_arch_find_static_call_vtable (host_mgreg_t *regs, guint8 *code) return (MonoVTable*)regs [MONO_ARCH_RGCTX_REG]; } +GSList* +mono_arch_get_cie_program (void) +{ + GSList *l = NULL; + + mono_add_unwind_op_def_cfa (l, (guint8*)NULL, (guint8*)NULL, ARMREG_SP, 0); + + return l; +} + host_mgreg_t mono_arch_context_get_int_reg (MonoContext *ctx, int reg) { diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index a8bac8f41474f..e76f06f4186a0 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -516,6 +516,7 @@ mono_tramp_info_register_internal (MonoTrampInfo *info, MonoDomain *domain, gboo copy->code = info->code; copy->code_size = info->code_size; copy->name = g_strdup (info->name); + copy->method = info->method; if (info->unwind_ops) { copy->uw_info = mono_unwind_ops_encode (info->unwind_ops, ©->uw_info_len); @@ -546,8 +547,8 @@ mono_tramp_info_register_internal (MonoTrampInfo *info, MonoDomain *domain, gboo mono_jit_lock (); tramp_infos = g_slist_prepend (tramp_infos, copy); mono_jit_unlock (); - } else if (copy->uw_info) { - /* Only register trampolines that have unwind infos */ + } else if (copy->uw_info || info->method) { + /* Only register trampolines that have unwind info */ register_trampoline_jit_info (domain, copy); } @@ -3748,7 +3749,7 @@ create_delegate_method_ptr (MonoMethod *method, MonoError *error) func = mono_compile_method_checked (method, error); return_val_if_nok (error, NULL); } else { - gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, error); + gpointer trampoline = mono_create_jump_trampoline (mono_domain_get (), method, TRUE, error); return_val_if_nok (error, NULL); func = mono_create_ftnptr (mono_domain_get (), trampoline); } @@ -3756,9 +3757,52 @@ create_delegate_method_ptr (MonoMethod *method, MonoError *error) } static void -mini_init_delegate (MonoDelegateHandle delegate, MonoError *error) +mini_init_delegate (MonoDelegateHandle delegate, MonoObjectHandle target, gpointer addr, MonoMethod *method, MonoError *error) { MonoDelegate *del = MONO_HANDLE_RAW (delegate); + MonoDomain *domain = MONO_HANDLE_DOMAIN (delegate); + + if (!method) { + MonoJitInfo *ji; + + g_assert (addr); + ji = mono_jit_info_table_find_internal (domain, mono_get_addr_from_ftnptr (addr), TRUE, TRUE); + /* Shared code */ + if (!ji && domain != mono_get_root_domain ()) + ji = mono_jit_info_table_find_internal (mono_get_root_domain (), mono_get_addr_from_ftnptr (addr), TRUE, TRUE); + if (ji) { + if (ji->is_trampoline) { + /* Could be an unbox trampoline etc. */ + method = ji->d.tramp_info->method; + } else { + method = mono_jit_info_get_method (ji); + g_assert (!mono_class_is_gtd (method->klass)); + } + } + } + + if (method) + MONO_HANDLE_SETVAL (delegate, method, MonoMethod*, method); + + if (addr) + MONO_HANDLE_SETVAL (delegate, method_ptr, gpointer, addr); + +#ifndef DISABLE_REMOTING + if (!MONO_HANDLE_IS_NULL (target) && mono_class_is_transparent_proxy (mono_handle_class (target))) { + if (mono_use_interpreter) { + MONO_HANDLE_SETVAL (delegate, interp_method, gpointer, mini_get_interp_callbacks ()->get_remoting_invoke (method, addr, error)); + } else { + g_assert (method); + method = mono_marshal_get_remoting_invoke (method, error); + return_if_nok (error); + MONO_HANDLE_SETVAL (delegate, method_ptr, gpointer, mono_compile_method_checked (method, error)); + } + return_if_nok (error); + } +#endif + + MONO_HANDLE_SET (delegate, target, target); + MONO_HANDLE_SETVAL (delegate, invoke_impl, gpointer, mono_create_delegate_trampoline (domain, mono_handle_class (delegate))); if (mono_use_interpreter) { mini_get_interp_callbacks ()->init_delegate (del, error); @@ -4377,7 +4421,6 @@ mini_init (const char *filename, const char *runtime_version) #define JIT_TRAMPOLINES_WORK #ifdef JIT_TRAMPOLINES_WORK callbacks.compile_method = mono_jit_compile_method; - callbacks.create_jump_trampoline = mono_create_jump_trampoline; callbacks.create_jit_trampoline = mono_create_jit_trampoline; callbacks.create_delegate_trampoline = mono_create_delegate_trampoline; callbacks.free_method = mono_jit_free_method; diff --git a/src/mono/mono/mini/mini-wasm.c b/src/mono/mono/mini/mini-wasm.c index 8f1eef7f0c150..70e182efef6cb 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -455,6 +455,14 @@ mono_arch_find_static_call_vtable (host_mgreg_t *regs, guint8 *code) return (MonoVTable*) regs [MONO_ARCH_RGCTX_REG]; } +GSList* +mono_arch_get_cie_program (void) +{ + GSList *l = NULL; + + return l; +} + gpointer mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count, gpointer fail_tramp) { diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 0e632d0f4f617..1d09d6d4668d4 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -1943,8 +1943,8 @@ enum { /* * Information about a trampoline function. */ - struct MonoTrampInfo - { +struct MonoTrampInfo +{ /* * The native code of the trampoline. Not owned by this structure. */ @@ -1966,6 +1966,11 @@ enum { MonoJitICallInfo *jit_icall_info; + /* + * The method the trampoline is associated with, if any. + */ + MonoMethod *method; + /* * Encoded unwind info loaded from AOT images */ From e8589845bdd8e83465df04e1ac12602081e068ec Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Fri, 22 May 2020 23:33:25 -0700 Subject: [PATCH 362/420] Revert "Libunwind1.5rc2 (#36027)" (#36909) This reverts commit 8c6c7655bb7abc5c4ce769923aa5bea1daee6bd3. --- .../src/pal/src/exception/seh-unwind.cpp | 16 - src/coreclr/src/pal/src/libunwind/.gitignore | 2 - src/coreclr/src/pal/src/libunwind/.travis.yml | 16 - .../src/pal/src/libunwind/CMakeLists.txt | 5 +- src/coreclr/src/pal/src/libunwind/Makefile.am | 5 - src/coreclr/src/pal/src/libunwind/README | 244 +++++------ src/coreclr/src/pal/src/libunwind/autogen.sh | 2 +- .../src/pal/src/libunwind/configure.ac | 42 +- .../src/pal/src/libunwind/include/dwarf-eh.h | 1 - .../src/pal/src/libunwind/include/dwarf.h | 2 +- .../src/libunwind/include/libunwind-aarch64.h | 45 +- .../libunwind/include/libunwind-common.h.in | 15 +- .../src/libunwind/include/libunwind-mips.h | 2 +- .../src/libunwind/include/libunwind-s390x.h | 144 ------- .../pal/src/libunwind/include/libunwind.h.in | 2 - .../pal/src/libunwind/include/libunwind_i.h | 6 +- .../include/tdep-mips/dwarf-config.h | 3 + .../libunwind/include/tdep-mips/libunwind_i.h | 8 - .../include/tdep-s390x/dwarf-config.h | 52 --- .../src/libunwind/include/tdep-s390x/jmpbuf.h | 35 -- .../include/tdep-s390x/libunwind_i.h | 262 ------------ .../libunwind/include/tdep-x86_64/jmpbuf.h | 5 +- .../include/tdep-x86_64/libunwind_i.h | 5 - .../libunwind/include/tdep/libunwind_i.h.in | 2 - .../pal/src/libunwind/libunwind-version.txt | 2 - .../src/pal/src/libunwind/src/CMakeLists.txt | 21 +- .../src/pal/src/libunwind/src/Makefile.am | 55 +-- .../src/pal/src/libunwind/src/aarch64/Ginit.c | 23 +- .../src/libunwind/src/aarch64/Ginit_local.c | 2 +- .../pal/src/libunwind/src/aarch64/Gresume.c | 4 +- .../pal/src/libunwind/src/aarch64/unwind_i.h | 2 +- .../pal/src/libunwind/src/arm/Gex_tables.c | 5 +- .../src/pal/src/libunwind/src/arm/Ginit.c | 15 +- .../src/pal/src/libunwind/src/arm/Gresume.c | 4 +- .../src/pal/src/libunwind/src/arm/Gstep.c | 23 +- .../src/coredump/_UCD_access_reg_freebsd.c | 20 - .../src/coredump/_UCD_access_reg_linux.c | 3 - .../src/libunwind/src/coredump/_UCD_create.c | 13 +- .../src/coredump/_UCD_get_proc_name.c | 4 - .../coredump/_UPT_get_dyn_info_list_addr.c | 5 - .../src/pal/src/libunwind/src/dwarf/Gexpr.c | 16 +- .../libunwind/src/dwarf/Gfind_proc_info-lsb.c | 393 ++++++++---------- .../libunwind/src/dwarf/Gfind_unwind_table.c | 3 - .../src/pal/src/libunwind/src/dwarf/Gparser.c | 38 +- src/coreclr/src/pal/src/libunwind/src/elfxx.c | 1 - .../src/pal/src/libunwind/src/hppa/Ginit.c | 15 +- .../src/pal/src/libunwind/src/ia64/Ginit.c | 1 - .../src/mi/Gfind_dynamic_proc_info.c | 1 - .../pal/src/libunwind/src/mi/Gget_proc_name.c | 10 +- .../src/pal/src/libunwind/src/mi/backtrace.c | 6 +- .../pal/src/libunwind/src/mi/flush_cache.c | 19 +- .../libunwind/src/mips/Gcreate_addr_space.c | 9 +- .../src/libunwind/src/mips/Gget_proc_info.c | 11 +- .../src/pal/src/libunwind/src/mips/Ginit.c | 15 +- .../src/pal/src/libunwind/src/mips/Gregs.c | 3 +- .../src/pal/src/libunwind/src/mips/Gstep.c | 98 +---- .../src/pal/src/libunwind/src/os-solaris.c | 73 ---- .../src/pal/src/libunwind/src/ppc32/Ginit.c | 11 +- .../src/pal/src/libunwind/src/ppc64/Ginit.c | 11 +- .../libunwind/src/ptrace/_UPT_access_fpreg.c | 7 - .../src/ptrace/_UPT_get_dyn_info_list_addr.c | 5 - .../libunwind/src/ptrace/_UPT_reg_offset.c | 34 -- .../libunwind/src/s390x/Gapply_reg_state.c | 37 -- .../libunwind/src/s390x/Gcreate_addr_space.c | 62 --- .../src/libunwind/src/s390x/Gget_proc_info.c | 48 --- .../src/libunwind/src/s390x/Gget_save_loc.c | 86 ---- .../src/pal/src/libunwind/src/s390x/Gglobal.c | 101 ----- .../src/pal/src/libunwind/src/s390x/Ginit.c | 365 ---------------- .../pal/src/libunwind/src/s390x/Ginit_local.c | 81 ---- .../src/libunwind/src/s390x/Ginit_remote.c | 57 --- .../libunwind/src/s390x/Gis_signal_frame.c | 77 ---- .../libunwind/src/s390x/Greg_states_iterate.c | 37 -- .../src/pal/src/libunwind/src/s390x/Gregs.c | 116 ------ .../src/pal/src/libunwind/src/s390x/Gresume.c | 160 ------- .../src/pal/src/libunwind/src/s390x/Gstep.c | 146 ------- .../libunwind/src/s390x/Lapply_reg_state.c | 5 - .../libunwind/src/s390x/Lcreate_addr_space.c | 5 - .../src/libunwind/src/s390x/Lget_proc_info.c | 5 - .../src/libunwind/src/s390x/Lget_save_loc.c | 5 - .../src/pal/src/libunwind/src/s390x/Lglobal.c | 6 - .../src/pal/src/libunwind/src/s390x/Linit.c | 5 - .../pal/src/libunwind/src/s390x/Linit_local.c | 5 - .../src/libunwind/src/s390x/Linit_remote.c | 5 - .../libunwind/src/s390x/Lis_signal_frame.c | 5 - .../libunwind/src/s390x/Lreg_states_iterate.c | 5 - .../src/pal/src/libunwind/src/s390x/Lregs.c | 5 - .../src/pal/src/libunwind/src/s390x/Lresume.c | 5 - .../src/pal/src/libunwind/src/s390x/Lstep.c | 5 - .../pal/src/libunwind/src/s390x/getcontext.S | 74 ---- .../src/pal/src/libunwind/src/s390x/init.h | 71 ---- .../pal/src/libunwind/src/s390x/is_fpreg.c | 36 -- .../src/pal/src/libunwind/src/s390x/regname.c | 57 --- .../pal/src/libunwind/src/s390x/setcontext.S | 76 ---- .../pal/src/libunwind/src/s390x/unwind_i.h | 48 --- .../pal/src/libunwind/src/setjmp/siglongjmp.c | 10 +- .../src/pal/src/libunwind/src/sh/Ginit.c | 15 +- .../pal/src/libunwind/src/sh/Ginit_local.c | 2 +- .../src/pal/src/libunwind/src/sh/Gresume.c | 4 +- .../src/pal/src/libunwind/src/tilegx/Ginit.c | 15 +- .../src/libunwind/src/unwind/libunwind.pc.in | 2 +- .../src/pal/src/libunwind/src/x86/Ginit.c | 15 +- .../src/libunwind/src/x86_64/Gget_save_loc.c | 1 - .../pal/src/libunwind/src/x86_64/Gglobal.c | 21 +- .../src/pal/src/libunwind/src/x86_64/Ginit.c | 175 ++------ .../src/libunwind/src/x86_64/Ginit_local.c | 2 +- .../src/libunwind/src/x86_64/Ginit_remote.c | 2 +- .../src/libunwind/src/x86_64/Gos-solaris.c | 133 ------ .../src/libunwind/src/x86_64/Gstash_frame.c | 6 +- .../src/pal/src/libunwind/src/x86_64/Gstep.c | 121 ++---- .../src/pal/src/libunwind/src/x86_64/Gtrace.c | 2 +- .../src/libunwind/src/x86_64/Los-solaris.c | 5 - .../pal/src/libunwind/src/x86_64/getcontext.S | 4 +- .../pal/src/libunwind/src/x86_64/setcontext.S | 6 +- .../pal/src/libunwind/src/x86_64/ucontext_i.h | 20 - .../src/pal/src/libunwind/tests/Gtest-bt.c | 6 +- .../src/pal/src/libunwind/tests/Gtest-trace.c | 2 +- .../tests/Gx64-test-dwarf-expressions.c | 68 --- .../src/libunwind/tests/Ltest-mem-validate.c | 2 - .../tests/Lx64-test-dwarf-expressions.c | 5 - .../src/pal/src/libunwind/tests/Makefile.am | 19 +- .../src/libunwind/tests/check-namespace.sh.in | 22 +- .../src/pal/src/libunwind/tests/crasher.c | 7 +- .../libunwind/tests/test-coredump-unwind.c | 8 +- .../tests/x64-test-dwarf-expressions.S | 78 ---- .../tests/x64-unwind-badjmp-signal-frame.c | 124 ------ 125 files changed, 528 insertions(+), 4077 deletions(-) delete mode 100644 src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h delete mode 100644 src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/libunwind-version.txt delete mode 100644 src/coreclr/src/pal/src/libunwind/src/os-solaris.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/init.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/regname.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S delete mode 100644 src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c delete mode 100644 src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S delete mode 100644 src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c diff --git a/src/coreclr/src/pal/src/exception/seh-unwind.cpp b/src/coreclr/src/pal/src/exception/seh-unwind.cpp index 654e385dec40a..53c86a0045384 100644 --- a/src/coreclr/src/pal/src/exception/seh-unwind.cpp +++ b/src/coreclr/src/pal/src/exception/seh-unwind.cpp @@ -111,22 +111,6 @@ static void WinContextToUnwindContext(CONTEXT *winContext, unw_context_t *unwCon unwContext->regs[13] = winContext->Sp; unwContext->regs[14] = winContext->Lr; unwContext->regs[15] = winContext->Pc; -#elif defined(HOST_ARM64) - unwContext->uc_mcontext.pc = winContext->Pc; - unwContext->uc_mcontext.sp = winContext->Sp; - unwContext->uc_mcontext.regs[29] = winContext->Fp; - unwContext->uc_mcontext.regs[30] = winContext->Lr; - - unwContext->uc_mcontext.regs[19] = winContext->X19; - unwContext->uc_mcontext.regs[20] = winContext->X20; - unwContext->uc_mcontext.regs[21] = winContext->X21; - unwContext->uc_mcontext.regs[22] = winContext->X22; - unwContext->uc_mcontext.regs[23] = winContext->X23; - unwContext->uc_mcontext.regs[24] = winContext->X24; - unwContext->uc_mcontext.regs[25] = winContext->X25; - unwContext->uc_mcontext.regs[26] = winContext->X26; - unwContext->uc_mcontext.regs[27] = winContext->X27; - unwContext->uc_mcontext.regs[28] = winContext->X28; #endif } diff --git a/src/coreclr/src/pal/src/libunwind/.gitignore b/src/coreclr/src/pal/src/libunwind/.gitignore index 724a1f4882e2c..7b7905f0d5981 100644 --- a/src/coreclr/src/pal/src/libunwind/.gitignore +++ b/src/coreclr/src/pal/src/libunwind/.gitignore @@ -75,7 +75,5 @@ tests/[GL]ia64-test-readonly tests/[GL]ia64-test-stack tests/ia64-test-dyn1 tests/ia64-test-sig -tests/[GL]x64-test-dwarf-expressions -tests/x64-unwind-badjmp-signal-frame tests/*.log tests/*.trs diff --git a/src/coreclr/src/pal/src/libunwind/.travis.yml b/src/coreclr/src/pal/src/libunwind/.travis.yml index 7bf0f8d0638ef..4a74b4a1bcb3e 100644 --- a/src/coreclr/src/pal/src/libunwind/.travis.yml +++ b/src/coreclr/src/pal/src/libunwind/.travis.yml @@ -9,18 +9,6 @@ env: - TARGET=mipsel-unknown-linux-gnu # Currently experiencing build failures here #- TARGET=powerpc64-linux-gnu - -linux-s390x: &linux-s390x - os: linux - arch: s390x - env: TARGET=s390x-linux-gnu - script: - - ./autogen.sh - - ./configure - - make -j32 - - ulimit -c unlimited - - make check -j32 - script: - ./autogen.sh - ./configure --target=$TARGET --host=$HOST @@ -28,7 +16,3 @@ script: - sudo bash -c 'echo core.%p.%p > /proc/sys/kernel/core_pattern' - ulimit -c unlimited - if [ $TARGET == 'x86_64-linux-gnu' ]; then make check -j32; fi - -jobs: - include: - - <<: *linux-s390x diff --git a/src/coreclr/src/pal/src/libunwind/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/CMakeLists.txt index fc47c89f640cf..5c66b90fdb050 100644 --- a/src/coreclr/src/pal/src/libunwind/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/CMakeLists.txt @@ -13,9 +13,10 @@ elseif(CLR_CMAKE_HOST_ARCH_I386) endif() set(PKG_MAJOR "1") -set(PKG_MINOR "5") -set(PKG_EXTRA "-rc2") +set(PKG_MINOR "3") +set(PKG_EXTRA "-rc1") configure_file(include/libunwind-common.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind-common.h) configure_file(include/libunwind.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind.h) configure_file(include/tdep/libunwind_i.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/tdep/libunwind_i.h) + diff --git a/src/coreclr/src/pal/src/libunwind/Makefile.am b/src/coreclr/src/pal/src/libunwind/Makefile.am index 8132fa4cb952a..711d9100c7551 100644 --- a/src/coreclr/src/pal/src/libunwind/Makefile.am +++ b/src/coreclr/src/pal/src/libunwind/Makefile.am @@ -41,9 +41,6 @@ endif if ARCH_SH include_HEADERS += include/libunwind-sh.h endif -if ARCH_S390X -include_HEADERS += include/libunwind-s390x.h -endif if !REMOTE_ONLY include_HEADERS += include/libunwind.h include/unwind.h @@ -87,8 +84,6 @@ noinst_HEADERS = include/dwarf.h include/dwarf_i.h include/dwarf-eh.h \ include/tdep-ppc64/jmpbuf.h include/tdep-ppc64/libunwind_i.h \ include/tdep-sh/dwarf-config.h \ include/tdep-sh/jmpbuf.h include/tdep-sh/libunwind_i.h \ - include/tdep-s390x/dwarf-config.h \ - include/tdep-s390x/jmpbuf.h include/tdep-s390x/libunwind_i.h \ include/tdep/libunwind_i.h \ include/tdep/jmpbuf.h include/tdep/dwarf-config.h diff --git a/src/coreclr/src/pal/src/libunwind/README b/src/coreclr/src/pal/src/libunwind/README index b6d93ae4a6855..694f600b06dc9 100644 --- a/src/coreclr/src/pal/src/libunwind/README +++ b/src/coreclr/src/pal/src/libunwind/README @@ -1,83 +1,53 @@ -# libunwind +-*- mode: Outline -*- [![Build Status](https://travis-ci.org/libunwind/libunwind.svg?branch=master)](https://travis-ci.org/libunwind/libunwind) -This is version 1.5 of the unwind library. This library supports +This is version 1.3 of the unwind library. This library supports several architecture/operating-system combinations: -| System | Architecture | Status | -| :------ | :----------- | :----- | -| Linux | x86-64 | ✓ | -| Linux | x86 | ✓ | -| Linux | ARM | ✓ | -| Linux | AArch64 | ✓ | -| Linux | PPC64 | ✓ | -| Linux | SuperH | ✓ | -| Linux | IA-64 | ✓ | -| Linux | PARISC | Works well, but C library missing unwind-info | -| Linux | Tilegx | 64-bit mode only | -| Linux | MIPS | Newly added | -| HP-UX | IA-64 | Mostly works, but known to have serious limitations | -| FreeBSD | x86-64 | ✓ | -| FreeBSD | x86 | ✓ | -| FreeBSD | AArch64 | ✓ | -| Solaris | x86-64 | ✓ | - -## Libc Requirements - -libunwind depends on getcontext(), setcontext() functions which are missing -from C libraries like musl-libc because they are considered to be "obsolescent" -API by POSIX document. The following table tries to track current status of -such dependencies - - - r, requires - - p, provides its own implementation - - empty, no requirement - -| Archtecture | getcontext | setcontext | -|--------------|------------|------------| -| aarch64 | p | | -| arm | p | | -| hppa | p | p | -| ia64 | p | r | -| mips | p | | -| ppc32 | r | | -| ppc64 | r | r | -| s390x | p | p | -| sh | r | | -| tilegx | r | r | -| x86 | p | r | -| x86_64 | p | p | - -## General Build Instructions + Linux/x86-64: Works well. + Linux/x86: Works well. + Linux/ARM: Works well. + Linux/IA-64: Works well. + Linux/PARISC: Works well, but C library missing unwind-info. + HP-UX/IA-64: Mostly works but known to have some serious limitations. + MIPS: Newly added. + Linux/AArch64: Works well. + Linux/PPC64: Newly added. + Linux/SuperH: Newly added. + FreeBSD/i386: Works well. + FreeBSD/x86-64: Newly added (FreeBSD architecture is known as amd64). + Linux/Tilegx: Newly added (64-bit mode only). + +* General Build Instructions In general, this library can be built and installed with the following commands: - $ ./autogen.sh # Needed only for building from git. Depends on libtool. - $ ./configure - $ make - $ make install prefix=PREFIX + $ ./autogen.sh # Needed only for building from git. Depends on libtool. + $ ./configure + $ make + $ make install prefix=PREFIX -where `PREFIX` is the installation prefix. By default, a prefix of -`/usr/local` is used, such that `libunwind.a` is installed in -`/usr/local/lib` and `unwind.h` is installed in `/usr/local/include`. For -testing, you may want to use a prefix of `/usr/local` instead. +where PREFIX is the installation prefix. By default, a prefix of +/usr/local is used, such that libunwind.a is installed in +/usr/local/lib and unwind.h is installed in /usr/local/include. For +testing, you may want to use a prefix of /usr/local instead. -### Building with Intel compiler +* Building with Intel compiler -#### Version 8 and later +** Version 8 and later Starting with version 8, the preferred name for the IA-64 Intel -compiler is `icc` (same name as on x86). Thus, the configure-line +compiler is "icc" (same name as on x86). Thus, the configure-line should look like this: $ ./configure CC=icc CFLAGS="-g -O3 -ip" CXX=icc CCAS=gcc CCASFLAGS=-g \ - LDFLAGS="-L$PWD/src/.libs" + LDFLAGS="-L$PWD/src/.libs" -### Building on HP-UX +* Building on HP-UX For the time being, libunwind must be built with GCC on HP-UX. @@ -85,13 +55,14 @@ libunwind should be configured and installed on HP-UX like this: $ ./configure CFLAGS="-g -O2 -mlp64" CXXFLAGS="-g -O2 -mlp64" -Caveat: Unwinding of 32-bit (ILP32) binaries is not supported at the moment. +Caveat: Unwinding of 32-bit (ILP32) binaries is not supported + at the moment. -### Workaround for older versions of GCC +** Workaround for older versions of GCC -GCC v3.0 and GCC v3.2 ship with a bad version of `sys/types.h`. The +GCC v3.0 and GCC v3.2 ship with a bad version of sys/types.h. The workaround is to issue the following commands before running -`configure`: +"configure": $ mkdir $top_dir/include/sys $ cp /usr/include/sys/types.h $top_dir/include/sys @@ -99,141 +70,138 @@ workaround is to issue the following commands before running GCC v3.3.2 or later have been fixed and do not require this workaround. -### Building for PowerPC64 / Linux +* Building for PowerPC64 / Linux For building for power64 you should use: - $ ./configure CFLAGS="-g -O2 -m64" CXXFLAGS="-g -O2 -m64" + $ ./configure CFLAGS="-g -O2 -m64" CXXFLAGS="-g -O2 -m64" If your power support altivec registers: - - $ ./configure CFLAGS="-g -O2 -m64 -maltivec" CXXFLAGS="-g -O2 -m64 -maltivec" + $ ./configure CFLAGS="-g -O2 -m64 -maltivec" CXXFLAGS="-g -O2 -m64 -maltivec" To check if your processor has support for vector registers (altivec): - cat /proc/cpuinfo | grep altivec - and should have something like this: - cpu : PPC970, altivec supported If libunwind seems to not work (backtracing failing), try to compile -it with `-O0`, without optimizations. There are some compiler problems +it with -O0, without optimizations. There are some compiler problems depending on the version of your gcc. -### Building on FreeBSD +* Building on FreeBSD + +General building instructions apply. To build and execute several tests, +you need libexecinfo library available in ports as devel/libexecinfo. -General building instructions apply. To build and execute several tests -on older versions of FreeBSD, you need libexecinfo library available in -ports as devel/libexecinfo. This port has been removed as of 2017 and is -indeed no longer needed. +Development of the port was done of FreeBSD 8.0-STABLE. The library +was build with the system compiler that is modified version of gcc 4.2.1, +as well as the gcc 4.4.3. -## Regression Testing +* Regression Testing After building the library, you can run a set of regression tests with: - $ make check + $ make check -### Expected results on IA-64 Linux +** Expected results on IA-64 Linux Unless you have a very recent C library and compiler installed, it is currently expected to have the following tests fail on IA-64 Linux: -* `Gtest-init` (should pass starting with glibc-2.3.x/gcc-3.4) -* `Ltest-init` (should pass starting with glibc-2.3.x/gcc-3.4) -* `test-ptrace` (should pass starting with glibc-2.3.x/gcc-3.4) -* `run-ia64-test-dyn1` (should pass starting with glibc-2.3.x) + Gtest-init (should pass starting with glibc-2.3.x/gcc-3.4) + Ltest-init (should pass starting with glibc-2.3.x/gcc-3.4) + test-ptrace (should pass starting with glibc-2.3.x/gcc-3.4) + run-ia64-test-dyn1 (should pass starting with glibc-2.3.x) This does not mean that libunwind cannot be used with older compilers or C libraries, it just means that for certain corner cases, unwinding will fail. Since they're corner cases, it is not likely for applications to trigger them. -Note: If you get lots of errors in `Gia64-test-nat` and `Lia64-test-nat`, it's -almost certainly a sign of an old assembler. The GNU assembler used -to encode previous-stack-pointer-relative offsets incorrectly. -This bug was fixed on 21-Sep-2004 so any later assembler will be -fine. +Note: If you get lots of errors in Gia64-test-nat and Lia64-test-nat, it's + almost certainly a sign of an old assembler. The GNU assembler used + to encode previous-stack-pointer-relative offsets incorrectly. + This bug was fixed on 21-Sep-2004 so any later assembler will be + fine. -### Expected results on x86 Linux +** Expected results on x86 Linux The following tests are expected to fail on x86 Linux: -* `test-ptrace` + test-ptrace -### Expected results on x86-64 Linux +** Expected results on x86-64 Linux The following tests are expected to fail on x86-64 Linux: -* `run-ptrace-misc` (see - and ) + run-ptrace-misc (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18748 + and http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18749) -### Expected results on PARISC Linux +** Expected results on PARISC Linux Caveat: GCC v3.4 or newer is needed on PA-RISC Linux. Earlier versions of the compiler failed to generate the exception-handling -program header (`GNU_EH_FRAME`) needed for unwinding. +program header (GNU_EH_FRAME) needed for unwinding. The following tests are expected to fail on x86-64 Linux: -* `Gtest-bt` (backtrace truncated at `kill()` due to lack of unwind-info) -* `Ltest-bt` (likewise) -* `Gtest-resume-sig` (`Gresume.c:my_rt_sigreturn()` is wrong somehow) -* `Ltest-resume-sig` (likewise) -* `Gtest-init` (likewise) -* `Ltest-init` (likewise) -* `Gtest-dyn1` (no dynamic unwind info support yet) -* `Ltest-dyn1` (no dynamic unwind info support yet) -* `test-setjmp` (`longjmp()` not implemented yet) -* `run-check-namespace` (toolchain doesn't support `HIDDEN` yet) + Gtest-bt (backtrace truncated at kill() due to lack of unwind-info) + Ltest-bt (likewise) + Gtest-resume-sig (Gresume.c:my_rt_sigreturn() is wrong somehow) + Ltest-resume-sig (likewise) + Gtest-init (likewise) + Ltest-init (likewise) + Gtest-dyn1 (no dynamic unwind info support yet) + Ltest-dyn1 (no dynamic unwind info support yet) + test-setjmp (longjmp() not implemented yet) + run-check-namespace (toolchain doesn't support HIDDEN yet) -### Expected results on HP-UX +** Expected results on HP-UX -`make check` is currently unsupported for HP-UX. You can try to run +"make check" is currently unsupported for HP-UX. You can try to run it, but most tests will fail (and some may fail to terminate). The only test programs that are known to work at this time are: -* `tests/bt` -* `tests/Gperf-simple` -* `tests/test-proc-info` -* `tests/test-static-link` -* `tests/Gtest-init` -* `tests/Ltest-init` -* `tests/Gtest-resume-sig` -* `tests/Ltest-resume-sig` - -### Expected results on PPC64 Linux + tests/bt + tests/Gperf-simple + tests/test-proc-info + tests/test-static-link + tests/Gtest-init + tests/Ltest-init + tests/Gtest-resume-sig + tests/Ltest-resume-sig -`make check` should run with no more than 10 out of 24 tests failed. +** Expected results on PPC64 Linux -### Expected results on Solaris x86-64 +"make check" should run with no more than 10 out of 24 tests failed. -`make check` is passing 27 out of 33 tests. The following six tests are consistently -failing: -* `Gtest-concurrent` -* `Ltest-concurrent` -* `Ltest-init-local-signal` -* `Lrs-race` -* `test-setjmp` -* `x64-unwind-badjmp-signal-frame` - -## Performance Testing +* Performance Testing This distribution includes a few simple performance tests which give some idea of the basic cost of various libunwind operations. After building the library, you can run these tests with the following commands: - $ cd tests - $ make perf + $ cd tests + $ make perf + +* Contacting the Developers + +Please direct all questions regarding this library to: + + libunwind-devel@nongnu.org + +You can do this by sending a mail to libunwind-request@nongnu.org with +a body of: + + subscribe libunwind-devel -## Contacting the Developers +or you can subscribe and manage your subscription via the +web-interface at: -Please direct all questions regarding this library to . + https://savannah.nongnu.org/mail/?group=libunwind -You can do this by sending an email to with -a body of "subscribe libunwind-devel", or you can subscribe and manage your -subscription via the web-interface at . +Or interact at the gihub page: -You can also interact on our GitHub page: . + https://github.com/libunwind/libunwind diff --git a/src/coreclr/src/pal/src/libunwind/autogen.sh b/src/coreclr/src/pal/src/libunwind/autogen.sh index b08bc831f6447..aad9de6615c22 100755 --- a/src/coreclr/src/pal/src/libunwind/autogen.sh +++ b/src/coreclr/src/pal/src/libunwind/autogen.sh @@ -1,6 +1,6 @@ #!/bin/sh -test -n "$srcdir" || srcdir=`dirname "$0"` +test -n "$srcdir" || srcdir=`dirname "${BASH_SOURCE[0]}"` test -n "$srcdir" || srcdir=. ( cd "$srcdir" && diff --git a/src/coreclr/src/pal/src/libunwind/configure.ac b/src/coreclr/src/pal/src/libunwind/configure.ac index 226a10fb35047..0c5125971f7c6 100644 --- a/src/coreclr/src/pal/src/libunwind/configure.ac +++ b/src/coreclr/src/pal/src/libunwind/configure.ac @@ -1,5 +1,5 @@ define(pkg_major, 1) -define(pkg_minor, 5) +define(pkg_minor, 3) define(pkg_extra, -rc1) define(pkg_maintainer, libunwind-devel@nongnu.org) define(mkvers, $1.$2$3) @@ -70,7 +70,7 @@ PT_STEP, PT_SYSCALL], [], [], dnl Checks for library functions. AC_CHECK_FUNCS(dl_iterate_phdr dl_phdr_removals_counter dlmodinfo getunwind \ - ttrace mincore pipe2) + ttrace mincore) AC_MSG_CHECKING([if building with AltiVec]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ @@ -147,10 +147,6 @@ AC_ARG_ENABLE(tests, AS_HELP_STRING([--disable-tests],[Disable tests build]),, [enable_tests=yes]) -AC_ARG_ENABLE(weak-backtrace, - AS_HELP_STRING([--disable-weak-backtrace],[Do not provide the weak 'backtrace' symbol.]),, - [enable_weak_backtrace=yes]) - AC_MSG_CHECKING([if we should build libunwind-setjmp]) AC_MSG_RESULT([$enable_setjmp]) @@ -179,17 +175,15 @@ AM_CONDITIONAL(ARCH_PPC32, test x$target_arch = xppc32) AM_CONDITIONAL(ARCH_PPC64, test x$target_arch = xppc64) AM_CONDITIONAL(ARCH_SH, test x$target_arch = xsh) AM_CONDITIONAL(ARCH_TILEGX, test x$target_arch = xtilegx) -AM_CONDITIONAL(ARCH_S390X, test x$target_arch = xs390x) AM_CONDITIONAL(OS_LINUX, expr x$target_os : xlinux >/dev/null) AM_CONDITIONAL(OS_HPUX, expr x$target_os : xhpux >/dev/null) AM_CONDITIONAL(OS_FREEBSD, expr x$target_os : xfreebsd >/dev/null) AM_CONDITIONAL(OS_QNX, expr x$target_os : xnto-qnx >/dev/null) -AM_CONDITIONAL(OS_SOLARIS, expr x$target_os : xsolaris >/dev/null) AC_MSG_CHECKING([for ELF helper width]) case "${target_arch}" in (arm|hppa|ppc32|x86|sh) use_elf32=yes; AC_MSG_RESULT([32]);; -(aarch64|ia64|ppc64|x86_64|s390x|tilegx) use_elf64=yes; AC_MSG_RESULT([64]);; +(aarch64|ia64|ppc64|x86_64|tilegx) use_elf64=yes; AC_MSG_RESULT([64]);; (mips) use_elfxx=yes; AC_MSG_RESULT([xx]);; *) AC_MSG_ERROR([Unknown ELF target: ${target_arch}]) esac @@ -306,23 +300,6 @@ fi AC_SUBST([LIBLZMA]) AM_CONDITIONAL(HAVE_LZMA, test x$enable_minidebuginfo = xyes) -LIBZ= -AC_MSG_CHECKING([whether to support ZLIB-compressed symbol tables]) -AC_ARG_ENABLE(zlibdebuginfo, -AS_HELP_STRING([--enable-zlibdebuginfo], [Enables support for ZLIB-compressed symbol tables]),, [enable_zlibdebuginfo=auto]) -AC_MSG_RESULT([$enable_zlibdebuginfo]) -if test x$enable_zlibdebuginfo != xno; then - AC_CHECK_LIB([z], [uncompress], - [LIBZ=-lz - AC_DEFINE([HAVE_ZLIB], [1], [Define if you have libz]) - enable_zlibdebuginfo=yes], - [if test x$enable_zlibdebuginfo = xyes; then - AC_MSG_FAILURE([libz not found]) - fi]) -fi -AC_SUBST([LIBZ]) -AM_CONDITIONAL(HAVE_ZLIB, test x$enable_zlibdebuginfo = xyes) - AC_MSG_CHECKING([whether to support UNW_CACHE_PER_THREAD]) AC_ARG_ENABLE([per-thread-cache], AS_HELP_STRING([--enable-per-thread-cache], [build with support for UNW_CACHE_PER_THREAD (which imposes a hight TLS memory usage) (default: disabled)])) @@ -344,14 +321,6 @@ if test x$GCC = xyes -a x$intel_compiler != xyes; then fi AC_MSG_RESULT([$intel_compiler]) -AC_MSG_CHECKING([if building on Solaris then define __EXTENSIONS__ macro]) -if $OS_SOLARIS; then - CFLAGS="${CFLAGS} -D__EXTENSIONS__" - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - AC_MSG_CHECKING([for QCC compiler]) AS_CASE([$CC], [qcc*|QCC*], [qcc_compiler=yes], [qcc_compiler=no]) AC_MSG_RESULT([$qcc_compiler]) @@ -467,11 +436,6 @@ if test "x$enable_tests" = "xyes"; then AC_CONFIG_FILES(tests/Makefile tests/check-namespace.sh) fi -AM_CONDITIONAL([CONFIG_WEAK_BACKTRACE], [test "x$enable_weak_backtrace" = xyes]) -AM_COND_IF([CONFIG_WEAK_BACKTRACE], [ - AC_DEFINE([CONFIG_WEAK_BACKTRACE], [1], [Define if the weak 'backtrace' symbol is provided.]) -]) - AC_CONFIG_FILES(Makefile src/Makefile include/libunwind-common.h include/libunwind.h include/tdep/libunwind_i.h) diff --git a/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h b/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h index 96002a1b9d2d2..e03750760c529 100644 --- a/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h +++ b/src/coreclr/src/pal/src/libunwind/include/dwarf-eh.h @@ -27,7 +27,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define dwarf_eh_h #include "dwarf.h" -#include "libunwind_i.h" /* This header file defines the format of a DWARF exception-header section (.eh_frame_hdr, pointed to by program-header diff --git a/src/coreclr/src/pal/src/libunwind/include/dwarf.h b/src/coreclr/src/pal/src/libunwind/include/dwarf.h index 764f6f20ac22b..fab93c614518e 100644 --- a/src/coreclr/src/pal/src/libunwind/include/dwarf.h +++ b/src/coreclr/src/pal/src/libunwind/include/dwarf.h @@ -419,7 +419,7 @@ extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t a unw_word_t ip); extern void dwarf_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg); -extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_word_t *addr, +extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, unw_word_t len, unw_word_t *valp, int *is_register); extern int diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h index 2716afccb815b..85812e151d782 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-aarch64.h @@ -44,13 +44,9 @@ extern "C" { leaving some slack for future expansion. Changing this value will require recompiling all users of this library. Stack allocation is relatively cheap and unwind-state copying is relatively rare, so we - want to err on making it rather too big than too small. + want to err on making it rather too big than too small. */ - Calculation is regs used (64 + 34) * 2 + 40 (bytes of rest of - cursor) + padding -*/ - -#define UNW_TDEP_CURSOR_LEN 250 +#define UNW_TDEP_CURSOR_LEN 512 typedef uint64_t unw_word_t; typedef int64_t unw_sword_t; @@ -173,46 +169,15 @@ typedef struct unw_tdep_save_loc unw_tdep_save_loc_t; -/* On AArch64, we can directly use ucontext_t as the unwind context, - * however, the __reserved struct is quite large: tune it down to only - * the necessary used fields. */ - -struct unw_sigcontext - { - uint64_t fault_address; - uint64_t regs[31]; - uint64_t sp; - uint64_t pc; - uint64_t pstate; - uint8_t __reserved[(66 * 8)] __attribute__((__aligned__(16))); -}; - -typedef struct - { - unsigned long uc_flags; - struct ucontext *uc_link; - stack_t uc_stack; - __sigset_t uc_sigmask; - struct unw_sigcontext uc_mcontext; - } unw_tdep_context_t; - -typedef struct - { - uint32_t _ctx_magic; - uint32_t _ctx_size; - uint32_t fpsr; - uint32_t fpcr; - uint64_t vregs[64]; - } unw_fpsimd_context_t; - - +/* On AArch64, we can directly use ucontext_t as the unwind context. */ +typedef ucontext_t unw_tdep_context_t; #include "libunwind-common.h" #include "libunwind-dynamic.h" #define unw_tdep_getcontext(uc) (({ \ unw_tdep_context_t *unw_ctx = (uc); \ - register uint64_t *unw_base __asm__ ("x0") = (uint64_t*) unw_ctx->uc_mcontext.regs; \ + register uint64_t *unw_base asm ("x0") = (uint64_t*) unw_ctx->uc_mcontext.regs; \ __asm__ __volatile__ ( \ "stp x0, x1, [%[base], #0]\n" \ "stp x2, x3, [%[base], #16]\n" \ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in b/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in index 9dbb415f50441..8d96ddca2abc3 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-common.h.in @@ -30,19 +30,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define UNW_VERSION_CODE(maj,min) (((maj) << 16) | (min)) #define UNW_VERSION UNW_VERSION_CODE(UNW_VERSION_MAJOR, UNW_VERSION_MINOR) -#ifdef __sun -// On SmartOS, gcc fails with the following error: -// -// ../include/libunwind-common.h:43:41: error: expected identifier or '(' before numeric constant -// # define UNW_PREFIX UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_) -// ^ -// -// workaround is to undefine _U explicitly. -// see https://github.com/libunwind/libunwind/issues/118 for more details. -// -#undef _U -#endif - #define UNW_PASTE2(x,y) x##y #define UNW_PASTE(x,y) UNW_PASTE2(x,y) #define UNW_OBJ(fn) UNW_PASTE(UNW_PREFIX, fn) @@ -253,6 +240,7 @@ unw_save_loc_t; #define unw_set_fpreg UNW_OBJ(set_fpreg) #define unw_get_save_loc UNW_OBJ(get_save_loc) #define unw_is_signal_frame UNW_OBJ(is_signal_frame) +#define unw_handle_signal_frame UNW_OBJ(handle_signal_frame) #define unw_get_proc_name UNW_OBJ(get_proc_name) #define unw_set_caching_policy UNW_OBJ(set_caching_policy) #define unw_set_cache_size UNW_OBJ(set_cache_size) @@ -285,6 +273,7 @@ extern int unw_get_fpreg (unw_cursor_t *, int, unw_fpreg_t *); extern int unw_set_fpreg (unw_cursor_t *, int, unw_fpreg_t); extern int unw_get_save_loc (unw_cursor_t *, int, unw_save_loc_t *); extern int unw_is_signal_frame (unw_cursor_t *); +extern int unw_handle_signal_frame (unw_cursor_t *); extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *); extern const char *unw_strerror (int); extern int unw_backtrace (void **, int); diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h index ced34b2027af6..97c95e2463ac1 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind-mips.h @@ -98,7 +98,7 @@ typedef enum UNW_MIPS_R30, UNW_MIPS_R31, - UNW_MIPS_PC = 64, + UNW_MIPS_PC = 34, /* FIXME: Other registers! */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h b/src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h deleted file mode 100644 index ebda40d57af9b..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind-s390x.h +++ /dev/null @@ -1,144 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifndef LIBUNWIND_H -#define LIBUNWIND_H - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -#include -#include -#include - -#define UNW_TARGET s390x -#define UNW_TARGET_S390X 1 - -#define _U_TDEP_QP_TRUE 0 /* see libunwind-dynamic.h */ - -/* This needs to be big enough to accommodate "struct cursor", while - leaving some slack for future expansion. Changing this value will - require recompiling all users of this library. Stack allocation is - relatively cheap and unwind-state copying is relatively rare, so we - want to err on making it rather too big than too small. */ -#define UNW_TDEP_CURSOR_LEN 384 - -typedef uint64_t unw_word_t; -typedef int64_t unw_sword_t; - -typedef double unw_tdep_fpreg_t; - -typedef enum - { - /* general purpose registers */ - UNW_S390X_R0, - UNW_S390X_R1, - UNW_S390X_R2, - UNW_S390X_R3, - UNW_S390X_R4, - UNW_S390X_R5, - UNW_S390X_R6, - UNW_S390X_R7, - UNW_S390X_R8, - UNW_S390X_R9, - UNW_S390X_R10, - UNW_S390X_R11, - UNW_S390X_R12, - UNW_S390X_R13, - UNW_S390X_R14, - UNW_S390X_R15, - - /* floating point registers */ - UNW_S390X_F0, - UNW_S390X_F1, - UNW_S390X_F2, - UNW_S390X_F3, - UNW_S390X_F4, - UNW_S390X_F5, - UNW_S390X_F6, - UNW_S390X_F7, - UNW_S390X_F8, - UNW_S390X_F9, - UNW_S390X_F10, - UNW_S390X_F11, - UNW_S390X_F12, - UNW_S390X_F13, - UNW_S390X_F14, - UNW_S390X_F15, - - /* PSW */ - UNW_S390X_IP, - - UNW_TDEP_LAST_REG = UNW_S390X_IP, - - /* TODO: access, vector registers */ - - /* frame info (read-only) */ - UNW_S390X_CFA, - - UNW_TDEP_IP = UNW_S390X_IP, - UNW_TDEP_SP = UNW_S390X_R15, - - /* TODO: placeholders */ - UNW_TDEP_EH = UNW_S390X_R0, - } -s390x_regnum_t; - -#define UNW_TDEP_NUM_EH_REGS 2 /* XXX Not sure what this means */ - -typedef struct unw_tdep_save_loc - { - /* Additional target-dependent info on a save location. */ - char unused; - } -unw_tdep_save_loc_t; - -/* On s390x, we can directly use ucontext_t as the unwind context. */ -typedef ucontext_t unw_tdep_context_t; - -typedef struct - { - /* no s390x-specific auxiliary proc-info */ - char unused; - } -unw_tdep_proc_info_t; - -#include "libunwind-dynamic.h" -#include "libunwind-common.h" - -#define unw_tdep_getcontext UNW_ARCH_OBJ(getcontext) -#define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) - -extern int unw_tdep_getcontext (unw_tdep_context_t *); -extern int unw_tdep_is_fpreg (int); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* LIBUNWIND_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in b/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in index a13e7767325df..7a56168c8b272 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind.h.in @@ -25,8 +25,6 @@ # include "libunwind-x86_64.h" #elif defined __tilegx__ # include "libunwind-tilegx.h" -#elif defined __s390x__ -# include "libunwind-s390x.h" #else # error "Unsupported arch" #endif diff --git a/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h index e0f4540144230..0fcf32695e2ba 100644 --- a/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h +++ b/src/coreclr/src/pal/src/libunwind/include/libunwind_i.h @@ -140,7 +140,6 @@ cmpxchg_ptr (void *addr, void *old, void *new) } # define fetch_and_add1(_ptr) AO_fetch_and_add1(_ptr) # define fetch_and_add(_ptr, value) AO_fetch_and_add(_ptr, value) -# define atomic_read(ptr) (AO_load(ptr)) /* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */ # if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2) # define HAVE_CMPXCHG @@ -165,14 +164,10 @@ cmpxchg_ptr (void *addr, void *old, void *new) } # define fetch_and_add1(_ptr) __sync_fetch_and_add(_ptr, 1) # define fetch_and_add(_ptr, value) __sync_fetch_and_add(_ptr, value) -# define atomic_read(ptr) (__atomic_load_n(ptr,__ATOMIC_RELAXED)) # define HAVE_CMPXCHG # define HAVE_FETCH_AND_ADD #endif - -#ifndef atomic_read #define atomic_read(ptr) (*(ptr)) -#endif #define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn)) #define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn) @@ -368,3 +363,4 @@ static inline void invalidate_edi (struct elf_dyn_info *edi) #define UNW_ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL)) #endif /* libunwind_i_h */ + diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h index 74b821f5c0d70..8006d0b8dd4fe 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/dwarf-config.h @@ -35,6 +35,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ #define dwarf_is_big_endian(addr_space) ((addr_space)->big_endian) +/* Return the size of an address, for DWARF purposes. */ +#define dwarf_addr_size(addr_space) ((addr_space)->addr_size) + /* Convert a pointer to a dwarf_cursor structure to a pointer to unw_cursor_t. */ #define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h index 0c0fd3cf47eb3..3fe40c0c05319 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-mips/libunwind_i.h @@ -247,14 +247,6 @@ dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) 0, c->as_arg); else if (c->as->abi == UNW_MIPS_ABI_O32) return read_s32 (c, DWARF_GET_LOC (loc), val); - else if (c->as->abi == UNW_MIPS_ABI_N32) { - if (tdep_big_endian(c->as)) - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc) + 4, val, - 0, c->as_arg); - else - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - } else return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, 0, c->as_arg); diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h deleted file mode 100644 index ca419bd52acdd..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/dwarf-config.h +++ /dev/null @@ -1,52 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -/* copy of include/tdep-x86/dwarf-config.h, modified slightly for x86-64 - some consolidation is possible here */ - -#ifndef dwarf_config_h -#define dwarf_config_h - -/* derived from DWARF register mappings in Z ELF ABI */ -#define DWARF_NUM_PRESERVED_REGS 66 -#define DWARF_REGNUM_MAP_LENGTH DWARF_NUM_PRESERVED_REGS - -/* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */ -#define dwarf_is_big_endian(addr_space) 1 - -/* Convert a pointer to a dwarf_cursor structure to a pointer to - unw_cursor_t. */ -#define dwarf_to_cursor(c) ((unw_cursor_t *) (c)) - -typedef struct dwarf_loc - { - unw_word_t val; - unw_word_t type; /* see S390X_LOC_TYPE_* macros. */ - } -dwarf_loc_t; - -#endif /* dwarf_config_h */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h deleted file mode 100644 index 509237525553a..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/jmpbuf.h +++ /dev/null @@ -1,35 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#if defined __linux__ - -/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ - -#define JB_SP 9 // __gregs[9] -#define JB_RP 8 // __gregs[8] -#define JB_MASK_SAVED 18 // __mask_was_saved -#define JB_MASK 19 // __saved_mask - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h deleted file mode 100644 index 137a0b8a4f928..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-s390x/libunwind_i.h +++ /dev/null @@ -1,262 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifndef S390X_LIBUNWIND_I_H -#define S390X_LIBUNWIND_I_H - -/* Target-dependent definitions that are internal to libunwind but need - to be shared with target-independent code. */ - -#include -#include - -#include "elf64.h" -#include "mempool.h" -#include "dwarf.h" - -struct unw_addr_space - { - struct unw_accessors acc; - unw_caching_policy_t caching_policy; -#ifdef HAVE_ATOMIC_OPS_H - AO_t cache_generation; -#else - uint32_t cache_generation; -#endif - unw_word_t dyn_generation; /* see dyn-common.h */ - unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ - struct dwarf_rs_cache global_cache; - struct unw_debug_frame_list *debug_frames; - }; - -struct cursor - { - struct dwarf_cursor dwarf; /* must be first */ - - /* Format of sigcontext structure and address at which it is - stored: */ - enum - { - S390X_SCF_NONE = 0, /* no signal frame encountered */ - S390X_SCF_LINUX_SIGFRAME = 1, /* Linux struct sigcontext */ - S390X_SCF_LINUX_RT_SIGFRAME = 2, /* Linux ucontext_t */ - } - sigcontext_format; - unw_word_t sigcontext_addr; - unw_word_t sigcontext_sp; - unw_word_t sigcontext_pc; - int validate; - ucontext_t *uc; - }; - -static inline ucontext_t * -dwarf_get_uc(const struct dwarf_cursor *cursor) -{ - const struct cursor *c = (struct cursor *) cursor->as_arg; - return c->uc; -} - -#define DWARF_GET_LOC(l) ((l).val) -# define DWARF_LOC_TYPE_MEM (0 << 0) -# define DWARF_LOC_TYPE_FP (1 << 0) -# define DWARF_LOC_TYPE_REG (1 << 1) -# define DWARF_LOC_TYPE_VAL (1 << 2) - -# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) -# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) -# define DWARF_IS_MEM_LOC(l) ((l).type == DWARF_LOC_TYPE_MEM) -# define DWARF_IS_VAL_LOC(l) (((l).type & DWARF_LOC_TYPE_VAL) != 0) - -# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) -# define DWARF_VAL_LOC(c,v) DWARF_LOC ((v), DWARF_LOC_TYPE_VAL) -# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), DWARF_LOC_TYPE_MEM) - -#ifdef UNW_LOCAL_ONLY -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) -# define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) -# define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ - tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) - -#else /* !UNW_LOCAL_ONLY */ - -# define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) -# define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) -# define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ - | DWARF_LOC_TYPE_FP)) - -#endif /* !UNW_LOCAL_ONLY */ - -static inline int -dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val) -{ - assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_FP_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - /* FPRs may be saved in GPRs */ - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), (unw_word_t*)val, - 0, c->as_arg); - if (DWARF_IS_MEM_LOC (loc)) - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), (unw_word_t*)val, - 0, c->as_arg); - assert(DWARF_IS_VAL_LOC (loc)); - *val = *(unw_fpreg_t*) DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) -{ - assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); - assert(!DWARF_IS_VAL_LOC (loc)); - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_FP_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - /* FPRs may be saved in GPRs */ - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), (unw_word_t*) &val, - 1, c->as_arg); - - assert(DWARF_IS_MEM_LOC (loc)); - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), (unw_word_t*) &val, - 1, c->as_arg); -} - -static inline int -dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) -{ - assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - if (DWARF_IS_MEM_LOC (loc)) - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, - 0, c->as_arg); - /* GPRs may be saved in FPRs */ - if (DWARF_IS_FP_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), (unw_fpreg_t*)val, - 0, c->as_arg); - assert(DWARF_IS_VAL_LOC (loc)); - *val = DWARF_GET_LOC (loc); - return 0; -} - -static inline int -dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) -{ - assert(sizeof(unw_fpreg_t) == sizeof(unw_word_t)); - assert(!DWARF_IS_VAL_LOC (loc)); - - if (DWARF_IS_NULL_LOC (loc)) - return -UNW_EBADREG; - - if (DWARF_IS_REG_LOC (loc)) - return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); - /* GPRs may be saved in FPRs */ - if (DWARF_IS_FP_LOC (loc)) - return (*c->as->acc.access_fpreg) (c->as, DWARF_GET_LOC (loc), (unw_fpreg_t*) &val, - 1, c->as_arg); - - assert(DWARF_IS_MEM_LOC (loc)); - return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, - 1, c->as_arg); -} - -#define tdep_getcontext_trace unw_getcontext -#define tdep_init_done UNW_OBJ(init_done) -#define tdep_init_mem_validate UNW_OBJ(init_mem_validate) -#define tdep_init UNW_OBJ(init) -/* Platforms that support UNW_INFO_FORMAT_TABLE need to define - tdep_search_unwind_table. */ -#define tdep_search_unwind_table dwarf_search_unwind_table -#define tdep_find_unwind_table dwarf_find_unwind_table -#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) -#define tdep_get_exe_image_path UNW_ARCH_OBJ(get_exe_image_path) -#define tdep_access_reg UNW_OBJ(access_reg) -#define tdep_access_fpreg UNW_OBJ(access_fpreg) -#define tdep_fetch_frame(c,ip,n) do {} while(0) -#define tdep_cache_frame(c) 0 -#define tdep_reuse_frame(c,rs) do {} while(0) -#define tdep_stash_frame(cs,rs) do {} while(0) -#define tdep_trace(cur,addr,n) (-UNW_ENOINFO) -#define tdep_uc_addr UNW_OBJ(uc_addr) - -#ifdef UNW_LOCAL_ONLY -# define tdep_find_proc_info(c,ip,n) \ - dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - dwarf_put_unwind_info((as), (pi), (arg)) -#else -# define tdep_find_proc_info(c,ip,n) \ - (*(c)->as->acc.find_proc_info)((c)->as, (ip), &(c)->pi, (n), \ - (c)->as_arg) -# define tdep_put_unwind_info(as,pi,arg) \ - (*(as)->acc.put_unwind_info)((as), (pi), (arg)) -#endif - -#define tdep_get_as(c) ((c)->dwarf.as) -#define tdep_get_as_arg(c) ((c)->dwarf.as_arg) -#define tdep_get_ip(c) ((c)->dwarf.ip) -#define tdep_big_endian(as) 1 - -extern int tdep_init_done; - -extern void tdep_init (void); -extern void tdep_init_mem_validate (void); -extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, - unw_dyn_info_t *di, unw_proc_info_t *pi, - int need_unwind_info, void *arg); -extern void *tdep_uc_addr (unw_tdep_context_t *uc, int reg); -extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen); -extern void tdep_get_exe_image_path (char *path); -extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, - unw_word_t *valp, int write); -extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, - unw_fpreg_t *valp, int write); - -#endif /* S390X_LIBUNWIND_I_H */ diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h index b2e5332b05966..d57196676db20 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/jmpbuf.h @@ -23,10 +23,9 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if defined __linux__ || defined __sun +#if defined __linux__ -/* Use glibc's jump-buffer indices; NPTL peeks at SP: - https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=sysdeps/x86_64/jmpbuf-offsets.h;h=ea94a1f90554deecceaf995ca5ee485ae8bffab7;hb=HEAD */ +/* Use glibc's jump-buffer indices; NPTL peeks at SP: */ #define JB_SP 6 #define JB_RP 7 diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h index 6b798c7115f3c..283525c16a38d 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h +++ b/src/coreclr/src/pal/src/libunwind/include/tdep-x86_64/libunwind_i.h @@ -89,7 +89,6 @@ struct cursor X86_64_SCF_LINUX_RT_SIGFRAME, /* Linux ucontext_t */ X86_64_SCF_FREEBSD_SIGFRAME, /* FreeBSD signal frame */ X86_64_SCF_FREEBSD_SYSCALL, /* FreeBSD syscall */ - X86_64_SCF_SOLARIS_SIGFRAME, /* illumos/Solaris signal frame */ } sigcontext_format; unw_word_t sigcontext_addr; @@ -233,11 +232,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) #define tdep_get_ip(c) ((c)->dwarf.ip) #define tdep_big_endian(as) 0 -#ifdef HAVE_ATOMIC_OPS_H -extern AO_t tdep_init_done; -#else extern int tdep_init_done; -#endif extern void tdep_init (void); extern void tdep_init_mem_validate (void); diff --git a/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in b/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in index c47299640e8e6..af05a7fba24f9 100644 --- a/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in +++ b/src/coreclr/src/pal/src/libunwind/include/tdep/libunwind_i.h.in @@ -25,8 +25,6 @@ # include "tdep-x86_64/libunwind_i.h" #elif defined __tilegx__ # include "tdep-tilegx/libunwind_i.h" -#elif defined __s390x__ -# include "tdep-s390x/libunwind_i.h" #else # error "Unsupported arch" #endif diff --git a/src/coreclr/src/pal/src/libunwind/libunwind-version.txt b/src/coreclr/src/pal/src/libunwind/libunwind-version.txt deleted file mode 100644 index e96a102894ad4..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/libunwind-version.txt +++ /dev/null @@ -1,2 +0,0 @@ -v1.5-rc2 -https://github.com/libunwind/libunwind/releases/tag/v1.5-rc2 diff --git a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt index 386d8ba326030..891eadd158fa5 100644 --- a/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/libunwind/src/CMakeLists.txt @@ -14,6 +14,8 @@ add_definitions(-DPACKAGE_STRING="") add_definitions(-DPACKAGE_BUGREPORT="") add_definitions(-D_GNU_SOURCE) +# Ensure that the remote and local unwind code can reside in the same binary without name clashing +add_definitions("-Ddwarf_search_unwind_table_int=UNW_OBJ(dwarf_search_unwind_table_int)") # Disable warning due to incorrect format specifier in debugging printf via the Debug macro add_compile_options(-Wno-format -Wno-format-security) @@ -23,8 +25,6 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") else() add_compile_options(-Wno-unused-value) add_compile_options(-Wno-unused-result) - add_compile_options(-Wno-implicit-function-declaration) - add_compile_options(-Wno-incompatible-pointer-types) endif() if(CLR_CMAKE_HOST_ARCH_ARM) @@ -51,10 +51,6 @@ elseif(CLR_CMAKE_HOST_ARCH_ARM64) # Disable warning due to labs function called on unsigned argument add_compile_options(-Wno-absolute-value) endif() - # Issue https://github.com/libunwind/libunwind/issues/176 - if (CLR_CMAKE_HOST_ALPINE_LINUX) - add_definitions("-D__sigset_t=sigset_t") - endif() # We compile code with -std=c99 and the asm keyword is not recognized as it is a gnu extension add_definitions(-Dasm=__asm__) elseif(CLR_CMAKE_HOST_ARCH_I386) @@ -119,14 +115,6 @@ SET(libunwind_la_SOURCES_os_freebsd_local # Nothing ) -SET(libunwind_la_SOURCES_os_solaris - os-solaris.c -) - -SET(libunwind_la_SOURCES_os_solaris_local -# Nothing -) - if(CLR_CMAKE_HOST_LINUX) SET(libunwind_la_SOURCES_os ${libunwind_la_SOURCES_os_linux}) SET(libunwind_la_SOURCES_os_local ${libunwind_la_SOURCES_os_linux_local}) @@ -149,11 +137,6 @@ elseif(CLR_CMAKE_HOST_FREEBSD) SET(libunwind_la_SOURCES_arm_os arm/Gos-freebsd.c) SET(libunwind_la_SOURCES_arm_os_local arm/Los-freebsd.c) list(APPEND libunwind_coredump_la_SOURCES coredump/_UCD_access_reg_freebsd.c) -elseif(CLR_CMAKE_HOST_SUNOS) - SET(libunwind_la_SOURCES_os ${libunwind_la_SOURCES_os_solaris}) - SET(libunwind_la_SOURCES_os_local ${libunwind_la_SOURCES_os_solaris_local}) - SET(libunwind_la_SOURCES_x86_64_os x86_64/Gos-solaris.c) - SET(libunwind_la_SOURCES_x86_64_os_local x86_64/Los-solaris.c) endif() # List of arch-independent files needed by both local-only and generic diff --git a/src/coreclr/src/pal/src/libunwind/src/Makefile.am b/src/coreclr/src/pal/src/libunwind/src/Makefile.am index ff977446a7c2b..a557d8d1f4fb3 100644 --- a/src/coreclr/src/pal/src/libunwind/src/Makefile.am +++ b/src/coreclr/src/pal/src/libunwind/src/Makefile.am @@ -68,7 +68,7 @@ libunwind_coredump_la_SOURCES = \ coredump/_UPT_resume.c libunwind_coredump_la_LDFLAGS = $(COMMON_SO_LDFLAGS) \ -version-info $(COREDUMP_SO_VERSION) -libunwind_coredump_la_LIBADD = $(LIBLZMA) $(LIBZ) +libunwind_coredump_la_LIBADD = $(LIBLZMA) noinst_HEADERS += coredump/_UCD_internal.h coredump/_UCD_lib.h ### libunwind-setjmp: @@ -154,8 +154,6 @@ libunwind_la_SOURCES_os_freebsd = os-freebsd.c libunwind_la_SOURCES_os_qnx = os-qnx.c -libunwind_la_SOURCES_os_solaris = os-solaris.c - libunwind_dwarf_common_la_SOURCES = dwarf/global.c libunwind_dwarf_local_la_SOURCES = \ @@ -183,9 +181,9 @@ noinst_HEADERS += elf32.h elf64.h elfxx.h libunwind_elf32_la_SOURCES = elf32.c libunwind_elf64_la_SOURCES = elf64.c libunwind_elfxx_la_SOURCES = elfxx.c -libunwind_elf32_la_LIBADD = $(LIBLZMA) $(LIBZ) -libunwind_elf64_la_LIBADD = $(LIBLZMA) $(LIBZ) -libunwind_elfxx_la_LIBADD = $(LIBLZMA) $(LIBZ) +libunwind_elf32_la_LIBADD = $(LIBLZMA) +libunwind_elf64_la_LIBADD = $(LIBLZMA) +libunwind_elfxx_la_LIBADD = $(LIBLZMA) noinst_LTLIBRARIES += $(LIBUNWIND_ELF) libunwind_la_LIBADD += $(LIBUNWIND_ELF) @@ -465,30 +463,6 @@ libunwind_sh_la_SOURCES_sh = $(libunwind_la_SOURCES_sh_common) \ sh/Gglobal.c sh/Ginit.c sh/Ginit_local.c sh/Ginit_remote.c \ sh/Gis_signal_frame.c sh/Gregs.c sh/Gresume.c sh/Gstep.c -# The list of files that go both into libunwind and libunwind-s390x: -noinst_HEADERS += s390x/init.h s390x/unwind_i.h -libunwind_la_SOURCES_s390x_common = $(libunwind_la_SOURCES_common) \ - s390x/is_fpreg.c s390x/regname.c - -# The list of files that go into libunwind: -libunwind_la_SOURCES_s390x = $(libunwind_la_SOURCES_s390x_common) \ - $(libunwind_la_SOURCES_local) \ - s390x/Lapply_reg_state.c s390x/Lreg_states_iterate.c \ - s390x/Lcreate_addr_space.c s390x/Lget_save_loc.c s390x/Lglobal.c \ - s390x/Linit.c s390x/Linit_local.c s390x/Linit_remote.c \ - s390x/Lget_proc_info.c s390x/Lregs.c s390x/Lresume.c \ - s390x/Lis_signal_frame.c s390x/Lstep.c \ - s390x/getcontext.S s390x/setcontext.S - -# The list of files that go into libunwind-s390x: -libunwind_s390x_la_SOURCES_s390x = $(libunwind_la_SOURCES_s390x_common) \ - $(libunwind_la_SOURCES_generic) \ - s390x/Gapply_reg_state.c s390x/Greg_states_iterate.c \ - s390x/Gcreate_addr_space.c s390x/Gget_save_loc.c s390x/Gglobal.c \ - s390x/Ginit.c s390x/Ginit_local.c s390x/Ginit_remote.c \ - s390x/Gget_proc_info.c s390x/Gregs.c s390x/Gresume.c \ - s390x/Gis_signal_frame.c s390x/Gstep.c - if REMOTE_ONLY install-exec-hook: # Nothing to do here.... @@ -540,12 +514,6 @@ if OS_FREEBSD libunwind_coredump_la_SOURCES += coredump/_UCD_access_reg_freebsd.c endif -if OS_SOLARIS - libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_solaris) - libunwind_la_SOURCES_x86_64_os = x86_64/Gos-solaris.c - libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-solaris.c -endif - if OS_QNX libunwind_la_SOURCES_os = $(libunwind_la_SOURCES_os_qnx) libunwind_la_SOURCES_os_local = $(libunwind_la_SOURCES_os_qnx_local) @@ -694,19 +662,7 @@ if !REMOTE_ONLY libunwind_sh_la_LIBADD += libunwind.la -lc endif libunwind_setjmp_la_SOURCES += sh/siglongjmp.S -else -if ARCH_S390X - lib_LTLIBRARIES += libunwind-s390x.la - libunwind_la_SOURCES = $(libunwind_la_SOURCES_s390x) - libunwind_s390x_la_SOURCES = $(libunwind_s390x_la_SOURCES_s390x) - libunwind_s390x_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -version-info $(SOVERSION) - libunwind_s390x_la_LIBADD = libunwind-dwarf-generic.la - libunwind_s390x_la_LIBADD += libunwind-elf64.la -if !REMOTE_ONLY - libunwind_s390x_la_LIBADD += libunwind.la -lc -endif -endif # ARCH_S390X endif # ARCH_SH endif # ARCH_PPC64 endif # ARCH_PPC32 @@ -732,7 +688,7 @@ endif libunwind_la_LDFLAGS = $(COMMON_SO_LDFLAGS) -XCClinker -nostdlib \ $(LDFLAGS_STATIC_LIBCXA) -version-info $(SOVERSION) libunwind_la_LIBADD += -lc $(LIBCRTS) -libunwind_la_LIBADD += $(LIBLZMA) $(LIBZ) +libunwind_la_LIBADD += $(LIBLZMA) AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/include/tdep-$(arch) -I. AM_CCASFLAGS = $(AM_CPPFLAGS) @@ -749,7 +705,6 @@ EXTRA_DIST = $(libunwind_la_SOURCES_aarch64) \ $(libunwind_la_SOURCES_os_linux) \ $(libunwind_la_SOURCES_os_hpux) \ $(libunwind_la_SOURCES_os_qnx) \ - $(libunwind_la_SOURCES_os_solaris) \ $(libunwind_la_SOURCES_common) \ $(libunwind_la_SOURCES_local) \ $(libunwind_la_SOURCES_generic) \ diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c index 35389762f27ed..9c4eae8298ee3 100644 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit.c @@ -41,7 +41,7 @@ static struct unw_addr_space local_addr_space; unw_addr_space_t unw_local_addr_space = &local_addr_space; static inline void * -uc_addr (unw_tdep_context_t *uc, int reg) +uc_addr (ucontext_t *uc, int reg) { if (reg >= UNW_AARCH64_X0 && reg < UNW_AARCH64_V0) return &uc->uc_mcontext.regs[reg]; @@ -54,13 +54,20 @@ uc_addr (unw_tdep_context_t *uc, int reg) # ifdef UNW_LOCAL_ONLY HIDDEN void * -tdep_uc_addr (unw_tdep_context_t *uc, int reg) +tdep_uc_addr (ucontext_t *uc, int reg) { return uc_addr (uc, reg); } # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -71,13 +78,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } @@ -103,7 +104,7 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, void *arg) { unw_word_t *addr; - unw_tdep_context_t *uc = arg; + ucontext_t *uc = arg; if (unw_is_fpreg (reg)) goto badreg; @@ -132,7 +133,7 @@ static int access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, int write, void *arg) { - unw_tdep_context_t *uc = arg; + ucontext_t *uc = arg; unw_fpreg_t *addr; if (!unw_is_fpreg (reg)) diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c index 69d4ed3861db9..cd60ca840f508 100644 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Ginit_local.c @@ -59,7 +59,7 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) } int -unw_init_local2 (unw_cursor_t *cursor, unw_tdep_context_t *uc, int flag) +unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) { if (!flag) { diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c index 2cc161360ef53..3d82739293e11 100644 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/Gresume.c @@ -71,7 +71,7 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) char x[sizeof(regs)]; }; - __asm__ __volatile__ ( + asm volatile ( "mov x4, %0\n" "mov x5, %1\n" "ldp x0, x1, [x4]\n" @@ -134,7 +134,7 @@ aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) sc->pc = uc->uc_mcontext.pc; sc->pstate = uc->uc_mcontext.pstate; - __asm__ __volatile__ ( + asm volatile ( "mov sp, %0\n" "ret %1\n" : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) diff --git a/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h index db7e29dd722e9..3d324c2b08bd5 100644 --- a/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h +++ b/src/coreclr/src/pal/src/libunwind/src/aarch64/unwind_i.h @@ -59,6 +59,6 @@ extern int aarch64_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, } while (0) #endif -#define GET_FPCTX(uc) ((unw_fpsimd_context_t *)(&uc->uc_mcontext.__reserved)) +#define GET_FPCTX(uc) ((struct fpsimd_context *)(&uc->uc_mcontext.__reserved)) #endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c index d6573a65e0c7d..e79903cd87d3f 100644 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gex_tables.c @@ -152,13 +152,12 @@ HIDDEN int arm_exidx_decode (const uint8_t *buf, uint8_t len, struct dwarf_cursor *c) { #define READ_OP() *buf++ + assert(buf != NULL); + assert(len > 0); const uint8_t *end = buf + len; int ret; struct arm_exbuf_data edata; - assert(buf != NULL); - assert(len > 0); - while (buf < end) { uint8_t op = READ_OP (); diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c index 0bac0d72da6fe..2720d063a2424 100644 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Ginit.c @@ -57,17 +57,18 @@ tdep_uc_addr (unw_tdep_context_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c index 3b9dfb33e60a7..a8288628a6cd6 100644 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gresume.c @@ -56,7 +56,7 @@ arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) char x[sizeof(regs)]; }; - __asm__ __volatile__ ( + asm __volatile__ ( "ldmia %0, {r4-r12, lr}\n" "mov sp, r12\n" "bx lr\n" @@ -90,7 +90,7 @@ arm_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) /* Set the SP and the PC in order to continue execution at the modified trampoline which restores the signal mask and the registers. */ - __asm__ __volatile__ ( + asm __volatile__ ( "mov sp, %0\n" "bx %1\n" : : "r" (c->sigcontext_sp), "r" (c->sigcontext_pc) diff --git a/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c index 895e8a892afce..516c9f4d1837d 100644 --- a/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c +++ b/src/coreclr/src/pal/src/libunwind/src/arm/Gstep.c @@ -46,8 +46,7 @@ arm_exidx_step (struct cursor *c) c->dwarf.loc[UNW_ARM_R15] = DWARF_NULL_LOC; unw_word_t ip = c->dwarf.ip; if (c->dwarf.use_prev_instr) - /* The least bit denotes thumb/arm mode, clear it. */ - ip = (ip & ~(unw_word_t)0x1) - 1; + --ip; /* check dynamic info first --- it overrides everything else */ ret = unwi_find_dynamic_proc_info (c->dwarf.as, ip, &c->dwarf.pi, 1, @@ -107,20 +106,17 @@ unw_step (unw_cursor_t *cursor) else if (unlikely (ret == -UNW_ESTOPUNWIND)) return ret; - if (ret < 0 && ret != -UNW_ENOINFO) - { - Debug (2, "returning %d\n", ret); - return ret; - } + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } } #endif /* CONFIG_DEBUG_FRAME */ /* Next, try extbl-based unwinding. */ if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)) { - Debug (13, "%s(ret=%d), trying extbl\n", - UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) ? "dwarf_step() failed " : "", - ret); ret = arm_exidx_step (c); if (ret > 0) return 1; @@ -138,12 +134,7 @@ unw_step (unw_cursor_t *cursor) { if (UNW_TRY_METHOD(UNW_ARM_METHOD_FRAME)) { - Debug (13, "%s%s%s%s(ret=%d), trying frame-chain\n", - UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) ? "dwarf_step() " : "", - (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) && UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX)) ? "and " : "", - UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX) ? "arm_exidx_step() " : "", - (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) || UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX)) ? "failed " : "", - ret); + Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret); ret = UNW_ESUCCESS; /* DWARF unwinding failed, try to follow APCS/optimized APCS frame chain */ unw_word_t instr, i; diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c index 930a1148e4f44..0e3a83bdc6ca3 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_freebsd.c @@ -129,26 +129,6 @@ _UCD_access_reg (unw_addr_space_t as, return -UNW_EINVAL; } } -#elif defined(UNW_TARGET_AARCH64) - if (regnum >= UNW_AARCH64_X0 && regnum < UNW_AARCH64_X30) { - *valp = ui->prstatus->pr_reg.x[regnum]; - } else { - switch (regnum) { - case UNW_AARCH64_SP: - *valp = ui->prstatus->pr_reg.sp; - break; - case UNW_AARCH64_X30: - *valp = ui->prstatus->pr_reg.lr; - break; - case UNW_AARCH64_PC: - *valp = ui->prstatus->pr_reg.elr; - break; - default: - Debug(0, "bad regnum:%d\n", regnum); - return -UNW_EINVAL; - } - } - #else #error Port me #endif diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c index 43792f849b3d7..208d8d27b6581 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_access_reg_linux.c @@ -54,9 +54,6 @@ _UCD_access_reg (unw_addr_space_t as, #elif defined(UNW_TARGET_TILEGX) if (regnum > UNW_TILEGX_CFA) goto badreg; -#elif defined(UNW_TARGET_S390X) - if (regnum > UNW_S390X_R15) - goto badreg; #else #if defined(UNW_TARGET_MIPS) static const uint8_t remap_regs[] = diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c index 4c430efb27b53..62f6ee05c793b 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_create.c @@ -259,13 +259,9 @@ _UCD_create(const char *filename) cur->p_flags ); if (cur->p_filesz < cur->p_memsz) - { - Debug(2, " partial"); - } + Debug(2, " partial"); if (cur->p_flags & PF_X) - { - Debug(2, " executable"); - } + Debug(2, " executable"); } Debug(2, "\n"); i++; @@ -342,10 +338,7 @@ int _UCD_add_backing_file_at_segment(struct UCD_info *ui, int phdr_no, const cha phdr->backing_filesize = (uoff_t)statbuf.st_size; if (phdr->p_flags != (PF_X | PF_R)) - { - Debug(1, "Note: phdr[%u] is not r-x: flags are 0x%x\n", - phdr_no, phdr->p_flags); - } + Debug(1, "Note: phdr[%u] is not r-x: flags are 0x%x\n", phdr_no, phdr->p_flags); if (phdr->backing_filesize > phdr->p_memsz) { diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c index 3a4c9b8213c6d..00096c48d0770 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UCD_get_proc_name.c @@ -36,10 +36,6 @@ elf_w (CD_get_proc_name) (struct UCD_info *ui, unw_addr_space_t as, unw_word_t i unsigned long segbase, mapoff; int ret; - /* We're about to map an elf image. If there is an elf image currently mapped, - then make sure to unmap it. */ - invalidate_edi(&ui->edi); - /* Used to be tdep_get_elf_image() in ptrace unwinding code */ coredump_phdr_t *cphdr = _UCD_get_elf_image(ui, ip); if (!cphdr) diff --git a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c index 739ed0569b9e6..0d11905566c30 100644 --- a/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c +++ b/src/coreclr/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c @@ -74,11 +74,6 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, #else -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - static inline int get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, int *countp) diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c index 2af454332dd82..f63c3d220c6bd 100644 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gexpr.c @@ -60,8 +60,6 @@ static const uint8_t operands[256] = [DW_OP_const4s] = OPND1 (VAL32), [DW_OP_const8u] = OPND1 (VAL64), [DW_OP_const8s] = OPND1 (VAL64), - [DW_OP_constu] = OPND1 (ULEB128), - [DW_OP_consts] = OPND1 (SLEB128), [DW_OP_pick] = OPND1 (VAL8), [DW_OP_plus_uconst] = OPND1 (ULEB128), [DW_OP_skip] = OPND1 (VAL16), @@ -237,8 +235,8 @@ dwarf_stack_aligned(struct dwarf_cursor *c, unw_word_t cfa_addr, } HIDDEN int -dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_word_t *addr, - unw_word_t len, unw_word_t *valp, int *is_register) +dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, unw_word_t len, + unw_word_t *valp, int *is_register) { unw_word_t operand1 = 0, operand2 = 0, tmp1, tmp2 = 0, tmp3, end_addr; uint8_t opcode, operands_signature, u8; @@ -287,14 +285,10 @@ do { \ end_addr = *addr + len; *is_register = 0; - Debug (14, "len=%lu, pushing initial value=0x%lx\n", - (unsigned long) len, (unsigned long) stack_val); + Debug (14, "len=%lu, pushing cfa=0x%lx\n", + (unsigned long) len, (unsigned long) c->cfa); - /* The DWARF standard requires the current CFA to be pushed onto the stack */ - /* before evaluating DW_CFA_expression and DW_CFA_val_expression programs. */ - /* DW_CFA_def_cfa_expressions do not take an initial value, but we push on */ - /* a dummy value to keep this logic consistent. */ - push (stack_val); + push (c->cfa); /* push current CFA as required by DWARF spec */ while (*addr < end_addr) { diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c index 0cfb4d4faea05..509ceff47cbe3 100644 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_proc_info-lsb.c @@ -34,10 +34,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "dwarf-eh.h" #include "libunwind_i.h" -#ifdef HAVE_ZLIB -#include -#endif /* HAVE_ZLIB */ - struct table_entry { int32_t start_ip_offset; @@ -50,17 +46,12 @@ struct table_entry #include "os-linux.h" #endif -#ifndef __clang__ static ALIAS(dwarf_search_unwind_table) int dwarf_search_unwind_table_int (unw_addr_space_t as, unw_word_t ip, unw_dyn_info_t *di, unw_proc_info_t *pi, int need_unwind_info, void *arg); -#else -#define dwarf_search_unwind_table_int dwarf_search_unwind_table -#endif - static int linear_search (unw_addr_space_t as, unw_word_t ip, unw_word_t eh_frame_start, unw_word_t eh_frame_end, @@ -127,48 +118,14 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local) return 1; } - if (shdr->sh_flags & SHF_COMPRESSED) - { - unsigned long destSize; - Elf_W (Chdr) *chdr = (shdr->sh_offset + ei.image); -#ifdef HAVE_ZLIB - if (chdr->ch_type == ELFCOMPRESS_ZLIB) - { - *bufsize = destSize = chdr->ch_size; - GET_MEMORY(*buf, *bufsize); - ret = uncompress((unsigned char *)*buf, &destSize, - shdr->sh_offset + ei.image + sizeof(*chdr), - shdr->sh_size - sizeof(*chdr)); - if (ret != Z_OK) - { - Debug (2, "failed to decompress zlib .debug_frame, skipping\n"); - munmap(*buf, *bufsize); - munmap(ei.image, ei.size); - return 1; - } - - Debug (4, "read %zd->%zd bytes of .debug_frame from offset %zd\n", - shdr->sh_size, *bufsize, shdr->sh_offset); - } - else -#endif /* HAVE_ZLIB */ - { - Debug (2, "unknown compression type %d, skipping\n", - chdr->ch_type); - munmap(ei.image, ei.size); - return 1; - } - } - else - { - *bufsize = shdr->sh_size; - GET_MEMORY(*buf, *bufsize); + *bufsize = shdr->sh_size; + *buf = malloc (*bufsize); - memcpy(*buf, shdr->sh_offset + ei.image, *bufsize); + memcpy(*buf, shdr->sh_offset + ei.image, *bufsize); + + Debug (4, "read %zd bytes of .debug_frame from offset %zd\n", + *bufsize, shdr->sh_offset); - Debug (4, "read %zd bytes of .debug_frame from offset %zd\n", - *bufsize, shdr->sh_offset); - } munmap(ei.image, ei.size); return 0; } @@ -251,7 +208,7 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, if (!err) { - GET_MEMORY(fdesc, sizeof (struct unw_debug_frame_list)); + fdesc = malloc (sizeof (struct unw_debug_frame_list)); fdesc->start = start; fdesc->end = end; @@ -266,131 +223,66 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, return fdesc; } -static size_t -debug_frame_index_make (struct unw_debug_frame_list *fdesc) +struct debug_frame_tab + { + struct table_entry *tab; + uint32_t length; + uint32_t size; + }; + +static void +debug_frame_tab_append (struct debug_frame_tab *tab, + unw_word_t fde_offset, unw_word_t start_ip) { - unw_accessors_t *a = unw_get_accessors_int (unw_local_addr_space); - char *buf = fdesc->debug_frame; - size_t bufsize = fdesc->debug_frame_size; - unw_word_t addr = (unw_word_t) (uintptr_t) buf; - size_t count = 0; + unsigned int length = tab->length; - while (addr < (unw_word_t) (uintptr_t) (buf + bufsize)) + if (length == tab->size) { - unw_word_t item_start = addr, item_end = 0; - uint32_t u32val = 0; - uint64_t cie_id = 0; - uint64_t id_for_cie; - - dwarf_readu32 (unw_local_addr_space, a, &addr, &u32val, NULL); - - if (u32val == 0) - break; - - if (u32val != 0xffffffff) - { - uint32_t cie_id32 = 0; - - item_end = addr + u32val; - dwarf_readu32 (unw_local_addr_space, a, &addr, &cie_id32, NULL); - cie_id = cie_id32; - id_for_cie = 0xffffffff; - } - else - { - uint64_t u64val = 0; - - /* Extended length. */ - dwarf_readu64 (unw_local_addr_space, a, &addr, &u64val, NULL); - item_end = addr + u64val; - - dwarf_readu64 (unw_local_addr_space, a, &addr, &cie_id, NULL); - id_for_cie = 0xffffffffffffffffull; - } - - /*Debug (1, "CIE/FDE id = %.8x\n", (int) cie_id);*/ - - if (cie_id == id_for_cie) - { - ; - /*Debug (1, "Found CIE at %.8x.\n", item_start);*/ - } - else - { - unw_word_t fde_addr = item_start; - unw_proc_info_t this_pi; - int err; - - /*Debug (1, "Found FDE at %.8x\n", item_start);*/ - - err = dwarf_extract_proc_info_from_fde (unw_local_addr_space, - a, &fde_addr, - &this_pi, - (uintptr_t) buf, 0, 1, - NULL); - - if (!err) - { - Debug (15, "start_ip = %lx, end_ip = %lx\n", - (long) this_pi.start_ip, (long) this_pi.end_ip); - - if (fdesc->index) - { - struct table_entry *e = &fdesc->index[count]; - - e->fde_offset = item_start - (unw_word_t) (uintptr_t) buf; - e->start_ip_offset = this_pi.start_ip; - } + tab->size *= 2; + tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->size); + } - count++; - } - /*else - Debug (1, "FDE parse failed\n");*/ - } + tab->tab[length].fde_offset = fde_offset; + tab->tab[length].start_ip_offset = start_ip; - addr = item_end; - } - return count; + tab->length = length + 1; } static void -debug_frame_index_sort (struct unw_debug_frame_list *fdesc) +debug_frame_tab_shrink (struct debug_frame_tab *tab) { - size_t i, j, k, n = fdesc->index_size / sizeof (*fdesc->index); - struct table_entry *a = fdesc->index; - struct table_entry t; - - /* Use a simple Shell sort as it relatively fast and - * does not require additional memory. */ - - for (k = n / 2; k > 0; k /= 2) + if (tab->size > tab->length) { - for (i = k; i < n; i++) - { - t = a[i]; - - for (j = i; j >= k; j -= k) - { - if (t.start_ip_offset >= a[j - k].start_ip_offset) - break; + tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->length); + tab->size = tab->length; + } +} - a[j] = a[j - k]; - } +static int +debug_frame_tab_compare (const void *a, const void *b) +{ + const struct table_entry *fa = a, *fb = b; - a[j] = t; - } - } + if (fa->start_ip_offset > fb->start_ip_offset) + return 1; + else if (fa->start_ip_offset < fb->start_ip_offset) + return -1; + else + return 0; } -int +HIDDEN int dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip, unw_word_t segbase, const char* obj_name, unw_word_t start, unw_word_t end) { - unw_dyn_info_t *di = di_debug; - struct unw_debug_frame_list *fdesc; + unw_dyn_info_t *di; + struct unw_debug_frame_list *fdesc = 0; + unw_accessors_t *a; + unw_word_t addr; Debug (15, "Trying to find .debug_frame for %s\n", obj_name); + di = di_debug; fdesc = locate_debug_info (unw_local_addr_space, ip, obj_name, start, end); @@ -399,69 +291,130 @@ dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip, Debug (15, "couldn't load .debug_frame\n"); return found; } - - Debug (15, "loaded .debug_frame\n"); - - if (fdesc->debug_frame_size == 0) - { - Debug (15, "zero-length .debug_frame\n"); - return found; - } - - /* Now create a binary-search table, if it does not already exist. */ - - if (!fdesc->index) + else { - /* Find all FDE entries in debug_frame, and make into a sorted - index. First determine an index element count. */ + char *buf; + size_t bufsize; + unw_word_t item_start, item_end = 0; + uint32_t u32val = 0; + uint64_t cie_id = 0; + struct debug_frame_tab tab; - size_t count = debug_frame_index_make (fdesc); + Debug (15, "loaded .debug_frame\n"); - if (!count) - { - Debug (15, "no CIE/FDE found in .debug_frame\n"); - return found; - } + buf = fdesc->debug_frame; + bufsize = fdesc->debug_frame_size; - fdesc->index_size = count * sizeof (*fdesc->index); - GET_MEMORY (fdesc->index, fdesc->index_size); + if (bufsize == 0) + { + Debug (15, "zero-length .debug_frame\n"); + return found; + } + /* Now create a binary-search table, if it does not already exist. */ if (!fdesc->index) - { - Debug (15, "couldn't allocate a frame index table\n"); - fdesc->index_size = 0; - return found; - } - - /* Then fill and sort the index. */ - - debug_frame_index_make (fdesc); - debug_frame_index_sort (fdesc); - - /*for (i = 0; i < count; i++) - { - const struct table_entry *e = &fdesc->index[i]; - - Debug (15, "ip %x, FDE offset %x\n", - e->start_ip_offset, e->fde_offset); - }*/ + { + addr = (unw_word_t) (uintptr_t) buf; + + a = unw_get_accessors_int (unw_local_addr_space); + + /* Find all FDE entries in debug_frame, and make into a sorted + index. */ + + tab.length = 0; + tab.size = 16; + tab.tab = calloc (tab.size, sizeof (struct table_entry)); + + while (addr < (unw_word_t) (uintptr_t) (buf + bufsize)) + { + uint64_t id_for_cie; + item_start = addr; + + dwarf_readu32 (unw_local_addr_space, a, &addr, &u32val, NULL); + + if (u32val == 0) + break; + else if (u32val != 0xffffffff) + { + uint32_t cie_id32 = 0; + item_end = addr + u32val; + dwarf_readu32 (unw_local_addr_space, a, &addr, &cie_id32, + NULL); + cie_id = cie_id32; + id_for_cie = 0xffffffff; + } + else + { + uint64_t u64val = 0; + /* Extended length. */ + dwarf_readu64 (unw_local_addr_space, a, &addr, &u64val, NULL); + item_end = addr + u64val; + + dwarf_readu64 (unw_local_addr_space, a, &addr, &cie_id, NULL); + id_for_cie = 0xffffffffffffffffull; + } + + /*Debug (1, "CIE/FDE id = %.8x\n", (int) cie_id);*/ + + if (cie_id == id_for_cie) + ; + /*Debug (1, "Found CIE at %.8x.\n", item_start);*/ + else + { + unw_word_t fde_addr = item_start; + unw_proc_info_t this_pi; + int err; + + /*Debug (1, "Found FDE at %.8x\n", item_start);*/ + + err = dwarf_extract_proc_info_from_fde (unw_local_addr_space, + a, &fde_addr, + &this_pi, + (uintptr_t) buf, 0, 1, + NULL); + if (err == 0) + { + Debug (15, "start_ip = %lx, end_ip = %lx\n", + (long) this_pi.start_ip, (long) this_pi.end_ip); + debug_frame_tab_append (&tab, + item_start - (unw_word_t) (uintptr_t) buf, + this_pi.start_ip); + } + /*else + Debug (1, "FDE parse failed\n");*/ + } + + addr = item_end; + } + + debug_frame_tab_shrink (&tab); + qsort (tab.tab, tab.length, sizeof (struct table_entry), + debug_frame_tab_compare); + /* for (i = 0; i < tab.length; i++) + { + fprintf (stderr, "ip %x, fde offset %x\n", + (int) tab.tab[i].start_ip_offset, + (int) tab.tab[i].fde_offset); + }*/ + fdesc->index = tab.tab; + fdesc->index_size = tab.length; + } + + di->format = UNW_INFO_FORMAT_TABLE; + di->start_ip = fdesc->start; + di->end_ip = fdesc->end; + di->u.ti.name_ptr = (unw_word_t) (uintptr_t) obj_name; + di->u.ti.table_data = (unw_word_t *) fdesc; + di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t); + di->u.ti.segbase = segbase; + + found = 1; + Debug (15, "found debug_frame table `%s': segbase=0x%lx, len=%lu, " + "gp=0x%lx, table_data=0x%lx\n", + (char *) (uintptr_t) di->u.ti.name_ptr, + (long) di->u.ti.segbase, (long) di->u.ti.table_len, + (long) di->gp, (long) di->u.ti.table_data); } - - di->format = UNW_INFO_FORMAT_TABLE; - di->start_ip = fdesc->start; - di->end_ip = fdesc->end; - di->u.ti.name_ptr = (unw_word_t) (uintptr_t) obj_name; - di->u.ti.table_data = (unw_word_t *) fdesc; - di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t); - di->u.ti.segbase = segbase; - - found = 1; - Debug (15, "found debug_frame table `%s': segbase=0x%lx, len=%lu, " - "gp=0x%lx, table_data=0x%lx\n", - (char *) (uintptr_t) di->u.ti.name_ptr, - (long) di->u.ti.segbase, (long) di->u.ti.table_len, - (long) di->gp, (long) di->u.ti.table_data); - return found; } @@ -572,10 +525,6 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) } else if (phdr->p_type == PT_GNU_EH_FRAME) p_eh_hdr = phdr; -#if defined __sun - else if (phdr->p_type == PT_SUNW_UNWIND) - p_eh_hdr = phdr; -#endif else if (phdr->p_type == PT_DYNAMIC) p_dynamic = phdr; } @@ -657,15 +606,11 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) /* If there is no search table or it has an unsupported encoding, fall back on linear search. */ if (hdr->table_enc == DW_EH_PE_omit) - { - Debug (4, "table `%s' lacks search table; doing linear search\n", - info->dlpi_name); - } + Debug (4, "table `%s' lacks search table; doing linear search\n", + info->dlpi_name); else - { - Debug (4, "table `%s' has encoding 0x%x; doing linear search\n", - info->dlpi_name, hdr->table_enc); - } + Debug (4, "table `%s' has encoding 0x%x; doing linear search\n", + info->dlpi_name, hdr->table_enc); eh_frame_end = max_load_addr; /* XXX can we do better? */ @@ -898,7 +843,7 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip, endianness is the target one. */ as = unw_local_addr_space; table = fdesc->index; - table_len = fdesc->index_size; + table_len = fdesc->index_size * sizeof (struct table_entry); debug_frame_base = (uintptr_t) fdesc->debug_frame; #endif } diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c index f5f7ad06c3b67..6a2ad504078af 100644 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gfind_unwind_table.c @@ -80,9 +80,6 @@ dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as, break; case PT_GNU_EH_FRAME: -#if defined __sun - case PT_SUNW_UNWIND: -#endif peh_hdr = phdr + i; break; diff --git a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c index 28fd73c6b0f7f..7d255aeeaf3c9 100644 --- a/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c +++ b/src/coreclr/src/pal/src/libunwind/src/dwarf/Gparser.c @@ -440,15 +440,8 @@ fetch_proc_info (struct dwarf_cursor *c, unw_word_t ip) continue, and it's important we get this right, as 'ip' could be right at the function entry and hence FDE edge, or at instruction that manipulates CFA (push/pop). */ - if (c->use_prev_instr) - { -#if defined(__arm__) - /* On arm, the least bit denotes thumb/arm mode, clear it. */ - ip &= ~(unw_word_t)0x1; -#endif - --ip; - } + --ip; memset (&c->pi, 0, sizeof (c->pi)); @@ -741,7 +734,7 @@ create_state_record_for (struct dwarf_cursor *c, dwarf_state_record_t *sr, } static inline int -eval_location_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_addr_space_t as, +eval_location_expr (struct dwarf_cursor *c, unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr, dwarf_loc_t *locp, void *arg) { @@ -753,7 +746,7 @@ eval_location_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_addr_space return ret; /* evaluate the expression: */ - if ((ret = dwarf_eval_expr (c, stack_val, &addr, len, &val, &is_register)) < 0) + if ((ret = dwarf_eval_expr (c, &addr, len, &val, &is_register)) < 0) return ret; if (is_register) @@ -811,10 +804,7 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) assert (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_EXPR); addr = rs->reg.val[DWARF_CFA_REG_COLUMN]; - /* The dwarf standard doesn't specify an initial value to be pushed on */ - /* the stack before DW_CFA_def_cfa_expression evaluation. We push on a */ - /* dummy value (0) to keep the eval_location_expr function consistent. */ - if ((ret = eval_location_expr (c, 0, as, a, addr, &cfa_loc, arg)) < 0) + if ((ret = eval_location_expr (c, as, a, addr, &cfa_loc, arg)) < 0) return ret; /* the returned location better be a memory location... */ if (DWARF_IS_REG_LOC (cfa_loc)) @@ -841,30 +831,18 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) break; case DWARF_WHERE_REG: -#ifdef __s390x__ - /* GPRs can be saved in FPRs on s390x */ - if (unw_is_fpreg (dwarf_to_unw_regnum (rs->reg.val[i]))) - { - new_loc[i] = DWARF_FPREG_LOC (c, dwarf_to_unw_regnum (rs->reg.val[i])); - break; - } -#endif - new_loc[i] = new_loc[rs->reg.val[i]]; + new_loc[i] = DWARF_REG_LOC (c, dwarf_to_unw_regnum (rs->reg.val[i])); break; case DWARF_WHERE_EXPR: addr = rs->reg.val[i]; - /* The dwarf standard requires the current CFA to be pushed on the */ - /* stack before DW_CFA_expression evaluation. */ - if ((ret = eval_location_expr (c, cfa, as, a, addr, new_loc + i, arg)) < 0) + if ((ret = eval_location_expr (c, as, a, addr, new_loc + i, arg)) < 0) return ret; break; case DWARF_WHERE_VAL_EXPR: addr = rs->reg.val[i]; - /* The dwarf standard requires the current CFA to be pushed on the */ - /* stack before DW_CFA_val_expression evaluation. */ - if ((ret = eval_location_expr (c, cfa, as, a, addr, new_loc + i, arg)) < 0) + if ((ret = eval_location_expr (c, as, a, addr, new_loc + i, arg)) < 0) return ret; new_loc[i] = DWARF_VAL_LOC (c, DWARF_GET_LOC (new_loc[i])); break; @@ -946,6 +924,7 @@ find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr) unsigned short index = -1; if (cache) { + put_rs_cache (c->as, cache, &saved_mask); if (rs) { index = rs - cache->buckets; @@ -953,7 +932,6 @@ find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr) cache->links[c->prev_rs].hint = index + 1; c->prev_rs = index; } - put_rs_cache (c->as, cache, &saved_mask); } if (ret < 0) return ret; diff --git a/src/coreclr/src/pal/src/libunwind/src/elfxx.c b/src/coreclr/src/pal/src/libunwind/src/elfxx.c index 2589a3d43b628..b03dfcb734cda 100644 --- a/src/coreclr/src/pal/src/libunwind/src/elfxx.c +++ b/src/coreclr/src/pal/src/libunwind/src/elfxx.c @@ -28,7 +28,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include -#include #ifdef HAVE_LZMA #include diff --git a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c index 265455a68c82a..461e4b93da65f 100644 --- a/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/hppa/Ginit.c @@ -64,6 +64,13 @@ _Uhppa_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -74,13 +81,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c index 8601bb3ca885f..b09a2ad57c7a7 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/ia64/Ginit.c @@ -68,7 +68,6 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, if (!_U_dyn_info_list_addr) return -UNW_ENOINFO; #endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. *dyn_info_list_addr = _U_dyn_info_list_addr (); return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c index 2e7c62e5e8623..98d35012861cf 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c @@ -49,7 +49,6 @@ local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, return -UNW_ENOINFO; #endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. list = (unw_dyn_info_list_t *) (uintptr_t) _U_dyn_info_list_addr (); for (di = list->first; di; di = di->next) if (ip >= di->start_ip && ip < di->end_ip) diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c index 0b77fa59523cd..840d9007f4c1d 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c +++ b/src/coreclr/src/pal/src/libunwind/src/mi/Gget_proc_name.c @@ -106,15 +106,7 @@ unw_get_proc_name (unw_cursor_t *cursor, char *buf, size_t buf_len, ip = tdep_get_ip (c); #if !defined(__ia64__) if (c->dwarf.use_prev_instr) - { -#if defined(__arm__) - /* On arm, the least bit denotes thumb/arm mode, clear it. */ - ip &= ~(unw_word_t)0x1; -#endif - --ip; - } - - + --ip; #endif error = get_proc_name (tdep_get_as (c), ip, buf, buf_len, offp, tdep_get_as_arg (c)); diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c b/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c index b28151370cdcc..c7aa2bdcdcbf0 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c +++ b/src/coreclr/src/pal/src/libunwind/src/mi/backtrace.c @@ -23,9 +23,9 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined(UNW_REMOTE_ONLY) && !defined(UNW_LOCAL_ONLY) -#define UNW_LOCAL_ONLY +#ifndef UNW_REMOTE_ONLY +#define UNW_LOCAL_ONLY #include #include #include @@ -75,9 +75,7 @@ unw_backtrace (void **buffer, int size) return n; } -#ifdef CONFIG_WEAK_BACKTRACE extern int backtrace (void **buffer, int size) WEAK ALIAS(unw_backtrace); -#endif #endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c b/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c index f2b01158a0ec7..cbd93e1a11cff 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c +++ b/src/coreclr/src/pal/src/libunwind/src/mi/flush_cache.c @@ -30,24 +30,21 @@ unw_flush_cache (unw_addr_space_t as, unw_word_t lo, unw_word_t hi) { #if !UNW_TARGET_IA64 struct unw_debug_frame_list *w = as->debug_frames; +#endif - while (w) - { - struct unw_debug_frame_list *n = w->next; + /* clear dyn_info_list_addr cache: */ + as->dyn_info_list_addr = 0; +#if !UNW_TARGET_IA64 + for (; w; w = w->next) + { if (w->index) - munmap (w->index, w->index_size); - - munmap (w->debug_frame, w->debug_frame_size); - munmap (w, sizeof (*w)); - w = n; + free (w->index); + free (w->debug_frame); } as->debug_frames = NULL; #endif - /* clear dyn_info_list_addr cache: */ - as->dyn_info_list_addr = 0; - /* This lets us flush caches lazily. The implementation currently ignores the flush range arguments (lo-hi). This is OK because unw_flush_cache() is allowed to flush more than the requested diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c index 24e0d3b1536a2..493d03db662b9 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gcreate_addr_space.c @@ -58,15 +58,8 @@ unw_create_addr_space (unw_accessors_t *a, int byte_order) as->big_endian = (byte_order == __BIG_ENDIAN); /* FIXME! There is no way to specify the ABI. */ -#if _MIPS_SIM == _ABIO32 as->abi = UNW_MIPS_ABI_O32; -#elif _MIPS_SIM == _ABIN32 - as->abi = UNW_MIPS_ABI_N32; -#elif _MIPS_SIM == _ABI64 - as->abi = UNW_MIPS_ABI_N64; -#else -# error Unsupported ABI -#endif + as->addr_size = 4; return as; #endif diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c index 04c4326d45c69..7b84be87b917d 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gget_proc_info.c @@ -30,14 +30,11 @@ unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) struct cursor *c = (struct cursor *) cursor; int ret; + /* We can only unwind using Dwarf into on MIPS: return failure code + if it's not present. */ ret = dwarf_make_proc_info (&c->dwarf); - if (ret < 0) { - /* Construct a dummy proc info if Dwarf failed */ - memset (pi, 0, sizeof (*pi)); - pi->start_ip = c->dwarf.ip; - pi->end_ip = c->dwarf.ip + 4; - return 0; - } + if (ret < 0) + return ret; *pi = c->dwarf.pi; return 0; diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c index bf7a8f5a8f444..3df170c754934 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Ginit.c @@ -69,6 +69,13 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -79,13 +86,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c index e967324d67d6e..95194022d2be1 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gregs.c @@ -63,7 +63,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, case UNW_MIPS_R26: case UNW_MIPS_R27: case UNW_MIPS_R28: - + case UNW_MIPS_R29: case UNW_MIPS_R30: case UNW_MIPS_R31: loc = c->dwarf.loc[reg - UNW_MIPS_R0]; @@ -75,7 +75,6 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, loc = c->dwarf.loc[reg]; break; - case UNW_MIPS_R29: case UNW_MIPS_CFA: if (write) return -UNW_EREADONLYREG; diff --git a/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c index 0235d523f0399..937136aef1f76 100644 --- a/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c +++ b/src/coreclr/src/pal/src/libunwind/src/mips/Gstep.c @@ -110,96 +110,6 @@ mips_handle_signal_frame (unw_cursor_t *cursor) return 1; } - - -static inline -int is_valid_fp_val(unw_word_t cfa_val, unw_word_t fp_val) -{ - return fp_val > 0 && cfa_val > 0 && fp_val >cfa_val && (fp_val - cfa_val < 0x4000); -} - -static int _step_n64(struct cursor *c) -{ - #define FP_REG UNW_MIPS_R30 - #define SP_REG UNW_MIPS_R29 - #define RA_REG UNW_MIPS_R31 - - //TODO:handle plt entry - int ret; - unw_word_t current_fp_val = 0; - unw_word_t current_ra_val = 0; - unw_word_t current_sp_val = 0; - struct dwarf_loc up_fp_loc = DWARF_NULL_LOC; - struct dwarf_loc up_ra_loc = DWARF_NULL_LOC; - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[SP_REG], ¤t_sp_val); - if (ret < 0) - { - Debug (2, "returning %d [SP=0x%lx]\n", ret, - DWARF_GET_LOC (c->dwarf.loc[FP_REG])); - return ret; - } - ret = dwarf_get (&c->dwarf, c->dwarf.loc[FP_REG], ¤t_fp_val); - if (ret < 0) - { - Debug (2, "returning %d [FP=0x%lx]\n", ret, - DWARF_GET_LOC (c->dwarf.loc[FP_REG])); - return ret; - } - ret = dwarf_get (&c->dwarf, c->dwarf.loc[RA_REG], ¤t_ra_val); - if (ret < 0) - { - Debug (2, "returning %d [RA=0x%lx]\n", ret, - DWARF_GET_LOC (c->dwarf.loc[RA_REG])); - return ret; - } - - Debug(2, "BEGIN GUESSING WITH SP:%p FP:%p CFA:%p at %p, RA:%p\n", - current_sp_val, current_fp_val, c->dwarf.cfa, - c->dwarf.ip, current_ra_val - ); - - if (current_fp_val == current_sp_val) { - // Don't adjust FP - up_fp_loc = c->dwarf.loc[FP_REG]; - up_ra_loc = c->dwarf.loc[RA_REG]; - } else if (is_valid_fp_val(c->dwarf.cfa, current_fp_val)) { - /* Heuristic to determine incorrect guess. For FP to be a - valid frame it needs to be above current CFA, but don't - let it go more than a little. Note that we can't deduce - anything about new FP (fp1) since it may not be a frame - pointer in the frame above. Just check we get the value. */ - up_fp_loc = DWARF_MEM_LOC (c, current_fp_val+16); - up_ra_loc = DWARF_MEM_LOC (c, current_fp_val+24); - unw_word_t up_fp_val = 0; - ret = dwarf_get (&c->dwarf, up_fp_loc, &up_fp_val); - if (ret > 0 && is_valid_fp_val(current_fp_val, up_fp_val)) { - c->dwarf.loc[FP_REG] = up_fp_loc; - } - } - - if (DWARF_IS_NULL_LOC (up_fp_loc)) - { - ret = 0; - Debug (2, "NULL %%fp loc, returning %d\n", ret); - return ret; - } - - c->dwarf.loc[UNW_MIPS_PC] = c->dwarf.loc[RA_REG]; - c->dwarf.loc[RA_REG] = up_ra_loc; - c->dwarf.loc[SP_REG] = up_fp_loc; - c->dwarf.loc[FP_REG] = up_fp_loc; - c->dwarf.use_prev_instr = 1; - - if (c->dwarf.ip == current_ra_val && current_fp_val == current_sp_val) { - // Backtrace stopped: frame did not save the PC - c->dwarf.ip = 0; - } else { - c->dwarf.ip = current_ra_val; - } - return (c->dwarf.ip == 0) ? 0 : 1; -} - int unw_step (unw_cursor_t *cursor) { @@ -214,11 +124,9 @@ unw_step (unw_cursor_t *cursor) if (unlikely (ret == -UNW_ESTOPUNWIND)) return ret; -#if _MIPS_SIM == _ABI64 + /* Dwarf unwinding didn't work, stop. */ if (unlikely (ret < 0)) - { - return _step_n64(c); - } -#endif + return 0; + return (c->dwarf.ip == 0) ? 0 : 1; } diff --git a/src/coreclr/src/pal/src/libunwind/src/os-solaris.c b/src/coreclr/src/pal/src/libunwind/src/os-solaris.c deleted file mode 100644 index 3c140ef29c93e..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/os-solaris.c +++ /dev/null @@ -1,73 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003-2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include - -#include "libunwind_i.h" -#include "os-linux.h" // using linux header for map_iterator implementation - -int -tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, - unsigned long *segbase, unsigned long *mapoff, - char *path, size_t pathlen) -{ - struct map_iterator mi; - int found = 0, rc; - unsigned long hi; - - if (maps_init (&mi, pid) < 0) - return -1; - - while (maps_next (&mi, segbase, &hi, mapoff)) - if (ip >= *segbase && ip < hi) - { - found = 1; - break; - } - - if (!found) - { - maps_close (&mi); - return -1; - } - if (path) - { - strncpy(path, mi.path, pathlen); - } - rc = elf_map_image (ei, mi.path); - maps_close (&mi); - return rc; -} - -#ifndef UNW_REMOTE_ONLY - -void -tdep_get_exe_image_path (char *path) -{ - strcpy(path, getexecname()); -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c index 7b45455807c89..ba302448a314b 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/ppc32/Ginit.c @@ -91,6 +91,9 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -101,13 +104,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c index 7bfb395a7923c..4c88cd6e77ff0 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/ppc64/Ginit.c @@ -95,6 +95,9 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -105,13 +108,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c index 37cd4ffe1c2f7..2b92462fa927f 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_access_fpreg.c @@ -84,9 +84,6 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, #elif defined(__arm__) if ((unsigned) reg < UNW_ARM_F0 || (unsigned) reg > UNW_ARM_F7) return -UNW_EBADREG; -#elif defined(__aarch64__) - if ((unsigned) reg < UNW_AARCH64_V0 || (unsigned) reg > UNW_AARCH64_V31) - return -UNW_EBADREG; #else #error Fix me #endif @@ -102,8 +99,6 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, memcpy(&fpreg.fpr_acc[reg], val, sizeof(unw_fpreg_t)); #elif defined(__arm__) memcpy(&fpreg.fpr[reg], val, sizeof(unw_fpreg_t)); -#elif defined(__aarch64__) - memcpy(&fpreg.fp_q[reg], val, sizeof(unw_fpreg_t)); #else #error Fix me #endif @@ -116,8 +111,6 @@ _UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, memcpy(val, &fpreg.fpr_acc[reg], sizeof(unw_fpreg_t)); #elif defined(__arm__) memcpy(val, &fpreg.fpr[reg], sizeof(unw_fpreg_t)); -#elif defined(__aarch64__) - memcpy(val, &fpreg.fp_q[reg], sizeof(unw_fpreg_t)); #else #error Fix me #endif diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c index 16671d453e1f2..cc5ed0441865e 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c @@ -71,11 +71,6 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, #else -/* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with - DWARF2 unwind info. */ - static inline int get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, int *countp) diff --git a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c index 52be799980db3..c82d1c9887295 100644 --- a/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c +++ b/src/coreclr/src/pal/src/libunwind/src/ptrace/_UPT_reg_offset.c @@ -632,40 +632,6 @@ const int _UPT_reg_offset[UNW_REG_LAST + 1] = [UNW_TILEGX_R54] = 0x1b0, [UNW_TILEGX_R55] = 0x1b8, [UNW_TILEGX_PC] = 0x1a0 -#elif defined(UNW_TARGET_S390X) - [UNW_S390X_R0] = 0x10, - [UNW_S390X_R1] = 0x18, - [UNW_S390X_R2] = 0x20, - [UNW_S390X_R3] = 0x28, - [UNW_S390X_R4] = 0x30, - [UNW_S390X_R5] = 0x38, - [UNW_S390X_R6] = 0x40, - [UNW_S390X_R7] = 0x48, - [UNW_S390X_R8] = 0x50, - [UNW_S390X_R9] = 0x58, - [UNW_S390X_R10] = 0x60, - [UNW_S390X_R11] = 0x68, - [UNW_S390X_R12] = 0x70, - [UNW_S390X_R13] = 0x78, - [UNW_S390X_R14] = 0x80, - [UNW_S390X_R15] = 0x88, - [UNW_S390X_F0] = 0xe0, - [UNW_S390X_F1] = 0xe8, - [UNW_S390X_F2] = 0xf0, - [UNW_S390X_F3] = 0xf8, - [UNW_S390X_F4] = 0x100, - [UNW_S390X_F5] = 0x108, - [UNW_S390X_F6] = 0x110, - [UNW_S390X_F7] = 0x118, - [UNW_S390X_F8] = 0x120, - [UNW_S390X_F9] = 0x128, - [UNW_S390X_F10] = 0x130, - [UNW_S390X_F11] = 0x138, - [UNW_S390X_F12] = 0x140, - [UNW_S390X_F13] = 0x148, - [UNW_S390X_F14] = 0x150, - [UNW_S390X_F15] = 0x150, - [UNW_S390X_IP] = 0x08 #else # error Fix me. #endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c deleted file mode 100644 index 82f056da67ebf..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gapply_reg_state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_apply_reg_state (unw_cursor_t *cursor, - void *reg_states_data) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_apply_reg_state (&c->dwarf, (dwarf_reg_state_t *)reg_states_data); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c deleted file mode 100644 index d411454932bc4..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gcreate_addr_space.c +++ /dev/null @@ -1,62 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Copyright (C) 2012 Tommi Rantala - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" - -#if defined(_BIG_ENDIAN) && !defined(__BIG_ENDIAN) -#define __BIG_ENDIAN _BIG_ENDIAN -#endif - -unw_addr_space_t -unw_create_addr_space (unw_accessors_t *a, int byte_order) -{ -#ifdef UNW_LOCAL_ONLY - return NULL; -#else - unw_addr_space_t as; - - /* - * s390x supports only big-endian. - */ - if (byte_order != 0 && byte_order != __BIG_ENDIAN) - return NULL; - - as = malloc (sizeof (*as)); - if (!as) - return NULL; - - memset (as, 0, sizeof (*as)); - - as->acc = *a; - - return as; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c deleted file mode 100644 index 50de1e423c2c9..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_proc_info.c +++ /dev/null @@ -1,48 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_get_proc_info (unw_cursor_t *cursor, unw_proc_info_t *pi) -{ - struct cursor *c = (struct cursor *) cursor; - - if (dwarf_make_proc_info (&c->dwarf) < 0) - { - /* On x86-64, some key routines such as _start() and _dl_start() - are missing DWARF unwind info. We don't want to fail in that - case, because those frames are uninteresting and just mark - the end of the frame-chain anyhow. */ - memset (pi, 0, sizeof (*pi)); - pi->start_ip = c->dwarf.ip; - pi->end_ip = c->dwarf.ip + 1; - return 0; - } - *pi = c->dwarf.pi; - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c deleted file mode 100644 index dc462c966e567..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gget_save_loc.c +++ /dev/null @@ -1,86 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) -{ - struct cursor *c = (struct cursor *) cursor; - dwarf_loc_t loc; - - loc = DWARF_NULL_LOC; /* default to "not saved" */ - - switch (reg) - { - case UNW_S390X_R6: - case UNW_S390X_R7: - case UNW_S390X_R8: - case UNW_S390X_R9: - case UNW_S390X_R10: - case UNW_S390X_R11: - case UNW_S390X_R12: - case UNW_S390X_R13: - case UNW_S390X_R15: - case UNW_S390X_F8: - case UNW_S390X_F9: - case UNW_S390X_F10: - case UNW_S390X_F11: - case UNW_S390X_F12: - case UNW_S390X_F13: - case UNW_S390X_F14: - case UNW_S390X_F15: - loc = c->dwarf.loc[reg]; - break; - - default: - break; - } - - memset (sloc, 0, sizeof (*sloc)); - - if (DWARF_IS_NULL_LOC (loc)) - { - sloc->type = UNW_SLT_NONE; - return 0; - } - -#if !defined(UNW_LOCAL_ONLY) - if (DWARF_IS_REG_LOC (loc)) - { - sloc->type = UNW_SLT_REG; - sloc->u.regnum = DWARF_GET_LOC (loc); - } - else -#endif - { - sloc->type = UNW_SLT_MEMORY; - sloc->u.addr = DWARF_GET_LOC (loc); - } - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c deleted file mode 100644 index e2abe89d30743..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gglobal.c +++ /dev/null @@ -1,101 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "config.h" -#include "unwind_i.h" -#include "dwarf_i.h" - -HIDDEN define_lock (s390x_lock); -HIDDEN int tdep_init_done; - -/* The API register numbers are exactly the same as the .eh_frame - registers, for now at least. */ -HIDDEN const uint8_t dwarf_to_unw_regnum_map[DWARF_NUM_PRESERVED_REGS] = - { - UNW_S390X_R0, - UNW_S390X_R1, - UNW_S390X_R2, - UNW_S390X_R3, - UNW_S390X_R4, - UNW_S390X_R5, - UNW_S390X_R6, - UNW_S390X_R7, - UNW_S390X_R8, - UNW_S390X_R9, - UNW_S390X_R10, - UNW_S390X_R11, - UNW_S390X_R12, - UNW_S390X_R13, - UNW_S390X_R14, - UNW_S390X_R15, - - UNW_S390X_F0, - UNW_S390X_F2, - UNW_S390X_F4, - UNW_S390X_F6, - UNW_S390X_F1, - UNW_S390X_F3, - UNW_S390X_F5, - UNW_S390X_F7, - UNW_S390X_F8, - UNW_S390X_F10, - UNW_S390X_F12, - UNW_S390X_F14, - UNW_S390X_F9, - UNW_S390X_F11, - UNW_S390X_F13, - UNW_S390X_F15, - }; - -HIDDEN void -tdep_init (void) -{ - intrmask_t saved_mask; - - sigfillset (&unwi_full_mask); - - lock_acquire (&s390x_lock, saved_mask); - { - if (tdep_init_done) - /* another thread else beat us to it... */ - goto out; - - mi_init (); - - dwarf_init (); - - tdep_init_mem_validate (); - -#ifndef UNW_REMOTE_ONLY - s390x_local_addr_space_init (); -#endif - tdep_init_done = 1; /* signal that we're initialized... */ - } - out: - lock_release (&s390x_lock, saved_mask); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c deleted file mode 100644 index db01743c06276..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit.c +++ /dev/null @@ -1,365 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002 Hewlett-Packard Co - Copyright (C) 2007 David Mosberger-Tang - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include - -#include "unwind_i.h" - -#ifdef UNW_REMOTE_ONLY - -/* unw_local_addr_space is a NULL pointer in this case. */ -unw_addr_space_t unw_local_addr_space; - -#else /* !UNW_REMOTE_ONLY */ - -static struct unw_addr_space local_addr_space; - -unw_addr_space_t unw_local_addr_space = &local_addr_space; - -static inline void * -uc_addr (ucontext_t *uc, int reg) -{ - if (reg >= UNW_S390X_R0 && reg <= UNW_S390X_R15) - return &uc->uc_mcontext.gregs[reg - UNW_S390X_R0]; - if (reg >= UNW_S390X_F0 && reg <= UNW_S390X_F15) - return &uc->uc_mcontext.fpregs.fprs[reg - UNW_S390X_F0]; - if (reg == UNW_S390X_IP) - return &uc->uc_mcontext.psw.addr; - - return NULL; -} - -# ifdef UNW_LOCAL_ONLY - -HIDDEN void * -tdep_uc_addr (ucontext_t *uc, int reg) -{ - return uc_addr (uc, reg); -} - -# endif /* UNW_LOCAL_ONLY */ - -static void -put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) -{ - /* it's a no-op */ -} - -static int -get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) -{ -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); - return 0; -} - -#define PAGE_SIZE 4096 -#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) - -static int mem_validate_pipe[2] = {-1, -1}; - -static inline void -open_pipe (void) -{ - /* ignore errors for closing invalid fd's */ - close (mem_validate_pipe[0]); - close (mem_validate_pipe[1]); - - pipe2 (mem_validate_pipe, O_CLOEXEC | O_NONBLOCK); -} - -ALWAYS_INLINE -static int -write_validate (void *addr) -{ - int ret = -1; - ssize_t bytes = 0; - - do - { - char buf; - bytes = read (mem_validate_pipe[0], &buf, 1); - } - while ( errno == EINTR ); - - int valid_read = (bytes > 0 || errno == EAGAIN || errno == EWOULDBLOCK); - if (!valid_read) - { - // re-open closed pipe - open_pipe (); - } - - do - { - /* use syscall insteadof write() so that ASAN does not complain */ - ret = syscall (SYS_write, mem_validate_pipe[1], addr, 1); - } - while ( errno == EINTR ); - - return ret; -} - -static int (*mem_validate_func) (void *addr, size_t len); -static int msync_validate (void *addr, size_t len) -{ - if (msync (addr, len, MS_ASYNC) != 0) - { - return -1; - } - - return write_validate (addr); -} - -#ifdef HAVE_MINCORE -static int mincore_validate (void *addr, size_t len) -{ - unsigned char mvec[2]; /* Unaligned access may cross page boundary */ - size_t i; - - /* mincore could fail with EAGAIN but we conservatively return -1 - instead of looping. */ - if (mincore (addr, len, mvec) != 0) - { - return -1; - } - - for (i = 0; i < (len + PAGE_SIZE - 1) / PAGE_SIZE; i++) - { - if (!(mvec[i] & 1)) return -1; - } - - return write_validate (addr); -} -#endif - -/* Initialise memory validation method. On linux kernels <2.6.21, - mincore() returns incorrect value for MAP_PRIVATE mappings, - such as stacks. If mincore() was available at compile time, - check if we can actually use it. If not, use msync() instead. */ -HIDDEN void -tdep_init_mem_validate (void) -{ - open_pipe (); - -#ifdef HAVE_MINCORE - unsigned char present = 1; - unw_word_t addr = PAGE_START((unw_word_t)&present); - unsigned char mvec[1]; - int ret; - while ((ret = mincore ((void*)addr, PAGE_SIZE, mvec)) == -1 && - errno == EAGAIN) {} - if (ret == 0 && (mvec[0] & 1)) - { - Debug(1, "using mincore to validate memory\n"); - mem_validate_func = mincore_validate; - } - else -#endif - { - Debug(1, "using msync to validate memory\n"); - mem_validate_func = msync_validate; - } -} - -/* Cache of already validated addresses */ -#define NLGA 4 -static unw_word_t last_good_addr[NLGA]; -static int lga_victim; - -static int -validate_mem (unw_word_t addr) -{ - int i, victim; - size_t len; - - if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) - len = PAGE_SIZE; - else - len = PAGE_SIZE * 2; - - addr = PAGE_START(addr); - - if (addr == 0) - return -1; - - for (i = 0; i < NLGA; i++) - { - if (last_good_addr[i] && (addr == last_good_addr[i])) - return 0; - } - - if (mem_validate_func ((void *) addr, len) == -1) - return -1; - - victim = lga_victim; - for (i = 0; i < NLGA; i++) { - if (!last_good_addr[victim]) { - last_good_addr[victim++] = addr; - return 0; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - last_good_addr[victim] = addr; - victim = (victim + 1) % NLGA; - lga_victim = victim; - - return 0; -} - -static int -access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, - void *arg) -{ - if (unlikely (write)) - { - Debug (16, "mem[%016lx] <- %lx\n", addr, *val); - *(unw_word_t *) addr = *val; - } - else - { - /* validate address */ - const struct cursor *c = (const struct cursor *)arg; - if (likely (c != NULL) && unlikely (c->validate) - && unlikely (validate_mem (addr))) { - Debug (16, "mem[%016lx] -> invalid\n", addr); - return -1; - } - *val = *(unw_word_t *) addr; - Debug (16, "mem[%016lx] -> %lx\n", addr, *val); - } - return 0; -} - -static int -access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, - void *arg) -{ - unw_word_t *addr; - ucontext_t *uc = ((struct cursor *)arg)->uc; - - if (unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - *(unw_word_t *) addr = *val; - Debug (12, "%s <- 0x%016lx\n", unw_regname (reg), *val); - } - else - { - *val = *(unw_word_t *) addr; - Debug (12, "%s -> 0x%016lx\n", unw_regname (reg), *val); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; -} - -static int -access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, - int write, void *arg) -{ - ucontext_t *uc = ((struct cursor *)arg)->uc; - unw_fpreg_t *addr; - - if (!unw_is_fpreg (reg)) - goto badreg; - - if (!(addr = uc_addr (uc, reg))) - goto badreg; - - if (write) - { - Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - *(unw_fpreg_t *) addr = *val; - } - else - { - *val = *(unw_fpreg_t *) addr; - Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), - ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); - } - return 0; - - badreg: - Debug (1, "bad register number %u\n", reg); - /* attempt to access a non-preserved register */ - return -UNW_EBADREG; -} - -static int -get_static_proc_name (unw_addr_space_t as, unw_word_t ip, - char *buf, size_t buf_len, unw_word_t *offp, - void *arg) -{ - return _Uelf64_get_proc_name (as, getpid (), ip, buf, buf_len, offp); -} - -HIDDEN void -s390x_local_addr_space_init (void) -{ - memset (&local_addr_space, 0, sizeof (local_addr_space)); - local_addr_space.caching_policy = UNW_CACHE_GLOBAL; - local_addr_space.acc.find_proc_info = dwarf_find_proc_info; - local_addr_space.acc.put_unwind_info = put_unwind_info; - local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; - local_addr_space.acc.access_mem = access_mem; - local_addr_space.acc.access_reg = access_reg; - local_addr_space.acc.access_fpreg = access_fpreg; - local_addr_space.acc.resume = s390x_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); - - memset (last_good_addr, 0, sizeof (unw_word_t) * NLGA); - lga_victim = 0; -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c deleted file mode 100644 index 5eaead0f840bb..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_local.c +++ /dev/null @@ -1,81 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "init.h" - -#ifdef UNW_REMOTE_ONLY - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - return -UNW_EINVAL; -} - -#else /* !UNW_REMOTE_ONLY */ - -static int -unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_instr) -{ - struct cursor *c = (struct cursor *) cursor; - - if (unlikely (!tdep_init_done)) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = unw_local_addr_space; - c->dwarf.as_arg = c; - c->uc = uc; - c->validate = 0; - return common_init (c, use_prev_instr); -} - -int -unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) -{ - return unw_init_local_common(cursor, uc, 1); -} - -int -unw_init_local2 (unw_cursor_t *cursor, ucontext_t *uc, int flag) -{ - if (!flag) - { - return unw_init_local_common(cursor, uc, 1); - } - else if (flag == UNW_INIT_SIGNAL_FRAME) - { - return unw_init_local_common(cursor, uc, 0); - } - else - { - return -UNW_EINVAL; - } -} - -#endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c deleted file mode 100644 index efd61d64d4b8f..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Ginit_remote.c +++ /dev/null @@ -1,57 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "init.h" -#include "unwind_i.h" - -int -unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) -{ -#ifdef UNW_LOCAL_ONLY - return -UNW_EINVAL; -#else /* !UNW_LOCAL_ONLY */ - struct cursor *c = (struct cursor *) cursor; - - if (!tdep_init_done) - tdep_init (); - - Debug (1, "(cursor=%p)\n", c); - - c->dwarf.as = as; - if (as == unw_local_addr_space) - { - c->dwarf.as_arg = c; - c->uc = as_arg; - } - else - { - c->dwarf.as_arg = as_arg; - c->uc = NULL; - } - return common_init (c, 0); -#endif /* !UNW_LOCAL_ONLY */ -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c deleted file mode 100644 index 7ed91e3ccfc02..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gis_signal_frame.c +++ /dev/null @@ -1,77 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2012 Tommi Rantala - Copyright (C) 2013 Linaro Limited - Copyright (C) 2017 IBM - - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -/* The restorer stub will be a system call: - - rt_sigreturn: svc 173 (0x0aad) - - sigreturn: svc 119 (0x0a77) -*/ - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ -#ifdef __linux__ - struct cursor *c = (struct cursor *) cursor; - unw_word_t w0, ip; - unw_addr_space_t as; - unw_accessors_t *a; - void *arg; - int ret, shift = 48; - - as = c->dwarf.as; - a = unw_get_accessors (as); - arg = c->dwarf.as_arg; - - /* Align the instruction pointer to 8 bytes so that we guarantee - an 8 byte read from it won't cross a page boundary. - Instructions on s390x are 2 byte aligned. */ - ip = c->dwarf.ip & ~7; - shift -= (c->dwarf.ip - ip) * 8; - - ret = (*a->access_mem) (as, ip, &w0, 0, arg); - if (ret < 0) - return ret; - - /* extract first 2 bytes of the next instruction */ - w0 = (w0 >> shift) & 0xffff; - - /* sigreturn */ - if (w0 == 0x0a77) - return 1; - - /* rt_sigreturn */ - if (w0 == 0x0aad) - return 2; - - return 0; - -#else - return -UNW_ENOINFO; -#endif -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c deleted file mode 100644 index a17dc1b561d6f..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Greg_states_iterate.c +++ /dev/null @@ -1,37 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2003 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -int -unw_reg_states_iterate (unw_cursor_t *cursor, - unw_reg_states_callback cb, void *token) -{ - struct cursor *c = (struct cursor *) cursor; - - return dwarf_reg_states_iterate (&c->dwarf, cb, token); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c deleted file mode 100644 index 1a48833d56e73..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gregs.c +++ /dev/null @@ -1,116 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -HIDDEN int -tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - int write) -{ - dwarf_loc_t loc = DWARF_NULL_LOC; - - switch (reg) - { - case UNW_S390X_CFA: - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; - return 0; - - case UNW_S390X_R0: - case UNW_S390X_R1: - case UNW_S390X_R2: - case UNW_S390X_R3: - case UNW_S390X_R4: - case UNW_S390X_R5: - case UNW_S390X_R6: - case UNW_S390X_R7: - case UNW_S390X_R8: - case UNW_S390X_R9: - case UNW_S390X_R10: - case UNW_S390X_R11: - case UNW_S390X_R12: - case UNW_S390X_R13: - case UNW_S390X_R14: - case UNW_S390X_IP: - loc = c->dwarf.loc[reg]; - break; - - case UNW_S390X_R15: - if (write) - return -UNW_EREADONLYREG; - loc = c->dwarf.loc[reg]; - break; - - default: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; - } - - if (write) - return dwarf_put (&c->dwarf, loc, *valp); - else - return dwarf_get (&c->dwarf, loc, valp); -} - -HIDDEN int -tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, - int write) -{ - dwarf_loc_t loc = DWARF_NULL_LOC; - - switch (reg) - { - case UNW_S390X_F0: - case UNW_S390X_F1: - case UNW_S390X_F2: - case UNW_S390X_F3: - case UNW_S390X_F4: - case UNW_S390X_F5: - case UNW_S390X_F6: - case UNW_S390X_F7: - case UNW_S390X_F8: - case UNW_S390X_F9: - case UNW_S390X_F10: - case UNW_S390X_F11: - case UNW_S390X_F12: - case UNW_S390X_F13: - case UNW_S390X_F14: - case UNW_S390X_F15: - loc = c->dwarf.loc[reg]; - break; - default: - Debug (1, "bad register number %u\n", reg); - return -UNW_EBADREG; - } - - if (write) - return dwarf_putfp (&c->dwarf, loc, *valp); - else - return dwarf_getfp (&c->dwarf, loc, valp); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c deleted file mode 100644 index fd9d13027e2a8..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gresume.c +++ /dev/null @@ -1,160 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include - -#include "unwind_i.h" - -#ifndef UNW_REMOTE_ONLY - -HIDDEN inline int -s390x_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) -{ - struct cursor *c = (struct cursor *) cursor; - ucontext_t uc = *c->uc; - ucontext_t *rt = NULL; - struct sigcontext *sc = NULL; - int i; - unw_word_t sp, ip; - uc.uc_mcontext.psw.addr = c->dwarf.ip; - - /* Ensure c->pi is up-to-date. On x86-64, it's relatively common to - be missing DWARF unwind info. We don't want to fail in that - case, because the frame-chain still would let us do a backtrace - at least. */ - dwarf_make_proc_info (&c->dwarf); - - switch (c->sigcontext_format) - { - case S390X_SCF_NONE: - Debug (8, "resuming at ip=%llx via setcontext()\n", - (unsigned long long) c->dwarf.ip); - setcontext (&uc); - abort(); /* unreachable */ - case S390X_SCF_LINUX_SIGFRAME: - Debug (8, "resuming at ip=%llx via signal trampoline\n", - (unsigned long long) c->dwarf.ip); - sc = (struct sigcontext*)c->sigcontext_addr; - for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) - sc->sregs->regs.gprs[i-UNW_S390X_R0] = uc.uc_mcontext.gregs[i-UNW_S390X_R0]; - for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) - sc->sregs->fpregs.fprs[i-UNW_S390X_F0] = uc.uc_mcontext.fpregs.fprs[i-UNW_S390X_F0].d; - sc->sregs->regs.psw.addr = uc.uc_mcontext.psw.addr; - - sp = c->sigcontext_sp; - ip = c->sigcontext_pc; - __asm__ __volatile__ ( - "lgr 15, %[sp]\n" - "br %[ip]\n" - : : [sp] "r" (sp), [ip] "r" (ip) - ); - abort(); /* unreachable */ - case S390X_SCF_LINUX_RT_SIGFRAME: - Debug (8, "resuming at ip=%llx via signal trampoline\n", - (unsigned long long) c->dwarf.ip); - rt = (ucontext_t*)c->sigcontext_addr; - for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) - rt->uc_mcontext.gregs[i-UNW_S390X_R0] = uc.uc_mcontext.gregs[i-UNW_S390X_R0]; - for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) - rt->uc_mcontext.fpregs.fprs[i-UNW_S390X_F0] = uc.uc_mcontext.fpregs.fprs[i-UNW_S390X_F0]; - rt->uc_mcontext.psw.addr = uc.uc_mcontext.psw.addr; - - sp = c->sigcontext_sp; - ip = c->sigcontext_pc; - __asm__ __volatile__ ( - "lgr 15, %[sp]\n" - "br %[ip]\n" - : : [sp] "r" (sp), [ip] "r" (ip) - ); - abort(); /* unreachable */ - } - return -UNW_EINVAL; -} - -#endif /* !UNW_REMOTE_ONLY */ - -/* This routine is responsible for copying the register values in - cursor C and establishing them as the current machine state. */ - -static inline int -establish_machine_state (struct cursor *c) -{ - int (*access_reg) (unw_addr_space_t, unw_regnum_t, unw_word_t *, - int write, void *); - int (*access_fpreg) (unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, - int write, void *); - unw_addr_space_t as = c->dwarf.as; - void *arg = c->dwarf.as_arg; - unw_fpreg_t fpval; - unw_word_t val; - int reg; - - access_reg = as->acc.access_reg; - access_fpreg = as->acc.access_fpreg; - - Debug (8, "copying out cursor state\n"); - - for (reg = 0; reg <= UNW_REG_LAST; ++reg) - { - Debug (16, "copying %s %d\n", unw_regname (reg), reg); - if (unw_is_fpreg (reg)) - { - if (tdep_access_fpreg (c, reg, &fpval, 0) >= 0) - (*access_fpreg) (as, reg, &fpval, 1, arg); - } - else - { - if (tdep_access_reg (c, reg, &val, 0) >= 0) - (*access_reg) (as, reg, &val, 1, arg); - } - } - - if (c->dwarf.args_size) - { - if (tdep_access_reg (c, UNW_S390X_R15, &val, 0) >= 0) - { - val += c->dwarf.args_size; - (*access_reg) (as, UNW_S390X_R15, &val, 1, arg); - } - } - return 0; -} - -int -unw_resume (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret; - - Debug (1, "(cursor=%p)\n", c); - - if ((ret = establish_machine_state (c)) < 0) - return ret; - - return (*c->dwarf.as->acc.resume) (c->dwarf.as, (unw_cursor_t *) c, - c->dwarf.as_arg); -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c deleted file mode 100644 index 0b79580b256bc..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Gstep.c +++ /dev/null @@ -1,146 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2004 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include - -static int -s390x_handle_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret, i; - unw_word_t sc_addr, sp, *gprs, *fprs, *psw; - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_R15], &sp); - if (ret < 0) - return ret; - - /* Save the SP and PC to be able to return execution at this point - later in time (unw_resume). */ - c->sigcontext_sp = sp; - c->sigcontext_pc = c->dwarf.ip; - switch (c->sigcontext_format) - { - case S390X_SCF_LINUX_SIGFRAME: /* sigreturn */ - sc_addr = sp + 160; - gprs = ((struct sigcontext*)sc_addr)->sregs->regs.gprs; - fprs = (unw_word_t*)((struct sigcontext*)sc_addr)->sregs->fpregs.fprs; - psw = &((struct sigcontext*)sc_addr)->sregs->regs.psw.addr; - break; - case S390X_SCF_LINUX_RT_SIGFRAME: /* rt_sigreturn */ - sc_addr = sp + sizeof(siginfo_t) + 8 + 160; - gprs = ((ucontext_t*)sc_addr)->uc_mcontext.gregs; - fprs = (unw_word_t*)((ucontext_t*)sc_addr)->uc_mcontext.fpregs.fprs; - psw = &((ucontext_t*)sc_addr)->uc_mcontext.psw.addr; - break; - default: - return -UNW_EUNSPEC; - } - - c->sigcontext_addr = sc_addr; - - /* Update the dwarf cursor. - Set the location of the registers to the corresponding addresses of the - uc_mcontext / sigcontext structure contents. */ - for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) - c->dwarf.loc[i] = DWARF_MEM_LOC (c, (unw_word_t) &gprs[i-UNW_S390X_R0]); - for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) - c->dwarf.loc[i] = DWARF_MEM_LOC (c, (unw_word_t) &fprs[i-UNW_S390X_F0]); - - c->dwarf.loc[UNW_S390X_IP] = DWARF_MEM_LOC (c, (unw_word_t) psw); - - /* Set SP/CFA and PC/IP. - Normally the default CFA on s390x is r15+160. We do not add that offset - here because dwarf_step will add the offset. */ - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_R15], &c->dwarf.cfa); - dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_IP], &c->dwarf.ip); - - c->dwarf.pi_valid = 0; - c->dwarf.use_prev_instr = 0; - - return 1; -} - -int -unw_step (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - int ret = 0, val = c->validate, sig; - -#if CONSERVATIVE_CHECKS - c->validate = 1; -#endif - - Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx)\n", - c, c->dwarf.ip, c->dwarf.cfa); - - /* Try DWARF-based unwinding... */ - c->sigcontext_format = S390X_SCF_NONE; - ret = dwarf_step (&c->dwarf); - -#if CONSERVATIVE_CHECKS - c->validate = val; -#endif - - if (unlikely (ret == -UNW_ENOINFO)) - { - /* GCC doesn't currently emit debug information for signal - trampolines on s390x so we check for them explicitly. - - If there isn't debug information available we could also - try using the backchain (if available). - - Other platforms also detect PLT entries here. That's - tricky to do reliably on s390x so I've left it out for - now. */ - - /* Memory accesses here are quite likely to be unsafe. */ - c->validate = 1; - - /* Check if this is a signal frame. */ - sig = unw_is_signal_frame (cursor); - if (sig > 0) - { - c->sigcontext_format = sig; - ret = s390x_handle_signal_frame (cursor); - } - else - { - c->dwarf.ip = 0; - ret = 0; - } - - c->validate = val; - return ret; - } - - if (unlikely (ret > 0 && c->dwarf.ip == 0)) - return 0; - - return ret; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c deleted file mode 100644 index 7ebada480e564..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lapply_reg_state.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gapply_reg_state.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c deleted file mode 100644 index 0f2dc6be90145..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lcreate_addr_space.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gcreate_addr_space.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c deleted file mode 100644 index 69028b019fcd5..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_proc_info.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_proc_info.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c deleted file mode 100644 index 9ea048a9076ba..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lget_save_loc.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gget_save_loc.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c deleted file mode 100644 index 8c43a67c0fff2..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lglobal.c +++ /dev/null @@ -1,6 +0,0 @@ -#define UNW_LOCAL_ONLY -#include "config.h" -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gglobal.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c deleted file mode 100644 index e9abfdd46a3e0..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c deleted file mode 100644 index 68a1687e85444..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_local.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_local.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c deleted file mode 100644 index 58cb04ab7cd1f..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Linit_remote.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Ginit_remote.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c deleted file mode 100644 index b9a7c4f51ad9f..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lis_signal_frame.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gis_signal_frame.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c deleted file mode 100644 index f1eb1e79dcdcc..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lreg_states_iterate.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Greg_states_iterate.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c deleted file mode 100644 index 2c9c75cd7d9a1..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lregs.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gregs.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c deleted file mode 100644 index 41a8cf003de4a..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lresume.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gresume.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c b/src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c deleted file mode 100644 index c1ac3c7547f00..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/Lstep.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gstep.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S deleted file mode 100644 index d35a3cf3a953d..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/getcontext.S +++ /dev/null @@ -1,74 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 Google, Inc - Contributed by Paul Pluzhnikov - Copyright (C) 2010 Konstantin Belousov - Copyright (C) 2017 IBM - - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -// int _Us390x_getcontext (unw_tdep_context_t *ucp) - - .global _Us390x_getcontext - .type _Us390x_getcontext, @function -_Us390x_getcontext: - .cfi_startproc - - // Save the minimal set of registers required to restore the - // context. Generally speaking this is just the preserved - // registers but we've also saved the parameter registers - // so that return values can be modified too. - - // save PSW address - // (not strictly needed but makes other code simpler) - stg %r14,0x30(%r2) - - // floating point parameters (not strictly needed) - std %f0,0x100(%r2) - std %f2,0x110(%r2) - std %f4,0x120(%r2) - std %f6,0x130(%r2) - - // floating point preserved registers - stfpc 0xf8(%r2) - std %f8,0x140(%r2) - std %f9,0x148(%r2) - std %f10,0x150(%r2) - std %f11,0x158(%r2) - std %f12,0x160(%r2) - std %f13,0x168(%r2) - std %f14,0x170(%r2) - std %f15,0x178(%r2) - - // preserved registers and parameters - lgr %r1,%r2 - lghi %r2,0 - stmg %r2,%r15,0x48(%r1) - - br %r14 - - .cfi_endproc - .size _Us390x_getcontext, . - _Us390x_getcontext - - // We do not need executable stack. - .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/init.h b/src/coreclr/src/pal/src/libunwind/src/s390x/init.h deleted file mode 100644 index 86ced38f66ca5..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/init.h +++ /dev/null @@ -1,71 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static inline int -common_init (struct cursor *c, unsigned use_prev_instr) -{ - int ret; - int i; - - for (i = UNW_S390X_R0; i <= UNW_S390X_R15; ++i) { - c->dwarf.loc[i] = DWARF_REG_LOC(&c->dwarf, i); - } - for (i = UNW_S390X_F0; i <= UNW_S390X_F15; ++i) { - c->dwarf.loc[i] = DWARF_FPREG_LOC(&c->dwarf, i); - } - /* IP isn't a real register, it is encoded in the PSW */ - c->dwarf.loc[UNW_S390X_IP] = DWARF_REG_LOC(&c->dwarf, UNW_S390X_IP); - - ret = dwarf_get (&c->dwarf, c->dwarf.loc[UNW_S390X_IP], &c->dwarf.ip); - if (ret < 0) - return ret; - - /* Normally the CFA offset on s390x is biased, however this is taken - into account by the CFA offset in dwarf_step, so here we just mark - make it equal to the stack pointer. */ - ret = dwarf_get (&c->dwarf, DWARF_REG_LOC (&c->dwarf, UNW_S390X_R15), - &c->dwarf.cfa); - if (ret < 0) - return ret; - - c->sigcontext_format = S390X_SCF_NONE; - c->sigcontext_addr = 0; - - c->dwarf.args_size = 0; - c->dwarf.stash_frames = 0; - c->dwarf.use_prev_instr = use_prev_instr; - c->dwarf.pi_valid = 0; - c->dwarf.pi_is_dynamic = 0; - c->dwarf.hint = 0; - c->dwarf.prev_rs = 0; - c->dwarf.eh_valid_mask = 0; - - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c b/src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c deleted file mode 100644 index bc31f3e917011..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/is_fpreg.c +++ /dev/null @@ -1,36 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (c) 2004-2005 Hewlett-Packard Development Company, L.P. - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "libunwind_i.h" - -int -unw_is_fpreg (int regnum) -{ - /* vector registers? */ - return regnum >= UNW_S390X_F0 && regnum <= UNW_S390X_F15; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/regname.c b/src/coreclr/src/pal/src/libunwind/src/s390x/regname.c deleted file mode 100644 index 2421b37ebb0d3..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/regname.c +++ /dev/null @@ -1,57 +0,0 @@ -/* libunwind - a platform-independent unwind library - - Contributed by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" - -static const char *regname[] = - { - [UNW_S390X_R0]="R0", - [UNW_S390X_R1]="R1", - [UNW_S390X_R2]="R2", - [UNW_S390X_R3]="R3", - [UNW_S390X_R4]="R4", - [UNW_S390X_R5]="R5", - [UNW_S390X_R6]="R6", - [UNW_S390X_R7]="R7", - [UNW_S390X_R8]="R8", - [UNW_S390X_R9]="R9", - [UNW_S390X_R10]="R10", - [UNW_S390X_R11]="R11", - [UNW_S390X_R12]="R12", - [UNW_S390X_R13]="R13", - [UNW_S390X_R14]="R14", - [UNW_S390X_R15]="R15", - - [UNW_S390X_IP]="IP" - }; - -const char * -unw_regname (unw_regnum_t reg) -{ - if (reg < (unw_regnum_t) ARRAY_SIZE (regname)) - return regname[reg]; - else - return "???"; -} diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S deleted file mode 100644 index 6cf55688aa436..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/setcontext.S +++ /dev/null @@ -1,76 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2008 Google, Inc - Contributed by Paul Pluzhnikov - Copyright (C) 2010 Konstantin Belousov - Copyright (C) 2017 IBM - - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -// int _Us390x_setcontext (const ucontext_t *ucp) - - .global _Us390x_setcontext - .type _Us390x_setcontext, @function -_Us390x_setcontext: - .cfi_startproc - - // Must only restore registers saved by getcontext, other fields - // in the ucontext_t might be uninitialised. - - // Stop this function being unwound. We are clobbering callee-save - // registers in this function so unwinding it is unsafe. - // Ideally we'd save callee-save registers, update the CFI for them - // and then switch to the new CFI once the context switch is - // complete. - .cfi_undefined %r14 - - // floating point parameters - ld %f0,0x100(%r2) - ld %f2,0x110(%r2) - ld %f4,0x120(%r2) - ld %f6,0x130(%r2) - - // floating point preserved registers - lfpc 0xf8(%r2) - ld %f8,0x140(%r2) - ld %f9,0x148(%r2) - ld %f10,0x150(%r2) - ld %f11,0x158(%r2) - ld %f12,0x160(%r2) - ld %f13,0x168(%r2) - ld %f14,0x170(%r2) - ld %f15,0x178(%r2) - - // preserved registers and parameters - lgr %r1,%r2 - lmg %r2,%r15,0x48(%r1) - - // restore PSW address - lg %r1,0x30(%r1) - br %r1 - - .cfi_endproc - .size _Us390x_setcontext, . - _Us390x_setcontext - - // We do not need executable stack. - .section .note.GNU-stack,"",@progbits diff --git a/src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h b/src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h deleted file mode 100644 index 6e4b99baaa8da..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/s390x/unwind_i.h +++ /dev/null @@ -1,48 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002, 2005 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - Modified for s390x by Michael Munday - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifndef unwind_i_h -#define unwind_i_h - -#include - -#include - -#include "libunwind_i.h" -#include - -#define s390x_lock UNW_OBJ(lock) -#define s390x_local_resume UNW_OBJ(local_resume) -#define s390x_local_addr_space_init UNW_OBJ(local_addr_space_init) -#define setcontext UNW_ARCH_OBJ(setcontext) - -extern void s390x_local_addr_space_init (void); -extern int s390x_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg); -extern int setcontext (const ucontext_t *ucp); - -#endif /* unwind_i_h */ diff --git a/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c b/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c index dd330ce9e19db..0e286f6f0851c 100644 --- a/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c +++ b/src/coreclr/src/pal/src/libunwind/src/setjmp/siglongjmp.c @@ -31,12 +31,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "jmpbuf.h" #include "setjmp_i.h" -#if !defined(_NSIG) -# if defined(_SIG_MAXSIG) -# define _NSIG (_SIG_MAXSIG - 1) -# elif defined(NSIG) -# define _NSIG NSIG -# endif +#if !defined(_NSIG) && defined(_SIG_MAXSIG) +# define _NSIG (_SIG_MAXSIG - 1) #endif #if defined(__GLIBC__) @@ -96,7 +92,7 @@ siglongjmp (sigjmp_buf env, int val) if (!resume_restores_sigmask (&c, wp) && wp[JB_MASK_SAVED]) { /* sigmask was saved */ -#if defined(__linux__) || defined(__sun) +#if defined(__linux__) if (UNW_NUM_EH_REGS < 4 || _NSIG > 16 * sizeof (unw_word_t)) /* signal mask doesn't fit into EH arguments and we can't put it on the stack without overwriting something diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c index 9fe96d2bd4d8e..52988a721e9d7 100644 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit.c @@ -58,6 +58,13 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -68,13 +75,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c index 45631306bcd81..99ddb36fb3e33 100644 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Ginit_local.c @@ -37,7 +37,7 @@ unw_init_local (unw_cursor_t *cursor, unw_context_t *uc) #else /* !UNW_REMOTE_ONLY */ static int -unw_init_local_common (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr) +unw_init_local (unw_cursor_t *cursor, unw_context_t *uc, unsigned use_prev_instr) { struct cursor *c = (struct cursor *) cursor; diff --git a/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c b/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c index 5590bafa61242..a263c92718a0b 100644 --- a/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c +++ b/src/coreclr/src/pal/src/libunwind/src/sh/Gresume.c @@ -55,7 +55,7 @@ sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) char x[sizeof(regs)]; }; - __asm__ __volatile__ ( + asm volatile ( "mov.l @%0+, r8\n" "mov.l @%0+, r9\n" "mov.l @%0+, r10\n" @@ -99,7 +99,7 @@ sh_local_resume (unw_addr_space_t as, unw_cursor_t *cursor, void *arg) /* Set the SP and the PC in order to continue execution at the modified trampoline which restores the signal mask and the registers. */ - __asm__ __volatile__ ( + asm __volatile__ ( "mov %0, r15\n" "lds %1, pr\n" "rts\n" diff --git a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c index 925e6413246be..7564a558be436 100644 --- a/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/tilegx/Ginit.c @@ -64,6 +64,13 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -74,13 +81,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in b/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in index 9a65faf39e125..1505c5d6f67d3 100644 --- a/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in +++ b/src/coreclr/src/pal/src/libunwind/src/unwind/libunwind.pc.in @@ -7,5 +7,5 @@ Name: libunwind Description: libunwind base library Version: @VERSION@ Libs: -L${libdir} -lunwind -Libs.private: @LIBLZMA@ @LIBZ@ +Libs.private: @LIBLZMA@ Cflags: -I${includedir} diff --git a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c index 3cec74a216b1f..f6b8dc27d4934 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86/Ginit.c @@ -54,6 +54,13 @@ tdep_uc_addr (ucontext_t *uc, int reg) # endif /* UNW_LOCAL_ONLY */ +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -64,13 +71,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c index 40568700e0e40..0057c62d648bf 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gget_save_loc.c @@ -44,7 +44,6 @@ unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) case UNW_X86_64_R13: loc = c->dwarf.loc[R13]; break; case UNW_X86_64_R14: loc = c->dwarf.loc[R14]; break; case UNW_X86_64_R15: loc = c->dwarf.loc[R15]; break; - case UNW_X86_64_RIP: loc = c->dwarf.loc[RIP]; break; default: break; diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c index 9a7b1957eb8d9..8d1fbb4b0a991 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gglobal.c @@ -30,11 +30,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "dwarf_i.h" HIDDEN define_lock (x86_64_lock); -#ifdef HAVE_ATOMIC_OPS_H - HIDDEN AO_t tdep_init_done; -#else - HIDDEN int tdep_init_done; -#endif +HIDDEN int tdep_init_done; /* See comments for svr4_dbx_register_map[] in gcc/config/i386/i386.c. */ @@ -81,17 +77,15 @@ HIDDEN void tdep_init (void) { intrmask_t saved_mask; - intrmask_t full_mask; - sigfillset (&full_mask); - SIGPROCMASK (SIG_SETMASK, &full_mask, &saved_mask); - mutex_lock (&x86_64_lock); + sigfillset (&unwi_full_mask); + + lock_acquire (&x86_64_lock, saved_mask); { - if (atomic_read(&tdep_init_done)) + if (tdep_init_done) /* another thread else beat us to it... */ goto out; - sigfillset (&unwi_full_mask); mi_init (); dwarf_init (); @@ -101,9 +95,8 @@ tdep_init (void) #ifndef UNW_REMOTE_ONLY x86_64_local_addr_space_init (); #endif - fetch_and_add1(&tdep_init_done); /* signal that we're initialized... */ + tdep_init_done = 1; /* signal that we're initialized... */ } out: - mutex_unlock(&x86_64_lock); - SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); + lock_release (&x86_64_lock, saved_mask); } diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c index fd8d418b1a576..2a84a1eec75e7 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit.c @@ -49,6 +49,13 @@ static struct unw_addr_space local_addr_space; unw_addr_space_t unw_local_addr_space = &local_addr_space; +HIDDEN unw_dyn_info_list_t _U_dyn_info_list; + +/* XXX fix me: there is currently no way to locate the dyn-info list + by a remote unwinder. On ia64, this is done via a special + unwind-table entry. Perhaps something similar can be done with + DWARF2 unwind info. */ + static void put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { @@ -59,13 +66,7 @@ static int get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, void *arg) { -#ifndef UNW_LOCAL_ONLY -# pragma weak _U_dyn_info_list_addr - if (!_U_dyn_info_list_addr) - return -UNW_ENOINFO; -#endif - // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so. - *dyn_info_list_addr = _U_dyn_info_list_addr (); + *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; return 0; } @@ -74,44 +75,14 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, static int mem_validate_pipe[2] = {-1, -1}; -#ifdef HAVE_PIPE2 -static inline void -do_pipe2 (int pipefd[2]) -{ - pipe2 (pipefd, O_CLOEXEC | O_NONBLOCK); -} -#else -static inline void -set_pipe_flags (int fd) -{ - int fd_flags = fcntl (fd, F_GETFD, 0); - int status_flags = fcntl (fd, F_GETFL, 0); - - fd_flags |= FD_CLOEXEC; - fcntl (fd, F_SETFD, fd_flags); - - status_flags |= O_NONBLOCK; - fcntl (fd, F_SETFL, status_flags); -} - -static inline void -do_pipe2 (int pipefd[2]) -{ - pipe (pipefd); - set_pipe_flags(pipefd[0]); - set_pipe_flags(pipefd[1]); -} -#endif - static inline void open_pipe (void) { - if (mem_validate_pipe[0] != -1) - close (mem_validate_pipe[0]); - if (mem_validate_pipe[1] != -1) - close (mem_validate_pipe[1]); + /* ignore errors for closing invalid fd's */ + close (mem_validate_pipe[0]); + close (mem_validate_pipe[1]); - do_pipe2 (mem_validate_pipe); + pipe2 (mem_validate_pipe, O_CLOEXEC | O_NONBLOCK); } ALWAYS_INLINE @@ -160,14 +131,20 @@ static int msync_validate (void *addr, size_t len) static int mincore_validate (void *addr, size_t len) { unsigned char mvec[2]; /* Unaligned access may cross page boundary */ + size_t i; /* mincore could fail with EAGAIN but we conservatively return -1 instead of looping. */ - if (mincore (addr, len, (char *)mvec) != 0) + if (mincore (addr, len, mvec) != 0) { return -1; } + for (i = 0; i < (len + PAGE_SIZE - 1) / PAGE_SIZE; i++) + { + if (!(mvec[i] & 1)) return -1; + } + return write_validate (addr); } #endif @@ -186,9 +163,9 @@ tdep_init_mem_validate (void) unw_word_t addr = PAGE_START((unw_word_t)&present); unsigned char mvec[1]; int ret; - while ((ret = mincore ((void*)addr, PAGE_SIZE, (char *)mvec)) == -1 && + while ((ret = mincore ((void*)addr, PAGE_SIZE, mvec)) == -1 && errno == EAGAIN) {} - if (ret == 0) + if (ret == 0 && (mvec[0] & 1)) { Debug(1, "using mincore to validate memory\n"); mem_validate_func = mincore_validate; @@ -203,93 +180,13 @@ tdep_init_mem_validate (void) /* Cache of already validated addresses */ #define NLGA 4 -#if defined(HAVE___THREAD) && HAVE___THREAD -// thread-local variant -static __thread unw_word_t last_good_addr[NLGA]; -static __thread int lga_victim; - -static int -is_cached_valid_mem(unw_word_t addr) -{ - int i; - for (i = 0; i < NLGA; i++) - { - if (addr == last_good_addr[i]) - return 1; - } - return 0; -} - -static void -cache_valid_mem(unw_word_t addr) -{ - int i, victim; - victim = lga_victim; - for (i = 0; i < NLGA; i++) { - if (last_good_addr[victim] == 0) { - last_good_addr[victim] = addr; - return; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - last_good_addr[victim] = addr; - victim = (victim + 1) % NLGA; - lga_victim = victim; -} - -#elif HAVE_ATOMIC_OPS_H -// global, thread safe variant -static AO_T last_good_addr[NLGA]; -static AO_T lga_victim; - -static int -is_cached_valid_mem(unw_word_t addr) -{ - int i; - for (i = 0; i < NLGA; i++) - { - if (addr == AO_load(&last_good_addr[i])) - return 1; - } - return 0; -} - -static void -cache_valid_mem(unw_word_t addr) -{ - int i, victim; - victim = AO_load(&lga_victim); - for (i = 0; i < NLGA; i++) { - if (AO_compare_and_swap(&last_good_addr[victim], 0, addr)) { - return; - } - victim = (victim + 1) % NLGA; - } - - /* All slots full. Evict the victim. */ - AO_store(&last_good_addr[victim], addr); - victim = (victim + 1) % NLGA; - AO_store(&lga_victim, victim); -} -#else -// disabled, no cache -static int -is_cached_valid_mem(unw_word_t addr UNUSED) -{ - return 0; -} - -static void -cache_valid_mem(unw_word_t addr UNUSED) -{ -} -#endif +static unw_word_t last_good_addr[NLGA]; +static int lga_victim; static int validate_mem (unw_word_t addr) { + int i, victim; size_t len; if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) @@ -302,13 +199,28 @@ validate_mem (unw_word_t addr) if (addr == 0) return -1; - if (is_cached_valid_mem(addr)) - return 0; + for (i = 0; i < NLGA; i++) + { + if (last_good_addr[i] && (addr == last_good_addr[i])) + return 0; + } if (mem_validate_func ((void *) addr, len) == -1) return -1; - cache_valid_mem(addr); + victim = lga_victim; + for (i = 0; i < NLGA; i++) { + if (!last_good_addr[victim]) { + last_good_addr[victim++] = addr; + return 0; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + last_good_addr[victim] = addr; + victim = (victim + 1) % NLGA; + lga_victim = victim; return 0; } @@ -422,6 +334,9 @@ x86_64_local_addr_space_init (void) local_addr_space.acc.resume = x86_64_local_resume; local_addr_space.acc.get_proc_name = get_static_proc_name; unw_flush_cache (&local_addr_space, 0, 0); + + memset (last_good_addr, 0, sizeof (unw_word_t) * NLGA); + lga_victim = 0; } #endif /* !UNW_REMOTE_ONLY */ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c index 12a9e3e4c96aa..5eaead0f840bb 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_local.c @@ -43,7 +43,7 @@ unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_i { struct cursor *c = (struct cursor *) cursor; - if (unlikely (!atomic_read(&tdep_init_done))) + if (unlikely (!tdep_init_done)) tdep_init (); Debug (1, "(cursor=%p)\n", c); diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c index f411b23331782..efd61d64d4b8f 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Ginit_remote.c @@ -36,7 +36,7 @@ unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) #else /* !UNW_LOCAL_ONLY */ struct cursor *c = (struct cursor *) cursor; - if (!atomic_read(&tdep_init_done)) + if (!tdep_init_done) tdep_init (); Debug (1, "(cursor=%p)\n", c); diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c deleted file mode 100644 index 75258d61d8755..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gos-solaris.c +++ /dev/null @@ -1,133 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2002-2003 Hewlett-Packard Co - Contributed by David Mosberger-Tang - - Modified for x86_64 by Max Asbock - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "unwind_i.h" -#include "ucontext_i.h" - -#include - -struct sigframe { - uint64_t signo; - uint64_t sip; -}; - -int -unw_is_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - - c->sigcontext_format = (c->dwarf.ip == (unw_word_t)-1) ? - X86_64_SCF_SOLARIS_SIGFRAME : X86_64_SCF_NONE; - - return (c->sigcontext_format); -} - -HIDDEN int -x86_64_handle_signal_frame (unw_cursor_t *cursor) -{ - struct cursor *c = (struct cursor *) cursor; - unw_word_t ucontext = c->dwarf.cfa + sizeof (struct sigframe); - - if (c->sigcontext_format != X86_64_SCF_SOLARIS_SIGFRAME) - return -UNW_EBADFRAME; - - c->sigcontext_addr = c->dwarf.cfa; - - Debug(1, "signal frame cfa = %lx ucontext = %lx\n", - (uint64_t)c->dwarf.cfa, (uint64_t)ucontext); - - struct dwarf_loc rsp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); - int ret = dwarf_get (&c->dwarf, rsp_loc, &c->dwarf.cfa); - - if (ret < 0) - { - Debug (2, "return %d\n", ret); - return ret; - } - - c->dwarf.loc[RAX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RAX, 0); - c->dwarf.loc[RDX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDX, 0); - c->dwarf.loc[RCX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RCX, 0); - c->dwarf.loc[RBX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBX, 0); - c->dwarf.loc[RSI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSI, 0); - c->dwarf.loc[RDI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDI, 0); - c->dwarf.loc[RBP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0); - c->dwarf.loc[RSP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0); - c->dwarf.loc[ R8] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0); - c->dwarf.loc[ R9] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0); - c->dwarf.loc[R10] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0); - c->dwarf.loc[R11] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0); - c->dwarf.loc[R12] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0); - c->dwarf.loc[R13] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0); - c->dwarf.loc[R14] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0); - c->dwarf.loc[R15] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0); - c->dwarf.loc[RIP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0); - - c->dwarf.use_prev_instr = 1; - return 0; -} - -#ifndef UNW_REMOTE_ONLY -HIDDEN void * -x86_64_r_uc_addr (ucontext_t *uc, int reg) -{ - /* NOTE: common_init() in init.h inlines these for fast path access. */ - void *addr; - - switch (reg) - { - case UNW_X86_64_R8: addr = &uc->uc_mcontext.gregs[REG_R8]; break; - case UNW_X86_64_R9: addr = &uc->uc_mcontext.gregs[REG_R9]; break; - case UNW_X86_64_R10: addr = &uc->uc_mcontext.gregs[REG_R10]; break; - case UNW_X86_64_R11: addr = &uc->uc_mcontext.gregs[REG_R11]; break; - case UNW_X86_64_R12: addr = &uc->uc_mcontext.gregs[REG_R12]; break; - case UNW_X86_64_R13: addr = &uc->uc_mcontext.gregs[REG_R13]; break; - case UNW_X86_64_R14: addr = &uc->uc_mcontext.gregs[REG_R14]; break; - case UNW_X86_64_R15: addr = &uc->uc_mcontext.gregs[REG_R15]; break; - case UNW_X86_64_RDI: addr = &uc->uc_mcontext.gregs[REG_RDI]; break; - case UNW_X86_64_RSI: addr = &uc->uc_mcontext.gregs[REG_RSI]; break; - case UNW_X86_64_RBP: addr = &uc->uc_mcontext.gregs[REG_RBP]; break; - case UNW_X86_64_RBX: addr = &uc->uc_mcontext.gregs[REG_RBX]; break; - case UNW_X86_64_RDX: addr = &uc->uc_mcontext.gregs[REG_RDX]; break; - case UNW_X86_64_RAX: addr = &uc->uc_mcontext.gregs[REG_RAX]; break; - case UNW_X86_64_RCX: addr = &uc->uc_mcontext.gregs[REG_RCX]; break; - case UNW_X86_64_RSP: addr = &uc->uc_mcontext.gregs[REG_RSP]; break; - case UNW_X86_64_RIP: addr = &uc->uc_mcontext.gregs[REG_RIP]; break; - - default: - addr = NULL; - } - return addr; -} - -HIDDEN NORETURN void -x86_64_sigreturn (unw_cursor_t *cursor) -{ - abort(); -} - -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c index 2a44f873e9edf..2c7bc312e28c0 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstash_frame.c @@ -110,10 +110,10 @@ tdep_stash_frame (struct dwarf_cursor *d, struct dwarf_reg_state *rs) } else if (f->frame_type == UNW_X86_64_FRAME_ALIGNED) { - Debug (4, " aligned frame, offset %i\n", f->cfa_reg_offset); + Debug (4, " aligned frame, offset %li\n", f->cfa_reg_offset); } + /* PLT and guessed RBP-walked frames are handled in unw_step(). */ - else { + else Debug (4, " unusual frame\n"); - } } diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c index d4831197cb39e..10498170ac76d 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gstep.c @@ -104,7 +104,6 @@ unw_step (unw_cursor_t *cursor) via CALLQ. Try this for all non-signal trampoline code. */ - unw_word_t invalid_prev_rip = 0; unw_word_t prev_ip = c->dwarf.ip, prev_cfa = c->dwarf.cfa; struct dwarf_loc rbp_loc, rsp_loc, rip_loc; @@ -150,10 +149,7 @@ unw_step (unw_cursor_t *cursor) return ret; } - unw_word_t not_used; - invalid_prev_rip = dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, prev_ip), ¬_used); - - if (!rbp && invalid_prev_rip == 0) + if (!rbp) { /* Looks like we may have reached the end of the call-chain. */ rbp_loc = DWARF_NULL_LOC; @@ -162,90 +158,38 @@ unw_step (unw_cursor_t *cursor) } else { - /* - * Check if previous RIP was invalid - * This could happen if a bad function pointer was - * followed and so the stack wasn't updated by the - * preamble - */ - int rip_fixup_success = 0; - if (invalid_prev_rip != 0) - { - Debug (2, "Previous RIP 0x%lx was invalid, attempting fixup\n", prev_ip); - unw_word_t rsp; - ret = dwarf_get (&c->dwarf, c->dwarf.loc[RSP], &rsp); - - /*Test to see if what we think is the previous RIP is valid*/ - unw_word_t new_ip = 0; - if (dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, rsp), &new_ip) == 0) - { - Debug (2, "RSP 0x%lx looks valid\n", rsp); - if ((ret = dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip), ¬_used)) == 0) - { - Debug (2, "new_ip 0x%lx looks valid\n", new_ip); - rip_fixup_success = 1; - c->frame_info.cfa_reg_offset = 8; - c->frame_info.cfa_reg_rsp = 1; - c->frame_info.rbp_cfa_offset = -1; - c->frame_info.rsp_cfa_offset = -1; - c->frame_info.frame_type = UNW_X86_64_FRAME_OTHER; - /* - * The call should have pushed RIP to the stack - * and since there was no preamble RSP hasn't been - * touched so RIP should be at RSP. - */ - c->dwarf.cfa += 8; - /* Optimised x64 binaries don't use RBP it seems? */ - rbp_loc = DWARF_LOC (rbp, 0); - rsp_loc = DWARF_LOC (rsp, 0); - rip_loc = DWARF_LOC (rsp, 0); - } - else - Debug (2, "new_ip 0x%lx dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip), ¬_used) != 0\n", new_ip); - } - else - Debug (2, "rsp 0x%lx dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, rsp), &new_ip) != 0\n", rsp); - } - /* - * If the previous rip we found on the stack didn't look valid fall back - * to the previous method for finding a valid stack frame - */ - if (!rip_fixup_success) + unw_word_t rbp1 = 0; + rbp_loc = DWARF_LOC(rbp, 0); + rsp_loc = DWARF_NULL_LOC; + rip_loc = DWARF_LOC (rbp + 8, 0); + ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1); + Debug (1, "[RBP=0x%lx] = 0x%lx (cfa = 0x%lx) -> 0x%lx\n", + (unsigned long) DWARF_GET_LOC (c->dwarf.loc[RBP]), + rbp, c->dwarf.cfa, rbp1); + + /* Heuristic to determine incorrect guess. For RBP to be a + valid frame it needs to be above current CFA, but don't + let it go more than a little. Note that we can't deduce + anything about new RBP (rbp1) since it may not be a frame + pointer in the frame above. Just check we get the value. */ + if (ret < 0 + || rbp < c->dwarf.cfa + || (rbp - c->dwarf.cfa) > 0x4000) { - Debug (2, "RIP fixup didn't work, falling back\n"); - unw_word_t rbp1 = 0; - rbp_loc = DWARF_LOC(rbp, 0); - rsp_loc = DWARF_NULL_LOC; - rip_loc = DWARF_LOC (rbp + 8, 0); - ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1); - Debug (1, "[RBP=0x%lx] = 0x%lx (cfa = 0x%lx) -> 0x%lx\n", - (unsigned long) DWARF_GET_LOC (c->dwarf.loc[RBP]), - rbp, c->dwarf.cfa, rbp1); - - /* Heuristic to determine incorrect guess. For RBP to be a - valid frame it needs to be above current CFA, but don't - let it go more than a little. Note that we can't deduce - anything about new RBP (rbp1) since it may not be a frame - pointer in the frame above. Just check we get the value. */ - if (ret < 0 - || rbp < c->dwarf.cfa - || (rbp - c->dwarf.cfa) > 0x4000) - { - rip_loc = DWARF_NULL_LOC; - rbp_loc = DWARF_NULL_LOC; - } - - c->frame_info.frame_type = UNW_X86_64_FRAME_GUESSED; - c->frame_info.cfa_reg_rsp = 0; - c->frame_info.cfa_reg_offset = 16; - c->frame_info.rbp_cfa_offset = -16; - c->dwarf.cfa += 16; - + rip_loc = DWARF_NULL_LOC; + rbp_loc = DWARF_NULL_LOC; } + + c->frame_info.frame_type = UNW_X86_64_FRAME_GUESSED; + c->frame_info.cfa_reg_rsp = 0; + c->frame_info.cfa_reg_offset = 16; + c->frame_info.rbp_cfa_offset = -16; + c->dwarf.cfa += 16; } + /* Mark all registers unsaved */ for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; + c->dwarf.loc[i] = DWARF_NULL_LOC; c->dwarf.loc[RBP] = rbp_loc; c->dwarf.loc[RSP] = rsp_loc; @@ -253,7 +197,7 @@ unw_step (unw_cursor_t *cursor) c->dwarf.use_prev_instr = 1; } - if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP]) && invalid_prev_rip == 0) + if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) { ret = 0; Debug (2, "NULL %%rbp loc, returning %d\n", ret); @@ -270,13 +214,6 @@ unw_step (unw_cursor_t *cursor) Debug (2, "returning %d\n", ret); return ret; } -#if __sun - if (c->dwarf.ip == 0) - { - Debug (2, "returning 0\n"); - return ret; - } -#endif ret = 1; } else diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c index 824527f9beaac..741227105e184 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/Gtrace.c @@ -540,7 +540,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size) break; /* Record this address in stack trace. We skipped the first address. */ - buffer[depth++] = (void *) rip; + buffer[depth++] = (void *) (rip - d->use_prev_instr); } #if UNW_DEBUG diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c b/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c deleted file mode 100644 index be64b2c695b89..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/Los-solaris.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) -#include "Gos-solaris.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S index e1450719b7da1..7a8b5664bdaeb 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/getcontext.S @@ -57,13 +57,11 @@ _Ux86_64_getcontext: movq %rax, UC_MCONTEXT_GREGS_RAX(%rdi) movq %rcx, UC_MCONTEXT_GREGS_RCX(%rdi) -#if defined __linux__ || defined __sun +#if defined __linux__ /* Save fp state (not needed, except for setcontext not restoring garbage). */ leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8 -#ifdef UC_MCONTEXT_FPREGS_PTR movq %r8, UC_MCONTEXT_FPREGS_PTR(%rdi) -#endif // UC_MCONTEXT_FPREGS_PTR fnstenv (%r8) stmxcsr FPREGS_OFFSET_MXCSR(%r8) #elif defined __FreeBSD__ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S b/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S index 17e5ae12032aa..358217defbaf3 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/setcontext.S @@ -37,13 +37,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ _Ux86_64_setcontext: -#if defined __linux__ || defined __sun +#if defined __linux__ /* restore fp state */ -#ifdef UC_MCONTEXT_FPREGS_PTR mov UC_MCONTEXT_FPREGS_PTR(%rdi),%r8 -#else // UC_MCONTEXT_FPREGS_PTR - leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8 -#endif // UC_MCONTEXT_FPREGS_PTR fldenv (%r8) ldmxcsr FPREGS_OFFSET_MXCSR(%r8) #elif defined __FreeBSD__ diff --git a/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h b/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h index e886c948453ce..aded941d053f7 100644 --- a/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h +++ b/src/coreclr/src/pal/src/libunwind/src/x86_64/ucontext_i.h @@ -78,25 +78,5 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define UC_MCONTEXT_FPOWNED_FPU 0x20001 #define UC_MCONTEXT_FPFMT_XMM 0x10002 #define UC_MCONTEXT_MC_LEN_VAL 0x320 -#elif defined __sun -#define UC_MCONTEXT_GREGS_R8 0x78 -#define UC_MCONTEXT_GREGS_R9 0x70 -#define UC_MCONTEXT_GREGS_R10 0x68 -#define UC_MCONTEXT_GREGS_R11 0x60 -#define UC_MCONTEXT_GREGS_R12 0x58 -#define UC_MCONTEXT_GREGS_R13 0x50 -#define UC_MCONTEXT_GREGS_R14 0x48 -#define UC_MCONTEXT_GREGS_R15 0x40 -#define UC_MCONTEXT_GREGS_RDI 0x80 -#define UC_MCONTEXT_GREGS_RSI 0x88 -#define UC_MCONTEXT_GREGS_RBP 0x90 -#define UC_MCONTEXT_GREGS_RBX 0x98 -#define UC_MCONTEXT_GREGS_RDX 0xa0 -#define UC_MCONTEXT_GREGS_RAX 0xb0 -#define UC_MCONTEXT_GREGS_RCX 0xa8 -#define UC_MCONTEXT_GREGS_RSP 0xe0 -#define UC_MCONTEXT_GREGS_RIP 0xc8 -#define UC_MCONTEXT_FPREGS_MEM 0x120 -#define FPREGS_OFFSET_MXCSR 0x18 #endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c index d5b484478705c..beae2a3ccd9b9 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-bt.c @@ -176,7 +176,7 @@ sighandler (int signal, void *siginfo UNUSED, void *context) { printf ("sighandler: got signal %d, sp=%p", signal, &sp); #if UNW_TARGET_IA64 -# if defined(__linux__) || defined __sun +# if defined(__linux__) printf (" @ %lx", uc->uc_mcontext.sc_ip); # else { @@ -189,13 +189,13 @@ sighandler (int signal, void *siginfo UNUSED, void *context) } # endif #elif UNW_TARGET_X86 -#if defined __linux__ || defined __sun +#if defined __linux__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_EIP]); #elif defined __FreeBSD__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip); #endif #elif UNW_TARGET_X86_64 -#if defined __linux__ || defined __sun +#if defined __linux__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]); #elif defined __FreeBSD__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip); diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c b/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c index 48667bb9f4df3..fc1f646eac6d0 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c +++ b/src/coreclr/src/pal/src/libunwind/tests/Gtest-trace.c @@ -207,7 +207,7 @@ sighandler (int signal, void *siginfo UNUSED, void *context) printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_eip); #endif #elif UNW_TARGET_X86_64 -#if defined __linux__ || defined __sun +#if defined __linux__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.gregs[REG_RIP]); #elif defined __FreeBSD__ printf (" @ %lx", (unsigned long) uc->uc_mcontext.mc_rip); diff --git a/src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c b/src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c deleted file mode 100644 index 209f87131248d..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Gx64-test-dwarf-expressions.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include - -#include - -static int verbose; -static int nerrors; - -#define panic(args...) \ - do { printf (args); ++nerrors; } while (0) - -// Assembly routine which sets up the stack for the test then calls another one -// which clobbers the stack, and which in turn calls recover_register below -extern int64_t DW_CFA_expression_testcase(int64_t regnum, int64_t height); - -// recover_register is called by the assembly routines. It returns the value of -// a register at a specified height from the inner-most frame. The return value -// is propagated back through the assembly routines to the testcase. -extern int64_t recover_register(int64_t regnum, int64_t height) -{ - // Initialize cursor to current frame - int rc, i; - unw_cursor_t cursor; - unw_context_t context; - unw_getcontext(&context); - unw_init_local(&cursor, &context); - // Unwind frames until required height from inner-most frame (i.e. this one) - for (i = 0; i < height; ++i) - { - rc = unw_step(&cursor); - if (rc < 0) - panic("%s: unw_step failed on step %d with return code %d", __FUNCTION__, i, rc); - else if (rc == 0) - panic("%s: unw_step failed to reach the end of the stack", __FUNCTION__); - unw_word_t pc; - rc = unw_get_reg(&cursor, UNW_REG_IP, &pc); - if (rc < 0 || pc == 0) - panic("%s: unw_get_reg failed to locate the program counter", __FUNCTION__); - } - // We're now at the required height, extract register - uint64_t value; - if ((rc = unw_get_reg(&cursor, (unw_regnum_t) regnum, &value)) != 0) - panic("%s: unw_get_reg failed to retrieve register %lu", __FUNCTION__, regnum); - return value; -} - -int -main (int argc, char **argv) -{ - if (argc > 1) - verbose = 1; - - if (DW_CFA_expression_testcase(12, 1) != 0) - panic("r12 should be clobbered at height 1 (DW_CFA_expression_inner)"); - if (DW_CFA_expression_testcase(12, 2) != 111222333) - panic("r12 should be restored at height 2 (DW_CFA_expression_testcase)"); - - if (nerrors > 0) - { - fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); - exit (-1); - } - - if (verbose) - printf ("SUCCESS.\n"); - return 0; -} diff --git a/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c b/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c index e5127b90628fc..1cacb9f028f15 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c +++ b/src/coreclr/src/pal/src/libunwind/tests/Ltest-mem-validate.c @@ -35,8 +35,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include -#include -#include #define panic(args...) \ { fprintf (stderr, args); exit (-1); } diff --git a/src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c b/src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c deleted file mode 100644 index 07e916e60a6ac..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/Lx64-test-dwarf-expressions.c +++ /dev/null @@ -1,5 +0,0 @@ -#define UNW_LOCAL_ONLY -#include -#if !defined(UNW_REMOTE_ONLY) -#include "Gx64-test-dwarf-expressions.c" -#endif diff --git a/src/coreclr/src/pal/src/libunwind/tests/Makefile.am b/src/coreclr/src/pal/src/libunwind/tests/Makefile.am index 61d1bf875a8c8..4b0b9db7d1699 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/Makefile.am +++ b/src/coreclr/src/pal/src/libunwind/tests/Makefile.am @@ -37,11 +37,7 @@ if ARCH_PPC64 if USE_ALTIVEC noinst_PROGRAMS_arch += ppc64-test-altivec endif #USE_ALTIVEC -else #!ARCH_PPC64 -if ARCH_X86_64 - check_PROGRAMS_arch += Gx64-test-dwarf-expressions Lx64-test-dwarf-expressions x64-unwind-badjmp-signal-frame -endif #ARCH X86_64 -endif #!ARCH_PPC64 +endif #ARCH_PPC64 endif #!ARCH_IA64 check_PROGRAMS_cdep += Gtest-bt Ltest-bt Gtest-exc Ltest-exc \ Gtest-init Ltest-init \ @@ -143,21 +139,12 @@ Gia64_test_nat_SOURCES = Gia64-test-nat.c ia64-test-nat-asm.S ia64_test_dyn1_SOURCES = ia64-test-dyn1.c ia64-dyn-asm.S flush-cache.S \ flush-cache.h ppc64_test_altivec_SOURCES = ppc64-test-altivec.c ppc64-test-altivec-utils.c - - -Gx64_test_dwarf_expressions_SOURCES = Gx64-test-dwarf-expressions.c \ - x64-test-dwarf-expressions.S -Lx64_test_dwarf_expressions_SOURCES = Lx64-test-dwarf-expressions.c \ - x64-test-dwarf-expressions.S - - Gtest_init_SOURCES = Gtest-init.cxx Ltest_init_SOURCES = Ltest-init.cxx Ltest_cxx_exceptions_SOURCES = Ltest-cxx-exceptions.cxx Ltest_init_local_signal_SOURCES = Ltest-init-local-signal.c Ltest-init-local-signal-lib.c -x64_unwind_badjmp_signal_frame_SOURCES = x64-unwind-badjmp-signal-frame.c Gtest_dyn1_SOURCES = Gtest-dyn1.c flush-cache.S flush-cache.h Ltest_dyn1_SOURCES = Ltest-dyn1.c flush-cache.S flush-cache.h test_static_link_SOURCES = test-static-link-loc.c test-static-link-gen.c @@ -204,7 +191,6 @@ Ltest_init_local_signal_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_bt_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_concurrent_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -lpthread -x64_unwind_badjmp_signal_frame_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_dyn1_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_exc_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) Gtest_init_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) @BACKTRACELIB@ @@ -246,6 +232,3 @@ Lia64_test_readonly_LDADD = $(LIBUNWIND_local) ia64_test_dyn1_LDADD = $(LIBUNWIND) ia64_test_sig_LDADD = $(LIBUNWIND) ppc64_test_altivec_LDADD = $(LIBUNWIND) - -Gx64_test_dwarf_expressions_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -Lx64_test_dwarf_expressions_LDADD = $(LIBUNWIND_local) diff --git a/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in b/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in index f43bca263bc35..6d0081732da00 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in +++ b/src/coreclr/src/pal/src/libunwind/tests/check-namespace.sh.in @@ -85,11 +85,6 @@ filter_misc () { ignore _ftext ignore _gp fi - - if [ ${os} == "solaris2.11" ]; then - ignore _PROCEDURE_LINKAGE_TABLE_ - ignore _etext - fi } check_local_unw_abi () { @@ -126,7 +121,7 @@ check_local_unw_abi () { match _U_dyn_register match unw_backtrace - @CONFIG_WEAK_BACKTRACE_TRUE@match backtrace + match backtrace case ${plat} in arm) @@ -181,14 +176,6 @@ check_local_unw_abi () { match _U${plat}_get_exe_image_path match ${plat}_lock ;; - s390x) - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_is_fpreg - match _UL${plat}_dwarf_search_unwind_table - match _UL${plat}_dwarf_find_unwind_table - match _U${plat}_setcontext - ;; *) match _U${plat}_is_fpreg @@ -289,13 +276,6 @@ check_generic_unw_abi () { match _U${plat}_local_addr_space_init match ${plat}_lock ;; - s390x) - match _U${plat}_is_fpreg - match _U${plat}_get_elf_image - match _U${plat}_get_exe_image_path - match _U${plat}_dwarf_search_unwind_table - match _U${plat}_dwarf_find_unwind_table - ;; *) match _U${plat}_is_fpreg match _U${plat}_dwarf_search_unwind_table diff --git a/src/coreclr/src/pal/src/libunwind/tests/crasher.c b/src/coreclr/src/pal/src/libunwind/tests/crasher.c index bb99e339c2639..24c78054c9478 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/crasher.c +++ b/src/coreclr/src/pal/src/libunwind/tests/crasher.c @@ -87,13 +87,8 @@ write_maps(char *fname) #endif #ifdef __GNUC__ -#ifndef __clang__ -// Gcc >= 8 became too good at inlining aliase c into b when using -O2 or -O3, -// so force -O1 in all cases, otherwise a frame will be missing in the tests. -#pragma GCC optimize "-O1" -#endif int c(int x) NOINLINE ALIAS(b); -#define compiler_barrier() __asm__ __volatile__ (""); +#define compiler_barrier() asm volatile(""); #else int c(int x); #define compiler_barrier() diff --git a/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c b/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c index fb06a38effa10..53498237c2fd0 100644 --- a/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c +++ b/src/coreclr/src/pal/src/libunwind/tests/test-coredump-unwind.c @@ -57,11 +57,7 @@ #include /* For SIGSEGV handler code */ -#if HAVE_EXECINFO_H -# include -#else - extern int backtrace (void **, int); -#endif +#include #include #include @@ -246,7 +242,7 @@ void handle_sigsegv(int sig, siginfo_t *info, void *ucontext) void *array[50]; int size; size = backtrace(array, 50); -#if defined __linux__ && HAVE_EXECINFO_H +#ifdef __linux__ backtrace_symbols_fd(array, size, 2); #endif } diff --git a/src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S b/src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S deleted file mode 100644 index f275625df1006..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/x64-test-dwarf-expressions.S +++ /dev/null @@ -1,78 +0,0 @@ -.global DW_CFA_expression_testcase - -.extern recover_register - -.text - -# CFI expressions were added in DWARF v3 to allow compilers to specify memory -# locations or register values using DWARF programs. These programs are simple -# stack-based operations which allow the compiler to encode integer mathematics -# and other complex logic. CFI expressions are therefore more powerful than the -# conventional register + offset schemes. -# -# These tests capture a bug we have fixed in libunwind. CFI expression programs -# always start with the current CFA pushed onto the stack. This file contains a -# pair of routines which test CFI expression parsing. Specifically they test -# DW_CFA_expression logic, which uses DWARF expressions to compute the address -# where a non-volatile register was stored. -# -# Main calls DW_CFA_expression_testcase, which sets up known state in a -# non-volatile (caller-saved) register. We use r12 for this purpose. After this -# DW_CFA_expression_testcase then calls DW_CFA_expression_inner, which clobbers -# r12 after stashing its value on the stack. This routine contains a DWARF3 CFI -# expression to restore the value of r12 on unwind which should allow libunwind -# to recover clobbered state. DW_CFA_expression_inner calls recover_register to -# retrieve the cached register value. This function recovers the register value -# by using libunwind to unwind the stack through DW_CFA_expression_inner and up -# to the call site in DW_CFA_expression_testcase. If our expression is correct, -# libunwind will be able to restore r12 from the stack. -# -# BE CAREFUL WITH rdi, rsi, rax HERE! The arguments to recover_register are -# passed in via rdi, rsi and I just let them flow through unchanged. Similarly -# RAX flows back unchanged. Adding any function calls to the below may clobber -# these registers and cause this test to fail mysteriously. - - -######################################################## -# Test: Restoring a register using a DW_CFA_expression # -# which uses implicit CFA pushed onto stack. # -######################################################## - -.type DW_CFA_expression_testcase STT_FUNC -DW_CFA_expression_testcase: - .cfi_startproc - push %r12 - .cfi_adjust_cfa_offset 8 - # Move our sentinel (known) value into non-volatile (Callee-saved) r12 - mov $111222333, %r12 - .cfi_rel_offset %r12, 0 - call DW_CFA_expression_inner - pop %r12 - .cfi_restore %r12 - .cfi_adjust_cfa_offset -8 - ret - .cfi_endproc -.size DW_CFA_expression_testcase,.-DW_CFA_expression_testcase - -.type DW_CFA_expression_inner STT_FUNC -DW_CFA_expression_inner: - .cfi_startproc - push %r12 - .cfi_adjust_cfa_offset 8 - # !! IMPORTANT BIT !! The test is all about how we parse the following bytes. - # Now we use an expression to describe where our sentinel value is stored: - # DW_CFA_expression(0x10), r12(0x0c), Length(0x02), (preamble) - # DW_OP_lit16(0x40), DW_OP_minus(0x1c) (instructions) - # Parsing starts with the CFA on the stack, then pushes 16, then does a minus - # which is eqivalent to a=pop(), b=pop(), push(b-a), leaving us with a value - # of cfa-16 (cfa points at old rsp, cfa-8 is our rip, so we stored r12 at - # cfa-16). - xor %r12, %r12 # Trash r12 - .cfi_escape 0x10, 0x0c, 0x2, 0x40, 0x1c # DW_CFA_expression for recovery - call recover_register - pop %r12 - .cfi_restore %r12 - .cfi_adjust_cfa_offset -8 - ret - .cfi_endproc -.size DW_CFA_expression_inner,.-DW_CFA_expression_inner diff --git a/src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c b/src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c deleted file mode 100644 index c7b7cf7335a8b..0000000000000 --- a/src/coreclr/src/pal/src/libunwind/tests/x64-unwind-badjmp-signal-frame.c +++ /dev/null @@ -1,124 +0,0 @@ -/* libunwind - a platform-independent unwind library - Copyright (C) 2019 Brock York - -This file is part of libunwind. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_PTRACE_H -#include -#endif - -#define UNW_LOCAL_ONLY -#include - -/* - * unwind in the signal handler checking the backtrace is correct - * after a bad jump. - */ -void handle_sigsegv(int signal, siginfo_t *info, void *ucontext) -{ - /* - * 0 = success - * !0 = general failure - * 77 = test skipped - * 99 = complete failure - */ - int test_status = 0; - unw_cursor_t cursor; unw_context_t uc; - unw_word_t ip, sp, offset; - char name[1000]; - int found_signal_frame = 0; - int i = 0; - char *names[] = { - "", - "main", - }; - int names_count = sizeof(names) / sizeof(*names); - - unw_getcontext(&uc); - unw_init_local(&cursor, &uc); - - while (unw_step(&cursor) > 0 && !test_status) - { - if (unw_is_signal_frame(&cursor)) - { - found_signal_frame = 1; - } - if (found_signal_frame) - { - unw_get_reg(&cursor, UNW_REG_IP, &ip); - unw_get_reg(&cursor, UNW_REG_SP, &sp); - memset(name, 0, sizeof(char) * 1000); - unw_get_proc_name(&cursor, name, sizeof(char) * 1000, &offset); - printf("ip = %lx, sp = %lx offset = %lx name = %s\n", (long) ip, (long) sp, (long) offset, name); - if (i < names_count) - { - if (strcmp(names[i], name) != 0) - { - test_status = 1; - printf("frame %s doesn't match expected frame %s\n", name, names[i]); - } - else - { - i += 1; - } - } - } - } - - if (i != names_count) //Make sure we found all the frames! - { - printf("Failed to find all frames i:%d != names_count:%d\n", i, names_count); - test_status = 1; - } - - /*return test_status to test harness*/ - exit(test_status); -} - -void (*invalid_function)() = (void*)1; - -int main(int argc, char *argv[]) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handle_sigsegv; - sa.sa_flags = SA_SIGINFO; - sigaction(SIGSEGV, &sa, NULL); - - invalid_function(); - - /* - * 99 is the hard error exit status for automake tests: - * https://www.gnu.org/software/automake/manual/html_node/Scripts_002dbased-Testsuites.html#Scripts_002dbased-Testsuites - * If we dont end up in the signal handler something went horribly wrong. - */ - return 99; -} From 49f40c34e4e18a4b80c7aa5d11104c9624a2667e Mon Sep 17 00:00:00 2001 From: Youssef Victor <31348972+Youssef1313@users.noreply.github.com> Date: Sat, 23 May 2020 11:31:08 +0200 Subject: [PATCH 363/420] Remove PreserveDependency from SR class (#36358) --- src/libraries/System.Private.CoreLib/src/System/SR.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/SR.cs b/src/libraries/System.Private.CoreLib/src/System/SR.cs index 017ce551e8b16..73e7e0015526b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SR.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SR.cs @@ -24,7 +24,6 @@ internal static string GetResourceString(string resourceKey) return GetResourceString(resourceKey, string.Empty); } - [PreserveDependency(".cctor()", "System.Resources.ResourceManager")] private static string InternalGetResourceString(string key) { if (key.Length == 0) From 30fb79750248a9813ea5fb4e08da9f74b3b30ec8 Mon Sep 17 00:00:00 2001 From: Mikhail Pilin Date: Sun, 24 May 2020 05:18:14 +0200 Subject: [PATCH 364/420] Use TARGET_64BIT instead of set of TARGET_ definitions for CLRConfig::EXTERNAL_CORECLR_PROFILER_PATH_64 and CLRConfig::EXTERNAL_CORECLR_PROFILER_PATH_32 checking. (#36924) --- src/coreclr/src/vm/profilinghelper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/vm/profilinghelper.cpp b/src/coreclr/src/vm/profilinghelper.cpp index 1d41007c7d8f7..e5af2fcdfacac 100644 --- a/src/coreclr/src/vm/profilinghelper.cpp +++ b/src/coreclr/src/vm/profilinghelper.cpp @@ -702,10 +702,10 @@ HRESULT ProfilingAPIUtility::AttemptLoadProfilerForStartup() IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CORECLR_PROFILER, &wszClsid)); -#if defined(TARGET_X86) || defined(TARGET_ARM) - IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CORECLR_PROFILER_PATH_32, &wszProfilerDLL)); -#elif defined(TARGET_AMD64) || defined(TARGET_ARM64) +#ifdef TARGET_64BIT IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CORECLR_PROFILER_PATH_64, &wszProfilerDLL)); +#else + IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CORECLR_PROFILER_PATH_32, &wszProfilerDLL)); #endif if(wszProfilerDLL == NULL) { From 6f01d724672a104e3b7259fdc756d7e9e0f5a897 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Sat, 23 May 2020 20:23:20 -0700 Subject: [PATCH 365/420] Follow ups for Math.BigMul (#36920) - Use more efficient and compact uint cast instead of bit masks where possible - Improved test coverage - Update comment in FastMod - Optimize BigMul for 32-bit platforms --- .../src/System/Collections/HashHelpers.cs | 7 ++-- .../System.Private.CoreLib/src/System/Math.cs | 33 ++++++++++++------- .../tests/System/Math.cs | 5 +++ 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/HashHelpers.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/HashHelpers.cs index abdf95c05ed79..9ae197ee1bcf9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/HashHelpers.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/HashHelpers.cs @@ -101,10 +101,9 @@ public static uint FastMod(uint value, uint divisor, ulong multiplier) // which allows to avoid the long multiplication if the divisor is less than 2**31. Debug.Assert(divisor <= int.MaxValue); - ulong lowbits = multiplier * value; - // 64bit * 64bit => 128bit isn't currently supported by Math https://github.com/dotnet/runtime/issues/31184 - // otherwise we'd want this to be (uint)Math.BigMul(lowbits, divisor, out _) - uint highbits = (uint)((((lowbits >> 32) + 1) * divisor) >> 32); + // This is equivalent of (uint)Math.BigMul(multiplier * value, divisor, out _). This version + // is faster than BigMul currently because we only need the high bits. + uint highbits = (uint)(((((multiplier * value) >> 32) + 1) * divisor) >> 32); Debug.Assert(highbits == value % divisor); return highbits; diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.cs b/src/libraries/System.Private.CoreLib/src/System/Math.cs index 9e80f5560fcba..2b0ca9e0f279b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.cs @@ -114,6 +114,11 @@ public static long BigMul(int a, int b) return ((long)a) * b; } + /// Produces the full product of two unsigned 64-bit numbers. + /// The first number to multiply. + /// The second number to multiply. + /// The low 64-bit of the product of the specied numbers. + /// The high 64-bit of the product of the specied numbers. [CLSCompliant(false)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe ulong BigMul(ulong a, ulong b, out ulong low) @@ -130,29 +135,33 @@ public static unsafe ulong BigMul(ulong a, ulong b, out ulong low) static ulong SoftwareFallback(ulong a, ulong b, out ulong low) { - // It's adoption of algorithm for multiplication + // Adaptation of algorithm for multiplication // of 32-bit unsigned integers described // in Hacker's Delight by Henry S. Warren, Jr. (ISBN 0-201-91465-4), Chapter 8 // Basically, it's an optimized version of FOIL method applied to // low and high dwords of each operand - const ulong lowBitsMask = 0xFFFFFFFFU; - ulong al = a & lowBitsMask; - ulong ah = a >> 32; - ulong bl = b & lowBitsMask; - ulong bh = b >> 32; + // Use 32-bit uints to optimize the fallback for 32-bit platforms. + uint al = (uint)a; + uint ah = (uint)(a >> 32); + uint bl = (uint)b; + uint bh = (uint)(b >> 32); - ulong mull = al * bl; - ulong t = ah * bl + (mull >> 32); - ulong tl = t & lowBitsMask; + ulong mull = ((ulong)al) * bl; + ulong t = ((ulong)ah) * bl + (mull >> 32); + ulong tl = ((ulong)al) * bh + (uint)t; - tl += al * bh; - low = tl << 32 | mull & lowBitsMask; + low = tl << 32 | (uint)mull; - return ah * bh + (t >> 32) + (tl >> 32); + return ((ulong)ah) * bh + (t >> 32) + (tl >> 32); } } + /// Produces the full product of two 64-bit numbers. + /// The first number to multiply. + /// The second number to multiply. + /// The low 64-bit of the product of the specied numbers. + /// The high 64-bit of the product of the specied numbers. public static long BigMul(long a, long b, out long low) { ulong high = BigMul((ulong)a, (ulong)b, out ulong ulow); diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Math.cs b/src/libraries/System.Runtime.Extensions/tests/System/Math.cs index f3c3bc0777b15..c2b43c8d8ec4d 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Math.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Math.cs @@ -1758,6 +1758,7 @@ public static void BigMul() [InlineData(ulong.MaxValue, 1, "0000000000000000FFFFFFFFFFFFFFFF")] [InlineData(ulong.MaxValue, ulong.MaxValue, "FFFFFFFFFFFFFFFE0000000000000001")] [InlineData(ulong.MaxValue, 3, "0000000000000002FFFFFFFFFFFFFFFD")] + [InlineData(0xE8FAF08929B46BB5, 0x26B442D59782BA17, "23394CF8915296631EB6255F4A612F43")] public static void BigMul128_Unsigned(ulong a, ulong b, string result) { ulong high = Math.BigMul(a, b, out ulong low); @@ -1773,6 +1774,10 @@ public static void BigMul128_Unsigned(ulong a, ulong b, string result) [InlineData(-1L, -1L, "00000000000000000000000000000001")] [InlineData(-1L, long.MinValue, "00000000000000008000000000000000")] [InlineData(1L, long.MinValue, "FFFFFFFFFFFFFFFF8000000000000000")] + [InlineData(0x7DD8FD06E61C42C7, 0x23B8308969A5D354, "118F366A0AEB79CDB340AA067592EE4C")] + [InlineData(0x6DACB8FC835F41B5, -0x2D90EF8C7ED29BBA, "EC7A8BB31D6035AD27742486E387AB7E")] + [InlineData(-0x166FA7C456154C28, 0x13CF93153370AB0B, "FE43855FCCDA31541A45864AC9B70248")] + [InlineData(-0x57A14FB8778E4F94, -0x33BDC4C7D41A44C9, "11B61855830A65CBA363C1FE50E7CB34")] public static void BigMul128_Signed(long a, long b, string result) { long high = Math.BigMul(a, b, out long low); From 78c1de87f73388ef029835fa80fcbeb8f90fd765 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Sun, 24 May 2020 00:26:47 -0400 Subject: [PATCH 366/420] Use BinaryPrimitives where possible. (#36881) --- .../src/Internal/Cryptography/Helpers.cs | 15 --------------- .../src/System/Security/Cryptography/DES.cs | 16 +++------------- .../Security/Cryptography/Rfc2898DeriveBytes.cs | 3 ++- .../Security/Cryptography/CapiHelper.Windows.cs | 3 ++- .../DSACryptoServiceProvider.Windows.cs | 3 ++- 5 files changed, 9 insertions(+), 31 deletions(-) diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/Helpers.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/Helpers.cs index 5ca3a10cf788f..1d3c1db2b877c 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/Helpers.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/Helpers.cs @@ -39,21 +39,6 @@ public static byte[] GenerateRandom(int count) return buffer; } - // encodes the integer i into a 4-byte array, in big endian. - public static void WriteInt(uint i, byte[] arr, int offset) - { - unchecked - { - Debug.Assert(arr != null); - Debug.Assert(arr.Length >= offset + sizeof(uint)); - - arr[offset] = (byte)(i >> 24); - arr[offset + 1] = (byte)(i >> 16); - arr[offset + 2] = (byte)(i >> 8); - arr[offset + 3] = (byte)i; - } - } - public static byte[] FixupKeyParity(this byte[] key) { byte[] oddParityKey = new byte[key.Length]; diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/DES.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/DES.cs index 443cc84d79b75..8ad67820c8fde 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/DES.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/DES.cs @@ -4,6 +4,7 @@ using Internal.Cryptography; using System.ComponentModel; +using System.Buffers.Binary; namespace System.Security.Cryptography { @@ -65,7 +66,7 @@ public static bool IsWeakKey(byte[] rgbKey) throw new CryptographicException(SR.Cryptography_InvalidKeySize); byte[] rgbOddParityKey = rgbKey.FixupKeyParity(); - ulong key = QuadWordFromBigEndian(rgbOddParityKey); + ulong key = BinaryPrimitives.ReadUInt64BigEndian(rgbOddParityKey); if ((key == 0x0101010101010101) || (key == 0xfefefefefefefefe) || (key == 0x1f1f1f1f0e0e0e0e) || @@ -83,7 +84,7 @@ public static bool IsSemiWeakKey(byte[] rgbKey) throw new CryptographicException(SR.Cryptography_InvalidKeySize); byte[] rgbOddParityKey = rgbKey.FixupKeyParity(); - ulong key = QuadWordFromBigEndian(rgbOddParityKey); + ulong key = BinaryPrimitives.ReadUInt64BigEndian(rgbOddParityKey); if ((key == 0x01fe01fe01fe01fe) || (key == 0xfe01fe01fe01fe01) || (key == 0x1fe01fe00ef10ef1) || @@ -111,17 +112,6 @@ private static bool IsLegalKeySize(byte[]? rgbKey) return false; } - private static ulong QuadWordFromBigEndian(byte[] block) - { - ulong x = ( - (((ulong)block[0]) << 56) | (((ulong)block[1]) << 48) | - (((ulong)block[2]) << 40) | (((ulong)block[3]) << 32) | - (((ulong)block[4]) << 24) | (((ulong)block[5]) << 16) | - (((ulong)block[6]) << 8) | ((ulong)block[7]) - ); - return x; - } - private static readonly KeySizes[] s_legalBlockSizes = { new KeySizes(minSize: 64, maxSize: 64, skipSize: 0) diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/Rfc2898DeriveBytes.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/Rfc2898DeriveBytes.cs index 61c4fa1bd8dc6..42c67d78f91b8 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/Rfc2898DeriveBytes.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/Rfc2898DeriveBytes.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Buffers; +using System.Buffers.Binary; using System.Text; using System.Diagnostics; @@ -258,7 +259,7 @@ private void Initialize() // where i is the block number. private void Func() { - Helpers.WriteInt(_block, _salt, _salt.Length - sizeof(uint)); + BinaryPrimitives.WriteUInt32BigEndian(_salt.AsSpan(_salt.Length - sizeof(uint)), _block); Debug.Assert(_blockSize == _buffer.Length); // The biggest _blockSize we have is from SHA512, which is 64 bytes. diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Windows.cs index 8deeddfc746a0..983fbd9ac26f8 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/CapiHelper.Windows.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Buffers.Binary; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; @@ -750,7 +751,7 @@ private static void ValidateCspFlags(CspProviderFlags flags) // check that this is indeed an RSA/DSS key. byte[] algid = CapiHelper.GetKeyParameter(hKey, Constants.CLR_ALGID); - int dwAlgId = (algid[0] | (algid[1] << 8) | (algid[2] << 16) | (algid[3] << 24)); + int dwAlgId = BinaryPrimitives.ReadInt32LittleEndian(algid); if ((keyType == CspAlgorithmType.Rsa && dwAlgId != CALG_RSA_KEYX && dwAlgId != CALG_RSA_SIGN) || (keyType == CspAlgorithmType.Dss && dwAlgId != CALG_DSS_SIGN)) diff --git a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs index ed51902db8a0f..567ce989bd7a5 100644 --- a/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/DSACryptoServiceProvider.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Buffers.Binary; using System.Diagnostics; using System.IO; using Internal.NativeCrypto; @@ -200,7 +201,7 @@ public override int KeySize get { byte[] keySize = CapiHelper.GetKeyParameter(SafeKeyHandle, Constants.CLR_KEYLEN); - _keySize = (keySize[0] | (keySize[1] << 8) | (keySize[2] << 16) | (keySize[3] << 24)); + _keySize = BinaryPrimitives.ReadInt32LittleEndian(keySize); return _keySize; } } From cbf517e031587ca607d0f5069136fdd75c56cb4f Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Sun, 24 May 2020 00:28:15 -0400 Subject: [PATCH 367/420] Fix exception message to indicate Cofactor is required. (#36821) --- .../src/Resources/Strings.resx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx index 76aed28615e9a..6e731527ea232 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Resources/Strings.resx @@ -199,10 +199,10 @@ Input string does not contain a valid encoding of the '{0}' '{1}' parameter. - The specified Characteristic2 curve parameters are not valid. Polynomial, A, B, G.X, G.Y, and Order are required. A, B, G.X, G.Y must be the same length, and the same length as Q.X, Q.Y and D if those are specified. Seed, Cofactor and Hash are optional. Other parameters are not allowed. + The specified Characteristic2 curve parameters are not valid. Polynomial, A, B, G.X, G.Y, and Order are required. A, B, G.X, G.Y must be the same length, and the same length as Q.X, Q.Y and D if those are specified. Cofactor is required. Seed and Hash are optional. Other parameters are not allowed. - The specified prime curve parameters are not valid. Prime, A, B, G.X, G.Y and Order are required and must be the same length, and the same length as Q.X, Q.Y and D if those are specified. Seed, Cofactor and Hash are optional. Other parameters are not allowed. + The specified prime curve parameters are not valid. Prime, A, B, G.X, G.Y and Order are required and must be the same length, and the same length as Q.X, Q.Y and D if those are specified. Cofactor is required. Seed and Hash are optional. Other parameters are not allowed. The specified named curve parameters are not valid. Only the Oid parameter must be set. From f6903fc2d37b3aa1588291d084e8dab63683cbbe Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Sun, 24 May 2020 00:01:32 -0700 Subject: [PATCH 368/420] Disable GC/API/GC/AddThresholdTest on ARM64 (#36940) Issue #36850 --- src/coreclr/tests/issues.targets | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index c1ce557f91bc3..0ab601012716a 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -333,6 +333,9 @@ https://github.com/dotnet/runtime/issues/13355 + + https://github.com/dotnet/runtime/issues/36850 + From d17d838b711d9aeeb08b59d08b25ca71653e7b2e Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Sun, 24 May 2020 02:33:12 -0700 Subject: [PATCH 369/420] Add comments per code review feedback --- src/coreclr/src/vm/eventpipeprovider.cpp | 5 ++++- src/coreclr/src/vm/eventtrace.cpp | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/vm/eventpipeprovider.cpp b/src/coreclr/src/vm/eventpipeprovider.cpp index f2d7760b5b32e..28a9bf68b040a 100644 --- a/src/coreclr/src/vm/eventpipeprovider.cpp +++ b/src/coreclr/src/vm/eventpipeprovider.cpp @@ -255,11 +255,14 @@ void EventPipeProvider::AddEvent(EventPipeEvent &event) isEventFilterDescriptorInitialized = true; } + // NOTE: When we call the callback, we pass in enabled (which is either 1 or 0) as the ControlCode. + // If we want to add new ControlCode, we have to make corresponding change in eventtrace.cpp:EtwCallbackCommon + // to address this. See https://github.com/dotnet/runtime/pull/36733 for more discussions on this. if (pCallbackFunction != NULL && !g_fEEShutDown) { (*pCallbackFunction)( NULL, /* providerId */ - enabled, + enabled, /* ControlCode */ (UCHAR)providerLevel, keywords, 0 /* matchAllKeywords */, diff --git a/src/coreclr/src/vm/eventtrace.cpp b/src/coreclr/src/vm/eventtrace.cpp index 6118a662a0b01..ef7f471c04b3b 100644 --- a/src/coreclr/src/vm/eventtrace.cpp +++ b/src/coreclr/src/vm/eventtrace.cpp @@ -4268,6 +4268,9 @@ VOID EtwCallbackCommon( ctxToUpdate->EventPipeProvider.Level = Level; ctxToUpdate->EventPipeProvider.EnabledKeywordsBitmask = MatchAnyKeyword; ctxToUpdate->EventPipeProvider.IsEnabled = ControlCode; + + // For EventPipe, ControlCode can only be either 0 or 1. + _ASSERTE(ControlCode == 0 || ControlCode == 1); } if ( From 8e6bd8cc1cdf2a1e38988f134ae309e2431857e9 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 24 May 2020 07:41:28 -0700 Subject: [PATCH 370/420] Fixing emitAnyConst and related functions to better handle alignment (#36432) * Fixing emitAnyConst and related functions to better handle alignment * Don't use small alignment where it might not be supported * Applying formatting patch * Adding some comments explaining how emitAnyConst works --- src/coreclr/src/jit/codegenxarch.cpp | 6 +- src/coreclr/src/jit/emit.cpp | 132 +++++++++++++-------------- src/coreclr/src/jit/emit.h | 13 +-- src/coreclr/src/jit/emitpub.h | 6 +- src/coreclr/src/jit/emitxarch.cpp | 6 +- src/coreclr/src/jit/lowerarmarch.cpp | 7 +- src/coreclr/src/jit/lowerxarch.cpp | 15 ++- 7 files changed, 100 insertions(+), 85 deletions(-) diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index 2b7a5556532dc..2d2d92fde1a81 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -6864,7 +6864,11 @@ void CodeGen::genSSE2BitwiseOp(GenTree* treeNode) if (*bitMask == nullptr) { assert(cnsAddr != nullptr); - *bitMask = GetEmitter()->emitAnyConst(cnsAddr, genTypeSize(targetType), emitDataAlignment::Preferred); + + UNATIVE_OFFSET cnsSize = genTypeSize(targetType); + UNATIVE_OFFSET cnsAlign = (compiler->compCodeOpt() != Compiler::SMALL_CODE) ? cnsSize : 1; + + *bitMask = GetEmitter()->emitAnyConst(cnsAddr, cnsSize, cnsAlign); } // We need an additional register for bitmask. diff --git a/src/coreclr/src/jit/emit.cpp b/src/coreclr/src/jit/emit.cpp index 8b9c2c7e21fe8..2613cd453e61a 100644 --- a/src/coreclr/src/jit/emit.cpp +++ b/src/coreclr/src/jit/emit.cpp @@ -4622,10 +4622,18 @@ unsigned emitter::emitEndCodeGen(Compiler* comp, } #endif - if (emitConsDsc.align16) + // This restricts the emitConsDsc.alignment to: 1, 2, 4, 8, 16, or 32 bytes + // Alignments greater than 32 would require VM support in ICorJitInfo::allocMem + assert(isPow2(emitConsDsc.alignment) && (emitConsDsc.alignment <= 32)); + + if (emitConsDsc.alignment == 16) { allocMemFlag = static_cast(allocMemFlag | CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN); } + else if (emitConsDsc.alignment == 32) + { + allocMemFlag = static_cast(allocMemFlag | CORJIT_ALLOCMEM_FLG_RODATA_32BYTE_ALIGN); + } #ifdef TARGET_ARM64 // For arm64, we want to allocate JIT data always adjacent to code similar to what native compiler does. @@ -4637,7 +4645,7 @@ unsigned emitter::emitEndCodeGen(Compiler* comp, } UNATIVE_OFFSET roDataAlignmentDelta = 0; - if (emitConsDsc.dsdOffs) + if (emitConsDsc.dsdOffs && (emitConsDsc.alignment == TARGET_POINTER_SIZE)) { UNATIVE_OFFSET roDataAlignment = TARGET_POINTER_SIZE; // 8 Byte align by default. roDataAlignmentDelta = (UNATIVE_OFFSET)ALIGN_UP(emitTotalHotCodeSize, roDataAlignment) - emitTotalHotCodeSize; @@ -5320,50 +5328,54 @@ UNATIVE_OFFSET emitter::emitFindOffset(insGroup* ig, unsigned insNum) * block. */ -UNATIVE_OFFSET emitter::emitDataGenBeg(UNATIVE_OFFSET size, bool align) +UNATIVE_OFFSET emitter::emitDataGenBeg(UNATIVE_OFFSET size, UNATIVE_OFFSET alignment) { unsigned secOffs; dataSection* secDesc; assert(emitDataSecCur == nullptr); - /* The size better not be some kind of an odd thing */ + // The size must not be zero and must be a multiple of 4 bytes + // Additionally, 4 bytes is the minimum alignment that will + // actually be used. That is, if the user requests an alignment + // of 1 or 2, they will get something that is at least 4-byte + // aligned. We allow the others since 4 is at least 1/2 and its + // simpler to allow it than to check and block. + assert((size != 0) && ((size % 4) == 0)); - assert(size && size % sizeof(int) == 0); + // This restricts the alignment to: 1, 2, 4, 8, 16, or 32 bytes + // Alignments greater than 32 would require VM support in ICorJitInfo::allocMem - /* Get hold of the current offset */ + const size_t MaxAlignment = 32; + assert(isPow2(alignment) && (alignment <= MaxAlignment)); + /* Get hold of the current offset */ secOffs = emitConsDsc.dsdOffs; - if (align) + if (alignment > 4) { - // Data can have any size but since alignment is deduced from the size there's no - // way to have a larger data size (e.g. 128) and request 4/8/16 byte alignment. - // As such, we restrict data above 16 bytes to be a multiple of 16 and assume 16-byte - // alignment. Alignment greater than 16 requires VM support (see ICorJitInfo::allocMem). - assert((size <= 16) || ((size % 16) == 0)); + // As per the above comment, the minimum alignment is actually 4 + // bytes so we don't need to make any adjustments if the requested + // alignment is 1, 2, or 4. + // + // The maximum requested alignment is tracked and the memory allocator + // will end up ensuring offset 0 is at an address matching that + // alignment. So if the requested alignment is greater than 4, we need + // to pad the space out so the offset is a multiple of the requested. - if (size >= 16) - { - emitConsDsc.align16 = true; - } + uint8_t zero[MaxAlignment] = {}; - while ((secOffs % size) != 0) - { - /* Need to skip 4 bytes to honor alignment */ - /* Must allocate a dummy 4 byte integer */ - int zero = 0; - emitDataGenBeg(4, false); - emitDataGenData(0, &zero, 4); - emitDataGenEnd(); + UNATIVE_OFFSET zeroSize = alignment - (secOffs % alignment); + UNATIVE_OFFSET zeroAlign = 4; - /* Get the new secOffs */ - secOffs = emitConsDsc.dsdOffs; - } + emitAnyConst(&zero, zeroSize, zeroAlign); + secOffs = emitConsDsc.dsdOffs; } - /* Advance the current offset */ + assert((secOffs % alignment) == 0); + emitConsDsc.alignment = max(emitConsDsc.alignment, alignment); + /* Advance the current offset */ emitConsDsc.dsdOffs += size; /* Allocate a data section descriptor and add it to the list */ @@ -5451,7 +5463,7 @@ UNATIVE_OFFSET emitter::emitBBTableDataGenBeg(unsigned numEntries, bool relative * Emit the given block of bits into the current data section. */ -void emitter::emitDataGenData(unsigned offs, const void* data, size_t size) +void emitter::emitDataGenData(unsigned offs, const void* data, UNATIVE_OFFSET size) { assert(emitDataSecCur && (emitDataSecCur->dsSize >= offs + size)); @@ -5498,19 +5510,13 @@ void emitter::emitDataGenEnd() * Parameters: * cnsAddr - memory location containing constant value * cnsSize - size of constant in bytes - * dblAlign - whether to double align the data section constant + * cnsAlign - alignment of constant in bytes * * Returns constant number as offset into data section. */ -UNATIVE_OFFSET emitter::emitDataConst(const void* cnsAddr, unsigned cnsSize, bool dblAlign) +UNATIVE_OFFSET emitter::emitDataConst(const void* cnsAddr, UNATIVE_OFFSET cnsSize, UNATIVE_OFFSET cnsAlign) { - // When generating SMALL_CODE, we don't bother with dblAlign - if (dblAlign && (emitComp->compCodeOpt() == Compiler::SMALL_CODE)) - { - dblAlign = false; - } - - UNATIVE_OFFSET cnum = emitDataGenBeg(cnsSize, dblAlign); + UNATIVE_OFFSET cnum = emitDataGenBeg(cnsSize, cnsAlign); emitDataGenData(0, cnsAddr, cnsSize); emitDataGenEnd(); @@ -5522,33 +5528,18 @@ UNATIVE_OFFSET emitter::emitDataConst(const void* cnsAddr, unsigned cnsSize, boo // // Arguments: // cnsAddr - pointer to the data to be placed in the data section -// cnsSize - size of the data -// alignment - indicates how to align the constant +// cnsSize - size of the data in bytes +// cnsAlign - alignment of the data in bytes // // Return Value: // A field handle representing the data offset to access the constant. // -CORINFO_FIELD_HANDLE emitter::emitAnyConst(const void* cnsAddr, unsigned cnsSize, emitDataAlignment alignment) +CORINFO_FIELD_HANDLE emitter::emitAnyConst(const void* cnsAddr, UNATIVE_OFFSET cnsSize, UNATIVE_OFFSET cnsAlign) { - bool align; - - switch (alignment) - { - case emitDataAlignment::None: - align = false; - break; - case emitDataAlignment::Preferred: - align = (emitComp->compCodeOpt() != Compiler::SMALL_CODE); - break; - case emitDataAlignment::Required: - default: - align = true; - break; - } - - UNATIVE_OFFSET cnum = emitDataGenBeg(cnsSize, align); + UNATIVE_OFFSET cnum = emitDataGenBeg(cnsSize, cnsAlign); emitDataGenData(0, cnsAddr, cnsSize); emitDataGenEnd(); + return emitComp->eeFindJitDataOffs(cnum); } @@ -5572,26 +5563,35 @@ CORINFO_FIELD_HANDLE emitter::emitFltOrDblConst(double constValue, emitAttr attr void* cnsAddr; float f; - bool dblAlign; if (attr == EA_4BYTE) { - f = forceCastToFloat(constValue); - cnsAddr = &f; - dblAlign = false; + f = forceCastToFloat(constValue); + cnsAddr = &f; } else { - cnsAddr = &constValue; - dblAlign = true; + cnsAddr = &constValue; } // Access to inline data is 'abstracted' by a special type of static member // (produced by eeFindJitDataOffs) which the emitter recognizes as being a reference // to constant data, not a real static field. - UNATIVE_OFFSET cnsSize = (attr == EA_4BYTE) ? 4 : 8; - UNATIVE_OFFSET cnum = emitDataConst(cnsAddr, cnsSize, dblAlign); + UNATIVE_OFFSET cnsSize = (attr == EA_4BYTE) ? 4 : 8; + UNATIVE_OFFSET cnsAlign = cnsSize; + +#ifdef TARGET_XARCH + if (emitComp->compCodeOpt() == Compiler::SMALL_CODE) + { + // Some platforms don't require doubles to be aligned and so + // we can use a smaller alignment to help with smaller code + + cnsAlign = 1; + } +#endif // TARGET_XARCH + + UNATIVE_OFFSET cnum = emitDataConst(cnsAddr, cnsSize, cnsAlign); return emitComp->eeFindJitDataOffs(cnum); } diff --git a/src/coreclr/src/jit/emit.h b/src/coreclr/src/jit/emit.h index 6574fef7af862..cd1616b37eb8c 100644 --- a/src/coreclr/src/jit/emit.h +++ b/src/coreclr/src/jit/emit.h @@ -200,13 +200,6 @@ class emitLocation unsigned codePos; // the code position within the IG (see emitCurOffset()) }; -enum class emitDataAlignment -{ - None, - Preferred, - Required -}; - /************************************************************************/ /* The following describes an instruction group */ /************************************************************************/ @@ -1685,7 +1678,7 @@ class emitter void emitSetMediumJump(instrDescJmp* id); public: - CORINFO_FIELD_HANDLE emitAnyConst(const void* cnsAddr, unsigned cnsSize, emitDataAlignment alignment); + CORINFO_FIELD_HANDLE emitAnyConst(const void* cnsAddr, UNATIVE_OFFSET cnsSize, UNATIVE_OFFSET cnsAlign); private: CORINFO_FIELD_HANDLE emitFltOrDblConst(double constValue, emitAttr attr); @@ -2180,9 +2173,9 @@ class emitter dataSection* dsdList; dataSection* dsdLast; UNATIVE_OFFSET dsdOffs; - bool align16; + UNATIVE_OFFSET alignment; // in bytes, defaults to 4 - dataSecDsc() : dsdList(nullptr), dsdLast(nullptr), dsdOffs(0), align16(false) + dataSecDsc() : dsdList(nullptr), dsdLast(nullptr), dsdOffs(0), alignment(4) { } }; diff --git a/src/coreclr/src/jit/emitpub.h b/src/coreclr/src/jit/emitpub.h index cd28e0355c03b..e1f5e80b5295b 100644 --- a/src/coreclr/src/jit/emitpub.h +++ b/src/coreclr/src/jit/emitpub.h @@ -83,17 +83,17 @@ void emitIns_J(instruction ins, BasicBlock* dst, int instrCount = 0); /* Emit initialized data sections */ /************************************************************************/ -UNATIVE_OFFSET emitDataGenBeg(UNATIVE_OFFSET size, bool align); +UNATIVE_OFFSET emitDataGenBeg(UNATIVE_OFFSET size, UNATIVE_OFFSET alignment); UNATIVE_OFFSET emitBBTableDataGenBeg(unsigned numEntries, bool relativeAddr); -void emitDataGenData(unsigned offs, const void* data, size_t size); +void emitDataGenData(unsigned offs, const void* data, UNATIVE_OFFSET size); void emitDataGenData(unsigned offs, BasicBlock* label); void emitDataGenEnd(); -UNATIVE_OFFSET emitDataConst(const void* cnsAddr, unsigned cnsSize, bool dblAlign); +UNATIVE_OFFSET emitDataConst(const void* cnsAddr, UNATIVE_OFFSET cnsSize, UNATIVE_OFFSET cnsAlign); UNATIVE_OFFSET emitDataSize(); diff --git a/src/coreclr/src/jit/emitxarch.cpp b/src/coreclr/src/jit/emitxarch.cpp index af753945e3d2f..0167887f0c919 100644 --- a/src/coreclr/src/jit/emitxarch.cpp +++ b/src/coreclr/src/jit/emitxarch.cpp @@ -10765,8 +10765,12 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) } // Check that the offset is properly aligned (i.e. the ddd in [ddd]) + // When SMALL_CODE is set, we only expect 4-byte alignment, otherwise + // we expect the same alignment as the size of the constant. + assert((emitChkAlign == false) || (ins == INS_lea) || - ((byteSize < 16) && (((size_t)addr & (byteSize - 1)) == 0)) || (((size_t)addr & (16 - 1)) == 0)); + ((emitComp->compCodeOpt() == Compiler::SMALL_CODE) && (((size_t)addr & 3) == 0)) || + (((size_t)addr & (byteSize - 1)) == 0)); } else { diff --git a/src/coreclr/src/jit/lowerarmarch.cpp b/src/coreclr/src/jit/lowerarmarch.cpp index fdebf70ecb9f1..827645576ec35 100644 --- a/src/coreclr/src/jit/lowerarmarch.cpp +++ b/src/coreclr/src/jit/lowerarmarch.cpp @@ -883,7 +883,12 @@ void Lowering::LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node) } } - CORINFO_FIELD_HANDLE hnd = comp->GetEmitter()->emitAnyConst(&vecCns, simdSize, emitDataAlignment::Required); + assert((simdSize == 8) || (simdSize == 16)); + + UNATIVE_OFFSET cnsSize = simdSize; + UNATIVE_OFFSET cnsAlign = cnsSize; + + CORINFO_FIELD_HANDLE hnd = comp->GetEmitter()->emitAnyConst(&vecCns, cnsSize, cnsAlign); GenTree* clsVarAddr = new (comp, GT_CLS_VAR_ADDR) GenTreeClsVar(GT_CLS_VAR_ADDR, TYP_I_IMPL, hnd, nullptr); BlockRange().InsertBefore(node, clsVarAddr); diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index b2c77ffb15569..52a4de5a1c2e4 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -712,8 +712,12 @@ void Lowering::LowerSIMD(GenTreeSIMD* simdNode) BlockRange().Remove(list->Current()); } - CORINFO_FIELD_HANDLE hnd = - comp->GetEmitter()->emitAnyConst(constArgValues, sizeof(constArgValues), emitDataAlignment::Required); + assert(sizeof(constArgValues) == 16); + + UNATIVE_OFFSET cnsSize = sizeof(constArgValues); + UNATIVE_OFFSET cnsAlign = (comp->compCodeOpt() != Compiler::SMALL_CODE) ? cnsSize : 1; + + CORINFO_FIELD_HANDLE hnd = comp->GetEmitter()->emitAnyConst(constArgValues, cnsSize, cnsAlign); GenTree* clsVarAddr = new (comp, GT_CLS_VAR_ADDR) GenTreeClsVar(GT_CLS_VAR_ADDR, TYP_I_IMPL, hnd, nullptr); BlockRange().InsertBefore(simdNode, clsVarAddr); simdNode->ChangeOper(GT_IND); @@ -1464,7 +1468,12 @@ void Lowering::LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node) } } - CORINFO_FIELD_HANDLE hnd = comp->GetEmitter()->emitAnyConst(&vecCns, simdSize, emitDataAlignment::Required); + assert((simdSize == 16) || (simdSize == 32)); + + UNATIVE_OFFSET cnsSize = simdSize; + UNATIVE_OFFSET cnsAlign = (comp->compCodeOpt() != Compiler::SMALL_CODE) ? cnsSize : 1; + + CORINFO_FIELD_HANDLE hnd = comp->GetEmitter()->emitAnyConst(&vecCns, cnsSize, cnsAlign); GenTree* clsVarAddr = new (comp, GT_CLS_VAR_ADDR) GenTreeClsVar(GT_CLS_VAR_ADDR, TYP_I_IMPL, hnd, nullptr); BlockRange().InsertBefore(node, clsVarAddr); From cb59fba4ede6ff0f3cf270a25e27031d7e4a9e70 Mon Sep 17 00:00:00 2001 From: Anton Lapounov Date: Sun, 24 May 2020 20:03:40 -0700 Subject: [PATCH 371/420] Fix output for user strings in R2RDump (#36935) Quote user strings and escape control characters, unpaired surrogates, and other unsafe characters. --- .../ReadyToRunSignature.cs | 3 +- .../StringExtensions.cs | 112 ++++++++++++++++++ src/coreclr/src/tools/r2rdump/R2RDump.cs | 6 +- src/coreclr/src/tools/r2rdump/TextDumper.cs | 12 +- 4 files changed, 123 insertions(+), 10 deletions(-) create mode 100644 src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/StringExtensions.cs diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs index fbbaf233118e6..3804ef60d4326 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs @@ -1723,12 +1723,11 @@ private void ParseHelper(StringBuilder builder) /// /// Read a string token from the signature stream and convert it to the actual string. /// - /// private void ParseStringHandle(StringBuilder builder) { uint rid = ReadUIntAndEmitInlineSignatureBinary(builder); UserStringHandle stringHandle = MetadataTokens.UserStringHandle((int)rid); - builder.Append(_metadataReader.GetUserString(stringHandle)); + builder.AppendEscapedString(_metadataReader.GetUserString(stringHandle)); } } } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/StringExtensions.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/StringExtensions.cs new file mode 100644 index 0000000000000..9cf7ca6655e7d --- /dev/null +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/StringExtensions.cs @@ -0,0 +1,112 @@ +// 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. + +using System.Globalization; +using System.Text; + +namespace ILCompiler.Reflection.ReadyToRun +{ + public static class StringBuilderExtensions + { + /// + /// Appends a C# string literal with the given value to the string builder. + /// + /// + /// This method closely follows the logic in + /// method in Roslyn .NET compiler; see its + /// sources for reference. + /// + public static StringBuilder AppendEscapedString(this StringBuilder builder, string value) + { + builder.Append('"'); + + for (int i = 0; i < value.Length; i++) + { + char c = value[i]; + UnicodeCategory category; + + // Fast check for printable ASCII characters + if ((c <= 0x7e) && (c >= 0x20) || !NeedsEscaping(category = CharUnicodeInfo.GetUnicodeCategory(c))) + { + if ((c == '"') || (c == '\\')) + { + builder.Append(@"\"); + } + builder.Append(c); + } + else if (category == UnicodeCategory.Surrogate) + { + // Check for a valid surrogate pair + category = CharUnicodeInfo.GetUnicodeCategory(value, i); + if (category == UnicodeCategory.Surrogate) + { + // Escape an unpaired surrogate + builder.Append(@"\u" + ((int)c).ToString("x4")); + } + else if (NeedsEscaping(category)) + { + // A surrogate pair that needs to be escaped + int codePoint = char.ConvertToUtf32(value, i); + builder.Append(@"\U" + codePoint.ToString("x8")); + i++; // Skip the already-encoded second surrogate of the pair + } + else + { + // Copy a printable surrogate pair + builder.Append(c); + builder.Append(value[++i]); + } + } + else + { + string escaped = c switch + { + '\0' => @"\0", + '\a' => @"\a", + '\b' => @"\b", + '\f' => @"\f", + '\n' => @"\n", + '\r' => @"\r", + '\t' => @"\t", + '\v' => @"\v", + _ => @"\u" + ((int)c).ToString("x4") + }; + builder.Append(escaped); + } + } + + builder.Append('"'); + return builder; + } + + /// + /// Determines whether characters of the given will be represented with escape sequences. + /// + private static bool NeedsEscaping(UnicodeCategory category) + { + switch (category) + { + case UnicodeCategory.LineSeparator: + case UnicodeCategory.ParagraphSeparator: + case UnicodeCategory.Control: + case UnicodeCategory.Surrogate: + case UnicodeCategory.OtherNotAssigned: + return true; + default: + return false; + } + } + } + + public static class StringExtensions + { + /// + /// Returns a C# string literal with the given value. + /// + public static string ToEscapedString(this string value) + { + return new StringBuilder(value.Length + 16).AppendEscapedString(value).ToString(); + } + } +} diff --git a/src/coreclr/src/tools/r2rdump/R2RDump.cs b/src/coreclr/src/tools/r2rdump/R2RDump.cs index e718bc955ccd4..88a4e0d5bd5c2 100644 --- a/src/coreclr/src/tools/r2rdump/R2RDump.cs +++ b/src/coreclr/src/tools/r2rdump/R2RDump.cs @@ -203,12 +203,14 @@ class R2RDump { private readonly DumpOptions _options; private readonly Dictionary _selectedSections = new Dictionary(); + private readonly Encoding _encoding; private readonly TextWriter _writer; private Dumper _dumper; private R2RDump(DumpOptions options) { _options = options; + _encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: false); if (_options.Verbose) { @@ -220,7 +222,7 @@ private R2RDump(DumpOptions options) if (_options.Out != null) { - _writer = new StreamWriter(_options.Out.FullName, append: false, encoding: new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: false)); + _writer = new StreamWriter(_options.Out.FullName, append: false, _encoding); } else { @@ -569,7 +571,7 @@ private int Run() else { string perFileOutput = filename.FullName + ".common-methods.r2r"; - _dumper = new TextDumper(r2r, new StreamWriter(perFileOutput), disassembler, _options); + _dumper = new TextDumper(r2r, new StreamWriter(perFileOutput, append: false, _encoding), disassembler, _options); if (previousDumper != null) { new R2RDiff(previousDumper, _dumper, _writer).Run(); diff --git a/src/coreclr/src/tools/r2rdump/TextDumper.cs b/src/coreclr/src/tools/r2rdump/TextDumper.cs index 9b67bad70af76..8491639798ec4 100644 --- a/src/coreclr/src/tools/r2rdump/TextDumper.cs +++ b/src/coreclr/src/tools/r2rdump/TextDumper.cs @@ -450,12 +450,12 @@ internal override void DumpSectionContents(ReadyToRunSection section) break; case ReadyToRunSectionType.OwnerCompositeExecutable: int oceOffset = _r2r.GetOffset(section.RelativeVirtualAddress); - Decoder decoder = Encoding.UTF8.GetDecoder(); - int charLength = decoder.GetCharCount(_r2r.Image, oceOffset, section.Size - 1); // exclude the zero terminator - char[] charArray = new char[charLength]; - decoder.GetChars(_r2r.Image, oceOffset, section.Size, charArray, 0, flush: true); - string ownerCompositeExecutable = new string(charArray); - _writer.WriteLine("Composite executable: {0}", ownerCompositeExecutable); + if (_r2r.Image[oceOffset + section.Size - 1] != 0) + { + R2RDump.WriteWarning("String is not zero-terminated"); + } + string ownerCompositeExecutable = Encoding.UTF8.GetString(_r2r.Image, oceOffset, section.Size - 1); // exclude the zero terminator + _writer.WriteLine("Composite executable: {0}", ownerCompositeExecutable.ToEscapedString()); break; } } From bd6cbe3642f51d70839912a6a666e5de747ad581 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 25 May 2020 08:07:50 +0000 Subject: [PATCH 372/420] [master] Update dependencies from mono/linker Microsoft/vstest dotnet/xharness (#36811) * Update dependencies from https://github.com/mono/linker build 20200520.1 Microsoft.NET.ILLink.Tasks From Version 5.0.0-preview.3.20269.1 -> To Version 5.0.0-preview.3.20270.1 * Update dependencies from https://github.com/microsoft/vstest build 20200521-01 Microsoft.NET.Test.Sdk From Version 16.7.0-preview-20200518-01 -> To Version 16.7.0-preview-20200521-01 * Update dependencies from https://github.com/dotnet/xharness build 20200520.2 Microsoft.DotNet.XHarness.Tests.Runners From Version 1.0.0-prerelease.20270.1 -> To Version 1.0.0-prerelease.20270.2 * Update dependencies from https://github.com/mono/linker build 20200521.1 Microsoft.NET.ILLink.Tasks From Version 5.0.0-preview.3.20269.1 -> To Version 5.0.0-preview.3.20271.1 * Update dependencies from https://github.com/dotnet/xharness build 20200521.3 Microsoft.DotNet.XHarness.Tests.Runners From Version 1.0.0-prerelease.20270.1 -> To Version 1.0.0-prerelease.20271.3 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 16d072aca3d99..3b210173b81f0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -82,9 +82,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization d0bb63d2ec7060714e63ee4082fac48f2e57f3e2 - + https://github.com/microsoft/vstest - 3f18c870db1776dab9c94e7b819c0dad90ff9686 + 8ee627ea54aba31b941e5d45a1a1614b50f7befb https://github.com/dotnet/runtime-assets @@ -170,13 +170,13 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - 3409a1a819e380c0ffeedfaaccc74f064b67b2ff + 5780105febb3018552f797fee40f7d60edcd594b - + https://github.com/dotnet/xharness - 875d086091bb053dbbefd8d55718245e6820ddc8 + 53d1b33f3562a166752b9ab24c8c69ef22b91bdd diff --git a/eng/Versions.props b/eng/Versions.props index d6acbf9f473e3..a0944014b84b1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -105,8 +105,8 @@ 4.8.0 - 16.7.0-preview-20200518-01 - 1.0.0-prerelease.20270.1 + 16.7.0-preview-20200521-01 + 1.0.0-prerelease.20271.3 2.4.1 1.2.1 2.0.5 @@ -115,7 +115,7 @@ 3.1.0-preview-20200129.1 - 5.0.0-preview.3.20269.1 + 5.0.0-preview.3.20271.1 9.0.1-alpha.1.20268.2 9.0.1-alpha.1.20268.2 From d0e22812943f358b438f1e379ccf99027d34789e Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Mon, 25 May 2020 07:18:01 -0400 Subject: [PATCH 373/420] Remove volatile on field in ConcurrentDictionary.Tables (#36976) --- .../src/System/Collections/Concurrent/ConcurrentDictionary.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs index e8a10a5d788eb..7667e21505e7c 100644 --- a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs +++ b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs @@ -44,7 +44,7 @@ private sealed class Tables { internal readonly Node[] _buckets; // A singly-linked list for each bucket. internal readonly object[] _locks; // A set of locks, each guarding a section of the table. - internal volatile int[] _countPerLock; // The number of elements guarded by each lock. + internal readonly int[] _countPerLock; // The number of elements guarded by each lock. internal Tables(Node[] buckets, object[] locks, int[] countPerLock) { From 6c4533b612a629e0b1cd0a5619aaaeabfe7fd228 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Mon, 25 May 2020 11:08:54 -0400 Subject: [PATCH 374/420] configure.ac: check for sockaddr_in6 on Win32 (#36742) HAVE_STRUCT_SOCKADDR_IN6 needs to be defined to enable IPv6 features in mono/metadata/w32socket.c. Fixes TcpListener issues in wine-mono. Co-authored-by: w-flo --- src/mono/configure.ac | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mono/configure.ac b/src/mono/configure.ac index 94c228bd8049f..98f8e86b254ff 100644 --- a/src/mono/configure.ac +++ b/src/mono/configure.ac @@ -3921,6 +3921,8 @@ else AC_CHECK_LIB(advapi32, main, LIBS="$LIBS -ladvapi32", AC_ERROR(bad mingw install?)) AC_CHECK_LIB(version, main, LIBS="$LIBS -lversion", AC_ERROR(bad mingw install?)) + AC_CHECK_TYPES([struct sockaddr_in6], [AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6)], , [#include ]) + dnl ********************************* dnl *** Check for struct ip_mreqn *** dnl ********************************* From 579c7e32c74fe94c00668305b675832cbae27ba8 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 25 May 2020 17:30:29 +0000 Subject: [PATCH 375/420] Update dependencies from https://github.com/dotnet/xharness build 20200525.1 (#36982) Microsoft.DotNet.XHarness.Tests.Runners From Version 1.0.0-prerelease.20271.3 -> To Version 1.0.0-prerelease.20275.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3b210173b81f0..0901fe72ef2f4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -174,9 +174,9 @@ https://github.com/mono/linker 5780105febb3018552f797fee40f7d60edcd594b - + https://github.com/dotnet/xharness - 53d1b33f3562a166752b9ab24c8c69ef22b91bdd + 1a11b8022ecc81242dafc48dbbc3e94f924c8ba2 diff --git a/eng/Versions.props b/eng/Versions.props index a0944014b84b1..ef6bf8f04a664 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -106,7 +106,7 @@ 4.8.0 16.7.0-preview-20200521-01 - 1.0.0-prerelease.20271.3 + 1.0.0-prerelease.20275.1 2.4.1 1.2.1 2.0.5 From e5d063b9604f58d3354818996ae82bd56d70d555 Mon Sep 17 00:00:00 2001 From: SRV Date: Mon, 25 May 2020 20:59:59 +0300 Subject: [PATCH 376/420] Timeout support for unprivileged Ping on Linux/BSD (#35461) * Added support of timeout when unprivileged ping is used * Fixed test according with new timeout parameter * Fixes code style issues * Fixed command-line flag for ping6 on BSD * Separated timeout test * Removed trailing whitespace * Workaround for OSX ping6 * Removed static local method * Suppress Ping stdout * Fixed variable name * Added test for zero timeout * Handle zero timeout correctly --- .../NetworkInformation/UnixCommandLinePing.cs | 60 ++++++++++++-- .../Net/NetworkInformation/Ping.Unix.cs | 8 +- .../FunctionalTests/UnixPingUtilityTests.cs | 83 ++++++++++++++----- 3 files changed, 117 insertions(+), 34 deletions(-) diff --git a/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs b/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs index 157986f7bf649..a4d3143a83cfa 100644 --- a/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs +++ b/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs @@ -19,7 +19,8 @@ internal static class UnixCommandLinePing private static readonly string? s_discoveredPing4UtilityPath = GetPingUtilityPath(ipv4: true); private static readonly string? s_discoveredPing6UtilityPath = GetPingUtilityPath(ipv4: false); - private static readonly bool s_isBSD = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")); + private static readonly bool s_isOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + private static readonly bool s_isBSD = RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD); private static readonly Lazy s_isBusybox = new Lazy(() => IsBusyboxPing(s_discoveredPing4UtilityPath)); // We don't want to pick up an arbitrary or malicious ping @@ -72,14 +73,59 @@ public enum PingFragmentOptions { Default, Do, Dont }; /// Constructs command line arguments appropriate for the ping or ping6 utility. /// /// The packet size to use in the ping. Exact packet payload cannot be specified. + /// The timeout to use in the ping, in milliseconds. /// A string representation of the IP address to ping. /// The constructed command line arguments, which can be passed to ping or ping6. - public static string ConstructCommandLine(int packetSize, string address, bool ipv4, int ttl = 0, PingFragmentOptions fragmentOption = PingFragmentOptions.Default) + public static string ConstructCommandLine(int packetSize, int timeout, string address, bool ipv4, int ttl = 0, PingFragmentOptions fragmentOption = PingFragmentOptions.Default) { - - StringBuilder sb = new StringBuilder(); + var sb = new StringBuilder(); sb.Append("-c 1"); // Just send a single ping ("count = 1") + //if timeout is zero then some ping implementations can stuck infinitely if endpoint is unreachable + if (timeout == 0) + timeout = 1; + + // Pass timeout argument to ping utility + // BusyBox, Linux: ping and ping6 requires -W flag which accepts timeout in SECONDS. + // FreeBSD: ping requires -W flag which accepts timeout in MILLISECONDS; + // ping6 requires -x which accepts timeout in MILLISECONDS + // OSX: ping requires -W flag which accepts timeout in MILLISECONDS; ping6 doesn't support timeout + if (s_isBSD) + { + if (ipv4) + { + sb.Append(" -W "); + } + else + { + sb.Append(" -x "); + } + } + else if (s_isOSX) + { + if (ipv4) + { + sb.Append(" -W "); + } + else + { + goto skipped_timeout; + } + } + else + { + sb.Append(" -W "); + const int millisInSecond = 1000; + timeout = Math.DivRem(timeout, millisInSecond, out int remainder); + if (remainder != 0) + { + timeout += 1; + } + } + sb.Append(timeout); + + skipped_timeout: + // The command-line flags for "Do-not-fragment" and "TTL" are not standard. // In fact, they are different even between ping and ping6 on the same machine. @@ -88,7 +134,7 @@ public static string ConstructCommandLine(int packetSize, string address, bool i if (ttl > 0) { - if (s_isBSD) + if (s_isBSD | s_isOSX) { // OSX and FreeBSD use -h to set hop limit for IPv6 and -m ttl for IPv4 if (ipv4) @@ -109,9 +155,9 @@ public static string ConstructCommandLine(int packetSize, string address, bool i sb.Append(ttl); } - if (fragmentOption != PingFragmentOptions.Default ) + if (fragmentOption != PingFragmentOptions.Default) { - if (s_isBSD) + if (s_isBSD | s_isOSX) { // The bit is off by default on OSX & FreeBSD if (fragmentOption == PingFragmentOptions.Dont) { diff --git a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs index 0d7af8cf3703f..9b5c56ed8ba69 100644 --- a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs +++ b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs @@ -278,7 +278,7 @@ private async Task SendIcmpEchoRequestOverRawSocketAsync(IPAddress ad } } - private Process GetPingProcess(IPAddress address, byte[] buffer, PingOptions? options) + private Process GetPingProcess(IPAddress address, byte[] buffer, int timeout, PingOptions? options) { bool isIpv4 = address.AddressFamily == AddressFamily.InterNetwork; string? pingExecutable = isIpv4 ? UnixCommandLinePing.Ping4UtilityPath : UnixCommandLinePing.Ping6UtilityPath; @@ -293,7 +293,7 @@ private Process GetPingProcess(IPAddress address, byte[] buffer, PingOptions? op fragmentOption = options.DontFragment ? UnixCommandLinePing.PingFragmentOptions.Do : UnixCommandLinePing.PingFragmentOptions.Dont; } - string processArgs = UnixCommandLinePing.ConstructCommandLine(buffer.Length, address.ToString(), isIpv4, options?.Ttl ?? 0, fragmentOption); + string processArgs = UnixCommandLinePing.ConstructCommandLine(buffer.Length, timeout, address.ToString(), isIpv4, options?.Ttl ?? 0, fragmentOption); ProcessStartInfo psi = new ProcessStartInfo(pingExecutable, processArgs); psi.RedirectStandardOutput = true; @@ -303,7 +303,7 @@ private Process GetPingProcess(IPAddress address, byte[] buffer, PingOptions? op private PingReply SendWithPingUtility(IPAddress address, byte[] buffer, int timeout, PingOptions? options) { - using (Process p = GetPingProcess(address, buffer, options)) + using (Process p = GetPingProcess(address, buffer, timeout, options)) { p.Start(); if (!p.WaitForExit(timeout) || p.ExitCode == 1 || p.ExitCode == 2) @@ -326,7 +326,7 @@ private PingReply SendWithPingUtility(IPAddress address, byte[] buffer, int time private async Task SendWithPingUtilityAsync(IPAddress address, byte[] buffer, int timeout, PingOptions? options) { - using (Process p = GetPingProcess(address, buffer, options)) + using (Process p = GetPingProcess(address, buffer, timeout, options)) { var processCompletion = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); p.EnableRaisingEvents = true; diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/UnixPingUtilityTests.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/UnixPingUtilityTests.cs index 7711aff9cb87c..899a2eaa17945 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/UnixPingUtilityTests.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/UnixPingUtilityTests.cs @@ -19,6 +19,28 @@ public class UnixPingUtilityTests { private const int IcmpHeaderLengthInBytes = 8; + [Theory] + [InlineData(0)] + [InlineData(100)] + [InlineData(1000)] + [InlineData(1500)] + [PlatformSpecific(TestPlatforms.AnyUnix)] + public static void TimeoutIsRespected(int timeout) + { + Process p = ConstructPingProcess(IPAddress.Parse(TestSettings.UnreachableAddress), 50, timeout); + //suppress Ping output to console/terminal stdout during test execution + p.StartInfo.RedirectStandardError = true; + p.StartInfo.RedirectStandardOutput = true; + + Stopwatch stopWatch = Stopwatch.StartNew(); + + p.Start(); + p.WaitForExit(); + + //ensure that the process takes longer than or equal to 'timeout' + Assert.True(stopWatch.ElapsedMilliseconds >= timeout); + } + [Theory] [InlineData(0)] [InlineData(1)] @@ -27,36 +49,28 @@ public class UnixPingUtilityTests [PlatformSpecific(TestPlatforms.AnyUnix)] // Tests un-priviledged Ping support on Unix public static async Task PacketSizeIsRespected(int payloadSize) { - IPAddress localAddress = await TestSettings.GetLocalIPAddressAsync(); - bool ipv4 = localAddress.AddressFamily == AddressFamily.InterNetwork; - string arguments = UnixCommandLinePing.ConstructCommandLine(payloadSize, localAddress.ToString(), ipv4); - string utilityPath = (localAddress.AddressFamily == AddressFamily.InterNetwork) - ? UnixCommandLinePing.Ping4UtilityPath - : UnixCommandLinePing.Ping6UtilityPath; - - var p = new Process(); - p.StartInfo.FileName = utilityPath; - p.StartInfo.Arguments = arguments; - p.StartInfo.UseShellExecute = false; + var stdOutLines = new List(); + var stdErrLines = new List(); + Process p = ConstructPingProcess(await TestSettings.GetLocalIPAddressAsync(), payloadSize, 1000); p.StartInfo.RedirectStandardOutput = true; - var stdOutLines = new List(); - p.OutputDataReceived += new DataReceivedEventHandler( - delegate (object sendingProcess, DataReceivedEventArgs outputLine) { stdOutLines.Add(outputLine.Data); }); + p.OutputDataReceived += delegate (object sendingProcess, DataReceivedEventArgs outputLine) + { + stdOutLines.Add(outputLine.Data); + }; p.StartInfo.RedirectStandardError = true; - var stdErrLines = new List(); - p.ErrorDataReceived += new DataReceivedEventHandler( - delegate (object sendingProcess, DataReceivedEventArgs errorLine) { stdErrLines.Add(errorLine.Data); }); + p.ErrorDataReceived += delegate (object sendingProcess, DataReceivedEventArgs errorLine) + { + stdErrLines.Add(errorLine.Data); + }; p.Start(); p.BeginOutputReadLine(); p.BeginErrorReadLine(); // There are multiple issues with ping6 in macOS 10.12 (Sierra), see https://github.com/dotnet/runtime/issues/24682. - bool isPing6OnMacSierra = utilityPath.Equals(UnixCommandLinePing.Ping6UtilityPath) && - RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && - !PlatformDetection.IsMacOsHighSierraOrHigher; + bool isPing6OnMacSierra = IsPing6OnMacSierra(p.StartInfo); string pingOutput; if (!p.WaitForExit(TestSettings.PingTimeout)) @@ -68,7 +82,7 @@ public static async Task PacketSizeIsRespected(int payloadSize) pingOutput = string.Join("\n", stdOutLines); string stdErr = string.Join("\n", stdErrLines); throw new Exception( - $"[{utilityPath} {arguments}] process did not exit in {TestSettings.PingTimeout} ms.\nStdOut:[{pingOutput}]\nStdErr:[{stdErr}]"); + $"[{p.StartInfo.FileName} {p.StartInfo.Arguments}] process did not exit in {TestSettings.PingTimeout} ms.\nStdOut:[{pingOutput}]\nStdErr:[{stdErr}]"); } // Ensure standard output and error are flushed @@ -84,7 +98,7 @@ public static async Task PacketSizeIsRespected(int payloadSize) string stdErr = string.Join("\n", stdErrLines); throw new Exception( - $"[{utilityPath} {arguments}] process exit code is {exitCode}.\nStdOut:[{pingOutput}]\nStdErr:[{stdErr}]"); + $"[{p.StartInfo.FileName} {p.StartInfo.Arguments}] process exit code is {exitCode}.\nStdOut:[{pingOutput}]\nStdErr:[{stdErr}]"); } try @@ -106,10 +120,33 @@ public static async Task PacketSizeIsRespected(int payloadSize) { string stdErr = string.Join("\n", stdErrLines); throw new Exception( - $"Parse error for [{utilityPath} {arguments}] process exit code is {exitCode}.\nStdOut:[{pingOutput}]\nStdErr:[{stdErr}]", e); + $"Parse error for [{p.StartInfo.FileName} {p.StartInfo.Arguments}] process exit code is {exitCode}.\nStdOut:[{pingOutput}]\nStdErr:[{stdErr}]", e); } } + private static bool IsPing6OnMacSierra(ProcessStartInfo startInfo) + { + return startInfo.FileName.Equals(UnixCommandLinePing.Ping6UtilityPath) && + RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && + !PlatformDetection.IsMacOsHighSierraOrHigher; + } + + private static Process ConstructPingProcess(IPAddress localAddress, int payloadSize, int timeout) + { + bool ipv4 = localAddress.AddressFamily == AddressFamily.InterNetwork; + string arguments = UnixCommandLinePing.ConstructCommandLine(payloadSize, timeout, localAddress.ToString(), ipv4); + string utilityPath = (localAddress.AddressFamily == AddressFamily.InterNetwork) + ? UnixCommandLinePing.Ping4UtilityPath + : UnixCommandLinePing.Ping6UtilityPath; + + var p = new Process(); + p.StartInfo.FileName = utilityPath; + p.StartInfo.Arguments = arguments; + p.StartInfo.UseShellExecute = false; + + return p; + } + private static int ParseReturnedPacketSize(string pingOutput) { int indexOfBytesFrom = pingOutput.IndexOf("bytes from"); From 064c5f15242b8ffe402cd50633b79bac76cd0134 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 25 May 2020 15:52:11 -0400 Subject: [PATCH 377/420] Fix accumulating the offset in PemReader The preebEndIndex offset was a total value in to the PEM's contents, not a moving offset. This would cause it to advance past the contents of the PEM and potentially miss valid PEM contents. --- .../Security/Cryptography/PemEncoding.cs | 11 +++--- .../tests/PemEncodingFindTests.cs | 35 +++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Security.Cryptography.Encoding/src/System/Security/Cryptography/PemEncoding.cs b/src/libraries/System.Security.Cryptography.Encoding/src/System/Security/Cryptography/PemEncoding.cs index 0315d5ba4b3e0..711b323136b08 100644 --- a/src/libraries/System.Security.Cryptography.Encoding/src/System/Security/Cryptography/PemEncoding.cs +++ b/src/libraries/System.Security.Cryptography.Encoding/src/System/Security/Cryptography/PemEncoding.cs @@ -88,7 +88,7 @@ public static bool TryFind(ReadOnlySpan pemData, out PemFields fields) // must be a white space character. if (preebIndex > 0 && !IsWhiteSpaceCharacter(pemData[preebIndex - 1])) { - areaOffset += labelStartIndex; + areaOffset = labelStartIndex; continue; } @@ -150,16 +150,16 @@ public static bool TryFind(ReadOnlySpan pemData, out PemFields fields) return true; NextAfterLabel: - if (preebEndIndex <= 0) + if (preebEndIndex <= areaOffset) { // We somehow ended up in a situation where we will advance - // 0 or -1 characters, which means we'll probably end up here again, - // advancing 0 or -1 characters, in a loop. To avoid getting stuck, + // backward or not at all, which means we'll probably end up here again, + // advancing backward, in a loop. To avoid getting stuck, // detect this situation and return. fields = default; return false; } - areaOffset += preebEndIndex; + areaOffset = preebEndIndex; } fields = default; @@ -178,6 +178,7 @@ static ReadOnlySpan WritePostEB(ReadOnlySpan label, Span desti private static int IndexOfByOffset(this ReadOnlySpan str, ReadOnlySpan value, int startPosition) { + Debug.Assert(startPosition <= str.Length); int index = str.Slice(startPosition).IndexOf(value); return index == -1 ? -1 : index + startPosition; } diff --git a/src/libraries/System.Security.Cryptography.Encoding/tests/PemEncodingFindTests.cs b/src/libraries/System.Security.Cryptography.Encoding/tests/PemEncodingFindTests.cs index 874b862cd4cf8..fe9e3723672f1 100644 --- a/src/libraries/System.Security.Cryptography.Encoding/tests/PemEncodingFindTests.cs +++ b/src/libraries/System.Security.Cryptography.Encoding/tests/PemEncodingFindTests.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Security.Cryptography; +using System.Text; using Xunit; namespace System.Security.Cryptography.Encoding.Tests @@ -260,12 +261,46 @@ public void Find_Success_FindsPemAfterPemWithInvalidLabel() Assert.Equal("Zm9v", content[fields.Base64Data]); } + [Fact] + public void TryFind_Success_AfterSuccessiveInvalidBase64() + { + StringBuilder builder = new StringBuilder(); + + for (int i = 0; i < 100; i++) + { + builder.Append($"-----BEGIN CERTIFICATE-----\n${i:000}\n-----END CERTIFICATE-----\n"); + } + + builder.Append($"-----BEGIN CERTIFICATE-----\nZm9v\n-----END CERTIFICATE-----"); + + AssertPemFound(builder.ToString(), + expectedLocation: 5900..5958, + expectedBase64: 5928..5932, + expectedLabel: 5911..5922); + } + [Fact] public void Find_Fail_Empty() { AssertNoPemFound(string.Empty); } + [Fact] + public void Find_Fail_InvalidBase64_MultipleInvalid_WithSurroundingText() + { + string content = @" +CN=Intermediate1 +-----BEGIN CERTIFICATE----- +MII +-----END CERTIFICATE----- +CN=Intermediate2 +-----BEGIN CERTIFICATE----- +MII +-----END CERTIFICATE----- +"; + AssertNoPemFound(content); + } + [Fact] public void Find_Fail_PostEbBeforePreEb() { From 45833cb6e43b481cdb1dabe2ce29fca48ee7bf6a Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Tue, 26 May 2020 10:33:44 +0200 Subject: [PATCH 378/420] Update mobile testing runner publishing target to insert before linker runs (#36687) --- eng/testing/tests.mobile.targets | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 58367c609f790..4728c595d981f 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -8,7 +8,7 @@ @@ -50,7 +50,7 @@ @@ -107,12 +107,12 @@ + AfterTargets="ComputeResolvedFilesToPublishList"> <_runnerFilesToPublish Include="$(AndroidTestRunnerDir)*" Condition="'$(TargetOS)' == 'Android'" /> <_runnerFilesToPublish Include="$(AppleTestRunnerDir)*" Condition="'$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'tvOS'" /> - + From 92760b595598373279709353e7f36f9a1d1ab0c6 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Tue, 26 May 2020 10:12:12 +0100 Subject: [PATCH 379/420] Avoid additional casts in SocketAsyncContext (#36997) --- .../Net/Sockets/SocketAsyncContext.Unix.cs | 66 ++++++------------- 1 file changed, 21 insertions(+), 45 deletions(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs index 9934e5c97f656..a35d181f32839 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs @@ -126,17 +126,12 @@ private enum State public readonly SocketAsyncContext AssociatedContext; public AsyncOperation Next = null!; // initialized by helper called from ctor - protected object? CallbackOrEvent; public SocketError ErrorCode; public byte[]? SocketAddress; public int SocketAddressLen; public CancellationTokenRegistration CancellationRegistration; - public ManualResetEventSlim? Event - { - get { return CallbackOrEvent as ManualResetEventSlim; } - set { CallbackOrEvent = value; } - } + public ManualResetEventSlim? Event { get; set; } public AsyncOperation(SocketAsyncContext context) { @@ -147,6 +142,7 @@ public AsyncOperation(SocketAsyncContext context) public void Reset() { _state = (int)State.Waiting; + Event = null; Next = this; #if DEBUG _callbackQueued = 0; @@ -240,10 +236,10 @@ public bool TryCancel() // It's our responsibility to set the error code and queue the completion. DoAbort(); - var @event = CallbackOrEvent as ManualResetEventSlim; - if (@event != null) + ManualResetEventSlim? e = Event; + if (e != null) { - @event.Set(); + e.Set(); } else { @@ -360,13 +356,10 @@ private abstract class SendOperation : WriteOperation protected sealed override void Abort() { } - public Action? Callback - { - set => CallbackOrEvent = value; - } + public Action? Callback { get; set; } public override void InvokeCallback(bool allowPooling) => - ((Action)CallbackOrEvent!)(BytesTransferred, SocketAddress, SocketAddressLen, SocketFlags.None, ErrorCode); + Callback!(BytesTransferred, SocketAddress, SocketAddressLen, SocketFlags.None, ErrorCode); } private sealed class BufferMemorySendOperation : SendOperation @@ -383,7 +376,7 @@ protected override bool DoTryComplete(SocketAsyncContext context) public override void InvokeCallback(bool allowPooling) { - var cb = (Action)CallbackOrEvent!; + var cb = Callback!; int bt = BytesTransferred; byte[]? sa = SocketAddress; int sal = SocketAddressLen; @@ -412,7 +405,7 @@ protected override bool DoTryComplete(SocketAsyncContext context) public override void InvokeCallback(bool allowPooling) { - var cb = (Action)CallbackOrEvent!; + var cb = Callback!; int bt = BytesTransferred; byte[]? sa = SocketAddress; int sal = SocketAddressLen; @@ -450,14 +443,10 @@ private abstract class ReceiveOperation : ReadOperation protected sealed override void Abort() { } - public Action? Callback - { - set => CallbackOrEvent = value; - } + public Action? Callback { get; set; } public override void InvokeCallback(bool allowPooling) => - ((Action)CallbackOrEvent!)( - BytesTransferred, SocketAddress, SocketAddressLen, ReceivedFlags, ErrorCode); + Callback!(BytesTransferred, SocketAddress, SocketAddressLen, ReceivedFlags, ErrorCode); } private sealed class BufferMemoryReceiveOperation : ReceiveOperation @@ -496,7 +485,7 @@ protected override bool DoTryComplete(SocketAsyncContext context) public override void InvokeCallback(bool allowPooling) { - var cb = (Action)CallbackOrEvent!; + var cb = Callback!; int bt = BytesTransferred; byte[]? sa = SocketAddress; int sal = SocketAddressLen; @@ -523,7 +512,7 @@ private sealed class BufferListReceiveOperation : ReceiveOperation public override void InvokeCallback(bool allowPooling) { - var cb = (Action)CallbackOrEvent!; + var cb = Callback!; int bt = BytesTransferred; byte[]? sa = SocketAddress; int sal = SocketAddressLen; @@ -566,17 +555,13 @@ private sealed class ReceiveMessageFromOperation : ReadOperation protected sealed override void Abort() { } - public Action Callback - { - set => CallbackOrEvent = value; - } + public Action? Callback { get; set; } protected override bool DoTryComplete(SocketAsyncContext context) => SocketPal.TryCompleteReceiveMessageFrom(context._socket, Buffer.Span, Buffers, Flags, SocketAddress!, ref SocketAddressLen, IsIPv4, IsIPv6, out BytesTransferred, out ReceivedFlags, out IPPacketInformation, out ErrorCode); public override void InvokeCallback(bool allowPooling) => - ((Action)CallbackOrEvent!)( - BytesTransferred, SocketAddress!, SocketAddressLen, ReceivedFlags, IPPacketInformation, ErrorCode); + Callback!(BytesTransferred, SocketAddress!, SocketAddressLen, ReceivedFlags, IPPacketInformation, ErrorCode); } private sealed class AcceptOperation : ReadOperation @@ -585,10 +570,7 @@ private sealed class AcceptOperation : ReadOperation public AcceptOperation(SocketAsyncContext context) : base(context) { } - public Action? Callback - { - set => CallbackOrEvent = value; - } + public Action? Callback { get; set; } protected override void Abort() => AcceptedFileDescriptor = (IntPtr)(-1); @@ -602,7 +584,7 @@ protected override bool DoTryComplete(SocketAsyncContext context) public override void InvokeCallback(bool allowPooling) { - var cb = (Action)CallbackOrEvent!; + var cb = Callback!; IntPtr fd = AcceptedFileDescriptor; byte[] sa = SocketAddress!; int sal = SocketAddressLen; @@ -621,10 +603,7 @@ private sealed class ConnectOperation : WriteOperation { public ConnectOperation(SocketAsyncContext context) : base(context) { } - public Action Callback - { - set => CallbackOrEvent = value; - } + public Action? Callback { get; set; } protected override void Abort() { } @@ -636,7 +615,7 @@ protected override bool DoTryComplete(SocketAsyncContext context) } public override void InvokeCallback(bool allowPooling) => - ((Action)CallbackOrEvent!)(ErrorCode); + Callback!(ErrorCode); } private sealed class SendFileOperation : WriteOperation @@ -650,13 +629,10 @@ private sealed class SendFileOperation : WriteOperation protected override void Abort() { } - public Action Callback - { - set => CallbackOrEvent = value; - } + public Action? Callback { get; set; } public override void InvokeCallback(bool allowPooling) => - ((Action)CallbackOrEvent!)(BytesTransferred, ErrorCode); + Callback!(BytesTransferred, ErrorCode); protected override bool DoTryComplete(SocketAsyncContext context) => SocketPal.TryCompleteSendFile(context._socket, FileHandle, ref Offset, ref Count, ref BytesTransferred, out ErrorCode); From 2641e23dc0cd8ace9ec84e842bc84309961bfd3a Mon Sep 17 00:00:00 2001 From: Peter Sollich Date: Tue, 26 May 2020 05:21:47 -0700 Subject: [PATCH 380/420] Optimize decommit (#35896) Optimize the way we decommit memory on both SVR and WKS GC. Key ideas for SVR GC: - in decommit_ephemeral_segment_pages, instead of decommitting right there, just remember what we intended to decommit. - in gc_thread function, have the thread with heap_number 0 periodically wake up and do gradual decommits for all heaps by calling the new method decommit_ephemeral_pages_step on them. This way, the decommit is not part of the GC pause and does not contribute to it. - decommit_ephemeral_pages_step will decommit a "reasonable" amount of space per heap and time interval, and return how much it decomitted. A return value of 0 indicates no further progress. - take into account Gen 1 budget size and Gen 1 free list when computing how much memory we are likely to need soon. For WKS GC: - As for SVR GC, take Gen 1 budget size and Gen 1 free list into account. - Decommit gradually, taking into account the elapsed time since the last GC to make sure decommit does not become a major part of the GC pause. As the validation scenario, I used an enhanced version of GCPerfSim that can be made to go through "phases", where the phases are programmed by an input text file. To cause decommits, I varied the amount of survivorship between phases - in one phase, one object out of 30 survived, in the next phase 1 out of 300 survived. 10 GB were allocated on each thread in each phase, and the phases with high and low survivorship were repeated 10 times. Test machine was an i9-7900X, 1 allocating thread was used for WKS GC, and 10 allocating threads for SVR GC. Metrics directly influenced by decommitting memory were selected: - Wall clock time (influenced both by GC pause time and page faults during allocation) - GC pause time (especially in SVR GC, impacted by decommitting during GC pause) - CPU samples spent decommitting - CPU samples spend in KiPagefault triggered by allocator Comparison with the master branch gave these results (numbers are medians of 3 runs): SVR Baseline Optimized ================================ Wallclock time (secs): 127.456 106.581 GC pause time (secs): 50.120 41.293 Samples in decommit: 5,467 1,918 Samples in KiPagefault 77,872 21,449 from allocator WKS Baseline Optimized ================================ Wallclock time (secs): 57.213 54.321 GC pause time (secs): 21.422 22.060 Samples in decommit: 465 48 Samples in KiPagefault 5,505 3,509 from allocator So all metrics are noticeably improved, with the exception of GC pause time for WKS. Given the scatter in the pause time numbers, it seems likely that this slight apparent regression is spurious. --- src/coreclr/src/gc/gc.cpp | 178 +++++++++++++++++++++++++++++------- src/coreclr/src/gc/gcpriv.h | 29 +++++- 2 files changed, 170 insertions(+), 37 deletions(-) diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index c09b2c0182f26..c3e52c7540bee 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -1866,7 +1866,14 @@ const int max_snoop_level = 128; #define MH_TH_CARD_BUNDLE (180*1024*1024) #endif //CARD_BUNDLE -#define GC_EPHEMERAL_DECOMMIT_TIMEOUT 5000 +// min size to decommit to make the OS call worthwhile +#define MIN_DECOMMIT_SIZE (100*OS_PAGE_SIZE) + +// max size to decommit per millisecond +#define DECOMMIT_SIZE_PER_MILLISECOND (160*1024) + +// time in milliseconds between decommit steps +#define DECOMMIT_TIME_STEP_MILLISECONDS (100) inline size_t align_on_page (size_t add) @@ -2112,6 +2119,8 @@ int* gc_heap::g_mark_stack_busy; size_t* gc_heap::g_bpromoted; #endif //BACKGROUND_GC +BOOL gc_heap::gradual_decommit_in_progress_p = FALSE; +size_t gc_heap::max_decommit_step_size = 0; #else //MULTIPLE_HEAPS size_t gc_heap::g_promoted; @@ -2138,8 +2147,6 @@ gc_history_global gc_heap::gc_data_global; size_t gc_heap::gc_last_ephemeral_decommit_time = 0; -size_t gc_heap::gc_gen0_desired_high; - CLRCriticalSection gc_heap::check_commit_cs; size_t gc_heap::current_total_committed = 0; @@ -5397,7 +5404,12 @@ void gc_heap::gc_thread_function () if (heap_number == 0) { - gc_heap::ee_suspend_event.Wait(INFINITE, FALSE); + uint32_t wait_result = gc_heap::ee_suspend_event.Wait(gradual_decommit_in_progress_p ? DECOMMIT_TIME_STEP_MILLISECONDS : INFINITE, FALSE); + if (wait_result == WAIT_TIMEOUT) + { + gradual_decommit_in_progress_p = decommit_step (); + continue; + } BEGIN_TIMING(suspend_ee_during_log); GCToEEInterface::SuspendEE(SUSPEND_FOR_GC); @@ -5479,6 +5491,12 @@ void gc_heap::gc_thread_function () hp->set_gc_done(); } } + + // check if we should do some decommitting + if (gradual_decommit_in_progress_p) + { + gradual_decommit_in_progress_p = decommit_step (); + } } else { @@ -9244,11 +9262,21 @@ void gc_heap::decommit_heap_segment_pages (heap_segment* seg, uint8_t* page_start = align_on_page (heap_segment_allocated(seg)); size_t size = heap_segment_committed (seg) - page_start; extra_space = align_on_page (extra_space); - if (size >= max ((extra_space + 2*OS_PAGE_SIZE), 100*OS_PAGE_SIZE)) + if (size >= max ((extra_space + 2*OS_PAGE_SIZE), MIN_DECOMMIT_SIZE)) { page_start += max(extra_space, 32*OS_PAGE_SIZE); - size -= max (extra_space, 32*OS_PAGE_SIZE); + decommit_heap_segment_pages_worker (seg, page_start); + } +} +size_t gc_heap::decommit_heap_segment_pages_worker (heap_segment* seg, + uint8_t* new_committed) +{ + assert (!use_large_pages_p); + uint8_t* page_start = align_on_page (new_committed); + size_t size = heap_segment_committed (seg) - page_start; + if (size > 0) + { virtual_decommit (page_start, size, heap_number); dprintf (3, ("Decommitting heap segment [%Ix, %Ix[(%d)", (size_t)page_start, @@ -9260,6 +9288,7 @@ void gc_heap::decommit_heap_segment_pages (heap_segment* seg, heap_segment_used (seg) = heap_segment_committed (seg); } } + return size; } //decommit all pages except one or 2 @@ -10028,6 +10057,14 @@ gc_heap::init_semi_shared() } #endif //MARK_LIST +#ifdef MULTIPLE_HEAPS + // gradual decommit: set size to some reasonable value per time interval + max_decommit_step_size = ((DECOMMIT_SIZE_PER_MILLISECOND * DECOMMIT_TIME_STEP_MILLISECONDS) / n_heaps); + + // but do at least MIN_DECOMMIT_SIZE per step to make the OS call worthwhile + max_decommit_step_size = max (max_decommit_step_size, MIN_DECOMMIT_SIZE); +#endif //MULTIPLE_HEAPS + #ifdef FEATURE_BASICFREEZE seg_table = sorted_table::make_sorted_table(); @@ -31729,56 +31766,133 @@ void gc_heap::trim_youngest_desired_low_memory() void gc_heap::decommit_ephemeral_segment_pages() { - if (settings.concurrent) + if (settings.concurrent || use_large_pages_p) { return; } - size_t slack_space = heap_segment_committed (ephemeral_heap_segment) - heap_segment_allocated (ephemeral_heap_segment); + dynamic_data* dd0 = dynamic_data_of (0); - dynamic_data* dd = dynamic_data_of (0); + // this is how much we are going to allocate in gen 0 + ptrdiff_t desired_allocation = dd_desired_allocation (dd0) + loh_size_threshold; -#ifndef MULTIPLE_HEAPS - size_t extra_space = (g_low_memory_status ? 0 : (512 * 1024)); - size_t decommit_timeout = (g_low_memory_status ? 0 : GC_EPHEMERAL_DECOMMIT_TIMEOUT); - size_t ephemeral_elapsed = dd_time_clock(dd) - gc_last_ephemeral_decommit_time; - - if (dd_desired_allocation (dd) > gc_gen0_desired_high) + // estimate how we are going to need in gen 1 - estimate half the free list space gets used + dynamic_data* dd1 = dynamic_data_of (1); + ptrdiff_t desired_allocation_1 = dd_new_allocation (dd1) - (generation_free_list_space (generation_of (1)) / 2); + if (desired_allocation_1 > 0) { - gc_gen0_desired_high = dd_desired_allocation (dd) + extra_space; + desired_allocation += desired_allocation_1; } - if (ephemeral_elapsed >= decommit_timeout) - { - slack_space = min (slack_space, gc_gen0_desired_high); - - gc_last_ephemeral_decommit_time = dd_time_clock(dd); - gc_gen0_desired_high = 0; - } -#endif //!MULTIPLE_HEAPS - - if (settings.condemned_generation >= (max_generation-1)) - { - size_t new_slack_space = + size_t slack_space = #ifdef HOST_64BIT - max(min(min(soh_segment_size/32, dd_max_size(dd)), (generation_size (max_generation) / 10)), dd_desired_allocation(dd)); + max(min(min(soh_segment_size/32, dd_max_size (dd0)), (generation_size (max_generation) / 10)), (size_t)desired_allocation); #else #ifdef FEATURE_CORECLR - dd_desired_allocation (dd); + desired_allocation; #else - dd_max_size (dd); + dd_max_size (dd0); #endif //FEATURE_CORECLR #endif // HOST_64BIT - slack_space = min (slack_space, new_slack_space); + uint8_t *decommit_target = heap_segment_allocated (ephemeral_heap_segment) + slack_space; + if (decommit_target < heap_segment_decommit_target (ephemeral_heap_segment)) + { + // we used to have a higher target - do exponential smoothing by computing + // essentially decommit_target = 1/3*decommit_target + 2/3*previous_decommit_target + // computation below is slightly different to avoid overflow + ptrdiff_t target_decrease = heap_segment_decommit_target (ephemeral_heap_segment) - decommit_target; + decommit_target += target_decrease * 2 / 3; } + heap_segment_decommit_target(ephemeral_heap_segment) = decommit_target; + +#ifdef MULTIPLE_HEAPS + if (decommit_target < heap_segment_committed (ephemeral_heap_segment)) + { + gradual_decommit_in_progress_p = TRUE; + } +#ifdef _DEBUG + // these are only for checking against logic errors + ephemeral_heap_segment->saved_committed = heap_segment_committed (ephemeral_heap_segment); + ephemeral_heap_segment->saved_desired_allocation = dd_desired_allocation (dd0); +#endif // _DEBUG +#endif // MULTIPLE_HEAPS + +#ifndef MULTIPLE_HEAPS + // we want to limit the amount of decommit we do per time to indirectly + // limit the amount of time spent in recommit and page faults + size_t ephemeral_elapsed = dd_time_clock (dd0) - gc_last_ephemeral_decommit_time; + gc_last_ephemeral_decommit_time = dd_time_clock (dd0); + + // this is the amount we were planning to decommit + ptrdiff_t decommit_size = heap_segment_committed (ephemeral_heap_segment) - decommit_target; + + // we do a max of DECOMMIT_SIZE_PER_MILLISECOND per millisecond of elapsed time since the last GC + // we limit the elapsed time to 10 seconds to avoid spending too much time decommitting + ptrdiff_t max_decommit_size = min (ephemeral_elapsed, (10*1000)) * DECOMMIT_SIZE_PER_MILLISECOND; + decommit_size = min (decommit_size, max_decommit_size); + + slack_space = heap_segment_committed (ephemeral_heap_segment) - heap_segment_allocated (ephemeral_heap_segment) - decommit_size; decommit_heap_segment_pages (ephemeral_heap_segment, slack_space); +#endif // !MULTIPLE_HEAPS gc_history_per_heap* current_gc_data_per_heap = get_gc_data_per_heap(); current_gc_data_per_heap->extra_gen0_committed = heap_segment_committed (ephemeral_heap_segment) - heap_segment_allocated (ephemeral_heap_segment); } +#ifdef MULTIPLE_HEAPS +// return true if we actually decommitted anything +bool gc_heap::decommit_step () +{ + // should never get here for large pages because decommit_ephemeral_segment_pages + // will not do anything if use_large_pages_p is true + assert (!use_large_pages_p); + + size_t decommit_size = 0; + for (int i = 0; i < n_heaps; i++) + { + gc_heap* hp = gc_heap::g_heaps[i]; + decommit_size += hp->decommit_ephemeral_segment_pages_step (); + } + return (decommit_size != 0); +} + +// return the decommitted size +size_t gc_heap::decommit_ephemeral_segment_pages_step () +{ + // we rely on desired allocation not being changed outside of GC + assert (ephemeral_heap_segment->saved_desired_allocation == dd_desired_allocation (dynamic_data_of (0))); + + uint8_t* decommit_target = heap_segment_decommit_target (ephemeral_heap_segment); + size_t EXTRA_SPACE = 2 * OS_PAGE_SIZE; + decommit_target += EXTRA_SPACE; + uint8_t* committed = heap_segment_committed (ephemeral_heap_segment); + if (decommit_target < committed) + { + // we rely on other threads not messing with committed if we are about to trim it down + assert (ephemeral_heap_segment->saved_committed == heap_segment_committed (ephemeral_heap_segment)); + + // how much would we need to decommit to get to decommit_target in one step? + size_t full_decommit_size = (committed - decommit_target); + + // don't do more than max_decommit_step_size per step + size_t decommit_size = min (max_decommit_step_size, full_decommit_size); + + // figure out where the new committed should be + uint8_t* new_committed = (committed - decommit_size); + size_t size = decommit_heap_segment_pages_worker (ephemeral_heap_segment, new_committed); + +#ifdef _DEBUG + ephemeral_heap_segment->saved_committed = committed - size; +#endif // _DEBUG + + return size; + } + return 0; +} +#endif //MULTIPLE_HEAPS + //This is meant to be called by decide_on_compacting. size_t gc_heap::generation_fragmentation (generation* gen, diff --git a/src/coreclr/src/gc/gcpriv.h b/src/coreclr/src/gc/gcpriv.h index e3a6c1f5b60ab..e9ac7a7bfd15f 100644 --- a/src/coreclr/src/gc/gcpriv.h +++ b/src/coreclr/src/gc/gcpriv.h @@ -1651,6 +1651,12 @@ class gc_heap PER_HEAP void decommit_heap_segment_pages (heap_segment* seg, size_t extra_space); PER_HEAP + size_t decommit_ephemeral_segment_pages_step (); + PER_HEAP + size_t decommit_heap_segment_pages_worker (heap_segment* seg, uint8_t *new_committed); + PER_HEAP_ISOLATED + bool decommit_step (); + PER_HEAP void decommit_heap_segment (heap_segment* seg); PER_HEAP_ISOLATED bool virtual_alloc_commit_for_heap (void* addr, size_t size, int h_number); @@ -2446,8 +2452,6 @@ class gc_heap void check_loh_compact_mode (BOOL all_heaps_compacted_p); #endif //FEATURE_LOH_COMPACTION - PER_HEAP - void decommit_ephemeral_segment_pages (int condemned_gen_number); PER_HEAP void fix_generation_bounds (int condemned_gen_number, generation* consing_gen); @@ -3255,9 +3259,6 @@ class gc_heap PER_HEAP_ISOLATED size_t gc_last_ephemeral_decommit_time; - PER_HEAP_ISOLATED - size_t gc_gen0_desired_high; - PER_HEAP size_t gen0_big_free_spaces; @@ -3785,6 +3786,14 @@ class gc_heap PER_HEAP_ISOLATED BOOL proceed_with_gc_p; +#ifdef MULTIPLE_HEAPS + PER_HEAP_ISOLATED + BOOL gradual_decommit_in_progress_p; + + PER_HEAP_ISOLATED + size_t max_decommit_step_size; +#endif //MULTIPLE_HEAPS + #define youngest_generation (generation_of (0)) #define large_object_generation (generation_of (loh_generation)) #define pinned_object_generation (generation_of (poh_generation)) @@ -4698,7 +4707,12 @@ class heap_segment uint8_t* background_allocated; #ifdef MULTIPLE_HEAPS gc_heap* heap; +#ifdef _DEBUG + uint8_t* saved_committed; + size_t saved_desired_allocation; +#endif // _DEBUG #endif //MULTIPLE_HEAPS + uint8_t* decommit_target; uint8_t* plan_allocated; uint8_t* saved_bg_allocated; @@ -4735,6 +4749,11 @@ uint8_t*& heap_segment_committed (heap_segment* inst) return inst->committed; } inline +uint8_t*& heap_segment_decommit_target (heap_segment* inst) +{ + return inst->decommit_target; +} +inline uint8_t*& heap_segment_used (heap_segment* inst) { return inst->used; From 2d88a3d4dc693e75debd477ec827bdf4b8b68316 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Tue, 26 May 2020 09:25:36 -0400 Subject: [PATCH 381/420] [reflection] Check whether a pointer is valid before dereferencing (#36981) `Xamarin.Android` native runtime calls `mono_reflection_type_from_name` and passes `NULL` as the `image` parameter. The parameter is then propagated all the way to `_mono_reflection_get_type_from_info` where, in case the assembly isn't loaded yet, it is used to obtain base directory of the assembly. However, since the `image` parameter is `NULL` in our case, attempt to dereference it causes a segfault: libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4c0 in tid 11029 (ompanyname.app3), pid 11029 (ompanyname.app3) crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstone /system/bin/tombstoned: received crash request for pid 11029 crash_dump64: performing dump of process 11029 (target tid = 11029) DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** DEBUG : Build fingerprint: 'google/sdk_gphone_x86_64/generic_x86_64:10/QSR1.190920.001/5891938:user/release-keys' DEBUG : Revision: '0' DEBUG : ABI: 'x86_64' DEBUG : Timestamp: 2020-05-25 14:45:29+0200 DEBUG : pid: 11029, tid: 11029, name: ompanyname.app3 >>> com.companyname.app3 <<< DEBUG : uid: 10134 DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4c0 DEBUG : Cause: null pointer dereference DEBUG : rax 000000000000002f rbx 0000000000000001 rcx 0000000000000000 rdx 0000000000000030 DEBUG : r8 0000000000000003 r9 000000000013e2e2 r10 0173eed800000000 r11 0000000000000206 DEBUG : r12 0000000000000000 r13 00007478530343c0 r14 00007478075eda33 r15 000074780763efb0 DEBUG : rdi 0000000000000000 rsi 00007478e2cb14d0 DEBUG : rbp 00007ffef3a35680 rsp 00007ffef3a355d0 rip 0000747807a4066a DEBUG : DEBUG : backtrace: DEBUG : mono/mono#00 pc 00000000003ba66a /data/app/com.companyname.app3-aQUF6Ge6_v-WaLb5i8Q7vw==/lib/x86_64/libmonosgen-2.0.so (_mono_reflection_get_type_from_info+474) DEBUG : mono/mono#01 pc 00000000003ba3d1 /data/app/com.companyname.app3-aQUF6Ge6_v-WaLb5i8Q7vw==/lib/x86_64/libmonosgen-2.0.so (mono_reflection_type_from_name_checked+321) DEBUG : mono/mono#02 pc 00000000003ba26d /data/app/com.companyname.app3-aQUF6Ge6_v-WaLb5i8Q7vw==/lib/x86_64/libmonosgen-2.0.so (mono_reflection_type_from_name+125) DEBUG : mono/mono#03 pc 000000000000ddb5 /data/app/com.companyname.app3-aQUF6Ge6_v-WaLb5i8Q7vw==/lib/x86_64/libmonodroid.so (xamarin::android::internal::EmbeddedAssemblies::typemap_java_to_managed(char const*)+389) (BuildId: 9952f1cfe0d910ae631abc73479f88eef34fd71d) DEBUG : mono/mono#04 pc 000000000000def3 /data/app/com.companyname.app3-aQUF6Ge6_v-WaLb5i8Q7vw==/lib/x86_64/libmonodroid.so (xamarin::android::internal::EmbeddedAssemblies::typemap_java_to_managed(_MonoString*)+99) (BuildId: 9952f1cfe0d910ae631abc73479f88eef34fd71d) DEBUG : mono/mono#05 pc 0000000000069532 Even though this happens in `Xamarin.Android`, the error may occur for any embedding application which passes `NULL` for the `image` parameter in situation when the assembly isn't in memory yet. Co-authored-by: grendello --- src/mono/mono/metadata/reflection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/reflection.c b/src/mono/mono/metadata/reflection.c index c6f2d7fd3340a..c28ce829a4990 100644 --- a/src/mono/mono/metadata/reflection.c +++ b/src/mono/mono/metadata/reflection.c @@ -1958,7 +1958,7 @@ _mono_reflection_get_type_from_info (MonoAssemblyLoadContext *alc, MonoTypeNameP MonoAssemblyByNameRequest req; mono_assembly_request_prepare_byname (&req, MONO_ASMCTX_DEFAULT, alc); req.requesting_assembly = NULL; - req.basedir = image->assembly->basedir; + req.basedir = image ? image->assembly->basedir : NULL; assembly = mono_assembly_request_byname (&info->assembly, &req, NULL); if (!assembly) return NULL; From c5b55f06d6d65c4673734198a87a31f7ace789c2 Mon Sep 17 00:00:00 2001 From: Johan Lorensson Date: Tue, 26 May 2020 15:28:53 +0200 Subject: [PATCH 382/420] Initial work of porting native diagnostic eventpipe library to C. (#34600) First bulk of changes related to porting EventPipe C++ library from CoreCLR into a C library that can be shared between Mono as well as CoreCLR runtime. Due to dependencies and current time line it has been decided to initially target Mono runtime (since it doesn't have event pipe functionality at the moment), but library is still designed to integrate into other runtimes, replacing current C++ library implementation, when time permits. Until that happens, we will need to make sure changes done in C++ code base gets ported over to C library. The amount of changes going into the native library should however be small and if major changes needs to be done, we should first make sure to move over to use the shared version of event pipe C-library in CoreCLR and then only do changes into shared version of the library. Port is currently mapping existing C++ code base, no focus on rewrite or change current implementation (unless needed to port code over to C). Library source files are currently placed into mono/eventpipe folder and build as a separate library, linked into runtime, but will be moved when ready to be shared between runtimes. We might also move all code into a loadable library and p/invokes, depending on size, at least for Mono runtime targeting mobile devices. There is also a unit test runner under mono/eventpipe/tests using eglib test runner, running through a set of unit tests covering the eventpipe library implementation. Library is split up over a couple of source files closely mapping corresponding coreclr source files. Most code could be shared between runtimes and artifacts that are runtime specific, like locks/lists/maps/strings/pal layer etc, a shim API is defined in ep-rt.h and ep-rt-types.h that gets implemented by the targeted runtime consuming the event pipe C library, like ep-rt-mono.h and ep-rt-types-mono.h. All function in the shim API is small and should be inlinable. For example, locking the configuration lock is declared like this in ep-rt.h: bool ep_rt_config_aquire (void); and in ep-rt-mono.h it is implemented like this: static inline bool ep_rt_config_aquire (void) { ep_rt_spin_lock_aquire (ep_rt_mono_config_lock_get ()); return true; } and CoreCLR should implement the function using its corresponding locking primitives. NOTE, since we primarily target Mono in initial port there might smaller adjustments needed to the shim API once bringing it over to CoreCLR, but those changes/adjustments can be done when needed. Since library could be shared, it tries to standardize on common C99 data types when available. If there are runtime specific types needed, they are declared in ep-rt-types.h and implemented by each runtime in corresponding file. Most of library is currently following Mono coding guidelines. For shared types naming is done like this, EventPipe[Type], like EventPipeProvider. This naming follow naming of other types in Mono as well as CoreCLR. There is one exception to this rule, types that are runtime specific implementation, naming is following function naming with a _t prefix, like ep_rt_session_provider_list_t, that is a list specific type, implemented by each runtime. This is done to make it easier to see difference of types implemented in the runtime specific shim and types implemented in the shared library API surface. Since library shim implemented by targeted runtime will be called by C code, it can't throw exceptions, the C library should however compile under C++, meaning that CoreCLR's shim should be able to use C++ constructions as long as it don't throw any exceptions. Library function naming follows the following pattern, for "public" functions included in ep-*.h , ep_ + object + action, so for example, ep_config_create_provider, corresponds to EventPipe::Configuration::CreateProvider in C++ library. For "private/internal" functions not, ep_ prefix is dropped, but object + action is still preserved, for example config_create_provider and function is marked as being static when possible. If a function assumes a lock is held when getting called, it is using _lock_held (similar to SAL annotations) postfix to indicate that function doesn't claim lock and if function needs lock to be held by caller, it will assert that condition on enter (similar to PRECONDITION(EventPipe::IsLockOwnedByCurrentThread())). Library uses asserts internally to validate state and conditions. This is a debug/checked build assert that should be excluded in release builds. It is defined in EP_ASSERT and should be redefined by targeted runtime. Private/internal functions asserts incorrect input parameters and state, while "public" functions return back error to caller when detecting incorrect input parameters. Incorrect state can still be assert in all kinds of functions. Getters/Setters are setup for accessing type members. All functions except a type's own alloc/init/fini/free implemented in ep-*.c are not allowed to use direct type member access and should go through available inlinable getter/setter functions. There is also a way to build the library that catches incorrect use of members at compile time (not in ep-*-internals.c since it include alloc/init/fini/free implementations, but in other source files). Types that can be stack allocated offers a init/fini function pairs. Types that should only be heap allocated, alloc/free, and types supporting both stack/heap, implements alloc/init/fini/free. Since C can't prevent incorrect usage patterns, the implementation needs to follow correct life time management patterns. Types allocated using alloc should be freed with corresponding free function. For example, ep_event_alloc should be freed by ep_event_free, the init/fini methods are then called by the alloc/free implementations. For types supporting stack allocation and allocated on stack or aggregated within other types, init must be called before first use and fini before going out of scope. Ownership of allocated objects is only considered complete on successful function calls. If a function fails, caller still owns resource and need to take actions. Library uses UTF8 strings internally, mainly since Mono runtime already uses that and it is more portable. Number of strings in the library is limited, and in cases where stream protocol uses UTF16 strings, a prealloc string is stored on the type, reducing need to do multiple UTF8 -> UTF16 conversions over the lifetime of the type. NOTE, this is first commit setting up most of the direction of the library and (as part of doing that) ported a great deal of eventpipe code and added ~40 native unittests. It is however not complete, or fully working, so there will be several follow up commit building on top of this work in order to get complete library. --- src/mono/cmake/config.h.in | 3 + src/mono/configure.ac | 10 + src/mono/m4/mono-output.m4 | 2 + src/mono/mono.proj | 1 + src/mono/mono/Makefile.am | 17 +- src/mono/mono/eventpipe/Makefile.am | 71 ++ src/mono/mono/eventpipe/ep-block-internals.c | 595 +++++++++ src/mono/mono/eventpipe/ep-block.c | 398 ++++++ src/mono/mono/eventpipe/ep-block.h | 375 ++++++ .../eventpipe/ep-buffer-manager-internals.c | 38 + src/mono/mono/eventpipe/ep-buffer-manager.c | 28 + src/mono/mono/eventpipe/ep-buffer-manager.h | 69 + src/mono/mono/eventpipe/ep-buffer.h | 40 + src/mono/mono/eventpipe/ep-config-internals.c | 68 + src/mono/mono/eventpipe/ep-config.c | 553 ++++++++ src/mono/mono/eventpipe/ep-config.h | 184 +++ .../eventpipe/ep-event-instance-internals.c | 143 +++ src/mono/mono/eventpipe/ep-event-instance.c | 93 ++ src/mono/mono/eventpipe/ep-event-instance.h | 122 ++ src/mono/mono/eventpipe/ep-event-internals.c | 111 ++ .../eventpipe/ep-event-payload-internals.c | 70 ++ src/mono/mono/eventpipe/ep-event-payload.h | 54 + .../eventpipe/ep-event-source-internals.c | 99 ++ src/mono/mono/eventpipe/ep-event-source.c | 52 + src/mono/mono/eventpipe/ep-event-source.h | 51 + src/mono/mono/eventpipe/ep-event.h | 64 + src/mono/mono/eventpipe/ep-file-internals.c | 295 +++++ src/mono/mono/eventpipe/ep-file.c | 331 +++++ src/mono/mono/eventpipe/ep-file.h | 164 +++ src/mono/mono/eventpipe/ep-internals.c | 242 ++++ .../ep-metadata-generator-internals.c | 40 + .../mono/eventpipe/ep-metadata-generator.c | 106 ++ .../mono/eventpipe/ep-metadata-generator.h | 57 + .../mono/eventpipe/ep-provider-internals.c | 86 ++ src/mono/mono/eventpipe/ep-provider.c | 317 +++++ src/mono/mono/eventpipe/ep-provider.h | 123 ++ src/mono/mono/eventpipe/ep-rt-config-mono.h | 7 + src/mono/mono/eventpipe/ep-rt-config.h | 9 + src/mono/mono/eventpipe/ep-rt-mono.c | 14 + src/mono/mono/eventpipe/ep-rt-mono.h | 1108 +++++++++++++++++ src/mono/mono/eventpipe/ep-rt-types-mono.h | 96 ++ src/mono/mono/eventpipe/ep-rt-types.h | 22 + src/mono/mono/eventpipe/ep-rt.h | 482 +++++++ .../mono/eventpipe/ep-session-internals.c | 123 ++ .../eventpipe/ep-session-provider-internals.c | 135 ++ src/mono/mono/eventpipe/ep-session-provider.c | 60 + src/mono/mono/eventpipe/ep-session-provider.h | 86 ++ src/mono/mono/eventpipe/ep-session.c | 255 ++++ src/mono/mono/eventpipe/ep-session.h | 130 ++ src/mono/mono/eventpipe/ep-stack-contents.h | 172 +++ src/mono/mono/eventpipe/ep-stream-internals.c | 392 ++++++ src/mono/mono/eventpipe/ep-stream.c | 280 +++++ src/mono/mono/eventpipe/ep-stream.h | 364 ++++++ src/mono/mono/eventpipe/ep-thread-internals.c | 219 ++++ src/mono/mono/eventpipe/ep-thread.c | 157 +++ src/mono/mono/eventpipe/ep-thread.h | 233 ++++ src/mono/mono/eventpipe/ep-types.h | 388 ++++++ src/mono/mono/eventpipe/ep.c | 711 +++++++++++ src/mono/mono/eventpipe/ep.h | 272 ++++ .../mono/eventpipe/test/Directory.Build.props | 3 + .../eventpipe/test/Directory.Build.targets | 3 + src/mono/mono/eventpipe/test/Makefile.am | 56 + src/mono/mono/eventpipe/test/ep-fake-tests.c | 1 + .../eventpipe/test/ep-fastserializer-tests.c | 346 +++++ src/mono/mono/eventpipe/test/ep-file-tests.c | 172 +++ .../ep-provider-callback-dataqueue-tests.c | 98 ++ .../mono/eventpipe/test/ep-session-tests.c | 244 ++++ src/mono/mono/eventpipe/test/ep-setup-tests.c | 27 + .../mono/eventpipe/test/ep-teardown-tests.c | 25 + src/mono/mono/eventpipe/test/ep-test-driver.c | 5 + src/mono/mono/eventpipe/test/ep-test-runner.c | 1 + src/mono/mono/eventpipe/test/ep-test.sln | 127 ++ src/mono/mono/eventpipe/test/ep-test.vcxproj | 186 +++ .../eventpipe/test/ep-test.vcxproj.filters | 63 + src/mono/mono/eventpipe/test/ep-tests-debug.h | 8 + src/mono/mono/eventpipe/test/ep-tests.c | 399 ++++++ src/mono/mono/eventpipe/test/ep-tests.h | 30 + .../mono/eventpipe/test/ep-thread-tests.c | 478 +++++++ src/mono/mono/metadata/Makefile.am | 9 +- src/mono/mono/metadata/icall-eventpipe.c | 489 ++++++++ src/mono/mono/metadata/icall.c | 109 -- src/mono/mono/mini/Makefile.am.in | 5 + src/mono/mono/mini/mini-runtime.c | 11 + src/mono/msvc/build-init.vcxproj | 1 + src/mono/msvc/libeventpipe.targets | 149 +++ src/mono/msvc/libeventpipe.targets.filters | 172 +++ src/mono/msvc/libmono-dynamic.vcxproj | 4 - src/mono/msvc/libmonoruntime-common.targets | 1 + .../libmonoruntime-common.targets.filters | 3 + src/mono/msvc/libmonoruntime.targets | 1 + src/mono/msvc/libmonoruntime.targets.filters | 1 + src/mono/msvc/mono.props | 8 +- src/mono/msvc/mono.winconfig.targets | 3 +- 93 files changed, 13904 insertions(+), 121 deletions(-) create mode 100644 src/mono/mono/eventpipe/Makefile.am create mode 100644 src/mono/mono/eventpipe/ep-block-internals.c create mode 100644 src/mono/mono/eventpipe/ep-block.c create mode 100644 src/mono/mono/eventpipe/ep-block.h create mode 100644 src/mono/mono/eventpipe/ep-buffer-manager-internals.c create mode 100644 src/mono/mono/eventpipe/ep-buffer-manager.c create mode 100644 src/mono/mono/eventpipe/ep-buffer-manager.h create mode 100644 src/mono/mono/eventpipe/ep-buffer.h create mode 100644 src/mono/mono/eventpipe/ep-config-internals.c create mode 100644 src/mono/mono/eventpipe/ep-config.c create mode 100644 src/mono/mono/eventpipe/ep-config.h create mode 100644 src/mono/mono/eventpipe/ep-event-instance-internals.c create mode 100644 src/mono/mono/eventpipe/ep-event-instance.c create mode 100644 src/mono/mono/eventpipe/ep-event-instance.h create mode 100644 src/mono/mono/eventpipe/ep-event-internals.c create mode 100644 src/mono/mono/eventpipe/ep-event-payload-internals.c create mode 100644 src/mono/mono/eventpipe/ep-event-payload.h create mode 100644 src/mono/mono/eventpipe/ep-event-source-internals.c create mode 100644 src/mono/mono/eventpipe/ep-event-source.c create mode 100644 src/mono/mono/eventpipe/ep-event-source.h create mode 100644 src/mono/mono/eventpipe/ep-event.h create mode 100644 src/mono/mono/eventpipe/ep-file-internals.c create mode 100644 src/mono/mono/eventpipe/ep-file.c create mode 100644 src/mono/mono/eventpipe/ep-file.h create mode 100644 src/mono/mono/eventpipe/ep-internals.c create mode 100644 src/mono/mono/eventpipe/ep-metadata-generator-internals.c create mode 100644 src/mono/mono/eventpipe/ep-metadata-generator.c create mode 100644 src/mono/mono/eventpipe/ep-metadata-generator.h create mode 100644 src/mono/mono/eventpipe/ep-provider-internals.c create mode 100644 src/mono/mono/eventpipe/ep-provider.c create mode 100644 src/mono/mono/eventpipe/ep-provider.h create mode 100644 src/mono/mono/eventpipe/ep-rt-config-mono.h create mode 100644 src/mono/mono/eventpipe/ep-rt-config.h create mode 100644 src/mono/mono/eventpipe/ep-rt-mono.c create mode 100644 src/mono/mono/eventpipe/ep-rt-mono.h create mode 100644 src/mono/mono/eventpipe/ep-rt-types-mono.h create mode 100644 src/mono/mono/eventpipe/ep-rt-types.h create mode 100644 src/mono/mono/eventpipe/ep-rt.h create mode 100644 src/mono/mono/eventpipe/ep-session-internals.c create mode 100644 src/mono/mono/eventpipe/ep-session-provider-internals.c create mode 100644 src/mono/mono/eventpipe/ep-session-provider.c create mode 100644 src/mono/mono/eventpipe/ep-session-provider.h create mode 100644 src/mono/mono/eventpipe/ep-session.c create mode 100644 src/mono/mono/eventpipe/ep-session.h create mode 100644 src/mono/mono/eventpipe/ep-stack-contents.h create mode 100644 src/mono/mono/eventpipe/ep-stream-internals.c create mode 100644 src/mono/mono/eventpipe/ep-stream.c create mode 100644 src/mono/mono/eventpipe/ep-stream.h create mode 100644 src/mono/mono/eventpipe/ep-thread-internals.c create mode 100644 src/mono/mono/eventpipe/ep-thread.c create mode 100644 src/mono/mono/eventpipe/ep-thread.h create mode 100644 src/mono/mono/eventpipe/ep-types.h create mode 100644 src/mono/mono/eventpipe/ep.c create mode 100644 src/mono/mono/eventpipe/ep.h create mode 100644 src/mono/mono/eventpipe/test/Directory.Build.props create mode 100644 src/mono/mono/eventpipe/test/Directory.Build.targets create mode 100644 src/mono/mono/eventpipe/test/Makefile.am create mode 100644 src/mono/mono/eventpipe/test/ep-fake-tests.c create mode 100644 src/mono/mono/eventpipe/test/ep-fastserializer-tests.c create mode 100644 src/mono/mono/eventpipe/test/ep-file-tests.c create mode 100644 src/mono/mono/eventpipe/test/ep-provider-callback-dataqueue-tests.c create mode 100644 src/mono/mono/eventpipe/test/ep-session-tests.c create mode 100644 src/mono/mono/eventpipe/test/ep-setup-tests.c create mode 100644 src/mono/mono/eventpipe/test/ep-teardown-tests.c create mode 100644 src/mono/mono/eventpipe/test/ep-test-driver.c create mode 100644 src/mono/mono/eventpipe/test/ep-test-runner.c create mode 100644 src/mono/mono/eventpipe/test/ep-test.sln create mode 100644 src/mono/mono/eventpipe/test/ep-test.vcxproj create mode 100644 src/mono/mono/eventpipe/test/ep-test.vcxproj.filters create mode 100644 src/mono/mono/eventpipe/test/ep-tests-debug.h create mode 100644 src/mono/mono/eventpipe/test/ep-tests.c create mode 100644 src/mono/mono/eventpipe/test/ep-tests.h create mode 100644 src/mono/mono/eventpipe/test/ep-thread-tests.c create mode 100644 src/mono/mono/metadata/icall-eventpipe.c create mode 100644 src/mono/msvc/libeventpipe.targets create mode 100644 src/mono/msvc/libeventpipe.targets.filters diff --git a/src/mono/cmake/config.h.in b/src/mono/cmake/config.h.in index b5754a613a877..e89b59c5f7100 100644 --- a/src/mono/cmake/config.h.in +++ b/src/mono/cmake/config.h.in @@ -1647,6 +1647,9 @@ /* Enable private types checked build */ #cmakedefine ENABLE_CHECKED_BUILD_CRASH_REPORTING 1 +/* Enable EventPipe library support */ +#cmakedefine ENABLE_PERFTRACING 1 + /* Define to 1 if you have /usr/include/malloc.h. */ #cmakedefine HAVE_USR_INCLUDE_MALLOC_H 1 diff --git a/src/mono/configure.ac b/src/mono/configure.ac index 98f8e86b254ff..6eb961f9dda00 100644 --- a/src/mono/configure.ac +++ b/src/mono/configure.ac @@ -943,6 +943,16 @@ if test x$with_core = xonly; then fi AM_CONDITIONAL(ENABLE_NETCORE, test x$with_core = xonly) +if test x$with_core = xonly; then + if test -f $srcdir/mono/eventpipe/ep.h; then + enable_perftracing=yes + fi + if test x$enable_perftracing = xyes; then + AC_DEFINE(ENABLE_PERFTRACING,1,[Enables support for eventpipe library]) + fi +fi +AM_CONDITIONAL(ENABLE_PERFTRACING, test x$enable_perftracing = xyes) + # # A sanity check to catch cases where the package was unpacked # with an ancient tar program (Solaris) diff --git a/src/mono/m4/mono-output.m4 b/src/mono/m4/mono-output.m4 index 40d72ea7d6d14..128c16f33633e 100644 --- a/src/mono/m4/mono-output.m4 +++ b/src/mono/m4/mono-output.m4 @@ -12,6 +12,8 @@ AC_DEFUN([AC_MONO_OUTPUT], [ mono/utils/Makefile mono/metadata/Makefile mono/zlib/Makefile + mono/eventpipe/Makefile + mono/eventpipe/test/Makefile mono/arch/Makefile mono/arch/x86/Makefile mono/arch/amd64/Makefile diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 20b28c5303cf6..446b216b77c93 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -728,6 +728,7 @@ <_MonoBuildParams Include="/p:MONO_BUILD_DIR_PREFIX=""$(MonoObjDir)""" /> <_MonoBuildParams Include="/p:MONO_ENABLE_NETCORE=true" /> + <_MonoBuildParams Include="/p:MONO_ENABLE_PERFTRACING=true" /> <_MonoBuildParams Include="/p:MONO_USE_STATIC_C_RUNTIME=true" /> <_MonoBuildParams Include="/p:CL_MPCount=$([System.Environment]::ProcessorCount)" /> <_MonoBuildParams Include="/v:minimal" /> diff --git a/src/mono/mono/Makefile.am b/src/mono/mono/Makefile.am index 226b8cab86854..fa19a4c0018dc 100644 --- a/src/mono/mono/Makefile.am +++ b/src/mono/mono/Makefile.am @@ -13,11 +13,20 @@ native_dirs = native endif if ENABLE_NETCORE -btls_dirs = +btls_dirs = +managed_unit_test_dirs = +native_unit_test_dirs = +else +managed_unit_test_dirs = tests +native_unit_test_dirs = unit-tests +endif + +if ENABLE_PERFTRACING +eventpipe_dirs = eventpipe endif if ENABLE_NETCORE -SUBDIRS = eglib arch utils sgen zlib metadata mini profiler +SUBDIRS = eglib arch utils sgen zlib $(eventpipe_dirs) metadata mini profiler $(native_unit_test_dirs) else if CROSS_COMPILING @@ -26,9 +35,9 @@ else if INSTALL_MONOTOUCH SUBDIRS = $(btls_dirs) eglib arch utils zlib $(sgen_dirs) metadata mini profiler $(native_dirs) else -SUBDIRS = $(btls_dirs) eglib arch utils cil zlib $(sgen_dirs) metadata mini dis tests unit-tests benchmark profiler $(native_dirs) +SUBDIRS = $(btls_dirs) eglib arch utils cil zlib $(sgen_dirs) metadata mini dis $(managed_unit_test_dirs) $(native_unit_test_dirs) benchmark profiler $(native_dirs) endif endif endif -DIST_SUBDIRS = btls native eglib arch utils cil zlib $(sgen_dirs) metadata mini dis tests unit-tests benchmark profiler +DIST_SUBDIRS = btls native eglib arch utils cil zlib $(sgen_dirs) metadata mini dis $(managed_unit_test_dirs) $(native_unit_test_dirs) benchmark profiler diff --git a/src/mono/mono/eventpipe/Makefile.am b/src/mono/mono/eventpipe/Makefile.am new file mode 100644 index 0000000000000..63d2edd8cf9dd --- /dev/null +++ b/src/mono/mono/eventpipe/Makefile.am @@ -0,0 +1,71 @@ +MAKEFLAGS := $(MAKEFLAGS) --no-builtin-rules + +if !ENABLE_MSVC_ONLY +if ENABLE_PERFTRACING + +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/mono $(GLIB_CFLAGS) $(SHARED_CFLAGS) + +noinst_LTLIBRARIES = libeventpipe.la + +eventpipe_sources = \ + ep.c \ + ep.h \ + ep-block.c \ + ep-block.h \ + ep-block-internals.c \ + ep-buffer.h \ + ep-buffer-manager.c \ + ep-buffer-manager.h \ + ep-buffer-manager-internals.c \ + ep-config.c \ + ep-config.h \ + ep-config-internals.c \ + ep-event.h \ + ep-event-instance.h \ + ep-event-instance.c \ + ep-event-instance-internals.c \ + ep-event-internals.c \ + ep-event-payload-internals.c \ + ep-event-payload.h \ + ep-event-source.c \ + ep-event-source.h \ + ep-event-source-internals.c \ + ep-file.c \ + ep-file.h \ + ep-file-internals.c \ + ep-internals.c \ + ep-metadata-generator.c \ + ep-metadata-generator.h \ + ep-metadata-generator-internals.c \ + ep-provider.c \ + ep-provider.h \ + ep-provider-internals.c \ + ep-rt.h \ + ep-rt-config.h \ + ep-rt-config-mono.h \ + ep-rt-mono.c \ + ep-rt-mono.h \ + ep-rt-types.h \ + ep-rt-types-mono.h \ + ep-thread.c \ + ep-thread.h \ + ep-thread-internals.c \ + ep-types.h \ + ep-session.c \ + ep-session.h \ + ep-session-internals.c \ + ep-session-provider.c \ + ep-session-provider-internals.h \ + ep-session-provider-internals.c \ + ep-stream.c \ + ep-stream.h \ + ep-stream-internals.c \ + ep-stack-contents.h + + +libeventpipe_la_SOURCES = $(eventpipe_sources) + +endif # ENABLE_PERFTRACING +endif # !ENABLE_MSVC_ONLY + +CFLAGS := $(filter-out @CXX_REMOVE_CFLAGS@, @CFLAGS@) @CXX_ADD_CFLAGS@ diff --git a/src/mono/mono/eventpipe/ep-block-internals.c b/src/mono/mono/eventpipe/ep-block-internals.c new file mode 100644 index 0000000000000..3d3f647722671 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-block-internals.c @@ -0,0 +1,595 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +/* + * Forward declares of all static functions. + */ + +static +void +block_base_fast_serialize_func ( + void *object, + FastSerializer *fast_serializer); + +static +void +block_base_clear_func (void *object); + +static +void +block_base_serialize_header_func ( + void *object, + FastSerializer *fast_serializer); + +static +uint32_t +block_base_get_header_size_func (void *object); + +static +const ep_char8_t * +event_block_get_type_name_func (void *object); + +static +void +event_block_free_func (void *object); + +static +void +metadata_block_free_func (void *object); + +static +const ep_char8_t * +metadata_block_get_type_name_func (void *object); + +static +int32_t +sequence_point_get_block_size (EventPipeSequencePoint *sequence_point); + +static +void +sequence_point_block_free_func (void *object); + +static +const ep_char8_t * +sequence_point_block_get_type_name_func (void *object); + +static +void +stack_block_free_func (void *object); + +static +const ep_char8_t * +stack_block_get_type_name_func (void *object); + +static +void +stack_block_clear_func (void *object); + +static +uint32_t +stack_block_get_header_size_func (void *object); + +static +void +stack_block_serialize_header_func (void *object, FastSerializer *fast_serializer); + +/* + * EventPipeBlock + */ + +EventPipeBlock * +ep_block_init ( + EventPipeBlock *block, + EventPipeBlockVtable *vtable, + uint32_t max_block_size, + EventPipeSerializationFormat format) +{ + EP_ASSERT (block != NULL && vtable != NULL); + + ep_raise_error_if_nok (ep_fast_serializable_object_init ( + &block->fast_serializer_object, + (FastSerializableObjectVtable *)vtable, + ep_file_get_file_version (format), + ep_file_get_file_minimum_version (format), + format >= EP_SERIALIZATION_FORMAT_NETTRACE_V4) != NULL); + + block->block = ep_rt_byte_array_alloc (max_block_size); + ep_raise_error_if_nok (block->block != NULL); + + memset (block->block, 0, max_block_size); + block->write_pointer = block->block; + block->end_of_the_buffer = block->block + max_block_size; + block->format = format; + +ep_on_exit: + return block; + +ep_on_error: + block = NULL; + ep_exit_error_handler (); +} + +void +ep_block_fini (EventPipeBlock *block) +{ + ep_return_void_if_nok (block != NULL); + ep_rt_byte_array_free (block->block); +} + +void +ep_block_clear_vcall (EventPipeBlock *block) +{ + EP_ASSERT (block != NULL && block->fast_serializer_object.vtable != NULL); + EventPipeBlockVtable *vtable = (EventPipeBlockVtable *)block->fast_serializer_object.vtable; + + EP_ASSERT (vtable->clear_func != NULL); + vtable->clear_func (block); +} + +uint32_t +ep_block_get_header_size_vcall (EventPipeBlock *block) +{ + EP_ASSERT (block != NULL && block->fast_serializer_object.vtable != NULL); + EventPipeBlockVtable *vtable = (EventPipeBlockVtable *)block->fast_serializer_object.vtable; + + EP_ASSERT (vtable->get_header_size_func != NULL); + return vtable->get_header_size_func (block); +} + +void +ep_block_serialize_header_vcall ( + EventPipeBlock *block, + FastSerializer *fast_serializer) +{ + EP_ASSERT (block != NULL && block->fast_serializer_object.vtable != NULL); + EventPipeBlockVtable *vtable = (EventPipeBlockVtable *)block->fast_serializer_object.vtable; + + EP_ASSERT (vtable->serialize_header_func != NULL); + vtable->serialize_header_func (block, fast_serializer); +} + +void +ep_block_fast_serialize_vcall ( + EventPipeBlock *block, + FastSerializer *fast_serializer) +{ + EP_ASSERT (block != NULL); + ep_fast_serializable_object_fast_serialize_vcall (&block->fast_serializer_object, fast_serializer); +} + +/* + * EventPipeEventBlockBase + */ + +static +void +block_base_fast_serialize_func ( + void *object, + FastSerializer *fast_serializer) +{ + EP_ASSERT (object != NULL && fast_serializer != NULL); + ep_block_fast_serialize (&((EventPipeEventBlockBase *)object)->block, fast_serializer); +} + +static +void +block_base_clear_func (void *object) +{ + EP_ASSERT (object != NULL); + ep_event_block_base_clear ((EventPipeEventBlockBase *)object); +} + +static +void +block_base_serialize_header_func ( + void *object, + FastSerializer *fast_serializer) +{ + EP_ASSERT (object != NULL && fast_serializer != NULL); + ep_event_block_base_serialize_header ((EventPipeEventBlockBase *)object, fast_serializer); +} + +static +uint32_t +block_base_get_header_size_func (void *object) +{ + EP_ASSERT (object != NULL); + return ep_event_block_base_get_header_size ((EventPipeEventBlockBase *)object); +} + +EventPipeEventBlockBase * +ep_event_block_base_init ( + EventPipeEventBlockBase *event_block_base, + EventPipeBlockVtable *vtable, + uint32_t max_block_size, + EventPipeSerializationFormat format, + bool use_header_compression) +{ + EP_ASSERT (event_block_base != NULL && vtable != NULL); + + ep_raise_error_if_nok (ep_block_init ( + &event_block_base->block, + vtable, + max_block_size, + format) != NULL); + + event_block_base->use_header_compression = use_header_compression; + + memset (event_block_base->compressed_header, 0, EP_ARRAY_SIZE (event_block_base->compressed_header)); + ep_event_block_base_clear (event_block_base); + +ep_on_exit: + return event_block_base; + +ep_on_error: + event_block_base = NULL; + ep_exit_error_handler (); +} + +void +ep_event_block_base_fini (EventPipeEventBlockBase *event_block_base) +{ + ep_return_void_if_nok (event_block_base != NULL); + ep_block_fini (&event_block_base->block); +} + +/* + * EventPipeEventBlock + */ + +static +const ep_char8_t * +event_block_get_type_name_func (void *object) +{ + EP_ASSERT (object != NULL); + return "EventBlock"; +} + +static +void +event_block_free_func (void *object) +{ + ep_event_block_free ((EventPipeEventBlock *)object); +} + +static EventPipeBlockVtable event_block_vtable = { + { + event_block_free_func, + block_base_fast_serialize_func, + event_block_get_type_name_func }, + block_base_clear_func, + block_base_get_header_size_func, + block_base_serialize_header_func }; + +EventPipeEventBlock * +ep_event_block_alloc ( + uint32_t max_block_size, + EventPipeSerializationFormat format) +{ + EventPipeEventBlock *instance = ep_rt_object_alloc (EventPipeEventBlock); + ep_raise_error_if_nok (instance != NULL); + + ep_raise_error_if_nok (ep_event_block_base_init ( + &instance->event_block_base, + &event_block_vtable, + max_block_size, + format, + format >= EP_SERIALIZATION_FORMAT_NETTRACE_V4) != NULL); + +ep_on_exit: + return instance; + +ep_on_error: + ep_event_block_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_event_block_free (EventPipeEventBlock *event_block) +{ + ep_return_void_if_nok (event_block != NULL); + + ep_event_block_base_fini (&event_block->event_block_base); + ep_rt_object_free (event_block); +} + +/* + * EventPipeMetadataBlock + */ + +static +void +metadata_block_free_func (void *object) +{ + ep_metadata_block_free ((EventPipeMetadataBlock *)object); +} + +static +const ep_char8_t * +metadata_block_get_type_name_func (void *object) +{ + EP_ASSERT (object != NULL); + return "MetadataBlock"; +} + +static EventPipeBlockVtable metadata_block_vtable = { + { + metadata_block_free_func, + block_base_fast_serialize_func, + metadata_block_get_type_name_func }, + block_base_clear_func, + block_base_get_header_size_func, + block_base_serialize_header_func }; + +EventPipeMetadataBlock * +ep_metadata_block_alloc (uint32_t max_block_size) +{ + EventPipeMetadataBlock *instance = ep_rt_object_alloc (EventPipeMetadataBlock); + ep_raise_error_if_nok (instance != NULL); + + ep_raise_error_if_nok (ep_event_block_base_init ( + &instance->event_block_base, + &metadata_block_vtable, + max_block_size, + EP_SERIALIZATION_FORMAT_NETTRACE_V4, + true) != NULL); + +ep_on_exit: + return instance; + +ep_on_error: + ep_metadata_block_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_metadata_block_free (EventPipeMetadataBlock *metadata_block) +{ + ep_return_void_if_nok (metadata_block != NULL); + + ep_event_block_base_fini (&metadata_block->event_block_base); + ep_rt_object_free (metadata_block); +} + +/* + * EventPipeSequencePointBlock. + */ + +static +int32_t +sequence_point_get_block_size (EventPipeSequencePoint *sequence_point) +{ + EP_ASSERT (sequence_point != NULL); + + const uint32_t size_of_sequence_number = + sizeof (uint64_t) + //thread id + sizeof (uint32_t); //sequence number + + const uint32_t thread_count = ep_rt_thread_sequence_number_map_count (ep_sequence_point_get_thread_sequence_numbers_cref (sequence_point)); + + return sizeof (sequence_point->timestamp) + + sizeof (uint32_t) + //thread count + thread_count * size_of_sequence_number; +} + +static +void +sequence_point_block_free_func (void *object) +{ + ep_sequence_point_block_free ((EventPipeSequencePointBlock *)object); +} + +static +const ep_char8_t * +sequence_point_block_get_type_name_func (void *object) +{ + EP_ASSERT (object != NULL); + return "SPBlock"; +} + +static EventPipeBlockVtable sequence_point_block_vtable = { + { + sequence_point_block_free_func, + block_base_fast_serialize_func, + sequence_point_block_get_type_name_func }, + block_base_clear_func, + block_base_get_header_size_func, + block_base_serialize_header_func }; + +EventPipeSequencePointBlock * +ep_sequence_point_block_alloc (EventPipeSequencePoint *sequence_point) +{ + ep_return_null_if_nok (sequence_point != NULL); + + EventPipeSequencePointBlock *instance = ep_rt_object_alloc (EventPipeSequencePointBlock); + ep_raise_error_if_nok (instance != NULL); + + ep_raise_error_if_nok (ep_sequence_point_block_init (instance, sequence_point) != NULL); + +ep_on_exit: + return instance; + +ep_on_error: + ep_sequence_point_block_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +EventPipeSequencePointBlock * +ep_sequence_point_block_init ( + EventPipeSequencePointBlock *sequence_point_block, + EventPipeSequencePoint *sequence_point) +{ + EP_ASSERT (sequence_point_block != NULL); + ep_return_null_if_nok (sequence_point != NULL); + + ep_raise_error_if_nok (ep_event_block_base_init ( + &sequence_point_block->event_block_base, + &sequence_point_block_vtable, + sequence_point_get_block_size (sequence_point), + EP_SERIALIZATION_FORMAT_NETTRACE_V4, + true) != NULL); + + const int64_t timestamp = sequence_point->timestamp; + memcpy (sequence_point_block->event_block_base.block.write_pointer, ×tamp, sizeof (timestamp)); + sequence_point_block->event_block_base.block.write_pointer += sizeof (timestamp); + + const uint32_t thread_count = ep_rt_thread_sequence_number_map_count (ep_sequence_point_get_thread_sequence_numbers_cref (sequence_point)); + memcpy (sequence_point_block->event_block_base.block.write_pointer, &thread_count, sizeof (thread_count)); + sequence_point_block->event_block_base.block.write_pointer += sizeof (thread_count); + + ep_rt_thread_sequence_number_hash_map_iterator_t iterator; + for (ep_rt_thread_sequence_number_map_iterator_begin (&sequence_point->thread_sequence_numbers, &iterator); + !ep_rt_thread_sequence_number_map_iterator_end (&sequence_point->thread_sequence_numbers, &iterator); + ep_rt_thread_sequence_number_map_iterator_next (&sequence_point->thread_sequence_numbers, &iterator)) { + + const EventPipeThreadSessionState *key = ep_rt_thread_sequence_number_map_iterator_key (&iterator); + + const uint64_t thread_id = ep_thread_get_os_thread_id (ep_thread_session_state_get_thread (key)); + memcpy (sequence_point_block->event_block_base.block.write_pointer, &thread_id, sizeof (thread_id)); + sequence_point_block->event_block_base.block.write_pointer += sizeof (thread_id); + + const uint32_t sequence_number = ep_rt_thread_sequence_number_map_iterator_value (&iterator); + memcpy (sequence_point_block->event_block_base.block.write_pointer, &sequence_number, sizeof (sequence_number)); + sequence_point_block->event_block_base.block.write_pointer += sizeof (sequence_number); + } + +ep_on_exit: + return sequence_point_block; + +ep_on_error: + sequence_point_block = NULL; + ep_exit_error_handler (); +} + +void +ep_sequence_point_block_fini (EventPipeSequencePointBlock *sequence_point_block) +{ + ep_return_void_if_nok (sequence_point_block != NULL); + ep_event_block_base_fini (&sequence_point_block->event_block_base); +} + +void +ep_sequence_point_block_free (EventPipeSequencePointBlock *sequence_point_block) +{ + ep_return_void_if_nok (sequence_point_block != NULL); + + ep_sequence_point_block_fini (sequence_point_block); + ep_rt_object_free (sequence_point_block); +} + +/* + * EventPipeStackBlock. + */ + +static +void +stack_block_free_func (void *object) +{ + ep_stack_block_free ((EventPipeStackBlock *)object); +} + +static +const ep_char8_t * +stack_block_get_type_name_func (void *object) +{ + EP_ASSERT (object != NULL); + return "StackBlock"; +} + +static +void +stack_block_clear_func (void *object) +{ + EP_ASSERT (object != NULL); + + EventPipeStackBlock *stack_block = (EventPipeStackBlock *)object; + + stack_block->has_initial_index = false; + stack_block->has_initial_index = 0; + stack_block->count = 0; + + ep_block_clear (&stack_block->event_block_base.block); +} + +static +uint32_t +stack_block_get_header_size_func (void *object) +{ + EP_ASSERT (object != NULL); + return sizeof (uint32_t) + // start index + sizeof (uint32_t); // count of indices +} + +static +void +stack_block_serialize_header_func (void *object, FastSerializer *fast_serializer) +{ + EP_ASSERT (object != NULL && fast_serializer != NULL); + + EventPipeStackBlock *stack_block = (EventPipeStackBlock *)object; + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&stack_block->initial_index, sizeof (stack_block->initial_index)); + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&stack_block->count, sizeof (stack_block->count)); +} + +static EventPipeBlockVtable stack_block_vtable = { + { + stack_block_free_func, + block_base_fast_serialize_func, + stack_block_get_type_name_func }, + stack_block_clear_func, + stack_block_get_header_size_func, + stack_block_serialize_header_func }; + +EventPipeStackBlock * +ep_stack_block_alloc (uint32_t max_block_size) +{ + EventPipeStackBlock *instance = ep_rt_object_alloc (EventPipeStackBlock); + ep_raise_error_if_nok (instance != NULL); + + ep_raise_error_if_nok (ep_event_block_base_init ( + &instance->event_block_base, + &stack_block_vtable, + max_block_size, + EP_SERIALIZATION_FORMAT_NETTRACE_V4, + true) != NULL); + + stack_block_clear_func (instance); + +ep_on_exit: + return instance; + +ep_on_error: + ep_stack_block_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_stack_block_free (EventPipeStackBlock *stack_block) +{ + ep_return_void_if_nok (stack_block != NULL); + + ep_event_block_base_fini (&stack_block->event_block_base); + ep_rt_object_free (stack_block); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_block_internals; +const char quiet_linker_empty_file_warning_eventpipe_block_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-block.c b/src/mono/mono/eventpipe/ep-block.c new file mode 100644 index 0000000000000..214d3817fa645 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-block.c @@ -0,0 +1,398 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#include "ep.h" + +/* + * Forward declares of all static functions. + */ + +static +uint8_t * +event_block_base_write_var_uint32 ( + uint8_t * write_pointer, + uint32_t value); + +static +uint8_t * +event_block_base_write_var_uint64 ( + uint8_t * write_pointer, + uint64_t value); + +/* + * EventPipeBlock + */ + +void +ep_block_clear (EventPipeBlock *block) +{ + ep_return_void_if_nok (block != NULL); + ep_return_void_if_nok (ep_block_get_block (block) != NULL); + + EP_ASSERT (ep_block_get_write_pointer (block) <= ep_block_get_end_of_the_buffer (block)); + + memset (ep_block_get_block (block), 0, ep_block_get_end_of_the_buffer (block) - ep_block_get_block (block)); + ep_block_set_write_pointer (block, ep_block_get_block (block)); +} + +uint32_t +ep_block_get_header_size (EventPipeBlock *block) +{ + return 0; +} + +void +ep_block_serialize_header ( + EventPipeBlock *block, + FastSerializer *fast_serializer) +{ + ; +} + +void +ep_block_fast_serialize ( + EventPipeBlock *block, + FastSerializer *fast_serializer) +{ + ep_return_void_if_nok (block != NULL && fast_serializer != NULL && ep_block_get_block (block) != NULL); + + uint32_t data_size = ep_block_get_bytes_written (block); + EP_ASSERT (data_size != 0); + + uint32_t header_size = ep_block_get_header_size_vcall (block); + uint32_t total_size = data_size + header_size; + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&total_size, sizeof (total_size)); + + uint32_t required_padding = ep_fast_serializer_get_required_padding (fast_serializer); + if (required_padding != 0) { + uint8_t max_padding [FAST_SERIALIZER_ALIGNMENT_SIZE - 1] = { 0 }; // it's longest possible padding, we are going to use only part of it + + EP_ASSERT (required_padding <= FAST_SERIALIZER_ALIGNMENT_SIZE - 1); + ep_fast_serializer_write_buffer (fast_serializer, max_padding, required_padding); // we write zeros here, the reader is going to always read from the first aligned address of the serialized content + + EP_ASSERT (ep_fast_serializer_get_write_error_encountered (fast_serializer) || ep_fast_serializer_get_required_padding (fast_serializer)); + } + + ep_block_serialize_header_vcall (block, fast_serializer); + ep_fast_serializer_write_buffer (fast_serializer, ep_block_get_block (block), data_size); +} + +/* + * EventPipeEventBlockBase + */ + +static +uint8_t * +event_block_base_write_var_uint32 ( + uint8_t * write_pointer, + uint32_t value) +{ + while (value >= 0x80) { + *write_pointer = (uint8_t)(value | 0x80); + write_pointer++; + value >>= 7; + } + *write_pointer = (uint8_t)value; + write_pointer++; + return write_pointer; +} + +static +uint8_t * +event_block_base_write_var_uint64 ( + uint8_t * write_pointer, + uint64_t value) +{ + while (value >= 0x80) { + *write_pointer = (uint8_t)(value | 0x80); + write_pointer++; + value >>= 7; + } + *write_pointer = (uint8_t)value; + write_pointer++; + return write_pointer; +} + +void +ep_event_block_base_clear (EventPipeEventBlockBase *event_block_base) +{ + ep_return_void_if_nok (event_block_base != NULL); + + ep_block_clear (ep_event_block_base_get_block_ref (event_block_base)); + memset (ep_event_block_base_get_last_header_ref (event_block_base), 0, sizeof (EventPipeEventHeader)); + ep_event_block_base_set_min_timestamp (event_block_base, INT64_MAX); + ep_event_block_base_set_max_timestamp (event_block_base, INT64_MIN); +} + +uint32_t +ep_event_block_base_get_header_size (const EventPipeEventBlockBase *event_block_base) +{ + ep_return_zero_if_nok (event_block_base != NULL && ep_block_get_format ((EventPipeBlock *)event_block_base) != EP_SERIALIZATION_FORMAT_NETPERF_V3); + + return sizeof(uint16_t) + // header size + sizeof(uint16_t) + // flags + sizeof(int64_t) + // min timestamp + sizeof(int64_t); // max timestamp +} + +void +ep_event_block_base_serialize_header ( + EventPipeEventBlockBase *event_block_base, + FastSerializer *fast_serializer) +{ + ep_return_void_if_nok (event_block_base != NULL && ep_block_get_format ((EventPipeBlock *)event_block_base) != EP_SERIALIZATION_FORMAT_NETPERF_V3 && fast_serializer != NULL); + + const uint16_t header_size = (uint16_t)ep_block_get_header_size_vcall ((EventPipeBlock *)event_block_base); + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&header_size, sizeof (header_size)); + + const uint16_t flags = ep_event_block_base_get_use_header_compression (event_block_base) ? 1 : 0; + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&flags, sizeof (flags)); + + uint64_t min_timestamp = ep_event_block_base_get_min_timestamp (event_block_base); + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&min_timestamp, sizeof (min_timestamp)); + + uint64_t max_timestamp = ep_event_block_base_get_max_timestamp (event_block_base); + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&max_timestamp, sizeof (max_timestamp)); +} + +bool +ep_event_block_base_write_event ( + EventPipeEventBlockBase *event_block_base, + EventPipeEventInstance *event_instance, + uint64_t capture_thread_id, + uint32_t sequence_number, + int32_t stack_id, + bool is_sorted_event) +{ + ep_return_false_if_nok (event_block_base != NULL && event_instance != NULL); + + EventPipeBlock *block = ep_event_block_base_get_block_ref (event_block_base); + ep_raise_error_if_nok (ep_block_get_block (block) != NULL); + + uint32_t data_len = 0; + uint8_t * aligned_end = NULL; + uint32_t capture_proc_number = ep_event_instance_get_proc_num (event_instance); + uint8_t * write_pointer = ep_block_get_write_pointer (block); + + if (!ep_event_block_base_get_use_header_compression (event_block_base)) { + uint32_t total_size = ep_event_instance_get_aligned_total_size (event_instance, ep_block_get_format (block)); + ep_raise_error_if_nok (write_pointer + total_size < ep_block_get_end_of_the_buffer (block)); + + aligned_end = write_pointer + total_size + sizeof (total_size); + + memcpy (write_pointer, &total_size, sizeof (total_size)); + write_pointer += sizeof (total_size); + + uint32_t metadata_id = ep_event_instance_get_metadata_id (event_instance); + EP_ASSERT ((metadata_id & (1 << 31)) == 0); + + metadata_id |= (!is_sorted_event ? 1 << 31 : 0); + memcpy (write_pointer, &metadata_id, sizeof (metadata_id)); + write_pointer += sizeof (metadata_id); + + if (ep_block_get_format (block) == EP_SERIALIZATION_FORMAT_NETPERF_V3) { + int32_t thread_id = (int32_t)ep_event_instance_get_thread_id (event_instance); + memcpy (write_pointer, &thread_id, sizeof (thread_id)); + write_pointer += sizeof (thread_id); + } else if (ep_block_get_format (block) == EP_SERIALIZATION_FORMAT_NETTRACE_V4) { + memcpy (write_pointer, &sequence_number, sizeof (sequence_number)); + write_pointer += sizeof (sequence_number); + + uint64_t thread_id = ep_event_instance_get_thread_id (event_instance); + memcpy (write_pointer, &thread_id, sizeof (thread_id)); + write_pointer += sizeof (thread_id); + + memcpy (write_pointer, &capture_thread_id, sizeof (capture_thread_id)); + write_pointer += sizeof (capture_thread_id); + + memcpy (write_pointer, &capture_proc_number, sizeof (capture_proc_number)); + write_pointer += sizeof (capture_proc_number); + + memcpy (write_pointer, &stack_id, sizeof (stack_id)); + write_pointer += sizeof (stack_id); + } + + int64_t timestamp = ep_event_instance_get_timestamp (event_instance); + memcpy (write_pointer, ×tamp, sizeof (timestamp)); + write_pointer += sizeof (timestamp); + + const uint8_t *activity_id = ep_event_instance_get_activity_id_cref (event_instance); + memcpy (write_pointer, activity_id, EP_ACTIVITY_ID_SIZE); + write_pointer += EP_ACTIVITY_ID_SIZE; + + const uint8_t *relative_activity_id = ep_event_instance_get_related_activity_id_cref (event_instance); + memcpy (write_pointer, relative_activity_id, EP_ACTIVITY_ID_SIZE); + write_pointer += EP_ACTIVITY_ID_SIZE; + + data_len = ep_event_instance_get_data_len (event_instance); + memcpy (write_pointer, &data_len, sizeof (data_len)); + write_pointer += sizeof (data_len); + } else { // using header compression + uint8_t flags = 0; + uint8_t *header_write_pointer = ep_event_block_base_get_compressed_header_ref (event_block_base); + EventPipeEventHeader *last_header = ep_event_block_base_get_last_header_ref (event_block_base); + + if (ep_event_instance_get_metadata_id (event_instance) != last_header->metadata_id) { + header_write_pointer = event_block_base_write_var_uint32 (header_write_pointer, ep_event_instance_get_metadata_id (event_instance)); + flags |= 1; + } + + if (is_sorted_event) { + flags |= (1 << 6); + } + + if (last_header->sequence_number + (ep_event_instance_get_metadata_id (event_instance) != 0 ? 1 : 0) != sequence_number || + last_header->capture_thread_id != capture_thread_id || last_header->capture_proc_number != capture_proc_number) { + header_write_pointer = event_block_base_write_var_uint32 (header_write_pointer, sequence_number - last_header->sequence_number - 1); + header_write_pointer = event_block_base_write_var_uint32 (header_write_pointer, (uint32_t)capture_thread_id); + header_write_pointer = event_block_base_write_var_uint32 (header_write_pointer, capture_proc_number); + flags |= (1 << 1); + } + + if (last_header->thread_id != ep_event_instance_get_thread_id (event_instance)) { + header_write_pointer = event_block_base_write_var_uint64 (header_write_pointer, ep_event_instance_get_thread_id (event_instance)); + flags |= (1 << 2); + } + + if (last_header->stack_id != stack_id) { + header_write_pointer = event_block_base_write_var_uint32 (header_write_pointer, stack_id); + flags |= (1 << 3); + } + + int64_t timestamp = ep_event_instance_get_timestamp (event_instance); + header_write_pointer = event_block_base_write_var_uint64 (header_write_pointer, timestamp - last_header->timestamp); + + if (memcmp (&last_header->activity_id, ep_event_instance_get_activity_id_cref (event_instance), EP_ACTIVITY_ID_SIZE) != 0) { + memcpy (header_write_pointer, ep_event_instance_get_activity_id_cref (event_instance), EP_ACTIVITY_ID_SIZE ); + header_write_pointer += EP_ACTIVITY_ID_SIZE; + flags |= (1 << 4); + } + + if (memcmp (&last_header->related_activity_id, ep_event_instance_get_related_activity_id_cref (event_instance), EP_ACTIVITY_ID_SIZE) != 0) { + memcpy (header_write_pointer, ep_event_instance_get_related_activity_id_cref (event_instance), EP_ACTIVITY_ID_SIZE ); + header_write_pointer += EP_ACTIVITY_ID_SIZE; + flags |= (1 << 5); + } + + data_len = ep_event_instance_get_data_len (event_instance); + if (last_header->data_len != data_len) { + header_write_pointer = event_block_base_write_var_uint32 (header_write_pointer, data_len); + flags |= (1 << 7); + } + + uint32_t bytes_written = (uint32_t)(header_write_pointer - ep_event_block_base_get_compressed_header_cref (event_block_base)); + uint32_t total_size = 1 + bytes_written + data_len; + + if (write_pointer + total_size >= ep_block_get_end_of_the_buffer (block)) { + //TODO: Orignal EP updates blocks write pointer continiously, doing the same here before + //bailing out. Question is if that is intentional or just a side effect of directly updating + //the member. + ep_block_set_write_pointer (block, write_pointer); + ep_raise_error (); + } + + last_header->metadata_id = ep_event_instance_get_metadata_id (event_instance); + last_header->sequence_number = sequence_number; + last_header->thread_id = ep_event_instance_get_thread_id (event_instance); + last_header->capture_thread_id = capture_thread_id; + last_header->capture_proc_number = capture_proc_number; + last_header->stack_id = stack_id; + last_header->timestamp = timestamp; + memcpy (&last_header->activity_id, ep_event_instance_get_activity_id_cref (event_instance), EP_ACTIVITY_ID_SIZE); + memcpy (&last_header->related_activity_id, ep_event_instance_get_related_activity_id_cref (event_instance), EP_ACTIVITY_ID_SIZE); + last_header->data_len = data_len; + + aligned_end = write_pointer + total_size; + *write_pointer = flags; + write_pointer++; + memcpy (write_pointer, ep_event_block_base_get_compressed_header_cref (event_block_base), bytes_written); + write_pointer += bytes_written; + } + + if (data_len > 0) { + memcpy (write_pointer, ep_event_instance_get_data (event_instance), data_len); + write_pointer += data_len; + } + + if (ep_block_get_format (block) == EP_SERIALIZATION_FORMAT_NETPERF_V3) { + uint32_t stack_size = ep_stack_contents_get_size (ep_event_instance_get_stack_contents_ref (event_instance)); + memcpy (write_pointer, &stack_size, sizeof (stack_size)); + write_pointer += sizeof (stack_size); + + if (stack_size > 0) { + memcpy (write_pointer, ep_event_instance_get_stack_contents_ref (event_instance), stack_size); + write_pointer += stack_size; + } + } + + while (write_pointer < aligned_end) + *write_pointer++ = (uint8_t)0; // put padding at the end to get 4 bytes alignment of the payload + + EP_ASSERT (write_pointer == aligned_end); + + int64_t instance_timestamp = ep_event_instance_get_timestamp (event_instance); + if (ep_event_block_base_get_min_timestamp (event_block_base) > instance_timestamp) + ep_event_block_base_set_min_timestamp (event_block_base, instance_timestamp); + if (ep_event_block_base_get_max_timestamp (event_block_base) > instance_timestamp) + ep_event_block_base_set_max_timestamp (event_block_base, instance_timestamp); + + ep_block_set_write_pointer (block, write_pointer); + return true; + +ep_on_error: + return false; +} + +/* + * EventPipeStackBlock. + */ + +bool +ep_stack_block_write_stack ( + EventPipeStackBlock *stack_block, + int32_t stack_id, + EventPipeStackContents *stack) +{ + ep_return_false_if_nok (stack_block != NULL); + + EventPipeBlock *block = ep_event_block_base_get_block_ref (ep_stack_block_get_event_block_base_ref (stack_block)); + ep_raise_error_if_nok (block != NULL && ep_block_get_block (block) != NULL); + + uint32_t stack_size = ep_stack_contents_get_size (stack); + uint32_t total_size = sizeof (stack_size) + stack_size; + uint8_t *write_pointer = ep_block_get_write_pointer (block); + + ep_raise_error_if_nok (write_pointer + total_size < ep_block_get_end_of_the_buffer (block)); + + if (!ep_stack_block_get_has_initial_index (stack_block)) { + ep_stack_block_set_has_initial_index (stack_block, true); + ep_stack_block_set_initial_index (stack_block, stack_id); + } + + ep_stack_block_set_count (stack_block, ep_stack_block_get_count (stack_block) + 1); + + memcpy (write_pointer, &stack_size, sizeof (stack_size)); + write_pointer += sizeof (stack_size); + + if (stack_size > 0) { + memcpy (write_pointer, ep_stack_contents_get_pointer (stack), stack_size); + write_pointer += stack_size; + } + + ep_block_set_write_pointer (block, write_pointer); + return true; + +ep_on_error: + return false; +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_block; +const char quiet_linker_empty_file_warning_eventpipe_block = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-block.h b/src/mono/mono/eventpipe/ep-block.h new file mode 100644 index 0000000000000..f114cfd4eabba --- /dev/null +++ b/src/mono/mono/eventpipe/ep-block.h @@ -0,0 +1,375 @@ +#ifndef __EVENTPIPE_BLOCK_H__ +#define __EVENTPIPE_BLOCK_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventPipeBlock + */ + +typedef void (*EventPipeBlockClearFunc)(void *object); +typedef uint32_t (*EventPipeBlockGetHeaderSizeFunc)(void *object); +typedef void (*EventPipeBlockSerializeHeaderFunc)(void *object, FastSerializer *fast_serializer); + +struct _EventPipeBlockVtable { + FastSerializableObjectVtable fast_serializable_object_vtable; + EventPipeBlockClearFunc clear_func; + EventPipeBlockGetHeaderSizeFunc get_header_size_func; + EventPipeBlockSerializeHeaderFunc serialize_header_func; +}; + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeBlock { +#else +struct _EventPipeBlock_Internal { +#endif + FastSerializableObject fast_serializer_object; + uint8_t *block; + uint8_t *write_pointer; + uint8_t *end_of_the_buffer; + EventPipeSerializationFormat format; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeBlock { + uint8_t _internal [sizeof (struct _EventPipeBlock_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventPipeBlock *, block, uint8_t*, block) +EP_DEFINE_GETTER(EventPipeBlock *, block, uint8_t*, write_pointer) +EP_DEFINE_SETTER(EventPipeBlock *, block, uint8_t*, write_pointer) +EP_DEFINE_GETTER(EventPipeBlock *, block, uint8_t*, end_of_the_buffer) +EP_DEFINE_GETTER(EventPipeBlock *, block, EventPipeSerializationFormat, format) + +static +inline +uint32_t +ep_block_get_bytes_written (const EventPipeBlock *block) +{ + return block == NULL ? 0 : (uint32_t)(ep_block_get_write_pointer (block) - ep_block_get_block (block)); +} + +EventPipeBlock * +ep_block_init ( + EventPipeBlock *block, + EventPipeBlockVtable *vtable, + uint32_t max_block_size, + EventPipeSerializationFormat format); + +void +ep_block_fini (EventPipeBlock *block); + +void +ep_block_clear (EventPipeBlock *block); + +uint32_t +ep_block_get_header_size (EventPipeBlock *block); + +void +ep_block_serialize_header ( + EventPipeBlock *block, + FastSerializer *fast_serializer); + +void +ep_block_fast_serialize ( + EventPipeBlock *block, + FastSerializer *fast_serializer); + +void +ep_block_clear_vcall (EventPipeBlock *block); + +uint32_t +ep_block_get_header_size_vcall (EventPipeBlock *block); + +void +ep_block_serialize_header_vcall ( + EventPipeBlock *block, + FastSerializer *fast_serializer); + +void +ep_block_fast_serialize_vcall ( + EventPipeBlock *block, + FastSerializer *fast_serializer); + +/* + * EventPipeEventHeader. + */ + +struct _EventPipeEventHeader { + int32_t metadata_id; + int32_t sequence_number; + uint64_t thread_id; + uint64_t capture_thread_id; + int32_t capture_proc_number; + int32_t stack_id; + uint64_t timestamp; + uint8_t activity_id [EP_ACTIVITY_ID_SIZE]; + uint8_t related_activity_id [EP_ACTIVITY_ID_SIZE]; + int32_t data_len; +}; + +/* + * EventPipeEventBlockBase + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeEventBlockBase { +#else +struct _EventPipeEventBlockBase_Internal { +#endif + EventPipeBlock block; + EventPipeEventHeader last_header; + uint8_t compressed_header [100]; + bool use_header_compression; + uint64_t min_timestamp; + uint64_t max_timestamp; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeEventBlockBase { + uint8_t _internal [sizeof (struct _EventPipeEventBlockBase_Internal)]; +}; +#endif + +EP_DEFINE_GETTER_REF(EventPipeEventBlockBase *, event_block_base, EventPipeBlock *, block) +EP_DEFINE_GETTER_REF(EventPipeEventBlockBase *, event_block_base, EventPipeEventHeader *, last_header) +EP_DEFINE_GETTER(EventPipeEventBlockBase *, event_block_base, bool, use_header_compression) +EP_DEFINE_GETTER_ARRAY_REF(EventPipeEventBlockBase *, event_block_base, uint8_t *, const uint8_t *, compressed_header, compressed_header[0]) +EP_DEFINE_GETTER(EventPipeEventBlockBase *, event_block_base, uint64_t, min_timestamp) +EP_DEFINE_SETTER(EventPipeEventBlockBase *, event_block_base, uint64_t, min_timestamp) +EP_DEFINE_GETTER(EventPipeEventBlockBase *, event_block_base, uint64_t, max_timestamp) +EP_DEFINE_SETTER(EventPipeEventBlockBase *, event_block_base, uint64_t, max_timestamp) + +EventPipeEventBlockBase * +ep_event_block_base_init ( + EventPipeEventBlockBase *event_block_base, + EventPipeBlockVtable *vtable, + uint32_t max_block_size, + EventPipeSerializationFormat format, + bool use_header_compression); + +void +ep_event_block_base_fini (EventPipeEventBlockBase *event_block_base); + +void +ep_event_block_base_clear (EventPipeEventBlockBase *event_block_base); + +uint32_t +ep_event_block_base_get_header_size (const EventPipeEventBlockBase *event_block_base); + +void +ep_event_block_base_serialize_header ( + EventPipeEventBlockBase *event_block_base, + FastSerializer *fast_serializer); + +bool +ep_event_block_base_write_event ( + EventPipeEventBlockBase *event_block_base, + EventPipeEventInstance *event_instance, + uint64_t capture_thread_id, + uint32_t sequence_number, + int32_t stack_id, + bool is_sorted_event); + +/* + * EventPipeEventBlock. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeEventBlock { +#else +struct _EventPipeEventBlock_Internal { +#endif + EventPipeEventBlockBase event_block_base; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeEventBlock { + uint8_t _internal [sizeof (struct _EventPipeEventBlock_Internal)]; +}; +#endif + +EventPipeEventBlock * +ep_event_block_alloc ( + uint32_t max_block_size, + EventPipeSerializationFormat format); + +void +ep_event_block_free (EventPipeEventBlock *event_block); + +static +inline +uint32_t +ep_event_block_get_bytes_written (EventPipeEventBlock *event_block) +{ + return ep_block_get_bytes_written ((const EventPipeBlock *)event_block); +} + +static +inline +void +ep_event_block_serialize (EventPipeEventBlock *event_block, FastSerializer *fast_serializer) +{ + ep_fast_serializer_write_object (fast_serializer, (FastSerializableObject*)event_block); +} + +static +inline +void +ep_event_block_clear (EventPipeEventBlock *event_block) +{ + ep_block_clear_vcall ((EventPipeBlock *)event_block); +} + +/* + * EventPipeMetadataBlock. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeMetadataBlock { +#else +struct _EventPipeMetadataBlock_Internal { +#endif + EventPipeEventBlockBase event_block_base; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeMetadataBlock { + uint8_t _internal [sizeof (struct _EventPipeMetadataBlock_Internal)]; +}; +#endif + +EventPipeMetadataBlock * +ep_metadata_block_alloc (uint32_t max_block_size); + +void +ep_metadata_block_free (EventPipeMetadataBlock *metadata_block); + +static +inline +uint32_t +ep_metadata_block_get_bytes_written (EventPipeMetadataBlock *metadata_block) +{ + return ep_block_get_bytes_written ((const EventPipeBlock *)metadata_block); +} + +static +inline +void +ep_metadata_block_serialize (EventPipeMetadataBlock *metadata_block, FastSerializer *fast_serializer) +{ + ep_fast_serializer_write_object (fast_serializer, (FastSerializableObject *)metadata_block); +} + +static +inline +void +ep_metadata_block_clear (EventPipeMetadataBlock *metadata_block) +{ + ep_block_clear_vcall ((EventPipeBlock *)metadata_block); +} + +/* + * EventPipeSequencePointBlock. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeSequencePointBlock { +#else +struct _EventPipeSequencePointBlock_Internal { +#endif + EventPipeEventBlockBase event_block_base; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeSequencePointBlock { + uint8_t _internal [sizeof (struct _EventPipeSequencePointBlock_Internal)]; +}; +#endif + +EventPipeSequencePointBlock * +ep_sequence_point_block_alloc (EventPipeSequencePoint *sequence_point); + +EventPipeSequencePointBlock * +ep_sequence_point_block_init ( + EventPipeSequencePointBlock *sequence_point_block, + EventPipeSequencePoint *sequence_point); + +void +ep_sequence_point_block_fini (EventPipeSequencePointBlock *sequence_point_block); + +void +ep_sequence_point_block_free (EventPipeSequencePointBlock *sequence_point_block); + +/* + * EventPipeStackBlock. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeStackBlock { +#else +struct _EventPipeStackBlock_Internal { +#endif + EventPipeEventBlockBase event_block_base; + uint32_t initial_index; + uint32_t count; + bool has_initial_index; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeStackBlock { + uint8_t _internal [sizeof (struct _EventPipeStackBlock_Internal)]; +}; +#endif + +EP_DEFINE_GETTER_REF(EventPipeStackBlock *, stack_block, EventPipeEventBlockBase *, event_block_base) +EP_DEFINE_GETTER(EventPipeStackBlock *, stack_block, uint32_t, initial_index) +EP_DEFINE_SETTER(EventPipeStackBlock *, stack_block, uint32_t, initial_index) +EP_DEFINE_GETTER(EventPipeStackBlock *, stack_block, uint32_t, count) +EP_DEFINE_SETTER(EventPipeStackBlock *, stack_block, uint32_t, count) +EP_DEFINE_GETTER(EventPipeStackBlock *, stack_block, bool, has_initial_index) +EP_DEFINE_SETTER(EventPipeStackBlock *, stack_block, bool, has_initial_index) + +EventPipeStackBlock * +ep_stack_block_alloc (uint32_t max_block_size); + +void +ep_stack_block_free (EventPipeStackBlock *stack_block); + +bool +ep_stack_block_write_stack ( + EventPipeStackBlock *stack_block, + int32_t stack_id, + EventPipeStackContents *stack); + +static +inline +uint32_t +ep_stack_block_get_bytes_written (EventPipeStackBlock *stack_block) +{ + return ep_block_get_bytes_written ((const EventPipeBlock *)stack_block); +} + +static +inline +void +ep_stack_block_serialize (EventPipeStackBlock *stack_block, FastSerializer *fast_serializer) +{ + ep_fast_serializer_write_object (fast_serializer, (FastSerializableObject *)stack_block); +} + +static +inline +void +ep_stack_block_clear (EventPipeStackBlock *stack_block) +{ + ep_block_clear_vcall ((EventPipeBlock *)stack_block); +} + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_BLOCK_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-buffer-manager-internals.c b/src/mono/mono/eventpipe/ep-buffer-manager-internals.c new file mode 100644 index 0000000000000..aabec9ad60379 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-buffer-manager-internals.c @@ -0,0 +1,38 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +/* + * EventPipeBufferManager. + */ + +EventPipeBufferManager * +ep_buffer_manager_alloc ( + EventPipeSession *session, + size_t max_size_of_all_buffers, + size_t sequence_point_allocation_budget) +{ + //TODO: Implement. + return ep_rt_object_alloc (EventPipeBufferManager); +} + +void +ep_buffer_manager_free (EventPipeBufferManager * buffer_manager) +{ + //TODO: Implement. + ep_return_void_if_nok (buffer_manager != NULL); + ep_rt_object_free (buffer_manager); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_buffer_manager_internals; +const char quiet_linker_empty_file_warning_eventpipe_buffer_manager_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-buffer-manager.c b/src/mono/mono/eventpipe/ep-buffer-manager.c new file mode 100644 index 0000000000000..3e151790d6afb --- /dev/null +++ b/src/mono/mono/eventpipe/ep-buffer-manager.c @@ -0,0 +1,28 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#include "ep.h" + +/* + * EventPipeBufferManager. + */ + +#ifdef EP_CHECKED_BUILD +void +ep_buffer_manager_requires_lock_held (const EventPipeBufferManager *buffer_manager) +{ + EP_ASSERT (buffer_manager != NULL); + ep_rt_spin_lock_requires_lock_held (ep_buffer_manager_get_rt_lock_cref (buffer_manager)); +} +#endif + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_buffer_manager; +const char quiet_linker_empty_file_warning_eventpipe_buffer_manager = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-buffer-manager.h b/src/mono/mono/eventpipe/ep-buffer-manager.h new file mode 100644 index 0000000000000..2676114076bf4 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-buffer-manager.h @@ -0,0 +1,69 @@ +#ifndef __EVENTPIPE_BUFFERMANAGER_H__ +#define __EVENTPIPE_BUFFERMANAGER_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventPipeBufferList. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +//TODO: Implement. +struct _EventPipeBufferList { +#else +struct _EventPipeBufferList_Internal { +#endif + uint8_t x; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeBufferList { + uint8_t _internal [sizeof (struct _EventPipeBufferList_Internal)]; +}; +#endif + +/* + * EventPipeBufferManager. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +//TODO: Implement. +struct _EventPipeBufferManager { +#else +struct _EventPipeBufferManager_Internal { +#endif + ep_rt_wait_event_handle_t rt_wait_event; + ep_rt_spin_lock_handle_t rt_lock; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeBufferManager { + uint8_t _internal [sizeof (struct _EventPipeBufferManager_Internal)]; +}; +#endif + +EP_DEFINE_GETTER_REF(EventPipeBufferManager *, buffer_manager, ep_rt_wait_event_handle_t *, rt_wait_event) +EP_DEFINE_GETTER_REF(EventPipeBufferManager *, buffer_manager, ep_rt_spin_lock_handle_t *, rt_lock); + +EventPipeBufferManager * +ep_buffer_manager_alloc ( + EventPipeSession *session, + size_t max_size_of_all_buffers, + size_t sequence_point_allocation_budget); + +void +ep_buffer_manager_free (EventPipeBufferManager *buffer_manager); + +#ifdef EP_CHECKED_BUILD +void +ep_buffer_manager_requires_lock_held (const EventPipeBufferManager *buffer_manager); +#else +#define ep_buffer_manager_requires_lock_held(x) +#endif + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_BUFFERMANAGER_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-buffer.h b/src/mono/mono/eventpipe/ep-buffer.h new file mode 100644 index 0000000000000..cfc5f66c3e193 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-buffer.h @@ -0,0 +1,40 @@ +#ifndef __EVENTPIPE_BUFFER_H__ +#define __EVENTPIPE_BUFFER_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventPipeBuffer. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +//TODO: Implement. +struct _EventPipeBuffer { +#else +struct _EventPipeBuffer_Internal { +#endif + volatile uint32_t state; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeBuffer { + uint8_t _internal [sizeof (struct _EventPipeBuffer_Internal)]; +}; +#endif + +EP_DEFINE_GETTER_REF(EventPipeBuffer *, buffer, volatile uint32_t *, state) + +static +inline +void +ep_buffer_convert_to_read_only (EventPipeBuffer *buffer) +{ + //TODO: Implement. +} + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_BUFFER_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-config-internals.c b/src/mono/mono/eventpipe/ep-config-internals.c new file mode 100644 index 0000000000000..a26d76a7c0ac9 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-config-internals.c @@ -0,0 +1,68 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +EventPipeConfiguration _ep_config = { { 0 }, 0 }; + +/* + * EventPipeEventMetadataEvent. + */ + +EventPipeEventMetadataEvent * +ep_event_metdata_event_alloc ( + EventPipeEvent *ep_event, + uint32_t proc_num, + uint64_t thread_id, + uint8_t *data, + uint32_t data_len, + const uint8_t *activity_id, + const uint8_t *related_activity_id) +{ + EventPipeEventMetadataEvent *instance = ep_rt_object_alloc (EventPipeEventMetadataEvent); + ep_raise_error_if_nok (instance != NULL); + + ep_raise_error_if_nok (ep_event_instance_init ( + &instance->event_instance, + ep_event, + proc_num, + thread_id, + data, + data_len, + activity_id, + related_activity_id) != NULL); + + instance->payload_buffer = data; + instance->payload_buffer_len = data_len; + +ep_on_exit: + return instance; + +ep_on_error: + ep_event_metdata_event_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_event_metdata_event_free (EventPipeEventMetadataEvent *metadata_event) +{ + ep_return_void_if_nok (metadata_event != NULL); + + ep_event_instance_fini (&metadata_event->event_instance); + ep_rt_byte_array_free (metadata_event->payload_buffer); + ep_rt_object_free (metadata_event); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_configuration_internals; +const char quiet_linker_empty_file_warning_eventpipe_configuration_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-config.c b/src/mono/mono/eventpipe/ep-config.c new file mode 100644 index 0000000000000..24b6461adfed0 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-config.c @@ -0,0 +1,553 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#include "ep.h" + +/* + * Forward declares of all static functions. + */ + +static +void +config_compute_keyword_and_level_lock_held ( + const EventPipeConfiguration *config, + const EventPipeProvider *provider, + int64_t *keyword_for_all_sessions, + EventPipeEventLevel *level_for_all_sessions); + +static +bool +config_register_provider_lock_held ( + EventPipeConfiguration *config, + EventPipeProvider *provider, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue); + +static +bool +config_unregister_provider_lock_held ( + EventPipeConfiguration *config, + EventPipeProvider *provider); + +/* + * EventPipeConfiguration. + */ + +static +void +config_compute_keyword_and_level_lock_held ( + const EventPipeConfiguration *config, + const EventPipeProvider *provider, + int64_t *keyword_for_all_sessions, + EventPipeEventLevel *level_for_all_sessions) +{ + ep_rt_config_requires_lock_held (); + EP_ASSERT (provider != NULL); + EP_ASSERT (keyword_for_all_sessions != NULL); + EP_ASSERT (level_for_all_sessions != NULL); + + *keyword_for_all_sessions = 0; + *level_for_all_sessions = EP_EVENT_LEVEL_LOG_ALWAYS; + + for (int i = 0; i < EP_MAX_NUMBER_OF_SESSIONS; i++) { + // Entering EventPipe lock gave us a barrier, we don't need more of them. + EventPipeSession *session = ep_volatile_load_session_without_barrier (i); + if (session) { + EventPipeSessionProviderList *providers = ep_session_get_providers (session); + EP_ASSERT (providers != NULL); + + EventPipeSessionProvider *session_provider = ep_rt_session_provider_list_find_by_name (ep_session_provider_list_get_providers_cref (providers), ep_provider_get_provider_name (provider)); + if (session_provider) { + *keyword_for_all_sessions = *keyword_for_all_sessions | ep_session_provider_get_keywords (session_provider); + *level_for_all_sessions = (ep_session_provider_get_logging_level (session_provider) > *level_for_all_sessions) ? ep_session_provider_get_logging_level (session_provider) : *level_for_all_sessions; + } + } + } + + ep_rt_config_requires_lock_held (); + return; +} + +static +bool +config_register_provider_lock_held ( + EventPipeConfiguration *config, + EventPipeProvider *provider, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue) +{ + ep_rt_config_requires_lock_held (); + EP_ASSERT (config != NULL); + EP_ASSERT (provider != NULL); + + // See if we've already registered this provider. + EventPipeProvider *existing_provider = ep_config_get_provider_lock_held (config, ep_provider_get_provider_name (provider)); + if (existing_provider) + return false; + + // The provider has not been registered, so register it. + ep_rt_provider_list_append (ep_config_get_provider_list_ref (config), provider); + + int64_t keyword_for_all_sessions; + EventPipeEventLevel level_for_all_sessions; + config_compute_keyword_and_level_lock_held (config, provider, &keyword_for_all_sessions, &level_for_all_sessions); + + for (int i = 0; i < EP_MAX_NUMBER_OF_SESSIONS; i++) { + // Entering EventPipe lock gave us a barrier, we don't need more of them. + EventPipeSession *session = ep_volatile_load_session_without_barrier (i); + if (session) { + EventPipeSessionProviderList *providers = ep_session_get_providers (session); + EP_ASSERT (providers != NULL); + + EventPipeSessionProvider *session_provider = ep_rt_session_provider_list_find_by_name (ep_session_provider_list_get_providers_cref (providers), ep_provider_get_provider_name (provider)); + if (session_provider) { + EventPipeProviderCallbackData provider_callback_data; + ep_provider_set_config_lock_held ( + provider, + keyword_for_all_sessions, + level_for_all_sessions, + ((uint64_t)1 << ep_session_get_index (session)), + ep_session_provider_get_keywords (session_provider), + ep_session_provider_get_logging_level (session_provider), + ep_session_provider_get_filter_data (session_provider), + &provider_callback_data); + ep_provider_callback_data_queue_enqueue (provider_callback_data_queue, &provider_callback_data); + } + } + } + + ep_rt_config_requires_lock_held (); + return true; +} + +static +bool +config_unregister_provider_lock_held ( + EventPipeConfiguration *config, + EventPipeProvider *provider) +{ + ep_rt_config_requires_lock_held (); + EP_ASSERT (config != NULL); + + EventPipeProvider *existing_provider = NULL; + ep_rt_provider_list_t *provider_list = ep_config_get_provider_list_ref (config); + + // The provider list should be non-NULL, but can be NULL on shutdown. + if (!ep_rt_provider_list_is_empty (provider_list)) { + // If we found the provider, remove it. + if (ep_rt_provider_list_find (provider_list, provider, &existing_provider)) + ep_rt_provider_list_remove (provider_list, existing_provider); + } + + ep_rt_config_requires_lock_held (); + return (existing_provider != NULL); +} + +EventPipeConfiguration * +ep_config_init (EventPipeConfiguration *config) +{ + ep_rt_config_requires_lock_not_held (); + + ep_return_false_if_nok (config != NULL); + + ep_config_set_config_provider (config, ep_create_provider (ep_config_get_default_provider_name_utf8 (), NULL, NULL)); + ep_raise_error_if_nok (ep_config_get_config_provider (config) != NULL); + + // Create the metadata event. + ep_config_set_metadata_event (config, ep_provider_add_event ( + ep_config_get_config_provider (config), + 0, /* event_id */ + 0, /* keywords */ + 0, /* event_version */ + EP_EVENT_LEVEL_LOG_ALWAYS, + false, /* need_stack */ + NULL, /* meatadata */ + 0)); /* metadata_len */ + ep_raise_error_if_nok (ep_config_get_metadata_event (config) != NULL); + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return config; + +ep_on_error: + ep_config_shutdown (config); + + config = NULL; + ep_exit_error_handler (); +} + +void +ep_config_shutdown (EventPipeConfiguration *config) +{ + ep_rt_config_requires_lock_not_held (); + + ep_event_free (ep_config_get_metadata_event (config)); + ep_config_set_metadata_event (config, NULL); + + ep_delete_provider (ep_config_get_config_provider (config)); + ep_config_set_config_provider (config, NULL); + + // Take the lock before manipulating the list. + EP_CONFIG_LOCK_ENTER + // We don't delete provider itself because it can be in-use + ep_rt_provider_list_free (ep_config_get_provider_list_ref (config), NULL); + EP_CONFIG_LOCK_EXIT + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return; + +ep_on_error: + ep_exit_error_handler (); +} + +EventPipeProvider * +ep_config_create_provider ( + EventPipeConfiguration *config, + const ep_char8_t *provider_name, + EventPipeCallback callback_func, + void *callback_data, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue) +{ + ep_rt_config_requires_lock_not_held (); + + ep_return_null_if_nok (config != NULL && provider_name != NULL); + + EventPipeProvider *provider = NULL; + EP_CONFIG_LOCK_ENTER + provider = ep_config_create_provider_lock_held (config, provider_name, callback_func, callback_data, provider_callback_data_queue); + ep_raise_error_if_nok_holding_lock (provider != NULL); + EP_CONFIG_LOCK_EXIT + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return provider; + +ep_on_error: + ep_config_delete_provider (config, provider); + + provider = NULL; + ep_exit_error_handler (); +} + +void +ep_config_delete_provider ( + EventPipeConfiguration *config, + EventPipeProvider *provider) +{ + ep_rt_config_requires_lock_not_held (); + + ep_return_void_if_nok (config != NULL && provider != NULL); + + EP_CONFIG_LOCK_ENTER + ep_config_delete_provider_lock_held (config, provider); + EP_CONFIG_LOCK_EXIT + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return; + +ep_on_error: + ep_exit_error_handler (); +} + +void +ep_config_enable ( + EventPipeConfiguration *config, + const EventPipeSession *session, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue) +{ + ep_rt_config_requires_lock_not_held (); + + ep_return_void_if_nok (config != NULL && session != NULL); + + EP_CONFIG_LOCK_ENTER + ep_config_enable_disable_lock_held (config, session, provider_callback_data_queue, true); + EP_CONFIG_LOCK_EXIT + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return; + +ep_on_error: + ep_exit_error_handler (); +} + +void +ep_config_disable ( + EventPipeConfiguration *config, + const EventPipeSession *session, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue) +{ + ep_rt_config_requires_lock_not_held (); + + ep_return_void_if_nok (config != NULL && session != NULL); + + EP_CONFIG_LOCK_ENTER + ep_config_enable_disable_lock_held (config, session, provider_callback_data_queue, false); + EP_CONFIG_LOCK_EXIT + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return; + +ep_on_error: + ep_exit_error_handler (); +} + +EventPipeEventMetadataEvent * +ep_config_build_event_metadata_event ( + EventPipeConfiguration *config, + const EventPipeEventInstance *source_instance, + uint32_t metadata_id) +{ + ep_return_null_if_nok (config != NULL && source_instance != NULL); + + // The payload of the event should contain: + // - Metadata ID + // - GUID ProviderID. + // - Optional event description payload. + + uint8_t *instance_payload = NULL; + + // Calculate the size of the event. + EventPipeEvent *source_event = ep_event_instance_get_ep_event (source_instance); + EventPipeProvider *provider = ep_event_get_provider (source_event); + const ep_char16_t *provider_name_utf16 = ep_provider_get_provider_name_utf16 (provider); + const uint8_t *payload_data = ep_event_instance_get_data (source_instance); + uint32_t payload_data_len = ep_event_instance_get_data_len (source_instance); + uint32_t provider_name_len = (ep_rt_utf16_string_len (provider_name_utf16) + 1) * sizeof (ep_char16_t); + uint32_t instance_payload_size = sizeof (metadata_id) + provider_name_len + payload_data_len; + + // Allocate the payload. + instance_payload = ep_rt_byte_array_alloc (instance_payload_size); + ep_raise_error_if_nok (instance_payload != NULL); + + // Fill the buffer with the payload. + uint8_t *current = instance_payload; + + memcpy(current, &metadata_id, sizeof(metadata_id)); + current += sizeof(metadata_id); + + memcpy(current, provider_name_utf16, provider_name_len); + current += provider_name_len; + + // Write the incoming payload data. + memcpy(current, payload_data, payload_data_len); + + // Construct the metadata event instance. + EventPipeEventMetadataEvent *instance = ep_event_metdata_event_alloc ( + ep_config_get_metadata_event (config), + ep_rt_current_processor_get_number (), + ep_rt_current_thread_get_id (), + instance_payload, + instance_payload_size, + NULL /* pActivityId */, + NULL /* pRelatedActivityId */); + + ep_raise_error_if_nok (instance != NULL); + instance_payload = NULL; + + EP_ASSERT (ep_event_get_need_stack (ep_config_get_metadata_event (config)) == false); + + // Set the timestamp to match the source event, because the metadata event + // will be emitted right before the source event. + ep_event_instance_set_timestamp ((EventPipeEventInstance *)instance, ep_event_instance_get_timestamp (source_instance)); + +ep_on_exit: + return instance; + +ep_on_error: + ep_rt_byte_array_free (instance_payload); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_config_delete_deferred_providers (EventPipeConfiguration *config) +{ + ep_rt_config_requires_lock_not_held (); + + ep_return_void_if_nok (config != NULL); + + EP_CONFIG_LOCK_ENTER + ep_config_delete_deferred_providers_lock_held (config); + EP_CONFIG_LOCK_EXIT + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return; + +ep_on_error: + ep_exit_error_handler (); +} + +EventPipeSessionProvider * +ep_config_get_session_provider_lock_held ( + const EventPipeConfiguration *config, + const EventPipeSession *session, + const EventPipeProvider *provider) +{ + ep_rt_config_requires_lock_held (); + + ep_return_null_if_nok (config != NULL && session != NULL); + + EventPipeSessionProvider *existing_provider = ep_session_get_session_provider_lock_held (session, provider); + + ep_rt_config_requires_lock_held (); + return existing_provider; +} + +EventPipeProvider * +ep_config_get_provider_lock_held ( + EventPipeConfiguration *config, + const ep_char8_t *name) +{ + ep_rt_config_requires_lock_held (); + + ep_return_null_if_nok (config != NULL && name != NULL); + + // The provider list should be non-NULL, but can be NULL on shutdown. + ep_return_null_if_nok (ep_rt_provider_list_is_empty (ep_config_get_provider_list_cref (config)) != true); + EventPipeProvider *provider = ep_rt_provider_list_find_by_name (ep_config_get_provider_list_cref (config), name); + + ep_rt_config_requires_lock_held (); + return provider; +} + +EventPipeProvider * +ep_config_create_provider_lock_held ( + EventPipeConfiguration *config, + const ep_char8_t *provider_name, + EventPipeCallback callback_func, + void *callback_data, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue) +{ + ep_rt_config_requires_lock_held (); + + ep_return_null_if_nok (config != NULL && provider_name != NULL); + + EventPipeProvider *provider = ep_provider_alloc (config, provider_name, callback_func, callback_data); + ep_raise_error_if_nok (provider != NULL); + ep_raise_error_if_nok (config_register_provider_lock_held (config, provider, provider_callback_data_queue) == true); + +ep_on_exit: + ep_rt_config_requires_lock_held (); + return provider; + +ep_on_error: + ep_config_delete_provider_lock_held (config, provider); + + provider = NULL; + ep_exit_error_handler (); +} + +void +ep_config_delete_provider_lock_held ( + EventPipeConfiguration *config, + EventPipeProvider *provider) +{ + ep_rt_config_requires_lock_held (); + + ep_return_void_if_nok (config != NULL); + + config_unregister_provider_lock_held (config, provider); + ep_provider_free (provider); + + ep_rt_config_requires_lock_held (); + return; +} + +void +ep_config_delete_deferred_providers_lock_held (EventPipeConfiguration *config) +{ + ep_rt_config_requires_lock_held (); + + ep_return_void_if_nok (config != NULL); + + // The provider list should be non-NULL, but can be NULL on shutdown. + const ep_rt_provider_list_t *provider_list = ep_config_get_provider_list_ref (config); + if (!ep_rt_provider_list_is_empty (provider_list)) { + ep_rt_provider_list_iterator_t iterator; + ep_rt_provider_list_iterator_begin (provider_list, &iterator); + + while (!ep_rt_provider_list_iterator_end (provider_list, &iterator)) { + EventPipeProvider *provider = ep_rt_provider_list_iterator_value (&iterator); + EP_ASSERT (provider != NULL); + + // Get next item before deleting current. + ep_rt_provider_list_iterator_next (provider_list, &iterator); + if (ep_provider_get_delete_deferred (provider)) + ep_config_delete_provider_lock_held (config, provider); + } + } + + ep_rt_config_requires_lock_held (); + return; +} + +void +ep_config_enable_disable_lock_held ( + EventPipeConfiguration *config, + const EventPipeSession *session, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue, + bool enable) +{ + ep_rt_config_requires_lock_held (); + + ep_return_void_if_nok (config != NULL && session != NULL); + + // The provider list should be non-NULL, but can be NULL on shutdown. + const ep_rt_provider_list_t *provider_list = ep_config_get_provider_list_cref (config); + if (!ep_rt_provider_list_is_empty (provider_list)) { + ep_rt_provider_list_iterator_t iterator; + for (ep_rt_provider_list_iterator_begin (provider_list, &iterator); !ep_rt_provider_list_iterator_end (provider_list, &iterator); ep_rt_provider_list_iterator_next (provider_list, &iterator)) { + EventPipeProvider *provider = ep_rt_provider_list_iterator_value (&iterator); + if (provider) { + // Enable/Disable the provider if it has been configured. + EventPipeSessionProvider *session_provider = ep_config_get_session_provider_lock_held (config, session, provider); + if (session_provider) { + int64_t keyword_for_all_sessions; + EventPipeEventLevel level_for_all_sessions; + EventPipeProviderCallbackData provider_callback_data; + config_compute_keyword_and_level_lock_held (config, provider, &keyword_for_all_sessions, &level_for_all_sessions); + if (enable) { + ep_provider_set_config_lock_held ( + provider, + keyword_for_all_sessions, + level_for_all_sessions, + ep_session_get_mask (session), + ep_session_provider_get_keywords (session_provider), + ep_session_provider_get_logging_level (session_provider), + ep_session_provider_get_filter_data (session_provider), + &provider_callback_data); + } else { + ep_provider_unset_config_lock_held ( + provider, + keyword_for_all_sessions, + level_for_all_sessions, + ep_session_get_mask (session), + ep_session_provider_get_keywords (session_provider), + ep_session_provider_get_logging_level (session_provider), + ep_session_provider_get_filter_data (session_provider), + &provider_callback_data); + } + ep_provider_callback_data_queue_enqueue (provider_callback_data_queue, &provider_callback_data); + } + } + } + } + + ep_rt_config_requires_lock_held (); + return; +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_configuration; +const char quiet_linker_empty_file_warning_eventpipe_configuration = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-config.h b/src/mono/mono/eventpipe/ep-config.h new file mode 100644 index 0000000000000..577b78f8643bc --- /dev/null +++ b/src/mono/mono/eventpipe/ep-config.h @@ -0,0 +1,184 @@ +#ifndef __EVENTPIPE_CONFIGURATION_H__ +#define __EVENTPIPE_CONFIGURATION_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventPipeConfiguration. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeConfiguration { +#else +struct _EventPipeConfiguration_Internal { +#endif + ep_rt_provider_list_t provider_list; + EventPipeProvider *config_provider; + EventPipeEvent *metadata_event; + ep_char8_t *config_provider_name; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeConfiguration { + uint8_t _internal [sizeof (struct _EventPipeConfiguration_Internal)]; +}; +#endif + +EP_DEFINE_GETTER_REF(EventPipeConfiguration *, config, ep_rt_provider_list_t *, provider_list) +EP_DEFINE_GETTER(EventPipeConfiguration *, config, EventPipeProvider *, config_provider) +EP_DEFINE_SETTER(EventPipeConfiguration *, config, EventPipeProvider *, config_provider) +EP_DEFINE_GETTER(EventPipeConfiguration *, config, EventPipeEvent *, metadata_event) +EP_DEFINE_SETTER(EventPipeConfiguration *, config, EventPipeEvent *, metadata_event) +EP_DEFINE_GETTER(EventPipeConfiguration *, config, const ep_char8_t *, config_provider_name) + +static +inline +const ep_char8_t * +ep_config_get_default_provider_name_utf8 (void) +{ + return "Microsoft-DotNETCore-EventPipeConfiguration"; +} + +static +inline +const ep_char8_t * +ep_config_get_public_provider_name_utf8 (void) +{ + return "Microsoft-Windows-DotNETRuntime"; +} + +static +inline +const ep_char8_t * +ep_config_get_rundown_provider_name_utf8 (void) +{ + return "Microsoft-Windows-DotNETRuntimeRundown"; +} + +static +inline +EventPipeConfiguration * +ep_config_get (void) +{ + // Singelton. + extern EventPipeConfiguration _ep_config; + return &_ep_config; +} + +EventPipeConfiguration * +ep_config_init (EventPipeConfiguration *config); + +void +ep_config_shutdown (EventPipeConfiguration *config); + +EventPipeProvider * +ep_config_create_provider ( + EventPipeConfiguration *config, + const ep_char8_t *provider_name, + EventPipeCallback callback_func, + void *callback_data, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue); + +void +ep_config_delete_provider ( + EventPipeConfiguration *config, + EventPipeProvider *provider); + +void +ep_config_enable ( + EventPipeConfiguration *config, + const EventPipeSession *session, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue); + +void +ep_config_disable ( + EventPipeConfiguration *config, + const EventPipeSession *session, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue); + +EventPipeEventMetadataEvent * +ep_config_build_event_metadata_event ( + EventPipeConfiguration *config, + const EventPipeEventInstance *source_instance, + uint32_t metadata_id); + +void +ep_config_delete_deferred_providers (EventPipeConfiguration *config); + +EventPipeSessionProvider * +ep_config_get_session_provider_lock_held ( + const EventPipeConfiguration *config, + const EventPipeSession *session, + const EventPipeProvider *provider); + +EventPipeProvider * +ep_config_get_provider_lock_held ( + EventPipeConfiguration *config, + const ep_char8_t *name); + +EventPipeProvider * +ep_config_create_provider_lock_held ( + EventPipeConfiguration *config, + const ep_char8_t *provider_name, + EventPipeCallback callback_func, + void *callback_data, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue); + +void +ep_config_delete_provider_lock_held ( + EventPipeConfiguration *config, + EventPipeProvider *provider); + +void +ep_config_delete_deferred_providers_lock_held (EventPipeConfiguration *config); + +void +ep_config_enable_disable_lock_held ( + EventPipeConfiguration *config, + const EventPipeSession *session, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue, + bool enable); + +/* + * EventPipeEventMetadataEvent. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeEventMetadataEvent { +#else +struct _EventPipeEventMetadataEvent_Internal { +#endif + EventPipeEventInstance event_instance; + uint8_t *payload_buffer; + uint32_t payload_buffer_len; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeEventMetadataEvent { + uint8_t _internal [sizeof (struct _EventPipeEventMetadataEvent_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventPipeEventMetadataEvent *, event_metadata_event, uint8_t *, payload_buffer) +EP_DEFINE_GETTER(EventPipeEventMetadataEvent *, event_instance, uint32_t, payload_buffer_len) + + +EventPipeEventMetadataEvent * +ep_event_metdata_event_alloc ( + EventPipeEvent *ep_event, + uint32_t proc_num, + uint64_t thread_id, + uint8_t *data, + uint32_t data_len, + const uint8_t *activity_id, + const uint8_t *related_activity_id); + +void +ep_event_metdata_event_free (EventPipeEventMetadataEvent *metadata_event); + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_CONFIGURATION_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-event-instance-internals.c b/src/mono/mono/eventpipe/ep-event-instance-internals.c new file mode 100644 index 0000000000000..123675616d8f9 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-event-instance-internals.c @@ -0,0 +1,143 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +/* + * EventPipeEventInstance. + */ + +EventPipeEventInstance * +ep_event_instance_alloc ( + EventPipeEvent *ep_event, + uint32_t proc_num, + uint64_t thread_id, + const uint8_t *data, + uint32_t data_len, + const uint8_t *activity_id, + const uint8_t *related_activity_id) +{ + EventPipeEventInstance *instance = ep_rt_object_alloc (EventPipeEventInstance); + ep_raise_error_if_nok (instance != NULL); + + ep_raise_error_if_nok (ep_event_instance_init ( + instance, + ep_event, + proc_num, + thread_id, + data, + data_len, + activity_id, + related_activity_id) != NULL); + +ep_on_exit: + return instance; + +ep_on_error: + ep_event_instance_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +EventPipeEventInstance * +ep_event_instance_init ( + EventPipeEventInstance *event_instance, + EventPipeEvent *ep_event, + uint32_t proc_num, + uint64_t thread_id, + const uint8_t *data, + uint32_t data_len, + const uint8_t *activity_id, + const uint8_t *related_activity_id) +{ + EP_ASSERT (event_instance != NULL); + ep_return_null_if_nok (ep_event != NULL); + +#ifdef EP_CHECKED_BUILD + event_instance->debug_event_start = 0xDEADBEEF; + event_instance->debug_event_end = 0xCAFEBABE; +#endif + + event_instance->ep_event = ep_event; + event_instance->proc_num = proc_num; + event_instance->thread_id = thread_id; + + if (activity_id) + memcpy (&(event_instance->activity_id), activity_id, EP_ACTIVITY_ID_SIZE); + + if (related_activity_id) + memcpy (&(event_instance->related_activity_id), related_activity_id, EP_ACTIVITY_ID_SIZE); + + event_instance->data = data; + event_instance->data_len = data_len; + + event_instance->timestamp = ep_perf_counter_query (); + EP_ASSERT (event_instance->timestamp > 0); + + ep_event_instance_ensure_consistency (event_instance); + + return event_instance; +} + +void +ep_event_instance_fini (EventPipeEventInstance *ep_event_instance) +{ + ; +} + +void +ep_event_instance_free (EventPipeEventInstance *ep_event_instance) +{ + ep_return_void_if_nok (ep_event_instance != NULL); + + ep_event_instance_fini (ep_event_instance); + ep_rt_object_free (ep_event_instance); +} + +/* + * EventPipeSequencePoint. + */ + +EventPipeSequencePoint * +ep_sequence_point_init (EventPipeSequencePoint *sequence_point) +{ + EP_ASSERT (sequence_point != NULL); + + sequence_point->timestamp = 0; + sequence_point->thread_sequence_numbers.table = NULL; + sequence_point->thread_sequence_numbers.count = 0; + + return sequence_point; +} + +void +ep_sequence_point_fini (EventPipeSequencePoint *sequence_point) +{ + ep_return_void_if_nok (sequence_point != NULL); + + // Each entry in the map owns a ref-count on the corresponding thread + if (sequence_point->thread_sequence_numbers.table) { + ep_rt_thread_sequence_number_hash_map_iterator_t iterator; + for ( + ep_rt_thread_sequence_number_map_iterator_begin (&sequence_point->thread_sequence_numbers, &iterator); + !ep_rt_thread_sequence_number_map_iterator_end (&sequence_point->thread_sequence_numbers, &iterator); + ep_rt_thread_sequence_number_map_iterator_next (&sequence_point->thread_sequence_numbers, &iterator)) { + + EventPipeThreadSessionState *key = ep_rt_thread_sequence_number_map_iterator_key (&iterator); + ep_thread_release (ep_thread_session_state_get_thread (key)); + } + } +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_event_instance_internals; +const char quiet_linker_empty_file_warning_eventpipe_event_instance_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-event-instance.c b/src/mono/mono/eventpipe/ep-event-instance.c new file mode 100644 index 0000000000000..1702b5d922c87 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-event-instance.c @@ -0,0 +1,93 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#include "ep.h" + +/* + * EventPipeEventInstance. + */ + +bool +ep_event_instance_ensure_consistency (const EventPipeEventInstance *ep_event_instance) +{ +#ifdef EP_CHECKED_BUILD + EP_ASSERT (ep_event_instance_get_debug_event_start (ep_event_instance) == 0xDEADBEEF); + EP_ASSERT (ep_event_instance_get_debug_event_end (ep_event_instance) == 0xCAFEBABE); +#endif + + return true; +} + +uint32_t +ep_event_instance_get_aligned_total_size ( + const EventPipeEventInstance *ep_event_instance, + EventPipeSerializationFormat format) +{ + // Calculate the size of the total payload so that it can be written to the file. + uint32_t payload_len = 0; + + if (format == EP_SERIALIZATION_FORMAT_NETPERF_V3) { + payload_len = + // Metadata ID + ep_event_instance_sizeof_metadata_id (ep_event_instance) + + // Thread ID + sizeof (int32_t) + + // TimeStamp + ep_event_instance_sizeof_timestamp (ep_event_instance) + + // Activity ID + EP_ACTIVITY_ID_SIZE + + // Related Activity ID + EP_ACTIVITY_ID_SIZE + + // Data payload length + ep_event_instance_sizeof_data_len (ep_event_instance) + + // Event payload data + ep_event_instance_get_data_len (ep_event_instance) + + // Prepended stack payload size in bytes + sizeof (uint32_t) + + // Stack payload size + ep_stack_contents_get_size (ep_event_instance_get_stack_contents_cref (ep_event_instance)); + } else if (format == EP_SERIALIZATION_FORMAT_NETTRACE_V4) { + payload_len = + // Metadata ID + ep_event_instance_sizeof_metadata_id (ep_event_instance) + + // Sequence number (implied by the buffer containing the event instance) + sizeof (uint32_t) + + // Thread ID + sizeof (int32_t) + + // Capture Thread ID (implied by the buffer containing the event instance) + sizeof (uint64_t) + + // ProcNumber + ep_event_instance_sizeof_proc_num (ep_event_instance) + + // Stack intern table id + sizeof (uint32_t) + + // TimeStamp + ep_event_instance_sizeof_timestamp (ep_event_instance) + + // Activity ID + EP_ACTIVITY_ID_SIZE + + // Related Activity ID + EP_ACTIVITY_ID_SIZE + + // Data payload length + ep_event_instance_sizeof_data_len (ep_event_instance) + + // Event payload data + ep_event_instance_get_data_len (ep_event_instance); + } else { + EP_ASSERT (!"Unrecognized format"); + } + + // round up to FAST_SERIALIZER_ALIGNMENT_SIZE bytes + if (payload_len % FAST_SERIALIZER_ALIGNMENT_SIZE != 0) + payload_len += FAST_SERIALIZER_ALIGNMENT_SIZE - (payload_len % FAST_SERIALIZER_ALIGNMENT_SIZE); + + return payload_len; +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_event_instance; +const char quiet_linker_empty_file_warning_eventpipe_event_instance = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-event-instance.h b/src/mono/mono/eventpipe/ep-event-instance.h new file mode 100644 index 0000000000000..391e7d36f3774 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-event-instance.h @@ -0,0 +1,122 @@ +#ifndef __EVENTPIPE_EVENTINSTANCE_H__ +#define __EVENTPIPE_EVENTINSTANCE_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventPipeEventInstance. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeEventInstance { +#else +struct _EventPipeEventInstance_Internal { +#endif +#ifdef EP_CHECKED_BUILD + uint32_t debug_event_start; + uint32_t debug_event_end; +#endif + EventPipeEvent *ep_event; + uint32_t metadata_id; + uint32_t proc_num; + uint64_t thread_id; + uint64_t timestamp; + uint8_t activity_id [EP_ACTIVITY_ID_SIZE]; + uint8_t related_activity_id [EP_ACTIVITY_ID_SIZE]; + const uint8_t *data; + uint32_t data_len; + EventPipeStackContents stack_contents; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeEventInstance { + uint8_t _internal [sizeof (struct _EventPipeEventInstance_Internal)]; +}; +#endif + +#ifdef EP_CHECKED_BUILD +EP_DEFINE_GETTER(EventPipeEventInstance *, event_instance, uint32_t, debug_event_start) +EP_DEFINE_GETTER(EventPipeEventInstance *, event_instance, uint32_t, debug_event_end) +#endif +EP_DEFINE_GETTER(EventPipeEventInstance *, event_instance, EventPipeEvent *, ep_event) +EP_DEFINE_GETTER(EventPipeEventInstance *, event_instance, uint32_t, metadata_id) +EP_DEFINE_SETTER(EventPipeEventInstance *, event_instance, uint32_t, metadata_id) +EP_DEFINE_GETTER(EventPipeEventInstance *, event_instance, uint32_t, proc_num) +EP_DEFINE_GETTER(EventPipeEventInstance *, event_instance, uint64_t, thread_id) +EP_DEFINE_GETTER(EventPipeEventInstance *, event_instance, uint64_t, timestamp) +EP_DEFINE_SETTER(EventPipeEventInstance *, event_instance, uint64_t, timestamp) +EP_DEFINE_GETTER_ARRAY_REF(EventPipeEventInstance *, event_instance, uint8_t *, const uint8_t *, activity_id, activity_id[0]) +EP_DEFINE_GETTER_ARRAY_REF(EventPipeEventInstance *, event_instance, uint8_t *, const uint8_t *, related_activity_id, related_activity_id[0]) +EP_DEFINE_GETTER(EventPipeEventInstance *, event_instance, const uint8_t *, data) +EP_DEFINE_GETTER(EventPipeEventInstance *, event_instance, uint32_t, data_len) +EP_DEFINE_GETTER_REF(EventPipeEventInstance *, event_instance, EventPipeStackContents *, stack_contents) + +EventPipeEventInstance * +ep_event_instance_alloc ( + EventPipeEvent *ep_event, + uint32_t proc_num, + uint64_t thread_id, + const uint8_t *data, + uint32_t data_len, + const uint8_t *activity_id, + const uint8_t *related_activity_id); + +EventPipeEventInstance * +ep_event_instance_init ( + EventPipeEventInstance *ep_event_instance, + EventPipeEvent *ep_event, + uint32_t proc_num, + uint64_t thread_id, + const uint8_t *data, + uint32_t data_len, + const uint8_t *activity_id, + const uint8_t *related_activity_id); + +void +ep_event_instance_fini (EventPipeEventInstance *ep_event_instance); + +void +ep_event_instance_free (EventPipeEventInstance *ep_event_instance); + +bool +ep_event_instance_ensure_consistency (const EventPipeEventInstance *ep_event_instance); + +uint32_t +ep_event_instance_get_aligned_total_size ( + const EventPipeEventInstance *ep_event_instance, + EventPipeSerializationFormat format); + +/* + * EventPipeSequencePoint. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeSequencePoint { +#else +struct _EventPipeSequencePoint_Internal { +#endif + uint64_t timestamp; + ep_rt_thread_sequence_number_hash_map_t thread_sequence_numbers; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeSequencePoint { + uint8_t _internal [sizeof (struct _EventPipeSequencePoint_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventPipeSequencePoint *, sequence_point, uint64_t, timestamp) +EP_DEFINE_GETTER_REF(EventPipeSequencePoint *, sequence_point, ep_rt_thread_sequence_number_hash_map_t *, thread_sequence_numbers) + +EventPipeSequencePoint * +ep_sequence_point_init (EventPipeSequencePoint *sequence_point); + +void +ep_sequence_point_fini (EventPipeSequencePoint *sequence_point); + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_EVENTINSTANCE_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-event-internals.c b/src/mono/mono/eventpipe/ep-event-internals.c new file mode 100644 index 0000000000000..02c9469d28f59 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-event-internals.c @@ -0,0 +1,111 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +/* + * Forward declares of all static functions. + */ + +static +void +event_build_minimum_metadata ( + EventPipeEvent *ep_event, + uint8_t **metadata, + uint32_t *metadata_len); + +/* + * EventPipeEvent. + */ + +static +void +event_build_minimum_metadata ( + EventPipeEvent *ep_event, + uint8_t **metadata, + uint32_t *metadata_len) +{ + EP_ASSERT (ep_event != NULL); + EP_ASSERT (metadata != NULL); + EP_ASSERT (metadata_len != NULL); + + size_t output_len = 0; + ep_char16_t empty_string [1] = { 0 }; + *metadata = ep_metadata_generator_generate_event_metadata ( + ep_event->event_id, + empty_string, + ep_event->keywords, + ep_event->event_version, + ep_event->level, + NULL, + 0, + &output_len); + + *metadata_len = (uint32_t)output_len; +} + +EventPipeEvent * +ep_event_alloc ( + EventPipeProvider *provider, + uint64_t keywords, + uint32_t event_id, + uint32_t event_version, + EventPipeEventLevel level, + bool need_stack, + const uint8_t *metadata, + uint32_t metadata_len) +{ + ep_return_null_if_nok (provider != NULL); + + EventPipeEvent *instance = ep_rt_object_alloc (EventPipeEvent); + ep_raise_error_if_nok (instance != NULL); + + instance->provider = provider; + instance->keywords = keywords; + instance->event_id = event_id; + instance->event_version = event_version; + instance->level = level; + instance->need_stack = need_stack; + instance->enabled_mask = 0; + + if (metadata != NULL) { + instance->metadata = ep_rt_byte_array_alloc (metadata_len); + ep_raise_error_if_nok (instance->metadata != NULL); + + memcpy (instance->metadata, metadata, metadata_len); + instance->metadata_len = metadata_len; + } else { + // if metadata is not provided, we have to build the minimum version. It's required by the serialization contract. + event_build_minimum_metadata (instance, &(instance->metadata), &(instance->metadata_len)); + } + +ep_on_exit: + return instance; + +ep_on_error: + ep_event_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_event_free (EventPipeEvent *ep_event) +{ + ep_return_void_if_nok (ep_event != NULL); + + ep_rt_byte_array_free (ep_event->metadata); + ep_rt_object_free (ep_event); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_event_internals; +const char quiet_linker_empty_file_warning_eventpipe_event_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-event-payload-internals.c b/src/mono/mono/eventpipe/ep-event-payload-internals.c new file mode 100644 index 0000000000000..1be0b43138e75 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-event-payload-internals.c @@ -0,0 +1,70 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +/* + * EventData. + */ + +EventData * +ep_event_data_alloc ( + uint64_t ptr, + uint32_t size, + uint32_t reserved) +{ + EventData *instance = ep_rt_object_alloc (EventData); + ep_raise_error_if_nok (ep_event_data_init (instance, ptr, size,reserved)); + +ep_on_exit: + return instance; + +ep_on_error: + ep_event_data_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +EventData * +ep_event_data_init ( + EventData *event_data, + uint64_t ptr, + uint32_t size, + uint32_t reserved) +{ + EP_ASSERT (event_data != NULL); + + event_data->ptr = ptr; + event_data->size = size; + event_data->reserved = reserved; + + return event_data; +} + +void +ep_event_data_fini (EventData *event_data) +{ + ; +} + +void +ep_event_data_free (EventData *event_data) +{ + ep_return_void_if_nok (event_data != NULL); + + ep_event_data_fini (event_data); + ep_rt_object_free (event_data); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_event_payload_internals; +const char quiet_linker_empty_file_warning_eventpipe_event_payload_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-event-payload.h b/src/mono/mono/eventpipe/ep-event-payload.h new file mode 100644 index 0000000000000..58532d7b1416a --- /dev/null +++ b/src/mono/mono/eventpipe/ep-event-payload.h @@ -0,0 +1,54 @@ +#ifndef __EVENTPIPE_EVENT_PAYLOAD_H__ +#define __EVENTPIPE_EVENT_PAYLOAD_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventData. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventData { +#else +struct _EventData_Internal { +#endif + uint64_t ptr; + uint32_t size; + uint32_t reserved; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventData { + uint8_t _internal [sizeof (struct _EventData_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventData *, event_data, uint64_t, ptr) +EP_DEFINE_GETTER(EventData *, event_data, uint32_t, size) +EP_DEFINE_GETTER(EventData *, event_data, uint32_t, reserved) + +EventData * +ep_event_data_alloc ( + uint64_t ptr, + uint32_t size, + uint32_t reserved); + +EventData * +ep_event_data_init ( + EventData *event_data, + uint64_t ptr, + uint32_t size, + uint32_t reserved); + +void +ep_event_data_fini (EventData *event_data); + +void +ep_event_data_free (EventData *event_data); + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_EVENT_PAYLOAD_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-event-source-internals.c b/src/mono/mono/eventpipe/ep-event-source-internals.c new file mode 100644 index 0000000000000..e283a37030a34 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-event-source-internals.c @@ -0,0 +1,99 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +/* + * EventPipeEventSource. + */ + +EventPipeEventSource * +ep_event_source_alloc (void) +{ + ep_char16_t *command_line_arg_utf16 = NULL; + ep_char16_t *event_name_utf16 = NULL; + uint8_t *metadata = NULL; + + EventPipeEventSource *instance = ep_rt_object_alloc (EventPipeEventSource); + ep_raise_error_if_nok (instance != NULL); + + instance->provider = ep_create_provider (ep_provider_get_default_name_utf8 (), NULL, NULL); + ep_raise_error_if_nok (instance->provider != NULL); + + // Generate metadata. + EventPipeParameterDesc params [1]; + const uint32_t params_len = EP_ARRAY_SIZE (params); + + command_line_arg_utf16 = ep_rt_utf8_to_utf16_string ("CommandLine", -1); + ep_raise_error_if_nok (command_line_arg_utf16 != NULL); + + ep_parameter_desc_init (params, EP_PARAMETER_TYPE_STRING, command_line_arg_utf16); + + event_name_utf16 = ep_rt_utf8_to_utf16_string ("ProcessInfo", -1); + ep_raise_error_if_nok (event_name_utf16 != NULL); + + size_t metadata_len = 0; + metadata = ep_metadata_generator_generate_event_metadata ( + 1, /* eventID */ + event_name_utf16, + 0, /* keywords */ + 0, /* version */ + EP_EVENT_LEVEL_LOG_ALWAYS, + params, + params_len, + &metadata_len); + + ep_raise_error_if_nok (metadata != NULL); + + // Add the event. + instance->process_info_event = ep_provider_add_event ( + instance->provider, + 1, /* eventID */ + 0, /* keywords */ + 0, /* eventVersion */ + EP_EVENT_LEVEL_LOG_ALWAYS, + false, /* needStack */ + metadata, + (uint32_t)metadata_len); + + ep_raise_error_if_nok (instance->process_info_event); + + // Delete the metadata after the event is created. + // The metadata blob will be copied into EventPipe-owned memory. + ep_rt_byte_array_free (metadata); + + // Delete the strings after the event is created. + // The strings will be copied into EventPipe-owned memory. + ep_rt_utf16_string_free (event_name_utf16); + ep_rt_utf16_string_free (command_line_arg_utf16); + +ep_on_exit: + return instance; + +ep_on_error: + ep_rt_byte_array_free (metadata); + ep_rt_utf16_string_free (event_name_utf16); + ep_rt_utf16_string_free (command_line_arg_utf16); + ep_event_source_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_event_source_free (EventPipeEventSource *event_source) +{ + ep_provider_free (event_source->provider); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_event_source_internals; +const char quiet_linker_empty_file_warning_eventpipe_event_source_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-event-source.c b/src/mono/mono/eventpipe/ep-event-source.c new file mode 100644 index 0000000000000..94b1283e3b414 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-event-source.c @@ -0,0 +1,52 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#include "ep.h" + +/* + * EventPipeEventSource. + */ + +static EventPipeEventSource *event_source_instance; + +void +ep_event_source_enable ( + EventPipeEventSource *event_source, + EventPipeSession *session) +{ + ep_return_void_if_nok (event_source != NULL); + ep_return_void_if_nok (session != NULL); + + EventPipeSessionProvider *session_provider = ep_session_provider_alloc (ep_event_source_get_provider_name (event_source), (uint64_t)-1, EP_EVENT_LEVEL_LOG_ALWAYS, NULL); + if (session_provider != NULL) + ep_session_add_session_provider (session, session_provider); +} + +void +ep_event_source_send_process_info ( + EventPipeEventSource * event_source, + const ep_char16_t *command_line) +{ + ep_return_void_if_nok (event_source != NULL); + + EventData data [1]; + ep_event_data_init (data, (uint64_t)command_line, (uint32_t)((ep_rt_utf16_string_len (command_line) + 1) * sizeof (ep_char16_t)), 0); + ep_write_event (ep_event_source_get_process_info_event (event_source), data, EP_ARRAY_SIZE (data), NULL, NULL); +} + +EventPipeEventSource * +ep_event_source_get (void) +{ + return event_source_instance; +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_event_source; +const char quiet_linker_empty_file_warning_eventpipe_event_source = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-event-source.h b/src/mono/mono/eventpipe/ep-event-source.h new file mode 100644 index 0000000000000..3a2195c27778f --- /dev/null +++ b/src/mono/mono/eventpipe/ep-event-source.h @@ -0,0 +1,51 @@ +#ifndef __EVENTPIPE_EVENT_SOURCE_H__ +#define __EVENTPIPE_EVENT_SOURCE_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventPipeEventSource. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeEventSource { +#else +struct _EventPipeEventSource_Internal { +#endif + const ep_char8_t *provider_name; + EventPipeProvider *provider; + const ep_char8_t *process_info_event_name; + EventPipeEvent *process_info_event; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeEventSource { + uint8_t _internal [sizeof (struct _EventPipeEventSource_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventPipeEventSource *, event_source, const ep_char8_t *, provider_name) +EP_DEFINE_GETTER(EventPipeEventSource *, event_source, const ep_char8_t *, process_info_event_name) +EP_DEFINE_GETTER(EventPipeEventSource *, event_source, EventPipeEvent *, process_info_event) + +EventPipeEventSource * +ep_event_source_alloc (void); + +void +ep_event_source_free (EventPipeEventSource *event_source); + +void +ep_event_source_enable (EventPipeEventSource *event_source, EventPipeSession *session); + +void +ep_event_source_send_process_info (EventPipeEventSource *event_source, const ep_char16_t *command_line); + +EventPipeEventSource * +ep_event_source_get (void); + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_EVENT_SOURCE_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-event.h b/src/mono/mono/eventpipe/ep-event.h new file mode 100644 index 0000000000000..8f0418b638ab9 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-event.h @@ -0,0 +1,64 @@ +#ifndef __EVENTPIPE_EVENT_H__ +#define __EVENTPIPE_EVENT_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventPipeEvent. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeEvent { +#else +struct _EventPipeEvent_Internal { +#endif + EventPipeProvider *provider; + uint64_t keywords; + uint32_t event_id; + uint32_t event_version; + EventPipeEventLevel level; + bool need_stack; + volatile int64_t enabled_mask; + uint8_t *metadata; + uint32_t metadata_len; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeEvent { + uint8_t _internal [sizeof (struct _EventPipeEvent_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventPipeEvent *, event, EventPipeProvider *, provider) +EP_DEFINE_GETTER(EventPipeEvent *, event, uint64_t, keywords) +EP_DEFINE_GETTER(EventPipeEvent *, event, uint32_t, event_id) +EP_DEFINE_GETTER(EventPipeEvent *, event, uint32_t, event_version) +EP_DEFINE_GETTER(EventPipeEvent *, event, EventPipeEventLevel, level) +EP_DEFINE_GETTER(EventPipeEvent *, event, bool, need_stack) +EP_DEFINE_GETTER(EventPipeEvent *, event, int64_t, enabled_mask) +EP_DEFINE_SETTER(EventPipeEvent *, event, int64_t, enabled_mask) +EP_DEFINE_GETTER(EventPipeEvent *, event, uint8_t *, metadata) +EP_DEFINE_SETTER(EventPipeEvent *, event, uint8_t *, metadata) +EP_DEFINE_GETTER(EventPipeEvent *, event, uint32_t, metadata_len) +EP_DEFINE_SETTER(EventPipeEvent *, event, uint32_t, metadata_len) + +EventPipeEvent * +ep_event_alloc ( + EventPipeProvider *provider, + uint64_t keywords, + uint32_t event_id, + uint32_t event_version, + EventPipeEventLevel level, + bool need_stack, + const uint8_t *metadata, + uint32_t metadata_len); + +void +ep_event_free (EventPipeEvent * ep_event); + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_EVENT_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-file-internals.c b/src/mono/mono/eventpipe/ep-file-internals.c new file mode 100644 index 0000000000000..b10351d792ea3 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-file-internals.c @@ -0,0 +1,295 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +/* + * Forward declares of all static functions. + */ + +static +void +file_fast_serialize_func (void *object, FastSerializer *fast_serializer); + +static +const ep_char8_t * +file_get_type_name_func (void *object); + +static +void +file_free_func (void *object); + +static +uint32_t +stack_hash_key_hash_func (const void *key); + +static +bool +stack_hash_key_eq_func (const void *key1, const void *key2); + +static +void +stack_hash_value_free_func (void *entry); + +/* + * EventPipeFile. + */ + +static +void +file_free_func (void *object) +{ + ep_file_free ((EventPipeFile*)object); +} + +static +void +file_fast_serialize_func (void *object, FastSerializer *fast_serializer) +{ + EP_ASSERT (object != NULL && fast_serializer != NULL); + + EventPipeFile *file = (EventPipeFile *)object; + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->file_open_system_time, sizeof (file->file_open_system_time)); + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->file_open_timestamp, sizeof (file->file_open_timestamp)); + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->timestamp_frequency, sizeof (file->timestamp_frequency)); + + // the beginning of V3 + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->pointer_size, sizeof (file->pointer_size)); + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->current_process_id, sizeof (file->current_process_id)); + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->number_of_processors, sizeof (file->number_of_processors)); + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->sampling_rate_in_ns, sizeof (file->sampling_rate_in_ns)); +} + +static +const ep_char8_t * +file_get_type_name_func (void *object) +{ + EP_ASSERT (object != NULL); + return "Trace"; +} + +static +FastSerializableObjectVtable +file_vtable = { + file_free_func, + file_fast_serialize_func, + file_get_type_name_func }; + +static +uint32_t +stack_hash_key_hash_func (const void *key) +{ + EP_ASSERT (key != NULL); + return ((const StackHashKey *)key)->hash; +} + +static +bool +stack_hash_key_eq_func (const void *key1, const void *key2) +{ + EP_ASSERT (key1 != NULL && key2 != NULL); + + const StackHashKey * stack_hash_key1 = (const StackHashKey *)key1; + const StackHashKey * stack_hash_key2 = (const StackHashKey *)key2; + + return stack_hash_key1->stack_size_in_bytes == stack_hash_key2->stack_size_in_bytes && + !memcmp (stack_hash_key1->stack_bytes, stack_hash_key2->stack_bytes, stack_hash_key1->stack_size_in_bytes); +} + +static +void +stack_hash_value_free_func (void *entry) +{ + ep_stack_hash_entry_free ((StackHashEntry *)entry); +} + +static +void +file_write_end (EventPipeFile *file) +{ + EP_ASSERT (file != NULL && ep_file_get_fast_serializer (file) != NULL); + + ep_file_flush (file, EP_FILE_FLUSH_FLAGS_ALL_BLOCKS); + + // "After the last EventBlock is emitted, the stream is ended by emitting a NullReference Tag which indicates that there are no more objects in the stream to read." + // see https://github.com/Microsoft/perfview/blob/master/src/TraceEvent/EventPipe/EventPipeFormat.md for more + ep_fast_serializer_write_tag (ep_file_get_fast_serializer (file), FAST_SERIALIZER_TAGS_NULL_REFERENCE, NULL, 0); +} + +EventPipeFile * +ep_file_alloc ( + StreamWriter *stream_writer, + EventPipeSerializationFormat format) +{ + EventPipeFile *instance = ep_rt_object_alloc (EventPipeFile); + ep_raise_error_if_nok (instance != NULL); + + ep_fast_serializable_object_init ( + &instance->fast_serializable_object, + &file_vtable, + ep_file_get_file_version (format), + ep_file_get_file_minimum_version (format), + format >= EP_SERIALIZATION_FORMAT_NETTRACE_V4); + + instance->stream_writer = stream_writer; + instance->format = format; + + instance->event_block = ep_event_block_alloc (100 * 1024, format); + ep_raise_error_if_nok (instance->event_block != NULL); + + instance->metadata_block = ep_metadata_block_alloc (100 * 1024); + ep_raise_error_if_nok (instance->metadata_block); + + instance->stack_block = ep_stack_block_alloc (100 * 1024); + ep_raise_error_if_nok (instance->stack_block != NULL); + + // File start time information. + instance->file_open_system_time = ep_rt_system_time_get (); + instance->file_open_timestamp = ep_perf_counter_query (); + instance->timestamp_frequency = ep_perf_frequency_query (); + + instance->pointer_size = SIZEOF_VOID_P; + instance->current_process_id = ep_rt_current_process_get_id (); + instance->number_of_processors = ep_rt_processors_get_count (); + + instance->sampling_rate_in_ns = ep_rt_sample_profiler_get_sampling_rate (); + + ep_rt_metadata_labels_alloc (&instance->metadata_ids, NULL, NULL, NULL, NULL); + ep_raise_error_if_nok (instance->metadata_ids.table); + + ep_rt_stack_hash_alloc (&instance->stack_hash, stack_hash_key_hash_func, stack_hash_key_eq_func, NULL, stack_hash_value_free_func); + ep_raise_error_if_nok (instance->stack_hash.table); + + // Start at 0 - The value is always incremented prior to use, so the first ID will be 1. + ep_rt_volatile_store_uint32_t (&instance->metadata_id_counter, 0); + + // Start at 0 - The value is always incremented prior to use, so the first ID will be 1. + instance->stack_id_counter = 0; + +#ifdef EP_CHECKED_BUILD + instance->last_sorted_timestamp = ep_perf_counter_query (); +#endif + +ep_on_exit: + return instance; + +ep_on_error: + ep_file_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_file_free (EventPipeFile *file) +{ + ep_return_void_if_nok (file != NULL); + + if (file->event_block != NULL && file->fast_serializer != NULL) + file_write_end (file); + + ep_event_block_free (file->event_block); + ep_metadata_block_free (file->metadata_block); + ep_stack_block_free (file->stack_block); + ep_fast_serializer_free (file->fast_serializer); + ep_rt_metadata_labels_free (&file->metadata_ids); + ep_rt_stack_hash_free (&file->stack_hash); + + // If there's no fast_serializer, stream_writer ownership + // have not been passed along and needs to be freed by file. + if (!file->fast_serializer) + ep_stream_writer_free_vcall (file->stream_writer); + + ep_fast_serializable_object_fini (&file->fast_serializable_object); + ep_rt_object_free (file); +} + +/* + * StackHashEntry. + */ + +StackHashEntry * +ep_stack_hash_entry_alloc ( + const EventPipeStackContents *stack_contents, + uint32_t id, + uint32_t hash) +{ + ep_return_null_if_nok (stack_contents != NULL); + + uint32_t stack_size = ep_stack_contents_get_size (stack_contents); + StackHashEntry *entry = (StackHashEntry *)ep_rt_byte_array_alloc (offsetof (StackHashEntry, stack_bytes) + stack_size); + ep_raise_error_if_nok (entry != NULL); + + entry->id = id; + entry->key.hash = hash; + entry->key.stack_size_in_bytes = stack_size; + entry->key.stack_bytes = entry->stack_bytes; + memcpy (entry->stack_bytes, ep_stack_contents_get_pointer (stack_contents), stack_size); + +ep_on_exit: + return entry; + +ep_on_error: + ep_stack_hash_entry_free (entry); + + entry = NULL; + ep_exit_error_handler (); +} + +void +ep_stack_hash_entry_free (StackHashEntry *stack_hash_entry) +{ + ep_return_void_if_nok (stack_hash_entry != NULL); + ep_rt_byte_array_free ((uint8_t *)stack_hash_entry); +} + +/* + * StackHashKey. + */ + +static +inline +uint32_t +hash_bytes (const uint8_t *data, size_t data_len) +{ + EP_ASSERT (data != NULL); + + uint32_t hash = 5381; + const uint8_t *data_end = data + data_len; + for (/**/ ; data < data_end; data++) + hash = ((hash << 5) + hash) ^ *data; + return hash; +} + +StackHashKey * +ep_stack_hash_key_init ( + StackHashKey *key, + const EventPipeStackContents *stack_contents) +{ + EP_ASSERT (key != NULL); + ep_return_null_if_nok (stack_contents != NULL); + + key->stack_bytes = ep_stack_contents_get_pointer (stack_contents); + key->stack_size_in_bytes = ep_stack_contents_get_size (stack_contents); + key->hash = hash_bytes (key->stack_bytes, key->stack_size_in_bytes); + + return key; +} + +void +ep_stack_hash_key_fini (StackHashKey *key) +{ + ; +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_file_internals; +const char quiet_linker_empty_file_warning_eventpipe_file_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-file.c b/src/mono/mono/eventpipe/ep-file.c new file mode 100644 index 0000000000000..e16acabc0b0d2 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-file.c @@ -0,0 +1,331 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#include "ep.h" + +/* + * Forward declares of all static functions. + */ + +static +uint32_t +file_get_stack_id ( + EventPipeFile *file, + EventPipeEventInstance *event_instance); + +static +uint32_t +file_generate_metadata_id (EventPipeFile *file); + +static +uint32_t +file_get_metadata_id ( + EventPipeFile *file, + EventPipeEvent *ep_event); + +static +void +file_write_event_to_block ( + EventPipeFile *file, + EventPipeEventInstance *event_instance, + uint32_t metadata_id, + uint64_t capture_thread_id, + uint32_t sequence_number, + uint32_t stack_id, + bool is_sotred_event); + +static +void +file_save_metadata_id ( + EventPipeFile *file, + EventPipeEvent *ep_event, + uint32_t metadata_id); + +/* + * EventPipeFile. + */ + +static +uint32_t +file_get_stack_id ( + EventPipeFile *file, + EventPipeEventInstance * event_instance) +{ + EP_ASSERT (file != NULL && event_instance != NULL); + EP_ASSERT (ep_file_get_format (file) >= EP_SERIALIZATION_FORMAT_NETTRACE_V4); + EP_ASSERT (ep_file_get_stack_block (file) != NULL); + + uint32_t stack_id = 0; + EventPipeStackContents *stack_contents = ep_event_instance_get_stack_contents_ref (event_instance); + EventPipeStackBlock *stack_block = ep_file_get_stack_block (file); + ep_rt_stack_hash_map_t *stack_hash = ep_file_get_stack_hash_ref (file); + StackHashEntry *entry = NULL; + StackHashKey key; + ep_stack_hash_key_init (&key, stack_contents); + if (!ep_rt_stack_hash_lookup (stack_hash, &key, &entry)) { + stack_id = ep_file_get_stack_id_counter (file) + 1; + ep_file_set_stack_id_counter (file, stack_id); + entry = ep_stack_hash_entry_alloc (stack_contents, stack_id, ep_stack_hash_key_get_hash (&key)); + if (entry) + ep_rt_stack_hash_add (stack_hash, ep_stack_hash_entry_get_key_ref (entry), entry); + + if (!ep_stack_block_write_stack (stack_block, stack_id, stack_contents)) { + // we can't write this stack to the current block (it's full) + // so we write what we have in the block to the serializer + ep_file_flush (file, EP_FILE_FLUSH_FLAGS_STACK_BLOCK); + bool result = ep_stack_block_write_stack (stack_block, stack_id, stack_contents); + EP_ASSERT (result == true); // we should never fail to add event to a clear block (if we do the max size is too small) + } + } else { + stack_id = ep_stack_hash_entry_get_id (entry); + } + + ep_stack_hash_key_fini (&key); + return stack_id; +} + +static +uint32_t +file_get_metadata_id ( + EventPipeFile *file, + EventPipeEvent *ep_event) +{ + EP_ASSERT (file != NULL && ep_event != NULL); + EP_ASSERT (ep_file_get_metadata_ids_cref (file) != NULL); + + uint32_t metadata_ids; + if (ep_rt_metadata_labels_lookup (ep_file_get_metadata_ids_cref (file), ep_event, &metadata_ids)) { + EP_ASSERT (metadata_ids != 0); + return metadata_ids; + } + + return 0; +} + +static +uint32_t +file_generate_metadata_id (EventPipeFile *file) +{ + return ep_rt_atomic_inc_uint32_t (ep_file_get_metadata_id_counter_ref (file)); +} + +static +void +file_write_event_to_block ( + EventPipeFile *file, + EventPipeEventInstance *event_instance, + uint32_t metadata_id, + uint64_t capture_thread_id, + uint32_t sequence_number, + uint32_t stack_id, + bool is_sotred_event) +{ + EP_ASSERT (file != NULL && event_instance != NULL); + EP_ASSERT (ep_file_get_event_block (file) != NULL); + EP_ASSERT (ep_file_get_metadata_block (file) != NULL); + + ep_event_instance_set_metadata_id (event_instance, metadata_id); + + // If we are flushing events we need to flush metadata and stacks as well + // to ensure referenced metadata/stacks were written to the file before the + // event which referenced them. + EventPipeFileFlushFlags flags = EP_FILE_FLUSH_FLAGS_ALL_BLOCKS; + EventPipeEventBlockBase *block = (EventPipeEventBlockBase *)ep_file_get_event_block (file); + if(metadata_id == 0 && ep_file_get_format (file) >= EP_SERIALIZATION_FORMAT_NETTRACE_V4) { + flags = EP_FILE_FLUSH_FLAGS_METADATA_BLOCK; + block = (EventPipeEventBlockBase *)ep_file_get_metadata_block (file); + } + + if (ep_event_block_base_write_event (block, event_instance, capture_thread_id, sequence_number, stack_id, is_sotred_event)) + return; // the block is not full, we added the event and continue + + // we can't write this event to the current block (it's full) + // so we write what we have in the block to the serializer + ep_file_flush (file, flags); + + bool result = ep_event_block_base_write_event (block, event_instance, capture_thread_id, sequence_number, stack_id, is_sotred_event); + EP_ASSERT (result == true); // we should never fail to add event to a clear block (if we do the max size is too small) +} + +static +void +file_save_metadata_id ( + EventPipeFile *file, + EventPipeEvent *ep_event, + uint32_t metadata_id) +{ + EP_ASSERT (file != NULL && ep_event != NULL); + EP_ASSERT (metadata_id > 0); + EP_ASSERT (ep_file_get_metadata_ids_cref (file) != NULL); + + // If a pre-existing metadata label exists, remove it. + uint32_t old_id; + if (ep_rt_metadata_labels_lookup (ep_file_get_metadata_ids_cref (file), ep_event, &old_id)) + ep_rt_metadata_labels_remove (ep_file_get_metadata_ids_ref (file), ep_event); + + // Add the metadata label. + ep_rt_metadata_labels_add (ep_file_get_metadata_ids_ref (file), ep_event, metadata_id); +} + +bool +ep_file_initialize_file (EventPipeFile *file) +{ + ep_return_false_if_nok (file != NULL); + + EP_ASSERT (ep_file_get_stream_writer (file) != NULL); + EP_ASSERT (ep_file_get_fast_serializer (file) == NULL); + + bool success = true; + if (ep_file_get_format (file) >= EP_SERIALIZATION_FORMAT_NETTRACE_V4) { + const ep_char8_t header[] = "Nettrace"; + const uint32_t bytes_to_write = EP_ARRAY_SIZE (header) - 1; + uint32_t bytes_written = 0; + success = ep_stream_writer_write (ep_file_get_stream_writer (file), (const uint8_t *)header, bytes_to_write, &bytes_written) && bytes_written == bytes_to_write; + } + + if (success) { + // Create the file stream and write the FastSerialization header. + ep_file_set_fast_serializer (file, ep_fast_serializer_alloc (ep_file_get_stream_writer (file))); + + // Write the first object to the file. + if (ep_file_get_fast_serializer (file)) + ep_fast_serializer_write_object (ep_file_get_fast_serializer (file), (FastSerializableObject *)file); + } + + return success; +} + +void +ep_file_write_event ( + EventPipeFile *file, + EventPipeEventInstance *event_instance, + uint64_t capture_thread_id, + uint32_t sequence_number, + bool is_sorted_event) +{ + ep_return_void_if_nok (file != NULL && event_instance != NULL); + EP_ASSERT (ep_file_get_fast_serializer (file) != NULL); + + EventPipeEventMetadataEvent *metadata_instance = NULL; + +#ifdef EP_CHECKED_BUILD + EP_ASSERT (ep_event_instance_get_timestamp (event_instance) >= ep_file_get_last_sorted_timestamp (file)); + if (is_sorted_event) + ep_file_set_last_sorted_timestamp (file, ep_event_instance_get_timestamp (event_instance)); +#endif + + uint32_t stack_id = 0; + if (ep_file_get_format (file) >= EP_SERIALIZATION_FORMAT_NETTRACE_V4) + stack_id = file_get_stack_id (file, event_instance); + + // Check to see if we've seen this event type before. + // If not, then write the event metadata to the event stream first. + unsigned int metadata_id = file_get_metadata_id (file, ep_event_instance_get_ep_event (event_instance)); + if(metadata_id == 0) { + metadata_id = file_generate_metadata_id (file); + + metadata_instance = ep_build_event_metadata_event (event_instance, metadata_id); + ep_raise_error_if_nok (metadata_instance != NULL); + + file_write_event_to_block (file, (EventPipeEventInstance *)metadata_instance, 0, 0, 0, 0, true); // metadataId=0 breaks recursion and represents the metadata event. + file_save_metadata_id (file, ep_event_instance_get_ep_event (event_instance), metadata_id); + } + + file_write_event_to_block (file, event_instance, metadata_id, capture_thread_id, sequence_number, stack_id, is_sorted_event); + +ep_on_exit: + ep_event_metdata_event_free (metadata_instance); + return; + +ep_on_error: + ep_exit_error_handler (); +} + +void +ep_file_write_sequence_point ( + EventPipeFile *file, + EventPipeSequencePoint *sequence_point) +{ + ep_return_void_if_nok (file != NULL && sequence_point != NULL); + EP_ASSERT (ep_file_get_fast_serializer (file) != NULL); + + if (ep_file_get_format (file) < EP_SERIALIZATION_FORMAT_NETTRACE_V4) + return; // sequence points aren't used in NetPerf format + + ep_file_flush (file, EP_FILE_FLUSH_FLAGS_ALL_BLOCKS); + EventPipeSequencePointBlock sequence_point_block; + + ep_sequence_point_block_init (&sequence_point_block, sequence_point); + ep_fast_serializer_write_object (ep_file_get_fast_serializer (file), (FastSerializableObject *)&sequence_point_block); + ep_sequence_point_block_fini (&sequence_point_block); + + // stack cache resets on sequence points + ep_file_set_stack_id_counter (file, 0); + ep_rt_stack_hash_remove_all (ep_file_get_stack_hash_ref (file)); +} + +void +ep_file_flush ( + EventPipeFile *file, + EventPipeFileFlushFlags flags) +{ + // Write existing buffer to the stream/file regardless of whether it is full or not. + ep_return_void_if_nok (file != NULL && ep_file_get_fast_serializer (file) != NULL && ep_file_get_metadata_block (file) != NULL && + ep_file_get_stack_block (file) != NULL && ep_file_get_event_block (file) != NULL); + + if ((ep_metadata_block_get_bytes_written (ep_file_get_metadata_block (file)) != 0) && ((flags & EP_FILE_FLUSH_FLAGS_METADATA_BLOCK) != 0)) { + EP_ASSERT (ep_file_get_format (file) >= EP_SERIALIZATION_FORMAT_NETTRACE_V4); + ep_metadata_block_serialize (ep_file_get_metadata_block (file), ep_file_get_fast_serializer (file)); + ep_metadata_block_clear (ep_file_get_metadata_block (file)); + } + + if ((ep_stack_block_get_bytes_written (ep_file_get_stack_block (file)) != 0) && ((flags & EP_FILE_FLUSH_FLAGS_STACK_BLOCK) != 0)) { + EP_ASSERT (ep_file_get_format (file) >= EP_SERIALIZATION_FORMAT_NETTRACE_V4); + ep_stack_block_serialize (ep_file_get_stack_block (file), ep_file_get_fast_serializer (file)); + ep_stack_block_clear (ep_file_get_stack_block (file)); + } + + if ((ep_event_block_get_bytes_written (ep_file_get_event_block (file)) != 0) && ((flags & EP_FILE_FLUSH_FLAGS_EVENT_BLOCK) != 0)) { + ep_event_block_serialize (ep_file_get_event_block (file), ep_file_get_fast_serializer (file)); + ep_event_block_clear (ep_file_get_event_block (file)); + } +} + +int32_t +ep_file_get_file_version (EventPipeSerializationFormat format) +{ + switch (format) { + case EP_SERIALIZATION_FORMAT_NETPERF_V3 : + return 3; + case EP_SERIALIZATION_FORMAT_NETTRACE_V4 : + return 4; + default : + EP_ASSERT (!"Unrecognized EventPipeSerializationFormat"); + return 0; + } +} + +int32_t +ep_file_get_file_minimum_version (EventPipeSerializationFormat format) +{ + switch (format) { + case EP_SERIALIZATION_FORMAT_NETPERF_V3 : + return 0; + case EP_SERIALIZATION_FORMAT_NETTRACE_V4 : + return 4; + default : + EP_ASSERT (!"Unrecognized EventPipeSerializationFormat"); + return 0; + } +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_file; +const char quiet_linker_empty_file_warning_eventpipe_file = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-file.h b/src/mono/mono/eventpipe/ep-file.h new file mode 100644 index 0000000000000..7c78e405e9464 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-file.h @@ -0,0 +1,164 @@ +#ifndef __EVENTPIPE_FILE_H__ +#define __EVENTPIPE_FILE_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventPipeFile. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeFile { +#else +struct _EventPipeFile_Internal { +#endif + FastSerializableObject fast_serializable_object; + StreamWriter *stream_writer; + FastSerializer *fast_serializer; + EventPipeEventBlock *event_block; + EventPipeMetadataBlock *metadata_block; + EventPipeStackBlock *stack_block; + ep_rt_metadata_labels_hash_map_t metadata_ids; + ep_rt_stack_hash_map_t stack_hash; + uint64_t file_open_system_time; + uint64_t file_open_timestamp; + uint64_t timestamp_frequency; +#ifdef EP_CHECKED_BUILD + uint64_t last_sorted_timestamp; +#endif + uint32_t pointer_size; + uint32_t current_process_id; + uint32_t number_of_processors; + uint32_t sampling_rate_in_ns; + uint32_t stack_id_counter; + volatile uint32_t metadata_id_counter; + EventPipeSerializationFormat format; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeFile { + uint8_t _internal [sizeof (struct _EventPipeFile_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventPipeFile *, file, StreamWriter *, stream_writer) +EP_DEFINE_GETTER(EventPipeFile *, file, FastSerializer *, fast_serializer) +EP_DEFINE_SETTER(EventPipeFile *, file, FastSerializer *, fast_serializer) +EP_DEFINE_GETTER(EventPipeFile *, file, EventPipeEventBlock *, event_block) +EP_DEFINE_GETTER(EventPipeFile *, file, EventPipeMetadataBlock *, metadata_block) +EP_DEFINE_GETTER_REF(EventPipeFile *, file, ep_rt_metadata_labels_hash_map_t *, metadata_ids) +EP_DEFINE_GETTER_REF(EventPipeFile *, file, ep_rt_stack_hash_map_t *, stack_hash) +EP_DEFINE_GETTER(EventPipeFile *, file, EventPipeStackBlock *, stack_block) +EP_DEFINE_GETTER(EventPipeFile *, file, EventPipeSerializationFormat, format) +EP_DEFINE_GETTER(EventPipeFile *, file, uint32_t, stack_id_counter); +EP_DEFINE_SETTER(EventPipeFile *, file, uint32_t, stack_id_counter); +EP_DEFINE_GETTER_REF(EventPipeFile *, file, volatile uint32_t *, metadata_id_counter) +#ifdef EP_CHECKED_BUILD +EP_DEFINE_GETTER(EventPipeFile *, file, uint64_t, last_sorted_timestamp) +EP_DEFINE_SETTER(EventPipeFile *, file, uint64_t, last_sorted_timestamp) +#endif + +EventPipeFile * +ep_file_alloc ( + StreamWriter *stream_writer, + EventPipeSerializationFormat format); + +void +ep_file_free (EventPipeFile *file); + +bool +ep_file_initialize_file (EventPipeFile *file); + +void +ep_file_write_event ( + EventPipeFile *file, + EventPipeEventInstance * event_instance, + uint64_t capture_thread_id, + uint32_t sequence_number, + bool is_sorted_event); + +void +ep_file_write_sequence_point ( + EventPipeFile *file, + EventPipeSequencePoint *sequence_point); + +void +ep_file_flush ( + EventPipeFile *file, + EventPipeFileFlushFlags flags); + +int32_t +ep_file_get_file_version (EventPipeSerializationFormat format); + +int32_t +ep_file_get_file_minimum_version (EventPipeSerializationFormat format); + +/* + * StackHashKey. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _StackHashKey { +#else +struct _StackHashKey_Internal { +#endif + uint8_t *stack_bytes; + uint32_t hash; + uint32_t stack_size_in_bytes; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _StackHashKey { + uint8_t _internal [sizeof (struct _StackHashKey_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(StackHashKey *, stack_hash_key, uint32_t, hash) + +StackHashKey * +ep_stack_hash_key_init ( + StackHashKey *key, + const EventPipeStackContents *stack_contents); + +void +ep_stack_hash_key_fini (StackHashKey *key); + +/* + * StackHashEntry. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _StackHashEntry { +#else +struct _StackHashEntry_Internal { +#endif + StackHashKey key; + uint32_t id; + // This is the first byte of StackSizeInBytes bytes of stack data + uint8_t stack_bytes[1]; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _StackHashEntry { + uint8_t _internal [sizeof (struct _StackHashEntry_Internal)]; +}; +#endif + +EP_DEFINE_GETTER_REF(StackHashEntry *, stack_hash_entry, StackHashKey *, key) +EP_DEFINE_GETTER(StackHashEntry *, stack_hash_entry, uint32_t, id) + +StackHashEntry * +ep_stack_hash_entry_alloc ( + const EventPipeStackContents *stack_contents, + uint32_t id, + uint32_t hash); + +void +ep_stack_hash_entry_free (StackHashEntry *stack_hash_entry); + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_FILE_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-internals.c b/src/mono/mono/eventpipe/ep-internals.c new file mode 100644 index 0000000000000..58bc70df0e89b --- /dev/null +++ b/src/mono/mono/eventpipe/ep-internals.c @@ -0,0 +1,242 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" + +#ifndef EP_INLINE_GETTER_SETTER +#define EP_IMPL_GETTER_SETTER +#define EP_DEFINE_GETTER(instance_type, instance_type_name, return_type, instance_field_name) \ + return_type ep_ ## instance_type_name ## _get_ ## instance_field_name (const instance_type instance) { return instance-> instance_field_name; } \ + size_t ep_ ## instance_type_name ## _sizeof_ ## instance_field_name (const instance_type instance) { return sizeof (instance-> instance_field_name); } +#define EP_DEFINE_GETTER_REF(instance_type, instance_type_name, return_type, instance_field_name) \ + return_type ep_ ## instance_type_name ## _get_ ## instance_field_name ## _ref (instance_type instance) { return &(instance-> instance_field_name); } \ + const return_type ep_ ## instance_type_name ## _get_ ## instance_field_name ## _cref (const instance_type instance) { return &(instance-> instance_field_name); } +#define EP_DEFINE_GETTER_ARRAY_REF(instance_type, instance_type_name, return_type, const_return_type, instance_field_name, instance_field) \ + return_type ep_ ## instance_type_name ## _get_ ## instance_field_name ## _ref (instance_type instance) { return &(instance-> instance_field); } \ + const_return_type ep_ ## instance_type_name ## _get_ ## instance_field_name ## _cref (const instance_type instance) { return &(instance-> instance_field); } +#define EP_DEFINE_SETTER(instance_type, instance_type_name, instance_field_type, instance_field_name) \ + void ep_ ## instance_type_name ## _set_ ## instance_field_name (instance_type instance, instance_field_type instance_field_name) { instance-> instance_field_name = instance_field_name; } +#endif + +#include "ep.h" + +// Option to include all internal source files into ep-internals.c. +#ifdef EP_INCLUDE_SOURCE_FILES +#define EP_FORCE_INCLUDE_SOURCE_FILES +#include "ep-block-internals.c" +#include "ep-buffer-manager-internals.c" +#include "ep-config-internals.c" +#include "ep-event-internals.c" +#include "ep-event-instance-internals.c" +#include "ep-event-payload-internals.c" +#include "ep-event-source-internals.c" +#include "ep-file-internals.c" +#include "ep-metadata-generator-internals.c" +#include "ep-provider-internals.c" +#include "ep-session-internals.c" +#include "ep-session-provider-internals.c" +#include "ep-stream-internals.c" +#include "ep-thread-internals.c" +#endif + +/* + * EventFilterDescriptor. + */ + +EventFilterDescriptor * +ep_event_filter_desc_alloc ( + uint64_t ptr, + uint32_t size, + uint32_t type) +{ + EventFilterDescriptor *instance = ep_rt_object_alloc (EventFilterDescriptor); + ep_raise_error_if_nok (ep_event_filter_desc_init (instance, ptr, size, type) != NULL); + +ep_on_exit: + return instance; + +ep_on_error: + ep_event_filter_desc_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +EventFilterDescriptor * +ep_event_filter_desc_init ( + EventFilterDescriptor *event_filter_desc, + uint64_t ptr, + uint32_t size, + uint32_t type) +{ + EP_ASSERT (event_filter_desc != NULL); + + event_filter_desc->ptr = ptr; + event_filter_desc->size = size; + event_filter_desc->type = type; + + return event_filter_desc; +} + +void +ep_event_filter_desc_fini (EventFilterDescriptor * filter_desc) +{ + ; +} + +void +ep_event_filter_desc_free (EventFilterDescriptor * filter_desc) +{ + ep_return_void_if_nok (filter_desc != NULL); + + ep_event_filter_desc_fini (filter_desc); + ep_rt_object_free (filter_desc); +} + +/* + * EventPipeProviderCallbackDataQueue. + */ + +EventPipeProviderCallbackDataQueue * +ep_provider_callback_data_queue_init (EventPipeProviderCallbackDataQueue *provider_callback_data_queue) +{ + ep_return_null_if_nok (provider_callback_data_queue != NULL); + ep_rt_provider_callback_data_queue_alloc (&provider_callback_data_queue->queue); + return provider_callback_data_queue; +} + +void +ep_provider_callback_data_queue_fini (EventPipeProviderCallbackDataQueue *provider_callback_data_queue) +{ + ep_return_void_if_nok (provider_callback_data_queue != NULL); + ep_rt_provider_callback_data_queue_free (&provider_callback_data_queue->queue); +} + +/* + * EventPipeProviderCallbackData. + */ + +EventPipeProviderCallbackData * +ep_provider_callback_data_alloc ( + const ep_char8_t *filter_data, + EventPipeCallback callback_function, + void *callback_data, + int64_t keywords, + EventPipeEventLevel provider_level, + bool enabled) +{ + EventPipeProviderCallbackData *instance = ep_rt_object_alloc (EventPipeProviderCallbackData); + ep_raise_error_if_nok (instance != NULL); + + ep_raise_error_if_nok (ep_provider_callback_data_init ( + instance, + filter_data, + callback_function, + callback_data, + keywords, + provider_level, + enabled) != NULL); + +ep_on_exit: + return instance; + +ep_on_error: + instance = NULL; + ep_exit_error_handler (); +} + +EventPipeProviderCallbackData * +ep_provider_callback_data_alloc_copy (EventPipeProviderCallbackData *provider_callback_data_src) +{ + EventPipeProviderCallbackData *instance = ep_rt_object_alloc (EventPipeProviderCallbackData); + ep_raise_error_if_nok (instance != NULL); + + if (provider_callback_data_src) + *instance = *provider_callback_data_src; + +ep_on_exit: + return instance; + +ep_on_error: + instance = NULL; + ep_exit_error_handler (); +} + +EventPipeProviderCallbackData * +ep_provider_callback_data_init ( + EventPipeProviderCallbackData *provider_callback_data, + const ep_char8_t *filter_data, + EventPipeCallback callback_function, + void *callback_data, + int64_t keywords, + EventPipeEventLevel provider_level, + bool enabled) +{ + ep_return_null_if_nok (provider_callback_data != NULL); + + provider_callback_data->filter_data = filter_data; + provider_callback_data->callback_function = callback_function; + provider_callback_data->callback_data = callback_data; + provider_callback_data->keywords = keywords; + provider_callback_data->provider_level = provider_level; + provider_callback_data->enabled = enabled; + + return provider_callback_data; +} + +EventPipeProviderCallbackData * +ep_provider_callback_data_init_copy ( + EventPipeProviderCallbackData *provider_callback_data_dst, + EventPipeProviderCallbackData *provider_callback_data_src) +{ + ep_return_null_if_nok (provider_callback_data_dst != NULL && provider_callback_data_src != NULL); + *provider_callback_data_dst = *provider_callback_data_src; + return provider_callback_data_dst; +} + +void +ep_provider_callback_data_fini (EventPipeProviderCallbackData *provider_callback_data) +{ + ; +} + +void +ep_provider_callback_data_free (EventPipeProviderCallbackData *provider_callback_data) +{ + ep_return_void_if_nok (provider_callback_data != NULL); + ep_rt_object_free (provider_callback_data); +} + +/* + * EventPipeProviderConfiguration. + */ + +EventPipeProviderConfiguration * +ep_provider_config_init ( + EventPipeProviderConfiguration *provider_config, + const ep_char8_t *provider_name, + uint64_t keywords, + uint32_t logging_level, + const ep_char8_t *filter_data) +{ + EP_ASSERT (provider_config != NULL); + ep_return_null_if_nok (provider_name != NULL); + + provider_config->provider_name = provider_name; + provider_config->keywords = keywords; + provider_config->logging_level = logging_level; + provider_config->filter_data = filter_data; + + return provider_config; +} + +void +ep_provider_config_fini (EventPipeProviderConfiguration *provider_config) +{ + ; +} + +#endif /* ENABLE_PERFTRACING */ + +extern const char quiet_linker_empty_file_warning_eventpipe_internals; +const char quiet_linker_empty_file_warning_eventpipe_internals = 0; diff --git a/src/mono/mono/eventpipe/ep-metadata-generator-internals.c b/src/mono/mono/eventpipe/ep-metadata-generator-internals.c new file mode 100644 index 0000000000000..e2c8e76421d16 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-metadata-generator-internals.c @@ -0,0 +1,40 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +/* + * EventPipeParameterDesc. + */ + +EventPipeParameterDesc * +ep_parameter_desc_init ( + EventPipeParameterDesc *parameter_desc, + EventPipeParameterType type, + const ep_char16_t *name) +{ + EP_ASSERT (parameter_desc != NULL); + + parameter_desc->type = type; + parameter_desc->name = name; + + return parameter_desc; +} + +void +ep_parameter_desc_fini (EventPipeParameterDesc *parameter_desc) +{ + ; +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_metadata_generator_internals; +const char quiet_linker_empty_file_warning_eventpipe_metadata_generator_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-metadata-generator.c b/src/mono/mono/eventpipe/ep-metadata-generator.c new file mode 100644 index 0000000000000..4fd80356e9649 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-metadata-generator.c @@ -0,0 +1,106 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#include "ep.h" + +/* + * EventPipeMetadataGenerator. + */ + +uint8_t * +ep_metadata_generator_generate_event_metadata ( + uint32_t event_id, + const ep_char16_t *event_name, + uint64_t keywords, + uint32_t version, + EventPipeEventLevel level, + EventPipeParameterDesc *params, + uint32_t params_len, + size_t *metadata_len) +{ + ep_return_null_if_nok (event_name != NULL); + ep_return_null_if_nok (params_len == 0 || params != NULL); + ep_return_null_if_nok (metadata_len != NULL); + + // The order of fields is defined in coreclr\src\mscorlib\shared\System\Diagnostics\Tracing\EventSource.cs DefineEventPipeEvents method + // eventID : 4 bytes + // eventName : (eventName.Length + 1) * 2 bytes + // keywords : 8 bytes + // eventVersion : 4 bytes + // level : 4 bytes + // parameterCount : 4 bytes + size_t event_name_len = ep_rt_utf16_string_len (event_name); + *metadata_len = 24 + ((event_name_len + 1) * sizeof (ep_char16_t)); + + // Each parameter has a 4 byte TypeCode + (parameterName.Length + 1) * 2 bytes. + for (uint32_t i = 0; i < params_len; ++i) { + EP_ASSERT (ep_parameter_desc_get_name (¶ms [i]) != NULL); + *metadata_len += (4 + ((ep_rt_utf16_string_len (ep_parameter_desc_get_name (¶ms [i])) + 1) * sizeof (ep_char16_t))); + } + + // Allocate a metadata blob. + uint8_t *buffer = ep_rt_byte_array_alloc (*metadata_len); + ep_raise_error_if_nok (buffer != NULL); + + uint8_t * current = buffer; + + // Write the event ID. + memcpy (current, &event_id, sizeof (event_id)); + current += sizeof (event_id); + + // Write the event name. + memcpy (current, event_name, (event_name_len + 1) * sizeof (ep_char16_t)); + current += (event_name_len + 1) * sizeof (ep_char16_t); + + // Write the keywords. + memcpy (current, &keywords, sizeof (keywords)); + current += sizeof (keywords); + + // Write the version. + memcpy (current, &version, sizeof (version)); + current += sizeof (version); + + // Write the level. + memcpy (current, &level, sizeof (level)); + current += sizeof (level); + + // Write the parameter count. + memcpy(current, ¶ms_len, sizeof (params_len)); + current += sizeof (params_len); + + // Write the parameter descriptions. + for (uint32_t i = 0; i < params_len; ++i) { + EventPipeParameterType const param_type = ep_parameter_desc_get_type (¶ms [i]); + const ep_char16_t *const param_name = ep_parameter_desc_get_name (¶ms [i]); + size_t const param_name_len = ep_rt_utf16_string_len (param_name); + + memcpy (current, ¶m_type, sizeof (param_type)); + current += sizeof (param_type); + + memcpy (current, param_name, (param_name_len + 1) * sizeof (ep_char16_t)); + current += (param_name_len + 1) * sizeof (ep_char16_t); + } + + EP_ASSERT (*metadata_len == (size_t)(current - buffer)); + +ep_on_exit: + return buffer; + +ep_on_error: + ep_rt_byte_array_free (buffer); + *metadata_len = 0; + + buffer = NULL; + ep_exit_error_handler (); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_metadata_generator; +const char quiet_linker_empty_file_warning_eventpipe_metadata_generator = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-metadata-generator.h b/src/mono/mono/eventpipe/ep-metadata-generator.h new file mode 100644 index 0000000000000..5f1d90a7ca27b --- /dev/null +++ b/src/mono/mono/eventpipe/ep-metadata-generator.h @@ -0,0 +1,57 @@ +#ifndef __EVENTPIPE_METADATA_GENERATOR_H__ +#define __EVENTPIPE_METADATA_GENERATOR_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventPipeMetadataGenerator. + */ + +uint8_t * +ep_metadata_generator_generate_event_metadata ( + uint32_t event_id, + const ep_char16_t *event_name, + uint64_t keywords, + uint32_t version, + EventPipeEventLevel level, + EventPipeParameterDesc *params, + uint32_t params_len, + size_t *metadata_len); + +/* + * EventPipeParameterDesc. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeParameterDesc { +#else +struct _EventPipeParameterDesc_Internal { +#endif + EventPipeParameterType type; + const ep_char16_t *name; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeParameterDesc { + uint8_t _internal [sizeof (struct _EventPipeParameterDesc_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventPipeParameterDesc *, parameter_desc, EventPipeParameterType, type) +EP_DEFINE_GETTER(EventPipeParameterDesc *, parameter_desc, const ep_char16_t *, name) + +EventPipeParameterDesc * +ep_parameter_desc_init ( + EventPipeParameterDesc *parameter_desc, + EventPipeParameterType type, + const ep_char16_t *name); + +void +ep_parameter_desc_fini (EventPipeParameterDesc *parameter_desc); + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_METADATA_GENERATOR_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-provider-internals.c b/src/mono/mono/eventpipe/ep-provider-internals.c new file mode 100644 index 0000000000000..a93197ae76663 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-provider-internals.c @@ -0,0 +1,86 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +/* + * Forward declares of all static functions. + */ + +static +void +event_free_func (void *ep_event); + +/* + * EventPipeProvider. + */ + +static +void +event_free_func (void *ep_event) +{ + ep_event_free ((EventPipeEvent *)ep_event); +} + +EventPipeProvider * +ep_provider_alloc ( + EventPipeConfiguration *config, + const ep_char8_t *provider_name, + EventPipeCallback callback_func, + void *callback_data) +{ + ep_return_false_if_nok (config != NULL && provider_name != NULL); + + EventPipeProvider *instance = ep_rt_object_alloc (EventPipeProvider); + ep_raise_error_if_nok (instance != NULL); + + instance->provider_name = ep_rt_utf8_string_dup (provider_name); + ep_raise_error_if_nok (instance->provider_name != NULL); + + instance->provider_name_utf16 = ep_rt_utf8_to_utf16_string (provider_name, ep_rt_utf8_string_len (provider_name)); + ep_raise_error_if_nok (instance->provider_name_utf16 != NULL); + + instance->keywords = 0; + instance->provider_level = EP_EVENT_LEVEL_CRITICAL; + instance->callback_func = callback_func; + instance->callback_data = callback_data; + instance->config = config; + instance->delete_deferred = false; + instance->sessions = 0; + +ep_on_exit: + return instance; + +ep_on_error: + ep_provider_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_provider_free (EventPipeProvider * provider) +{ + ep_return_void_if_nok (provider != NULL); + + //TODO: CoreCLR takes the lock before manipulating the list, but since complete object is + // going away and list is only owned by provider, meaning that if we had a race related + // to the list, it will crash anyways once lock is released and list is gone. + ep_rt_event_list_free (&provider->event_list, event_free_func); + + ep_rt_utf16_string_free (provider->provider_name_utf16); + ep_rt_utf8_string_free (provider->provider_name); + ep_rt_object_free (provider); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_provider_internals; +const char quiet_linker_empty_file_warning_eventpipe_provider_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-provider.c b/src/mono/mono/eventpipe/ep-provider.c new file mode 100644 index 0000000000000..5e87cfbf7619d --- /dev/null +++ b/src/mono/mono/eventpipe/ep-provider.c @@ -0,0 +1,317 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#include "ep.h" + +/* + * Forward declares of all static functions. + */ + +static +const EventPipeProviderCallbackData * +provider_prepare_callback_data ( + EventPipeProvider *provider, + int64_t keywords, + EventPipeEventLevel provider_level, + const ep_char8_t *filter_data, + EventPipeProviderCallbackData *provider_callback_data); + +static +void +provider_refresh_all_events (EventPipeProvider *provider); + +static +void +provider_refresh_event_state_lock_held (EventPipeEvent *ep_event); + +static +int64_t +provider_compute_event_enable_mask_lock_held ( + const EventPipeConfiguration *config, + const EventPipeProvider *provider, + int64_t keywords, + EventPipeEventLevel event_level); + +/* + * EventPipeProvider. + */ + +static +const EventPipeProviderCallbackData * +provider_prepare_callback_data ( + EventPipeProvider *provider, + int64_t keywords, + EventPipeEventLevel provider_level, + const ep_char8_t *filter_data, + EventPipeProviderCallbackData *provider_callback_data) +{ + EP_ASSERT (provider != NULL && provider_callback_data != NULL); + + return ep_provider_callback_data_init ( + provider_callback_data, + filter_data, + ep_provider_get_callback_func (provider), + ep_provider_get_callback_data (provider), + keywords, + provider_level, + (ep_provider_get_sessions (provider) != 0)); +} + +static +void +provider_refresh_all_events (EventPipeProvider *provider) +{ + EP_ASSERT (provider != NULL); + ep_rt_config_requires_lock_held (); + + const ep_rt_event_list_t *event_list = ep_provider_get_event_list_cref (provider); + EP_ASSERT (event_list != NULL); + + ep_rt_event_list_iterator_t iterator; + for (ep_rt_event_list_iterator_begin (event_list, &iterator); !ep_rt_provider_list_iterator_end (event_list, &iterator); ep_rt_provider_list_iterator_next (event_list, &iterator)) + provider_refresh_event_state_lock_held(ep_rt_event_list_iterator_value (&iterator)); + + ep_rt_config_requires_lock_held (); + return; +} + +static +void +provider_refresh_event_state_lock_held (EventPipeEvent *ep_event) +{ + ep_rt_config_requires_lock_held (); + EP_ASSERT (ep_event != NULL); + + EventPipeProvider *provider = ep_event_get_provider (ep_event); + EP_ASSERT (provider != NULL); + + EventPipeConfiguration *config = ep_provider_get_config (provider); + EP_ASSERT (config != NULL); + + int64_t enable_mask = provider_compute_event_enable_mask_lock_held (config, provider, ep_event_get_keywords (ep_event), ep_event_get_level (ep_event)); + ep_event_set_enabled_mask (ep_event, enable_mask); + + ep_rt_config_requires_lock_held (); + return; +} + +static +int64_t +provider_compute_event_enable_mask_lock_held ( + const EventPipeConfiguration *config, + const EventPipeProvider *provider, + int64_t keywords, + EventPipeEventLevel event_level) +{ + ep_rt_config_requires_lock_held (); + EP_ASSERT (provider != NULL); + + int64_t result = 0; + bool provider_enabled = ep_provider_get_enabled (provider); + for (int i = 0; i < EP_MAX_NUMBER_OF_SESSIONS; i++) { + // Entering EventPipe lock gave us a barrier, we don't need more of them. + EventPipeSession *session = ep_volatile_load_session_without_barrier (i); + if (session) { + EventPipeSessionProvider *session_provider = ep_config_get_session_provider_lock_held (config, session, provider); + if (session_provider) { + int64_t session_keyword = ep_session_provider_get_keywords (session_provider); + EventPipeEventLevel session_level = ep_session_provider_get_logging_level (session_provider); + // The event is enabled if: + // - The provider is enabled. + // - The event keywords are unspecified in the manifest (== 0) or when masked with the enabled config are != 0. + // - The event level is LogAlways or the provider's verbosity level is set to greater than the event's verbosity level in the manifest. + bool keyword_enabled = (keywords == 0) || ((session_keyword & keywords) != 0); + bool level_enabled = ((event_level == EP_EVENT_LEVEL_LOG_ALWAYS) || (session_level >= event_level)); + if (provider_enabled && keyword_enabled && level_enabled) + result = result | ep_session_get_mask (session); + } + } + } + + ep_rt_config_requires_lock_held (); + return result; +} + +EventPipeEvent * +ep_provider_add_event ( + EventPipeProvider *provider, + uint32_t event_id, + uint64_t keywords, + uint32_t event_version, + EventPipeEventLevel level, + bool need_stack, + const uint8_t *metadata, + uint32_t metadata_len) +{ + ep_rt_config_requires_lock_not_held (); + + ep_return_null_if_nok (provider != NULL); + + EventPipeEvent *instance = ep_event_alloc ( + provider, + keywords, + event_id, + event_version, + level, + need_stack, + metadata, + metadata_len); + + ep_return_null_if_nok (instance != NULL); + + // Take the config lock before inserting a new event. + EP_CONFIG_LOCK_ENTER + ep_rt_event_list_append (ep_provider_get_event_list_ref (provider), instance); + provider_refresh_event_state_lock_held (instance); + EP_CONFIG_LOCK_EXIT + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return instance; + +ep_on_error: + instance = NULL; + ep_exit_error_handler (); +} + +const EventPipeProviderCallbackData * +ep_provider_set_config_lock_held ( + EventPipeProvider *provider, + int64_t keywords_for_all_sessions, + EventPipeEventLevel level_for_all_sessions, + uint64_t session_mask, + int64_t keywords, + EventPipeEventLevel level, + const ep_char8_t *filter_data, + EventPipeProviderCallbackData *callback_data) +{ + ep_rt_config_requires_lock_held (); + + ep_return_null_if_nok (provider != NULL); + + EP_ASSERT ((ep_provider_get_sessions (provider) & session_mask) == 0); + ep_provider_set_sessions (provider, (ep_provider_get_sessions (provider) | session_mask)); + ep_provider_set_keywords (provider, keywords_for_all_sessions); + ep_provider_set_provider_level (provider, level_for_all_sessions); + + provider_refresh_all_events (provider); + provider_prepare_callback_data (provider, ep_provider_get_keywords (provider), ep_provider_get_provider_level (provider), filter_data, callback_data); + + ep_rt_config_requires_lock_held (); + return callback_data; +} + +const EventPipeProviderCallbackData * +ep_provider_unset_config_lock_held ( + EventPipeProvider *provider, + int64_t keywords_for_all_sessions, + EventPipeEventLevel level_for_all_sessions, + uint64_t session_mask, + int64_t keywords, + EventPipeEventLevel level, + const ep_char8_t *filter_data, + EventPipeProviderCallbackData *callback_data) +{ + ep_rt_config_requires_lock_held (); + + ep_return_null_if_nok (provider != NULL); + + EP_ASSERT ((ep_provider_get_sessions (provider) & session_mask) != 0); + if (ep_provider_get_sessions (provider) & session_mask) + ep_provider_set_sessions (provider, (ep_provider_get_sessions (provider) & ~session_mask)); + + ep_provider_set_keywords (provider, keywords_for_all_sessions); + ep_provider_set_provider_level (provider, level_for_all_sessions); + + provider_refresh_all_events (provider); + provider_prepare_callback_data (provider, ep_provider_get_keywords (provider), ep_provider_get_provider_level (provider), filter_data, callback_data); + + ep_rt_config_requires_lock_held (); + return callback_data; +} + +void +ep_provider_invoke_callback (EventPipeProviderCallbackData *provider_callback_data) +{ + // Lock should not be held when invoking callback. + ep_rt_config_requires_lock_not_held (); + + ep_return_void_if_nok (provider_callback_data != NULL); + + const ep_char8_t *filter_data = ep_provider_callback_data_get_filter_data (provider_callback_data); + EventPipeCallback callback_function = ep_provider_callback_data_get_callback_function (provider_callback_data); + bool enabled = ep_provider_callback_data_get_enabled (provider_callback_data); + int64_t keywords = ep_provider_callback_data_get_keywords (provider_callback_data); + EventPipeEventLevel provider_level = ep_provider_callback_data_get_provider_level (provider_callback_data); + void *callback_data = ep_provider_callback_data_get_callback_data (provider_callback_data); + + bool is_event_filter_desc_init = false; + EventFilterDescriptor event_filter_desc; + uint8_t *buffer = NULL; + + if (filter_data) { + // The callback is expecting that filter data to be a concatenated list + // of pairs of null terminated strings. The first member of the pair is + // the key and the second is the value. + // To convert to this format we need to convert all '=' and ';' + // characters to '\0', except when in a quoted string. + const uint32_t filter_data_len = ep_rt_utf8_string_len (filter_data); + uint32_t buffer_size = filter_data_len + 1; + + buffer = ep_rt_byte_array_alloc (buffer_size); + ep_raise_error_if_nok (buffer != NULL); + + bool is_quoted_value = false; + uint32_t j = 0; + + for (uint32_t i = 0; i < buffer_size; ++i) { + // if a value is a quoted string, leave the quotes out from the destination + // and don't replace `=` or `;` characters until leaving the quoted section + // e.g., key="a;value=";foo=bar --> { key\0a;value=\0foo\0bar\0 } + if (filter_data [i] == '"') { + is_quoted_value = !is_quoted_value; + continue; + } + buffer [j++] = ((filter_data [i] == '=' || filter_data [i] == ';') && !is_quoted_value) ? '\0' : filter_data [i]; + } + + // In case we skipped over quotes in the filter string, shrink the buffer size accordingly + if (j < filter_data_len) + buffer_size = j + 1; + + ep_event_filter_desc_init (&event_filter_desc, (uint64_t)buffer, buffer_size, 0); + is_event_filter_desc_init = true; + } + + if (callback_function && !ep_rt_process_detach ()) { + (*callback_function)( + NULL, /* provider_id */ + enabled ? 1 : 0, + (uint8_t)provider_level, + (uint64_t)keywords, + 0, /* match_all_keywords */ + is_event_filter_desc_init ? &event_filter_desc : NULL, + callback_data /* CallbackContext */); + } + +ep_on_exit: + if (is_event_filter_desc_init) + ep_event_filter_desc_fini (&event_filter_desc); + + ep_rt_byte_array_free (buffer); + return; + +ep_on_error: + ep_exit_error_handler (); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_provider; +const char quiet_linker_empty_file_warning_eventpipe_provider = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-provider.h b/src/mono/mono/eventpipe/ep-provider.h new file mode 100644 index 0000000000000..3d95ec8122382 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-provider.h @@ -0,0 +1,123 @@ +#ifndef __EVENTPIPE_PROVIDER_H__ +#define __EVENTPIPE_PROVIDER_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventPipeProvider. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeProvider { +#else +struct _EventPipeProvider_Internal { +#endif + ep_char8_t *provider_name; + ep_char16_t *provider_name_utf16; + int64_t keywords; + EventPipeEventLevel provider_level; + ep_rt_event_list_t event_list; + EventPipeCallback callback_func; + void *callback_data; + EventPipeConfiguration *config; + bool delete_deferred; + uint64_t sessions; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeProvider { + uint8_t _internal [sizeof (struct _EventPipeProvider_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventPipeProvider *, provider, const ep_char8_t *, provider_name) +EP_DEFINE_GETTER(EventPipeProvider *, provider, const ep_char16_t *, provider_name_utf16) +EP_DEFINE_GETTER(EventPipeProvider *, provider, uint64_t, keywords) +EP_DEFINE_SETTER(EventPipeProvider *, provider, uint64_t, keywords) +EP_DEFINE_GETTER(EventPipeProvider *, provider, EventPipeEventLevel, provider_level) +EP_DEFINE_SETTER(EventPipeProvider *, provider, EventPipeEventLevel, provider_level) +EP_DEFINE_GETTER_REF(EventPipeProvider *, provider, ep_rt_event_list_t *, event_list) +EP_DEFINE_GETTER(EventPipeProvider *, provider, EventPipeCallback, callback_func) +EP_DEFINE_GETTER(EventPipeProvider *, provider, void *, callback_data) +EP_DEFINE_GETTER(EventPipeProvider *, provider, EventPipeConfiguration *, config) +EP_DEFINE_GETTER(EventPipeProvider *, provider, bool, delete_deferred) +EP_DEFINE_SETTER(EventPipeProvider *, provider, bool, delete_deferred) +EP_DEFINE_GETTER(EventPipeProvider *, provider, uint64_t, sessions) +EP_DEFINE_SETTER(EventPipeProvider *, provider, uint64_t, sessions) + +static +inline +bool +ep_provider_get_enabled (const EventPipeProvider *provider) +{ + return ep_provider_get_sessions (provider) != 0; +} + +static +inline +const ep_char8_t * +ep_provider_get_wildcard_name_utf8 (void) +{ + return "*"; +} + +static +inline +const ep_char8_t * +ep_provider_get_default_name_utf8 (void) +{ + return "Microsoft-DotNETCore-EventPipe"; +} + +EventPipeProvider * +ep_provider_alloc ( + EventPipeConfiguration *config, + const ep_char8_t *provider_name, + EventPipeCallback callback_func, + void *callback_data); + +void +ep_provider_free (EventPipeProvider * provider); + +EventPipeEvent * +ep_provider_add_event ( + EventPipeProvider *provider, + uint32_t event_id, + uint64_t keywords, + uint32_t event_version, + EventPipeEventLevel level, + bool need_stack, + const uint8_t *metadata, + uint32_t metadata_len); + +const EventPipeProviderCallbackData * +ep_provider_set_config_lock_held ( + EventPipeProvider *provider, + int64_t keywords_for_all_sessions, + EventPipeEventLevel level_for_all_sessions, + uint64_t session_mask, + int64_t keywords, + EventPipeEventLevel level, + const ep_char8_t *filter_data, + EventPipeProviderCallbackData *callback_data); + +const EventPipeProviderCallbackData * +ep_provider_unset_config_lock_held ( + EventPipeProvider *provider, + int64_t keywords_for_all_sessions, + EventPipeEventLevel level_for_all_sessions, + uint64_t session_mask, + int64_t keywords, + EventPipeEventLevel level, + const ep_char8_t *filter_data, + EventPipeProviderCallbackData *callback_data); + +void +ep_provider_invoke_callback (EventPipeProviderCallbackData *provider_callback_data); + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_PROVIDER_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-rt-config-mono.h b/src/mono/mono/eventpipe/ep-rt-config-mono.h new file mode 100644 index 0000000000000..0e5eb527c2f78 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-rt-config-mono.h @@ -0,0 +1,7 @@ +#ifndef __EVENTPIPE_RT_CONFIG_MONO_H__ +#define __EVENTPIPE_RT_CONFIG_MONO_H__ + +#include +#define EP_RT_MONO_USE_STATIC_RUNTIME + +#endif /* __EVENTPIPE_RT_CONFIG_MONO_H__ */ diff --git a/src/mono/mono/eventpipe/ep-rt-config.h b/src/mono/mono/eventpipe/ep-rt-config.h new file mode 100644 index 0000000000000..5c1499ca72c89 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-rt-config.h @@ -0,0 +1,9 @@ +#ifndef __EVENTPIPE_RT_CONFIG_H__ +#define __EVENTPIPE_RT_CONFIG_H__ + +#include "ep-rt-config-mono.h" + +#define EP_INLINE_GETTER_SETTER +#define EP_INCLUDE_SOURCE_FILES + +#endif /* __EVENTPIPE_RT_CONFIG_H__ */ diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c new file mode 100644 index 0000000000000..26d3df4a2fda6 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -0,0 +1,14 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" + +#include "ep.h" + +ep_rt_spin_lock_handle_t _ep_rt_mono_config_lock = {0}; +EventPipeMonoFuncTable _ep_rt_mono_func_table = {0}; + +#endif /* ENABLE_PERFTRACING */ + +extern const char quiet_linker_empty_file_warning_eventpipe_rt_mono; +const char quiet_linker_empty_file_warning_eventpipe_rt_mono = 0; diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h new file mode 100644 index 0000000000000..8bcb8a1b39505 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -0,0 +1,1108 @@ +// Implementation of ep-rt.h targeting Mono runtime. +#ifndef __EVENTPIPE_RT_MONO_H__ +#define __EVENTPIPE_RT_MONO_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "ep.h" + +#undef EP_ARRAY_SIZE +#define EP_ARRAY_SIZE(expr) G_N_ELEMENTS(expr) + +#undef EP_INFINITE_WAIT +#define EP_INFINITE_WAIT MONO_INFINITE_WAIT + +//TODO: Should make sure block is executed in safe mode. +#undef EP_GCX_PREEMP_ENTER +#define EP_GCX_PREEMP_ENTER { + +//TODO: Should make sure block is returned back to previous mode. +#undef EP_GCX_PREEMP_EXIT +#define EP_GCX_PREEMP_EXIT } + +#define EP_RT_DEFINE_LIST(list_name, list_type, item_type) \ + static inline void ep_rt_ ## list_name ## _free (list_type *list, void (*callback)(void *)) { \ + for (GSList *l = list->list; l; l = l->next) { \ + if (callback != NULL) \ + callback (l->data); \ + } \ + g_slist_free (list->list); \ + list->list = NULL; \ + } \ + static inline void ep_rt_ ## list_name ## _clear (list_type *list, void (*callback)(void *)) { ep_rt_ ## list_name ## _free (list, callback); } \ + static inline void ep_rt_ ## list_name ## _append (list_type *list, item_type item) { list->list = g_slist_append (list->list, ((gpointer)(gsize)item)); } \ + static inline void ep_rt_ ## list_name ## _remove (list_type *list, const item_type item) { list->list = g_slist_remove (list->list, ((gconstpointer)(const gsize)item)); } \ + static inline bool ep_rt_ ## list_name ## _find (const list_type *list, const item_type item_to_find, item_type *found_item) { \ + GSList *found_glist_item = g_slist_find (list->list, ((gconstpointer)(const gsize)item_to_find)); \ + *found_item = (found_glist_item != NULL) ? ((item_type)(gsize)(found_glist_item->data)) : ((item_type)(gsize)NULL); \ + return *found_item != NULL; \ + } \ + static inline bool ep_rt_ ## list_name ## _is_empty (const list_type *list) { return list->list == NULL; } + +#define EP_RT_DEFINE_LIST_ITERATOR(list_name, list_type, iterator_type, item_type) \ + static inline void ep_rt_ ## list_name ## _iterator_begin (const list_type *list, iterator_type *iterator) { iterator->iterator = list->list; } \ + static inline bool ep_rt_ ## list_name ## _iterator_end (const list_type *list, const iterator_type *iterator) { return iterator->iterator == NULL; } \ + static inline void ep_rt_ ## list_name ## _iterator_next (const list_type *list, iterator_type *iterator) { iterator->iterator = iterator->iterator->next; } \ + static inline item_type ep_rt_ ## list_name ## _iterator_value (const iterator_type *iterator) { return ((item_type)(gsize)(iterator->iterator->data)); } + +#define EP_RT_DEFINE_QUEUE(queue_name, queue_type, item_type) \ + static inline void ep_rt_ ## queue_name ## _alloc (queue_type *queue) { \ + queue->queue = g_queue_new ();\ + } \ + static inline void ep_rt_ ## queue_name ## _free (queue_type *queue) { \ + g_queue_free (queue->queue); \ + queue->queue = NULL; \ + } \ + static inline void ep_rt_ ## queue_name ## _pop_head (queue_type *queue, item_type *item) { \ + *item = ((item_type)(gsize)g_queue_pop_head (queue->queue)); \ + } \ + static inline void ep_rt_ ## queue_name ## _push_head (queue_type *queue, item_type item) { \ + g_queue_push_head (queue->queue, ((gpointer)(gsize)item)); \ + } \ + static inline void ep_rt_ ## queue_name ## _push_tail (queue_type *queue, item_type item) { \ + g_queue_push_tail (queue->queue, ((gpointer)(gsize)item)); \ + } \ + static inline bool ep_rt_ ## queue_name ## _is_empty (const queue_type *queue) { \ + return g_queue_is_empty (queue->queue); \ + } + +#define EP_RT_DEFINE_HASH_MAP(hash_map_name, hash_map_type, key_type, value_type) \ + static inline void ep_rt_ ## hash_map_name ## _alloc (hash_map_type *hash_map, uint32_t (*hash_callback)(const void *), bool (*eq_callback)(const void *, const void *), void (*key_free_callback)(void *), void (*value_free_callback)(void *)) { \ + hash_map->table = g_hash_table_new_full ((GHashFunc)hash_callback, (GEqualFunc)eq_callback, (GDestroyNotify)key_free_callback, (GDestroyNotify)value_free_callback); \ + hash_map->count = 0;\ + } \ + static inline void ep_rt_ ## hash_map_name ## _free (hash_map_type *hash_map) { \ + g_hash_table_destroy (hash_map->table); \ + hash_map->table = NULL; \ + hash_map->count = 0; \ + } \ + static inline void ep_rt_ ## hash_map_name ## _add (hash_map_type *hash_map, key_type key, value_type value) { \ + g_hash_table_replace (hash_map->table, (gpointer)key, ((gpointer)(gsize)value)); \ + hash_map->count++; \ + } \ + static inline void ep_rt_ ## hash_map_name ## _remove (hash_map_type *hash_map, const key_type key) { \ + if (g_hash_table_remove (hash_map->table, (gconstpointer)key)) \ + hash_map->count--; \ + } \ + static inline void ep_rt_ ## hash_map_name ## _remove_all (hash_map_type *hash_map) { \ + g_hash_table_remove_all (hash_map->table); \ + hash_map->count = 0; \ + } \ + static inline bool ep_rt_ ## hash_map_name ## _lookup (const hash_map_type *hash_map, const key_type key, value_type *value) { \ + gpointer _value = NULL; \ + bool result = g_hash_table_lookup_extended (hash_map->table, (gconstpointer)key, NULL, &_value); \ + *value = ((value_type)(gsize)_value); \ + return result; \ + } \ + static inline uint32_t ep_rt_ ## hash_map_name ## _count (const hash_map_type *hash_map) { \ + return hash_map->count; \ + } + +#define EP_RT_DEFINE_HASH_MAP_ITERATOR(hash_map_name, hash_map_type, iterator_type, key_type, value_type) \ + static inline void ep_rt_ ## hash_map_name ## _iterator_begin (const hash_map_type *hash_map, iterator_type *iterator) { \ + g_hash_table_iter_init (&iterator->iterator, hash_map->table); \ + if (hash_map->table) \ + iterator->end = g_hash_table_iter_next (&iterator->iterator, &iterator->key, &iterator->value); \ + else \ + iterator->end = true; \ + } \ + static inline bool ep_rt_ ## hash_map_name ## _iterator_end (const hash_map_type *hash_map, const iterator_type *iterator) { \ + return iterator->end; \ + } \ + static inline void ep_rt_ ## hash_map_name ## _iterator_next (const hash_map_type *hash_map, iterator_type *iterator) { \ + iterator->end = g_hash_table_iter_next (&iterator->iterator, &iterator->key, &iterator->value); \ + } \ + static inline key_type ep_rt_ ## hash_map_name ## _iterator_key (const iterator_type *iterator) { \ + return ((key_type)(gsize)iterator->key); \ + } \ + static inline value_type ep_rt_ ## hash_map_name ## _iterator_value (const iterator_type *iterator) { \ + return ((value_type)(gsize)iterator->value); \ + } + +typedef gint64 (*ep_rt_mono_100ns_ticks_func)(void); +typedef gint64 (*ep_rt_mono_100ns_datetime_func)(void); +typedef int (*ep_rt_mono_cpu_count_func)(void); +typedef int (*ep_rt_mono_process_current_pid_func)(void); +typedef MonoNativeThreadId (*ep_rt_mono_native_thread_id_get_func)(void); +typedef gboolean (*ep_rt_mono_native_thread_id_equals_func)(MonoNativeThreadId, MonoNativeThreadId); +typedef mono_bool (*ep_rt_mono_runtime_is_shutting_down_func)(void); +typedef gboolean (*ep_rt_mono_rand_try_get_bytes_func)(guchar *buffer, gssize buffer_size, MonoError *error); +typedef EventPipeThread * (*ep_rt_mono_thread_get_func)(void); +typedef EventPipeThread * (*ep_rt_mono_thread_get_or_create_func)(void); +typedef void (*ep_rt_mono_thread_exited_func)(void); +typedef gpointer (*ep_rt_mono_w32file_create_func)(const gunichar2 *name, guint32 fileaccess, guint32 sharemode, guint32 createmode, guint32 attrs); +typedef gboolean (*ep_rt_mono_w32file_write_func)(gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten, gint32 *win32error); +typedef gboolean (*ep_rt_mono_w32file_close_func)(gpointer handle); + +typedef struct _EventPipeMonoFuncTable { + ep_rt_mono_100ns_ticks_func ep_rt_mono_100ns_ticks; + ep_rt_mono_100ns_datetime_func ep_rt_mono_100ns_datetime; + ep_rt_mono_process_current_pid_func ep_rt_mono_process_current_pid; + ep_rt_mono_cpu_count_func ep_rt_mono_cpu_count; + ep_rt_mono_native_thread_id_get_func ep_rt_mono_native_thread_id_get; + ep_rt_mono_native_thread_id_equals_func ep_rt_mono_native_thread_id_equals; + ep_rt_mono_runtime_is_shutting_down_func ep_rt_mono_runtime_is_shutting_down; + ep_rt_mono_rand_try_get_bytes_func ep_rt_mono_rand_try_get_bytes; + ep_rt_mono_thread_get_func ep_rt_mono_thread_get; + ep_rt_mono_thread_get_or_create_func ep_rt_mono_thread_get_or_create; + ep_rt_mono_thread_exited_func ep_rt_mono_thread_exited; + ep_rt_mono_w32file_create_func ep_rt_mono_w32file_create; + ep_rt_mono_w32file_write_func ep_rt_mono_w32file_write; + ep_rt_mono_w32file_close_func ep_rt_mono_w32file_close; +} EventPipeMonoFuncTable; + +typedef EventPipeThreadHolder * (*ep_rt_thread_holder_alloc_func)(void); +typedef void (*ep_rt_thread_holder_free_func)(EventPipeThreadHolder *thread_holder); + +static +inline +ep_rt_spin_lock_handle_t * +ep_rt_mono_config_lock_get (void) +{ + extern ep_rt_spin_lock_handle_t _ep_rt_mono_config_lock; + return &_ep_rt_mono_config_lock; +} + +static +inline +EventPipeMonoFuncTable * +ep_rt_mono_func_table_get (void) +{ + extern EventPipeMonoFuncTable _ep_rt_mono_func_table; + return &_ep_rt_mono_func_table; +} + +MONO_PROFILER_API +void +mono_eventpipe_init ( + EventPipeMonoFuncTable *table, + ep_rt_thread_holder_alloc_func thread_holder_alloc_func, + ep_rt_thread_holder_free_func thread_holder_free_func); + +MONO_PROFILER_API +void +mono_eventpipe_fini (void); + +/* +* Helpers +*/ + +static +inline +MonoNativeThreadId +ep_rt_mono_native_thread_id_get (void) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + return mono_native_thread_id_get (); +#else + return ep_rt_mono_func_table_get ()->ep_rt_mono_native_thread_id_get (); +#endif +} + +static +inline +gboolean +ep_rt_mono_native_thread_id_equals (MonoNativeThreadId id1, MonoNativeThreadId id2) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + return mono_native_thread_id_equals (id1, id2); +#else + return ep_rt_mono_func_table_get ()->ep_rt_mono_native_thread_id_equals (id1, id2); +#endif +} + +static +inline +gboolean +ep_rt_mono_rand_try_get_bytes (guchar *buffer, gssize buffer_size, MonoError *error) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + extern gpointer ep_rt_mono_rand_provider; + g_assert (ep_rt_mono_rand_provider != NULL); + return mono_rand_try_get_bytes (&ep_rt_mono_rand_provider, buffer, buffer_size, error); +#else + return ep_rt_mono_func_table_get ()->ep_rt_mono_rand_try_get_bytes (buffer, buffer_size, error); +#endif +} + +static +inline +void +ep_rt_mono_thread_exited (void) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + extern gboolean ep_rt_mono_initialized; + extern MonoNativeTlsKey ep_rt_mono_thread_holder_tls_id; + if (ep_rt_mono_initialized) { + EventPipeThreadHolder *thread_holder = (EventPipeThreadHolder *)mono_native_tls_get_value (ep_rt_mono_thread_holder_tls_id); + if (thread_holder) + ep_thread_holder_free (thread_holder); + mono_native_tls_set_value (ep_rt_mono_thread_holder_tls_id, NULL); + } +#else + ep_rt_mono_func_table_get ()->ep_rt_mono_thread_exited (); +#endif +} + +static +inline +gpointer +ep_rt_mono_w32file_create (const gunichar2 *name, guint32 fileaccess, guint32 sharemode, guint32 createmode, guint32 attrs) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + return mono_w32file_create (name, fileaccess, sharemode, createmode, attrs); +#else + return ep_rt_mono_func_table_get ()->ep_rt_mono_w32file_create (name, fileaccess, sharemode, createmode, attrs); +#endif +} + +static +inline +gboolean +ep_rt_mono_w32file_write (gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten, gint32 *win32error) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + return mono_w32file_write (handle, buffer, numbytes, byteswritten, win32error); +#else + return ep_rt_mono_func_table_get ()->ep_rt_mono_w32file_write (handle, buffer, numbytes, byteswritten, win32error); +#endif +} + +static +inline +gboolean +ep_rt_mono_w32file_close (gpointer handle) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + return mono_w32file_close (handle); +#else + return ep_rt_mono_func_table_get ()->ep_rt_mono_w32file_close (handle); +#endif +} + +/* +* Atomics. +*/ + +static +inline +uint32_t +ep_rt_atomic_inc_uint32_t (volatile uint32_t *value) +{ + return (uint32_t)mono_atomic_inc_i32 ((volatile gint32 *)value); +} + +static +inline +uint32_t +ep_rt_atomic_dec_uint32_t (volatile uint32_t *value) +{ + return (uint32_t)mono_atomic_dec_i32 ((volatile gint32 *)value); +} + +static +inline +int32_t +ep_rt_atomic_inc_int32_t (volatile int32_t *value) +{ + return (int32_t)mono_atomic_inc_i32 ((volatile gint32 *)value); +} + +static +inline +int32_t +ep_rt_atomic_dec_int32_t (volatile int32_t *value) +{ + return (int32_t)mono_atomic_dec_i32 ((volatile gint32 *)value); +} + +/* + * EventPipe. + */ + +static +EventPipeThreadHolder * +thread_holder_alloc_func (void) +{ + return ep_thread_holder_alloc (ep_thread_alloc()); +} + +static +void +thread_holder_free_func (EventPipeThreadHolder * thread_holder) +{ + ep_thread_holder_free (thread_holder); +} + +static +inline +void +ep_rt_init (void) +{ + mono_eventpipe_init (ep_rt_mono_func_table_get (), thread_holder_alloc_func, thread_holder_free_func); + ep_rt_spin_lock_alloc (ep_rt_mono_config_lock_get ()); +} + +static +inline +void +ep_rt_shutdown (void) +{ + ep_rt_spin_lock_free (ep_rt_mono_config_lock_get ()); + mono_eventpipe_fini (); +} + +static +inline +bool +ep_rt_config_aquire (void) +{ + ep_rt_spin_lock_aquire (ep_rt_mono_config_lock_get ()); + return true; +} + +static +inline +void +ep_rt_config_release (void) +{ + ep_rt_spin_lock_release (ep_rt_mono_config_lock_get ()); +} + +#ifdef EP_CHECKED_BUILD +static +inline +void +ep_rt_config_requires_lock_held (void) +{ + ep_rt_spin_lock_requires_lock_held (ep_rt_mono_config_lock_get ()); +} + +static +inline +void +ep_rt_config_requires_lock_not_held (void) +{ + ep_rt_spin_lock_requires_lock_not_held (ep_rt_mono_config_lock_get ()); +} +#endif + +/* + * EventPipeEvent. + */ + +EP_RT_DEFINE_LIST (event_list, ep_rt_event_list_t, EventPipeEvent *) +EP_RT_DEFINE_LIST_ITERATOR (event_list, ep_rt_event_list_t, ep_rt_event_list_iterator_t, EventPipeEvent *) + +/* + * EventPipeFile. + */ + +EP_RT_DEFINE_HASH_MAP(metadata_labels, ep_rt_metadata_labels_hash_map_t, EventPipeEvent *, uint32_t) +EP_RT_DEFINE_HASH_MAP(stack_hash, ep_rt_stack_hash_map_t, StackHashKey *, StackHashEntry *) +EP_RT_DEFINE_HASH_MAP_ITERATOR(stack_hash, ep_rt_stack_hash_map_t, ep_rt_stack_hash_map_iterator_t, StackHashKey *, StackHashEntry *) + +/* + * EventPipeProvider. + */ + +EP_RT_DEFINE_LIST (provider_list, ep_rt_provider_list_t, EventPipeProvider *) +EP_RT_DEFINE_LIST_ITERATOR (provider_list, ep_rt_provider_list_t, ep_rt_provider_list_iterator_t, EventPipeProvider *) + +EP_RT_DEFINE_QUEUE (provider_callback_data_queue, ep_rt_provider_callback_data_queue_t, EventPipeProviderCallbackData *) + +static +inline +int +compare_provider_name ( + gconstpointer a, + gconstpointer b) +{ + return (a) ? ep_rt_utf8_string_compare (ep_provider_get_provider_name ((EventPipeProvider *)a), (const ep_char8_t *)b) : 1; +} + +static +inline +EventPipeProvider * +ep_rt_provider_list_find_by_name ( + const ep_rt_provider_list_t *list, + const ep_char8_t *name) +{ + GSList *item = g_slist_find_custom (list->list, name, compare_provider_name); + return (item != NULL) ? (EventPipeProvider *)item->data : NULL; +} + +/* + * EventPipeSampleProfiler. + */ + +static +inline +void +ep_rt_sample_profiler_init (EventPipeProviderCallbackDataQueue *provider_callback_data_queue) +{ + //TODO: Not supported. +} + +static +inline +void +ep_rt_sample_profiler_enable (void) +{ + //TODO: Not supported. +} + +static +inline +void +ep_rt_sample_profiler_disable (void) +{ + //TODO: Not supported. +} + +static +uint32_t +ep_rt_sample_profiler_get_sampling_rate (void) +{ + //TODO: Not supported. + return 0; +} + +/* + * EvetPipeSessionProvider. + */ + +EP_RT_DEFINE_LIST (session_provider_list, ep_rt_session_provider_list_t, EventPipeSessionProvider *) +EP_RT_DEFINE_LIST_ITERATOR (session_provider_list, ep_rt_session_provider_list_t, ep_rt_session_provider_list_iterator_t, EventPipeSessionProvider *) + +static +inline +int +compare_session_provider_name ( + gconstpointer a, + gconstpointer b) +{ + return (a) ? ep_rt_utf8_string_compare (ep_session_provider_get_provider_name ((EventPipeSessionProvider *)a), (const ep_char8_t *)b) : 1; +} + +static +inline +EventPipeSessionProvider * +ep_rt_session_provider_list_find_by_name ( + const ep_rt_session_provider_list_t *list, + const ep_char8_t *name) +{ + GSList *item = g_slist_find_custom (list->list, name, compare_provider_name); + return (item != NULL) ? (EventPipeSessionProvider *)item->data : NULL; +} + +/* + * Arrays. + */ + +static +inline +uint8_t * +ep_rt_byte_array_alloc (size_t len) +{ + return g_new(uint8_t, len); +} + +static +inline +void +ep_rt_byte_array_free (uint8_t *ptr) +{ + g_free (ptr); +} + +/* + * Event. + */ + +static +inline +void +ep_rt_wait_event_alloc (ep_rt_wait_event_handle_t *wait_event) +{ + EP_ASSERT (wait_event != NULL); + wait_event->event = g_new0 (MonoOSEvent, 1); + if (wait_event->event) + mono_os_event_init (wait_event->event, false); +} + +static +inline +void +ep_rt_wait_event_free (ep_rt_wait_event_handle_t *wait_event) +{ + if (wait_event != NULL && wait_event->event != NULL) { + mono_os_event_destroy (wait_event->event); + g_free (wait_event->event); + wait_event->event = NULL; + } +} + +static +inline +bool +ep_rt_wait_event_set (ep_rt_wait_event_handle_t *wait_event) +{ + EP_ASSERT (wait_event != NULL && wait_event->event != NULL); + mono_os_event_set (wait_event->event); + return true; +} + +static +inline +int32_t +ep_rt_wait_event_wait ( + ep_rt_wait_event_handle_t *wait_event, + uint32_t timeout, + bool alertable) +{ + EP_ASSERT (wait_event != NULL && wait_event->event != NULL); + return mono_os_event_wait_one (wait_event->event, timeout, alertable); +} + +static +inline +EventPipeWaitHandle +ep_rt_wait_event_get_wait_handle (ep_rt_wait_event_handle_t *wait_event) +{ + EP_ASSERT (wait_event != NULL); + return (EventPipeWaitHandle)wait_event; +} + +/* + * Misc. + */ + +static +inline +bool +ep_rt_process_detach (void) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + return (bool)mono_runtime_is_shutting_down (); +#else + return (bool)ep_rt_mono_func_table_get ()->ep_rt_mono_runtime_is_shutting_down (); +#endif +} + +static +inline +void +ep_rt_create_activity_id ( + uint8_t *activity_id, + uint32_t activity_id_len) +{ + EP_ASSERT (activity_id_len == EP_ACTIVITY_ID_SIZE); + + ERROR_DECL (error); + ep_rt_mono_rand_try_get_bytes ((guchar *)activity_id, EP_ACTIVITY_ID_SIZE, error); + + const uint16_t version_mask = 0xF000; + const uint16_t random_guid_version = 0x4000; + const uint8_t clock_seq_hi_and_reserved_mask = 0xC0; + const uint8_t clock_seq_hi_and_reserved_value = 0x80; + + // Modify bits indicating the type of the GUID + uint8_t *activity_id_c = activity_id + sizeof (uint32_t) + sizeof (uint16_t); + uint8_t *activity_id_d = activity_id + sizeof (uint32_t) + sizeof (uint16_t) + sizeof (uint16_t); + + uint16_t c; + memcpy (&c, activity_id_c, sizeof (c)); + + uint8_t d; + memcpy (&d, activity_id_d, sizeof (d)); + + // time_hi_and_version + c = ((c & ~version_mask) | random_guid_version); + // clock_seq_hi_and_reserved + d = ((d & ~clock_seq_hi_and_reserved_mask) | clock_seq_hi_and_reserved_value); + + memcpy (activity_id_c, &c, sizeof (c)); + memcpy (activity_id_d, &d, sizeof (d)); +} + +/* + * Objects. + */ + +#undef ep_rt_object_alloc +#define ep_rt_object_alloc(obj_type) (g_new0 (obj_type, 1)) + +static +inline +void +ep_rt_object_free (void *ptr) +{ + g_free (ptr); +} + +/* + * PAL. + */ + +static +inline +uint32_t +ep_rt_current_process_get_id (void) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + return (uint32_t)mono_process_current_pid (); +#else + return (uint32_t)ep_rt_mono_func_table_get ()->ep_rt_mono_process_current_pid (); +#endif +} + +static +inline +uint32_t +ep_rt_current_processor_get_number (void) +{ + return 0xFFFFFFFF; +} + +static +inline +uint32_t +ep_rt_processors_get_count (void) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + return (uint32_t)mono_cpu_count (); +#else + return (uint32_t)ep_rt_mono_func_table_get ()->ep_rt_mono_cpu_count (); +#endif +} + +static +inline +size_t +ep_rt_current_thread_get_id (void) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + return MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ()); +#else + return MONO_NATIVE_THREAD_ID_TO_UINT (ep_rt_mono_func_table_get ()->ep_rt_mono_native_thread_id_get ()); +#endif +} + +static +inline +uint64_t +ep_rt_perf_counter_query (void) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + return (uint64_t)mono_100ns_ticks (); +#else + return (uint64_t)ep_rt_mono_func_table_get ()->ep_rt_mono_100ns_ticks (); +#endif +} + +static +inline +uint64_t +ep_rt_perf_frequency_query (void) +{ + //Counter uses resolution of 100ns ticks. + return 100 * 1000 * 1000; +} + +static +inline +uint64_t +ep_rt_system_time_get (void) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + return (uint64_t)mono_100ns_datetime (); +#else + return (uint64_t)ep_rt_mono_func_table_get ()->ep_rt_mono_100ns_datetime (); +#endif +} + +static +inline +const ep_char8_t * +ep_rt_command_line_get (void) +{ + //TODO: Implement. + return ""; +} + +static +inline +ep_rt_file_handle_t +ep_rt_file_open_write (const ep_char8_t *path) +{ + ep_char16_t *path_utf16 = ep_rt_utf8_to_utf16_string (path, -1); + ep_return_null_if_nok (path_utf16 != NULL); + + gpointer file_handle = ep_rt_mono_w32file_create (path_utf16, GENERIC_WRITE, FILE_SHARE_READ, CREATE_ALWAYS, FileAttributes_Normal); + ep_rt_utf16_string_free (path_utf16); + + return file_handle; +} + +static +bool +ep_rt_file_close (ep_rt_file_handle_t file_handle) +{ + ep_return_false_if_nok (file_handle != NULL); + return ep_rt_mono_w32file_close (file_handle); +} + +static +bool +ep_rt_file_write ( + ep_rt_file_handle_t file_handle, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written) +{ + ep_return_false_if_nok (file_handle != NULL); + EP_ASSERT (buffer != NULL); + + gint32 win32_error; + bool result = ep_rt_mono_w32file_write (file_handle, buffer, bytes_to_write, bytes_written, &win32_error); + if (result) + *bytes_written = bytes_to_write; + + return result; +} + +/* +* SpinLock. +*/ + +static +inline +void +ep_rt_spin_lock_alloc (ep_rt_spin_lock_handle_t *spin_lock) +{ +#ifdef EP_CHECKED_BUILD + spin_lock->lock_is_held = false; +#endif + spin_lock->lock = g_new0 (MonoCoopMutex, 1); + if (spin_lock->lock) + mono_coop_mutex_init (spin_lock->lock); +} + +static +inline +void +ep_rt_spin_lock_free (ep_rt_spin_lock_handle_t *spin_lock) +{ + if (spin_lock && spin_lock->lock) { + mono_coop_mutex_destroy (spin_lock->lock); + g_free (spin_lock->lock); + spin_lock->lock = NULL; + } +} + +static +inline +void +ep_rt_spin_lock_aquire (ep_rt_spin_lock_handle_t *spin_lock) +{ + if (spin_lock && spin_lock->lock) { + mono_coop_mutex_lock (spin_lock->lock); +#ifdef EP_CHECKED_BUILD + spin_lock->owning_thread_id = ep_rt_mono_native_thread_id_get (); + spin_lock->lock_is_held = true; +#endif + } +} + +static +inline +void +ep_rt_spin_lock_release (ep_rt_spin_lock_handle_t *spin_lock) +{ + if (spin_lock && spin_lock->lock) { +#ifdef EP_CHECKED_BUILD + spin_lock->lock_is_held = false; +#endif + mono_coop_mutex_unlock (spin_lock->lock); + } +} + +#ifdef EP_CHECKED_BUILD +static +inline +void +ep_rt_spin_lock_requires_lock_held (const ep_rt_spin_lock_handle_t *spin_lock) +{ + g_assert (spin_lock->lock_is_held && ep_rt_mono_native_thread_id_equals (spin_lock->owning_thread_id, ep_rt_mono_native_thread_id_get ())); +} + +static +inline +void +ep_rt_spin_lock_requires_lock_not_held (const ep_rt_spin_lock_handle_t *spin_lock) +{ + g_assert (!spin_lock->lock_is_held || (spin_lock->lock_is_held && !ep_rt_mono_native_thread_id_equals (spin_lock->owning_thread_id, ep_rt_mono_native_thread_id_get ()))); +} +#endif + +/* + * String. + */ + +static +inline +size_t +ep_rt_utf8_string_len (const ep_char8_t *str) +{ + return g_utf8_strlen ((const gchar *)str, -1); +} + +static +inline +int +ep_rt_utf8_string_compare ( + const ep_char8_t *str1, + const ep_char8_t *str2) +{ + return strcmp ((const char *)str1, (const char *)str2); +} + +static +inline +ep_char16_t * +ep_rt_utf8_to_utf16_string ( + const ep_char8_t *str, + size_t len) +{ + return (ep_char16_t *)(g_utf8_to_utf16 ((const gchar *)str, len, NULL, NULL, NULL)); +} + +static +inline +ep_char8_t * +ep_rt_utf8_string_dup (const ep_char8_t *str) +{ + return g_strdup (str); +} + +static +inline +void +ep_rt_utf8_string_free (ep_char8_t *str) +{ + g_free (str); +} + +static +inline +size_t +ep_rt_utf16_string_len (const ep_char16_t *str) +{ + return g_utf16_len ((const gunichar2 *)str); +} + +static +inline +ep_char8_t * +ep_rt_utf16_to_utf8_string ( + const ep_char16_t *str, + size_t len) +{ + return g_utf16_to_utf8 ((const gunichar2 *)str, len, NULL, NULL, NULL); +} + +static +inline +void +ep_rt_utf16_string_free (ep_char16_t *str) +{ + g_free (str); +} + +static +inline +const ep_char8_t * +ep_rt_managed_command_line_get (void) +{ + //TODO: Implement. + return ""; +} + +/* + * Thread. + */ +static +inline +void +ep_rt_thread_setup (void) +{ + //TODO: Is this needed on Mono runtime? Looks like a thread attach, making sure thread is attached to runtime. +} + +static +inline +EventPipeThread * +ep_rt_thread_get (void) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + extern MonoNativeTlsKey ep_rt_mono_thread_holder_tls_id; + EventPipeThreadHolder *thread_holder = (EventPipeThreadHolder *)mono_native_tls_get_value (ep_rt_mono_thread_holder_tls_id); + return thread_holder ? ep_thread_holder_get_thread (thread_holder) : NULL; +#else + return ep_rt_mono_func_table_get ()->ep_rt_mono_thread_get (); +#endif +} + +static +inline +EventPipeThread * +ep_rt_thread_get_or_create (void) +{ +#ifdef EP_RT_MONO_USE_STATIC_RUNTIME + extern MonoNativeTlsKey ep_rt_mono_thread_holder_tls_id; + EventPipeThreadHolder *thread_holder = (EventPipeThreadHolder *)mono_native_tls_get_value (ep_rt_mono_thread_holder_tls_id); + if (!thread_holder) { + thread_holder = thread_holder_alloc_func (); + mono_native_tls_set_value (ep_rt_mono_thread_holder_tls_id, thread_holder); + } + return ep_thread_holder_get_thread (thread_holder); +#else + return ep_rt_mono_func_table_get ()->ep_rt_mono_thread_get_or_create (); +#endif +} + +/* + * ThreadSequenceNumberMap. + */ + +EP_RT_DEFINE_HASH_MAP(thread_sequence_number_map, ep_rt_thread_sequence_number_hash_map_t, EventPipeThreadSessionState *, uint32_t) +EP_RT_DEFINE_HASH_MAP_ITERATOR(thread_sequence_number_map, ep_rt_thread_sequence_number_hash_map_t, ep_rt_thread_sequence_number_hash_map_iterator_t, EventPipeThreadSessionState *, uint32_t) + +/* + * Volatile. + */ + +static +inline +uint32_t +ep_rt_volatile_load_uint32_t (const volatile uint32_t *ptr) +{ + return mono_atomic_load_i32 ((volatile gint32 *)ptr); +} + +static +inline +uint32_t +ep_rt_volatile_load_uint32_t_without_barrier (const volatile uint32_t *ptr) +{ + uint32_t value = *ptr; + return value; +} + +static +inline +void +ep_rt_volatile_store_uint32_t ( + volatile uint32_t *ptr, + uint32_t value) +{ + mono_atomic_store_i32 ((volatile gint32 *)ptr, (gint32)value); +} + +static +inline +void +ep_rt_volatile_store_uint32_t_without_barrier ( + volatile uint32_t *ptr, + uint32_t value) +{ + *ptr = value; +} + +static +inline +uint64_t +ep_rt_volatile_load_uint64_t (const volatile uint64_t *ptr) +{ + return mono_atomic_load_i64 ((volatile gint64 *)ptr); +} + +static +inline +uint64_t +ep_rt_volatile_load_uint64_t_without_barrier (const volatile uint64_t *ptr) +{ + uint64_t value = *ptr; + return value; +} + +static +inline +void +ep_rt_volatile_store_uint64_t ( + volatile uint64_t *ptr, + uint64_t value) +{ + mono_atomic_store_i64 ((volatile gint64 *)ptr, (gint64)value); +} + +static +inline +void +ep_rt_volatile_store_uint64_t_without_barrier ( + volatile uint64_t *ptr, + uint64_t value) +{ + *ptr = value; +} + +static +inline +void * +ep_rt_volatile_load_ptr (volatile void **ptr) +{ + return mono_atomic_load_ptr ((volatile gpointer *)ptr); +} + +static +inline +void * +ep_rt_volatile_load_ptr_without_barrier (volatile void **ptr) +{ + void *value = (void *)(*ptr); + return value; +} + +static +inline +void +ep_rt_volatile_store_ptr ( + volatile void **ptr, + void *value) +{ + mono_atomic_store_ptr ((volatile gpointer *)ptr, (gpointer)value); +} + +static +inline +void +ep_rt_volatile_store_ptr_without_barrier ( + volatile void **ptr, + void *value) +{ + *ptr = value; +} + +#endif /* ENABLE_PERFTRACING */ +#endif /* __EVENTPIPE_RT_MONO_H__ */ diff --git a/src/mono/mono/eventpipe/ep-rt-types-mono.h b/src/mono/mono/eventpipe/ep-rt-types-mono.h new file mode 100644 index 0000000000000..266f1ee25cd1f --- /dev/null +++ b/src/mono/mono/eventpipe/ep-rt-types-mono.h @@ -0,0 +1,96 @@ +// Implementation of ep-rt-types.h targeting Mono runtime. +#ifndef __EVENTPIPE_RT_TYPES_MONO_H__ +#define __EVENTPIPE_RT_TYPES_MONO_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include +#include +#include +#include + +//#ifdef ENABLE_CHECKED_BUILD +#define EP_CHECKED_BUILD +//#endif + +#undef EP_ASSERT +//#define EP_ASSERT(expr) g_assert_checked(expr) +#define EP_ASSERT(expr) g_assert(expr) + +#undef EP_LIKELY +#define EP_LIKELY(expr) G_LIKELY(expr) + +#undef EP_UNLIKELY +#define EP_UNLIKELY(expr) G_UNLIKELY(expr) + +struct _rt_mono_list_internal_t { + GSList *list; +}; + +struct _rt_mono_list_iterator_internal_t { + GSList *iterator; +}; + +typedef struct _rt_mono_list_internal_t ep_rt_provider_list_t; +typedef struct _rt_mono_list_iterator_internal_t ep_rt_provider_list_iterator_t; + +typedef struct _rt_mono_list_internal_t ep_rt_event_list_t; +typedef struct _rt_mono_list_iterator_internal_t ep_rt_event_list_iterator_t; + +typedef struct _rt_mono_list_internal_t ep_rt_session_provider_list_t; +typedef struct _rt_mono_list_iterator_internal_t ep_rt_session_provider_list_iterator_t; + +struct _rt_mono_queue_internal_t { + GQueue *queue; +}; + +typedef struct _rt_mono_queue_internal_t ep_rt_provider_callback_data_queue_t; +typedef struct _rt_mono_queue_iterator_internal_t ep_rt_provider_callback_data_queue_iterator_t; + +struct _rt_mono_table_internal_t { + GHashTable *table; + uint32_t count; +}; + +struct _rt_mono_table_iterator_internal_t { + GHashTableIter iterator; + gpointer key; + gpointer value; + bool end; +}; + +typedef struct _rt_mono_table_internal_t ep_rt_metadata_labels_hash_map_t; +typedef struct _rt_mono_iterator_table_internal_t ep_rt_metadata_labels_hash_map_iterator_t; + +typedef struct _rt_mono_table_internal_t ep_rt_stack_hash_map_t; +typedef struct _rt_mono_table_iterator_internal_t ep_rt_stack_hash_map_iterator_t; + +typedef struct _rt_mono_table_internal_t ep_rt_thread_sequence_number_hash_map_t; +typedef struct _rt_mono_table_iterator_internal_t ep_rt_thread_sequence_number_hash_map_iterator_t; + +typedef MonoThreadHandle ep_rt_thread_handle_t; +typedef gpointer ep_rt_file_handle_t; +typedef gpointer ep_rt_ipc_handle_t; +typedef MonoMethod ep_rt_method_desc_t; + +struct _rt_mono_event_internal_t { + MonoOSEvent *event; +}; + +typedef struct _rt_mono_event_internal_t ep_rt_wait_event_handle_t; + +struct _rt_mono_lock_internal_t { + MonoCoopMutex *lock; +#ifdef EP_CHECKED_BUILD + MonoNativeThreadId owning_thread_id; + bool lock_is_held; +#endif +}; + +typedef struct _rt_mono_lock_internal_t ep_rt_lock_handle_t; +typedef ep_rt_lock_handle_t ep_rt_spin_lock_handle_t; + +#endif /* ENABLE_PERFTRACING */ +#endif /* __EVENTPIPE_RT_TYPES_MONO_H__ */ diff --git a/src/mono/mono/eventpipe/ep-rt-types.h b/src/mono/mono/eventpipe/ep-rt-types.h new file mode 100644 index 0000000000000..cb0a9af82fa6d --- /dev/null +++ b/src/mono/mono/eventpipe/ep-rt-types.h @@ -0,0 +1,22 @@ +#ifndef __EVENTPIPE_RT_TYPES_H__ +#define __EVENTPIPE_RT_TYPES_H__ + +#define EP_ASSERT(expr) ep_rt_redefine +#define EP_LIKELY(expr) ep_rt_redefine +#define EP_UNLIKELY(expr) ep_rt_redefine + +/* + * ErrorHandling. + */ + +#define ep_raise_error_if_nok(expr) do { if (EP_UNLIKELY(!(expr))) goto ep_on_error; } while (0) +#define ep_raise_error() do { goto ep_on_error; } while (0) +#define ep_exit_error_handler() do { goto ep_on_exit; } while (0) +#define ep_return_null_if_nok(expr) do { if (EP_UNLIKELY(!(expr))) return NULL; } while (0) +#define ep_return_void_if_nok(expr) do { if (EP_UNLIKELY(!(expr))) return; } while (0) +#define ep_return_false_if_nok(expr) do { if (EP_UNLIKELY(!(expr))) return false; } while (0) +#define ep_return_zero_if_nok(expr) do { if (EP_UNLIKELY(!(expr))) return 0; } while (0) + +#include "ep-rt-types-mono.h" + +#endif /* __EVENTPIPE_RT_TYPES_H__ */ diff --git a/src/mono/mono/eventpipe/ep-rt.h b/src/mono/mono/eventpipe/ep-rt.h new file mode 100644 index 0000000000000..0bcdbc8cd3624 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-rt.h @@ -0,0 +1,482 @@ +#ifndef __EVENTPIPE_RT_H__ +#define __EVENTPIPE_RT_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +#define EP_ARRAY_SIZE(expr) ep_rt_redefine +#define EP_INFINITE_WAIT ep_rt_redefine + +#define EP_GCX_PREEMP_ENTER ep_rt_redefine +#define EP_GCX_PREEMP_EXIT ep_rt_redefine + +#define EP_RT_DECLARE_LIST(list_name, list_type, item_type) \ + static void ep_rt_ ## list_name ## _free (list_type *list, void (*callback)(void *)); \ + static void ep_rt_ ## list_name ## _clear (list_type *list, void (*callback)(void *)); \ + static void ep_rt_ ## list_name ## _append (list_type *list, item_type item); \ + static void ep_rt_ ## list_name ## _remove (list_type *list, const item_type item); \ + static bool ep_rt_ ## list_name ## _find (const list_type *list, const item_type item_to_find, item_type *found_item); \ + static bool ep_rt_ ## list_name ## _is_empty (const list_type *list); + +#define EP_RT_DECLARE_LIST_ITERATOR(list_name, list_type, iterator_type, item_type) \ + static void ep_rt_ ## list_name ## _iterator_begin (const list_type *list, iterator_type *iterator); \ + static bool ep_rt_ ## list_name ## _iterator_end (const list_type *list, const iterator_type *iterator); \ + static void ep_rt_ ## list_name ## _iterator_next (const list_type *list, iterator_type *iterator); \ + static item_type ep_rt_ ## list_name ## _iterator_value (const iterator_type *iterator); + +#define EP_RT_DECLARE_QUEUE(queue_name, queue_type, item_type) \ + static void ep_rt_ ## queue_name ## _alloc (queue_type *queue); \ + static void ep_rt_ ## queue_name ## _free (queue_type *queue); \ + static void ep_rt_ ## queue_name ## _pop_head (queue_type *queue, item_type *item); \ + static void ep_rt_ ## queue_name ## _push_head (queue_type *queue, item_type item); \ + static void ep_rt_ ## queue_name ## _push_tail (queue_type *queue, item_type item); \ + static bool ep_rt_ ## queue_name ## _is_empty (const queue_type *queue); + +#define EP_RT_DECLARE_HASH_MAP(hash_map_name, hash_map_type, key_type, value_type) \ + static void ep_rt_ ## hash_map_name ## _alloc (hash_map_type *hash_map, uint32_t (*hash_callback)(const void *), bool (*eq_callback)(const void *, const void *), void (*key_free_callback)(void *), void (*value_free_callback)(void *)); \ + static void ep_rt_ ## hash_map_name ## _free (hash_map_type *hash_map); \ + static void ep_rt_ ## hash_map_name ## _add (hash_map_type *hash_map, key_type key, value_type value); \ + static void ep_rt_ ## hash_map_name ## _remove (hash_map_type *hash_map, const key_type key); \ + static void ep_rt_ ## hash_map_name ## _remove_all (hash_map_type *hash_map); \ + static bool ep_rt_ ## hash_map_name ## _lookup (const hash_map_type *hash_map, const key_type key, value_type *value); \ + static uint32_t ep_rt_ ## hash_map_name ## _count (const hash_map_type *hash_map); + +#define EP_RT_DECLARE_HASH_MAP_ITERATOR(hash_map_name, hash_map_type, iterator_type, key_type, value_type) \ + static void ep_rt_ ## hash_map_name ## _iterator_begin (const hash_map_type *hash_map, iterator_type *iterator); \ + static bool ep_rt_ ## hash_map_name ## _iterator_end (const hash_map_type *hash_map, const iterator_type *iterator); \ + static void ep_rt_ ## hash_map_name ## _iterator_next (const hash_map_type *hash_map, iterator_type *iterator); \ + static key_type ep_rt_ ## hash_map_name ## _iterator_key (const iterator_type *iterator); \ + static value_type ep_rt_ ## hash_map_name ## _iterator_value (const iterator_type *iterator); + +/* +* Atomics. +*/ + +static +uint32_t +ep_rt_atomic_inc_uint32_t (volatile uint32_t *value); + +static +uint32_t +ep_rt_atomic_dec_uint32_t (volatile uint32_t *value); + +static +int32_t +ep_rt_atomic_inc_int32_t (volatile int32_t *value); + +static +int32_t +ep_rt_atomic_dec_int32_t (volatile int32_t *value); + +/* + * EventPipe. + */ + +static +void +ep_rt_init (void); + +static +void +ep_rt_shutdown (void); + +static +bool +ep_rt_config_aquire (void); + +static +void +ep_rt_config_release (void); + +#ifdef EP_CHECKED_BUILD +static +void +ep_rt_config_requires_lock_held (void); + +static +void +ep_rt_config_requires_lock_not_held (void); +#else +#define ep_rt_config_requires_lock_held() +#define ep_rt_config_requires_lock_not_held() +#endif + +/* + * EventPipeEvent. + */ + +EP_RT_DECLARE_LIST (event_list, ep_rt_event_list_t, EventPipeEvent *) +EP_RT_DECLARE_LIST_ITERATOR (event_list, ep_rt_event_list_t, ep_rt_event_list_iterator_t, EventPipeEvent *) + +/* + * EventPipeFile. + */ + +EP_RT_DECLARE_HASH_MAP(metadata_labels, ep_rt_metadata_labels_hash_map_t, EventPipeEvent *, uint32_t) +EP_RT_DECLARE_HASH_MAP(stack_hash, ep_rt_stack_hash_map_t, StackHashKey *, StackHashEntry *) +EP_RT_DECLARE_HASH_MAP_ITERATOR(stack_hash, ep_rt_stack_hash_map_t, ep_rt_stack_hash_map_iterator_t, StackHashKey *, StackHashEntry *) + +/* + * EventPipeProvider. + */ + +EP_RT_DECLARE_LIST (provider_list, ep_rt_provider_list_t, EventPipeProvider *) +EP_RT_DECLARE_LIST_ITERATOR (provider_list, ep_rt_provider_list_t, ep_rt_provider_list_iterator_t, EventPipeProvider *) + +EP_RT_DECLARE_QUEUE (provider_callback_data_queue, ep_rt_provider_callback_data_queue_t, EventPipeProviderCallbackData *) + +static +EventPipeProvider * +ep_rt_provider_list_find_by_name ( + const ep_rt_provider_list_t *list, + const ep_char8_t *name); + +/* + * EventPipeSampleProfiler. + */ + +static +void +ep_rt_sample_profiler_init (EventPipeProviderCallbackDataQueue *provider_callback_data_queue); + +static +void +ep_rt_sample_profiler_enable (void); + +static +void +ep_rt_sample_profiler_disable (void); + +static +uint32_t +ep_rt_sample_profiler_get_sampling_rate (void); + +/* + * EventPipeSessionProvider. + */ + +EP_RT_DECLARE_LIST (session_provider_list, ep_rt_session_provider_list_t, EventPipeSessionProvider *) +EP_RT_DECLARE_LIST_ITERATOR (session_provider_list, ep_rt_session_provider_list_t, ep_rt_session_provider_list_iterator_t, EventPipeSessionProvider *) + +static +EventPipeSessionProvider * +ep_rt_session_provider_list_find_by_name ( + const ep_rt_session_provider_list_t *list, + const ep_char8_t *name); + +/* + * Arrays. + */ + +static +uint8_t * +ep_rt_byte_array_alloc (size_t len); + +static +void +ep_rt_byte_array_free (uint8_t *ptr); + +/* + * Event. + */ + +static +void +ep_rt_wait_event_alloc (ep_rt_wait_event_handle_t *wait_event); + +static +void +ep_rt_wait_event_free (ep_rt_wait_event_handle_t *wait_event); + +static +bool +ep_rt_wait_event_set (ep_rt_wait_event_handle_t *wait_event); + +static +int32_t +ep_rt_wait_event_wait ( + ep_rt_wait_event_handle_t *wait_event, + uint32_t timeout, + bool alertable); + +static +EventPipeWaitHandle +ep_rt_wait_event_get_handle (ep_rt_wait_event_handle_t *wait_event); + +/* + * Misc. + */ + +static +bool +ep_rt_process_detach (void); + +static +void +ep_rt_create_activity_id ( + uint8_t *activity_id, + uint32_t activity_id_len); + +/* + * Objects. + */ + +#define ep_rt_object_alloc(obj_type) ep_rt_redefine + +static +void +ep_rt_object_free (void *ptr); + +/* + * PAL. + */ + +static +uint32_t +ep_rt_current_process_get_id (void); + +static +uint32_t +ep_rt_current_processor_get_number (void); + +static +uint32_t +ep_rt_processors_get_count (void); + +static +size_t +ep_rt_current_thread_get_id (void); + +static +uint64_t +ep_rt_perf_counter_query (void); + +static +uint64_t +ep_rt_perf_frequency_query (void); + +static +uint64_t +ep_rt_system_time_get (void); + +static +const ep_char8_t * +ep_rt_command_line_get (void); + +static +ep_rt_file_handle_t +ep_rt_file_open_write (const ep_char8_t *path); + +static +bool +ep_rt_file_close (ep_rt_file_handle_t file_handle); + +static +bool +ep_rt_file_write ( + ep_rt_file_handle_t file_handle, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written); + +/* +* SpinLock. +*/ + +static +void +ep_rt_spin_lock_alloc (ep_rt_spin_lock_handle_t *spin_lock); + +static +void +ep_rt_spin_lock_free (ep_rt_spin_lock_handle_t *spin_lock); + +static +void +ep_rt_spin_lock_aquire (ep_rt_spin_lock_handle_t *spin_lock); + +static +void +ep_rt_spin_lock_release (ep_rt_spin_lock_handle_t *spin_lock); + +#ifdef EP_CHECKED_BUILD +static +void +ep_rt_spin_lock_requires_lock_held (const ep_rt_spin_lock_handle_t *spin_lock); + +static +void +ep_rt_spin_lock_requires_lock_not_held (const ep_rt_spin_lock_handle_t *spin_lock); +#else +#define ep_rt_spin_lock_requires_lock_held(spin_lock) +#define ep_rt_spin_lock_requires_lock_not_held(spin_lock) +#endif + +/* + * String. + */ + +static +size_t +ep_rt_utf8_string_len (const ep_char8_t *str); + +static +int +ep_rt_utf8_string_compare ( + const ep_char8_t *str1, + const ep_char8_t *str2); + +static +ep_char8_t * +ep_rt_utf8_string_dup (const ep_char8_t *str); + +static +ep_char16_t * +ep_rt_utf8_to_utf16_string ( + const ep_char8_t *str, + size_t len); + +static +void +ep_rt_utf8_string_free (ep_char8_t *str); + +static +size_t +ep_rt_utf16_string_len (const ep_char16_t *str); + +static +ep_char8_t * +ep_rt_utf16_to_utf8_string ( + const ep_char16_t *str, + size_t len); + +static +void +ep_rt_utf16_string_free (ep_char16_t *str); + +static +const ep_char8_t * +ep_rt_managed_command_line_get (void); + +/* + * Thread. + */ +static +void +ep_rt_thread_setup (void); + +static +EventPipeThread * +ep_rt_thread_get (void); + +static +EventPipeThread * +ep_rt_thread_get_or_create (void); + + +/* + * ThreadSequenceNumberMap. + */ + +EP_RT_DECLARE_HASH_MAP(thread_sequence_number_map, ep_rt_thread_sequence_number_hash_map_t, EventPipeThreadSessionState *, uint32_t) +EP_RT_DECLARE_HASH_MAP_ITERATOR(thread_sequence_number_map, ep_rt_thread_sequence_number_hash_map_t, ep_rt_thread_sequence_number_hash_map_iterator_t, EventPipeThreadSessionState *, uint32_t) + + +/* + * Volatile. + */ + +static +uint32_t +ep_rt_volatile_load_uint32_t (const volatile uint32_t *ptr); + +static +uint32_t +ep_rt_volatile_load_uint32_t_without_barrier (const volatile uint32_t *ptr); + +static +void +ep_rt_volatile_store_uint32_t ( + volatile uint32_t *ptr, + uint32_t value); + +static +void +ep_rt_volatile_store_uint32_t_without_barrier ( + volatile uint32_t *ptr, + uint32_t value); + +static +uint64_t +ep_rt_volatile_load_uint64_t (const volatile uint64_t *ptr); + +static +uint64_t +ep_rt_volatile_load_uint64_t_without_barrier (const volatile uint64_t *ptr); + +static +void +ep_rt_volatile_store_uint64_t ( + volatile uint64_t *ptr, + uint64_t value); + +static +void +ep_rt_volatile_store_uint64_t_without_barrier ( + volatile uint64_t *ptr, + uint64_t value); + +static +void * +ep_rt_volatile_load_ptr (volatile void **ptr); + +static +void * +ep_rt_volatile_load_ptr_without_barrier (volatile void **ptr); + +static +void +ep_rt_volatile_store_ptr ( + volatile void **ptr, + void *value); + +static +void +ep_rt_volatile_store_ptr_without_barrier ( + volatile void **ptr, + void *value); + +/* + * Enter/Exit config lock helper used with error handling macros. + */ + +#define EP_CONFIG_LOCK_ENTER \ +{ \ + ep_rt_config_requires_lock_not_held (); \ + bool _owns_lock = ep_rt_config_aquire (); \ + bool _no_error = false; \ + if (EP_UNLIKELY((!_owns_lock))) \ + goto _ep_on_lock_exit; + +#define EP_CONFIG_LOCK_EXIT \ + _no_error = true; \ +_ep_on_lock_exit: \ + if (EP_UNLIKELY((!_owns_lock))) \ + goto ep_on_error; \ + ep_rt_config_requires_lock_held (); \ + ep_rt_config_release (); \ + if (EP_UNLIKELY((!_no_error))) \ + goto ep_on_error; \ + ep_rt_config_requires_lock_not_held (); \ +} + +#define ep_raise_error_if_nok_holding_lock(expr) do { if (EP_UNLIKELY(!(expr))) goto _ep_on_lock_exit; } while (0) +#define ep_raise_error_holding_lock() do { goto _ep_on_lock_exit; } while (0) + +#include "ep-rt-mono.h" + +#endif /* ENABLE_PERFTRACING */ +#endif /* __EVENTPIPE_RT_H__ */ diff --git a/src/mono/mono/eventpipe/ep-session-internals.c b/src/mono/mono/eventpipe/ep-session-internals.c new file mode 100644 index 0000000000000..3ed2a1101cc22 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-session-internals.c @@ -0,0 +1,123 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +/* + * EventPipeSession. + */ + +EventPipeSession * +ep_session_alloc ( + uint32_t index, + const ep_char8_t *output_path, + IpcStream *stream, + EventPipeSessionType session_type, + EventPipeSerializationFormat format, + bool rundown_requested, + uint32_t circular_buffer_size_in_mb, + const EventPipeProviderConfiguration *providers, + uint32_t providers_len, + bool rundown_enabled) +{ + ep_rt_config_requires_lock_held (); + + ep_return_null_if_nok (index < EP_MAX_NUMBER_OF_SESSIONS && format < EP_SERIALIZATION_FORMAT_COUNT && circular_buffer_size_in_mb > 0 && providers_len > 0 && providers != NULL); + + FileStreamWriter *file_stream_writer = NULL; + IpcStreamWriter *ipc_stream_writer = NULL; + + EventPipeSession *instance = ep_rt_object_alloc (EventPipeSession); + ep_raise_error_if_nok (instance != NULL); + + instance->providers = ep_session_provider_list_alloc (providers, providers_len); + ep_raise_error_if_nok (instance->providers != NULL); + + instance->index = index; + instance->rundown_enabled = rundown_enabled ? 1 : 0; + instance->session_type = session_type; + instance->format = format; + instance->rundown_requested = rundown_requested; + + size_t sequence_point_alloc_budget = 0; + + // Hard coded 10MB for now, we'll probably want to make + // this configurable later. + if (instance->session_type != EP_SESSION_TYPE_LISTENER && instance->format >= EP_SERIALIZATION_FORMAT_NETTRACE_V4) { + sequence_point_alloc_budget = 10 * 1024 * 1024; + } + + instance->buffer_manager = ep_buffer_manager_alloc (instance, ((size_t)circular_buffer_size_in_mb) << 20, sequence_point_alloc_budget); + ep_raise_error_if_nok (instance->buffer_manager != NULL); + + // Create the event pipe file. + // A NULL output path means that we should not write the results to a file. + // This is used in the EventListener case. + switch (session_type) { + case EP_SESSION_TYPE_FILE : + if (output_path) { + file_stream_writer = ep_file_stream_writer_alloc (output_path); + instance->file = ep_file_alloc (ep_file_stream_writer_get_stream_writer_ref (file_stream_writer), format); + ep_raise_error_if_nok (instance->file != NULL); + file_stream_writer = NULL; + } + break; + + case EP_SESSION_TYPE_IPCSTREAM: + ipc_stream_writer = ep_ipc_stream_writer_alloc ((uint64_t)instance, stream); + ep_raise_error_if_nok (ipc_stream_writer != NULL); + instance->file = ep_file_alloc (ep_ipc_stream_writer_get_stream_writer_ref (ipc_stream_writer), format); + ep_raise_error_if_nok (instance->file != NULL); + ipc_stream_writer = NULL; + break; + + default: + break; + } + + instance->session_start_time = ep_rt_system_time_get (); + instance->session_start_timestamp = ep_perf_counter_query (); + + ep_rt_wait_event_alloc (&instance->rt_thread_shutdown_event); + +ep_on_exit: + ep_rt_config_requires_lock_held (); + return instance; + +ep_on_error: + ep_file_stream_writer_free (file_stream_writer); + ep_ipc_stream_writer_free (ipc_stream_writer); + ep_session_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_session_free (EventPipeSession *session) +{ + ep_return_void_if_nok (session != NULL); + + EP_ASSERT (ep_session_get_ipc_streaming_enabled (session) == false); + + ep_rt_wait_event_free (&session->rt_thread_shutdown_event); + + ep_session_provider_list_free (session->providers); + + ep_buffer_manager_free (session->buffer_manager); + ep_file_free (session->file); + + ep_rt_object_free (session); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_session_internals; +const char quiet_linker_empty_file_warning_eventpipe_session_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-session-provider-internals.c b/src/mono/mono/eventpipe/ep-session-provider-internals.c new file mode 100644 index 0000000000000..5c71bb7ef7af3 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-session-provider-internals.c @@ -0,0 +1,135 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +/* + * Forward declares of all static functions. + */ + +static +void +session_provider_free_func (void *session_provider); + +/* + * EventPipeSessionProvider. + */ + +static +void +session_provider_free_func (void *session_provider) +{ + ep_session_provider_free ((EventPipeSessionProvider *)session_provider); +} + +EventPipeSessionProvider * +ep_session_provider_alloc ( + const ep_char8_t *provider_name, + uint64_t keywords, + EventPipeEventLevel logging_level, + const ep_char8_t *filter_data) +{ + EventPipeSessionProvider *instance = ep_rt_object_alloc (EventPipeSessionProvider); + ep_raise_error_if_nok (instance != NULL); + + if (provider_name) { + instance->provider_name = ep_rt_utf8_string_dup (provider_name); + ep_raise_error_if_nok (instance->provider_name != NULL); + } + + if (filter_data) { + instance->filter_data = ep_rt_utf8_string_dup (filter_data); + ep_raise_error_if_nok (instance->filter_data != NULL); + } + + instance->keywords = keywords; + instance->logging_level = logging_level; + +ep_on_exit: + return instance; + +ep_on_error: + ep_session_provider_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_session_provider_free (EventPipeSessionProvider * session_provider) +{ + ep_return_void_if_nok (session_provider != NULL); + + ep_rt_utf8_string_free (session_provider->filter_data); + ep_rt_utf8_string_free (session_provider->provider_name); + ep_rt_object_free (session_provider); +} + +/* + * EventPipeSessionProviderList. + */ + +EventPipeSessionProviderList * +ep_session_provider_list_alloc ( + const EventPipeProviderConfiguration *configs, + uint32_t configs_len) +{ + ep_return_null_if_nok ((configs_len == 0) || (configs_len > 0 && configs != NULL)); + + EventPipeSessionProviderList *instance = ep_rt_object_alloc (EventPipeSessionProviderList); + ep_raise_error_if_nok (instance != NULL); + + instance->catch_all_provider = NULL; + + for (uint32_t i = 0; i < configs_len; ++i) { + const EventPipeProviderConfiguration *config = &configs [i]; + EP_ASSERT (config != NULL); + + // Enable all events if the provider name == '*', all keywords are on and the requested level == verbose. + if ((ep_rt_utf8_string_compare(ep_provider_get_wildcard_name_utf8 (), config->provider_name) == 0) && + (config->keywords == 0xFFFFFFFFFFFFFFFF) && + ((config->logging_level == EP_EVENT_LEVEL_VERBOSE) && (instance->catch_all_provider == NULL))) { + instance->catch_all_provider = ep_session_provider_alloc (NULL, 0xFFFFFFFFFFFFFFFF, EP_EVENT_LEVEL_VERBOSE, NULL ); + ep_raise_error_if_nok (instance->catch_all_provider != NULL); + } + else { + EventPipeSessionProvider * session_provider = ep_session_provider_alloc ( + config->provider_name, + config->keywords, + config->logging_level, + config->filter_data); + ep_rt_session_provider_list_append (&instance->providers, session_provider); + } + } + +ep_on_exit: + return instance; + +ep_on_error: + ep_session_provider_list_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_session_provider_list_free (EventPipeSessionProviderList *session_provider_list) +{ + ep_return_void_if_nok (session_provider_list != NULL); + + ep_rt_session_provider_list_free (&session_provider_list->providers, session_provider_free_func); + ep_session_provider_free (session_provider_list->catch_all_provider); + ep_rt_object_free (session_provider_list); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_session_provider_internals; +const char quiet_linker_empty_file_warning_eventpipe_session_provider_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-session-provider.c b/src/mono/mono/eventpipe/ep-session-provider.c new file mode 100644 index 0000000000000..08b6db7f5a0c3 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-session-provider.c @@ -0,0 +1,60 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#include "ep.h" + +/* + * Forward declares of all static functions. + */ + +static +void +session_provider_free_func (void *session_provider); + +/* + * EventPipeSessionProvider. + */ + +static +void +session_provider_free_func (void *session_provider) +{ + ep_session_provider_free ((EventPipeSessionProvider *)session_provider); +} + +/* + * EventPipeSessionProviderList. + */ + +void +ep_session_provider_list_clear (EventPipeSessionProviderList *session_provider_list) +{ + ep_return_void_if_nok (session_provider_list != NULL); + ep_rt_session_provider_list_clear (ep_session_provider_list_get_providers_ref (session_provider_list), session_provider_free_func); +} + +bool +ep_session_provider_list_is_empty (const EventPipeSessionProviderList *session_provider_list) +{ + return (ep_rt_provider_list_is_empty (ep_session_provider_list_get_providers_cref (session_provider_list)) && ep_session_provider_list_get_catch_all_provider (session_provider_list) == NULL); +} + +void +ep_session_provider_list_add_session_provider ( + EventPipeSessionProviderList *session_provider_list, + EventPipeSessionProvider *session_provider) +{ + ep_return_void_if_nok (session_provider != NULL); + ep_rt_session_provider_list_append (ep_session_provider_list_get_providers_ref (session_provider_list), session_provider); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_session_provider; +const char quiet_linker_empty_file_warning_eventpipe_session_provider = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-session-provider.h b/src/mono/mono/eventpipe/ep-session-provider.h new file mode 100644 index 0000000000000..7a2812f09f2e5 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-session-provider.h @@ -0,0 +1,86 @@ +#ifndef __EVENTPIPE_SESSION_PROVIDER_H__ +#define __EVENTPIPE_SESSION_PROVIDER_H__ + +#include "ep-rt-config.h" + +#ifdef ENABLE_PERFTRACING +#include "ep-types.h" + +/* + * EventPipeSessionProvider. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeSessionProvider { +#else +struct _EventPipeSessionProvider_Internal { +#endif + ep_char8_t *provider_name; + uint64_t keywords; + EventPipeEventLevel logging_level; + ep_char8_t *filter_data; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeSessionProvider { + uint8_t _internal [sizeof (struct _EventPipeSessionProvider_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventPipeSessionProvider *, session_provider, const ep_char8_t *, provider_name) +EP_DEFINE_GETTER(EventPipeSessionProvider *, session_provider, uint64_t, keywords) +EP_DEFINE_GETTER(EventPipeSessionProvider *, session_provider, EventPipeEventLevel, logging_level) +EP_DEFINE_GETTER(EventPipeSessionProvider *, session_provider, const ep_char8_t *, filter_data) + +EventPipeSessionProvider * +ep_session_provider_alloc ( + const ep_char8_t *provider_name, + uint64_t keywords, + EventPipeEventLevel logging_level, + const ep_char8_t *filter_data); + +void +ep_session_provider_free (EventPipeSessionProvider * session_provider); + +/* +* EventPipeSessionProviderList. + */ +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeSessionProviderList { +#else +struct _EventPipeSessionProviderList_Internal { +#endif + ep_rt_session_provider_list_t providers; + EventPipeSessionProvider *catch_all_provider; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeSessionProviderList { + uint8_t _internal [sizeof (struct _EventPipeSessionProviderList_Internal)]; +}; +#endif + +EP_DEFINE_GETTER_REF(EventPipeSessionProviderList *, session_provider_list, ep_rt_session_provider_list_t *, providers) +EP_DEFINE_GETTER(EventPipeSessionProviderList *, session_provider_list, EventPipeSessionProvider *, catch_all_provider) + +EventPipeSessionProviderList * +ep_session_provider_list_alloc ( + const EventPipeProviderConfiguration *configs, + uint32_t configs_len); + +void +ep_session_provider_list_free (EventPipeSessionProviderList *session_provider_list); + +void +ep_session_provider_list_clear (EventPipeSessionProviderList *session_provider_list); + +bool +ep_session_provider_list_is_empty (const EventPipeSessionProviderList *session_provider_list); + +void +ep_session_provider_list_add_session_provider ( + EventPipeSessionProviderList *session_provider_list, + EventPipeSessionProvider *session_provider); + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_SESSION_PROVIDER_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-session.c b/src/mono/mono/eventpipe/ep-session.c new file mode 100644 index 0000000000000..f4e4caa67e869 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-session.c @@ -0,0 +1,255 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#include "ep.h" + +/* + * Forward declares of all static functions. + */ + +static +void +session_disable_ipc_streaming_thread (EventPipeSession *session); + +static +void +session_create_ipc_streaming_thread_lock_held (EventPipeSession *session); + +/* + * EventPipeSession. + */ + +static +void +session_create_ipc_streaming_thread_lock_held (EventPipeSession *session) +{ + //TODO: Implement. +} + +static +void +session_disable_ipc_streaming_thread (EventPipeSession *session) +{ + EP_ASSERT (ep_session_get_session_type (session) == EP_SESSION_TYPE_IPCSTREAM); + EP_ASSERT (ep_session_get_ipc_streaming_enabled (session)); + + EP_ASSERT (!ep_rt_process_detach ()); + + // The IPC streaming thread will watch this value and exit + // when profiling is disabled. + ep_session_set_ipc_streaming_enabled (session, false); + + // Thread could be waiting on the event that there is new data to read. + ep_rt_wait_event_set (ep_buffer_manager_get_rt_wait_event_ref (ep_session_get_buffer_manager (session))); + + // Wait for the sampling thread to clean itself up. + ep_rt_wait_event_handle_t *rt_thread_shutdown_event = ep_session_get_rt_thread_shutdown_event_ref (session); + ep_rt_wait_event_wait (rt_thread_shutdown_event, EP_INFINITE_WAIT, false /* bAlertable */); + ep_rt_wait_event_free (rt_thread_shutdown_event); +} + +EventPipeSessionProvider * +ep_session_get_session_provider_lock_held ( + const EventPipeSession *session, + const EventPipeProvider *provider) +{ + ep_rt_config_requires_lock_held (); + + ep_return_null_if_nok (session != NULL && provider != NULL); + + EventPipeSessionProviderList *providers = ep_session_get_providers (session); + ep_return_null_if_nok (providers != NULL); + + EventPipeSessionProvider *catch_all = ep_session_provider_list_get_catch_all_provider (providers); + if (catch_all) + return catch_all; + + EventPipeSessionProvider *session_provider = ep_rt_session_provider_list_find_by_name (ep_session_provider_list_get_providers_ref (providers), ep_provider_get_provider_name (provider)); + + ep_rt_config_requires_lock_held (); + return session_provider; +} + +void +ep_session_enable_rundown_lock_held (EventPipeSession *session) +{ + ep_rt_config_requires_lock_held (); + + ep_return_void_if_nok (session != NULL); + + //TODO: This is CoreCLR specific keywords for native ETW events (ending up in event pipe). + //! The keywords below seems to correspond to: + //! LoaderKeyword (0x00000008) + //! JitKeyword (0x00000010) + //! NgenKeyword (0x00000020) + //! unused_keyword (0x00000100) + //! JittedMethodILToNativeMapKeyword (0x00020000) + //! ThreadTransferKeyword (0x80000000) + const uint64_t keywords = 0x80020138; + const uint32_t verbose_logging_level = (uint32_t)EP_EVENT_LEVEL_VERBOSE; + + EventPipeProviderConfiguration rundown_providers [2]; + uint32_t rundown_providers_len = EP_ARRAY_SIZE (rundown_providers); + + ep_provider_config_init (&rundown_providers [0], ep_config_get_public_provider_name_utf8 (), keywords, verbose_logging_level, NULL); // Public provider. + ep_provider_config_init (&rundown_providers [1], ep_config_get_rundown_provider_name_utf8 (), keywords, verbose_logging_level, NULL); // Rundown provider. + + //TODO: This is CoreCLR specific provider. + // update the provider context here since the callback doesn't happen till we actually try to do rundown. + //MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.Level = VerboseLoggingLevel; + //MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.EnabledKeywordsBitmask = Keywords; + //MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context.EventPipeProvider.IsEnabled = true; + + // Update provider list with rundown configuration. + for (uint32_t i = 0; i < rundown_providers_len; ++i) { + const EventPipeProviderConfiguration *config = &rundown_providers [i]; + + EventPipeSessionProvider *session_provider = ep_session_provider_alloc ( + ep_provider_config_get_provider_name (config), + ep_provider_config_get_keywords (config), + ep_provider_config_get_logging_level (config), + ep_provider_config_get_filter_data (config)); + + ep_session_add_session_provider (session, session_provider); + } + + ep_session_set_rundown_enabled (session, true); + + ep_rt_config_requires_lock_held (); + return; +} + +void +ep_session_execute_rundown_lock_held (EventPipeSession *session) +{ + //TODO: Implement. This is mainly runtime specific implementation + //since it will emit native trace events into the pipe (using CoreCLR's ETW support). +} + +void +ep_session_suspend_write_event_lock_held (EventPipeSession *session) +{ + //TODO: Implement. +} + +void +ep_session_write_sequence_point_unbuffered_lock_held (EventPipeSession *session) +{ + //TODO: Implement. +} + +void +ep_session_start_streaming_lock_held (EventPipeSession *session) +{ + ep_rt_config_requires_lock_held (); + + ep_return_void_if_nok (session != NULL); + + if (ep_session_get_file (session) != NULL) + ep_file_initialize_file (ep_session_get_file (session)); + + if (ep_session_get_session_type (session) == EP_SESSION_TYPE_IPCSTREAM) + session_create_ipc_streaming_thread_lock_held (session); + + ep_rt_config_requires_lock_held (); + return; +} + +bool +ep_session_is_valid (const EventPipeSession *session) +{ + return !ep_session_provider_list_is_empty (ep_session_get_providers (session)); +} + +void +ep_session_add_session_provider (EventPipeSession *session, EventPipeSessionProvider *session_provider) +{ + ep_return_void_if_nok (session != NULL); + ep_session_provider_list_add_session_provider (ep_session_get_providers (session), session_provider); +} + +void +ep_session_disable (EventPipeSession *session) +{ + ep_return_void_if_nok (session != NULL); + if (ep_session_get_session_type (session) == EP_SESSION_TYPE_IPCSTREAM && ep_session_get_ipc_streaming_enabled (session)) + session_disable_ipc_streaming_thread (session); + + bool ignored; + ep_session_write_all_buffers_to_file (session, &ignored); + ep_session_provider_list_clear (ep_session_get_providers (session)); +} + +bool +ep_session_write_all_buffers_to_file (EventPipeSession *session, bool *events_written) +{ + //TODO: Implement. + *events_written = false; + return true; +} + +EventPipeEventInstance * +ep_session_get_next_event (EventPipeSession *session) +{ + //TODO: Implement. + return NULL; +} + +EventPipeWaitHandle +ep_session_get_wait_event (EventPipeSession *session) +{ + ep_raise_error_if_nok (session != NULL); + + EventPipeBufferManager *buffer_manager = ep_session_get_buffer_manager (session); + ep_raise_error_if_nok (buffer_manager != NULL); + + return ep_rt_wait_event_get_wait_handle (ep_buffer_manager_get_rt_wait_event_ref (buffer_manager)); + +ep_on_error: + return 0; +} + +uint64_t +ep_session_get_mask (const EventPipeSession *session) +{ + return ((uint64_t)1 << ep_session_get_index (session)); +} + +bool +ep_session_get_rundown_enabled (const EventPipeSession *session) +{ + return (ep_rt_volatile_load_uint32_t(ep_session_get_rundown_enabled_cref (session)) ? true : false); +} + +void +ep_session_set_rundown_enabled ( + EventPipeSession *session, + bool enabled) +{ + ep_rt_volatile_store_uint32_t (ep_session_get_rundown_enabled_ref (session), (enabled) ? 1 : 0); +} + +bool +ep_session_get_ipc_streaming_enabled (const EventPipeSession *session) +{ + return (ep_rt_volatile_load_uint32_t(ep_session_get_ipc_streaming_enabled_cref (session)) ? true : false); +} + +void +ep_session_set_ipc_streaming_enabled ( + EventPipeSession *session, + bool enabled) +{ + ep_rt_volatile_store_uint32_t (ep_session_get_ipc_streaming_enabled_ref (session), (enabled) ? 1 : 0); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_session; +const char quiet_linker_empty_file_warning_eventpipe_session = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-session.h b/src/mono/mono/eventpipe/ep-session.h new file mode 100644 index 0000000000000..cfcf1476938be --- /dev/null +++ b/src/mono/mono/eventpipe/ep-session.h @@ -0,0 +1,130 @@ +#ifndef __EVENTPIPE_SESSION_H__ +#define __EVENTPIPE_SESSION_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventPipeSession. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeSession { +#else +struct _EventPipeSession_Internal { +#endif + uint32_t index; + EventPipeSessionProviderList *providers; + EventPipeBufferManager *buffer_manager; + volatile uint32_t rundown_enabled; + EventPipeSessionType session_type; + EventPipeSerializationFormat format; + bool rundown_requested; + uint64_t session_start_time; + uint64_t session_start_timestamp; + EventPipeFile *file; + volatile uint32_t ipc_streaming_enabled; + EventPipeThread ipc_streaming_thread; + ep_rt_wait_event_handle_t rt_thread_shutdown_event; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeSession { + uint8_t _internal [sizeof (struct _EventPipeSession_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventPipeSession *, session, uint32_t, index) +EP_DEFINE_GETTER(EventPipeSession *, session, EventPipeSessionProviderList *, providers) +EP_DEFINE_GETTER(EventPipeSession *, session, EventPipeBufferManager *, buffer_manager) +EP_DEFINE_GETTER_REF(EventPipeSession *, session, volatile uint32_t *, rundown_enabled) +EP_DEFINE_GETTER(EventPipeSession *, session, EventPipeSessionType, session_type) +EP_DEFINE_GETTER(EventPipeSession *, session, EventPipeSerializationFormat, format) +EP_DEFINE_GETTER(EventPipeSession *, session, bool, rundown_requested) +EP_DEFINE_GETTER(EventPipeSession *, session, uint64_t, session_start_time) +EP_DEFINE_GETTER(EventPipeSession *, session, uint64_t, session_start_timestamp) +EP_DEFINE_GETTER(EventPipeSession *, session, EventPipeFile *, file) +EP_DEFINE_GETTER_REF(EventPipeSession *, session, volatile uint32_t *, ipc_streaming_enabled) +EP_DEFINE_GETTER_REF(EventPipeSession *, session, EventPipeThread *, ipc_streaming_thread) +EP_DEFINE_GETTER_REF(EventPipeSession *, session, ep_rt_wait_event_handle_t *, rt_thread_shutdown_event) + +EventPipeSession * +ep_session_alloc ( + uint32_t index, + const ep_char8_t *output_path, + IpcStream *stream, + EventPipeSessionType session_type, + EventPipeSerializationFormat format, + bool rundown_requested, + uint32_t circular_buffer_size_in_mb, + const EventPipeProviderConfiguration *providers, + uint32_t providers_len, + bool rundown_enabled); + +void +ep_session_free (EventPipeSession *session); + +EventPipeSessionProvider * +ep_session_get_session_provider_lock_held ( + const EventPipeSession *session, + const EventPipeProvider *provider); + +void +ep_session_enable_rundown_lock_held (EventPipeSession *session); + +void +ep_session_execute_rundown_lock_held (EventPipeSession *session); + +void +ep_session_suspend_write_event_lock_held (EventPipeSession *session); + +void +ep_session_write_sequence_point_unbuffered_lock_held (EventPipeSession *session); + +void +ep_session_start_streaming_lock_held (EventPipeSession *session); + +bool +ep_session_is_valid (const EventPipeSession *session); + +void +ep_session_add_session_provider ( + EventPipeSession *session, + EventPipeSessionProvider *session_provider); + +void +ep_session_disable (EventPipeSession *session); + +bool +ep_session_write_all_buffers_to_file (EventPipeSession *session, bool *events_written); + +EventPipeEventInstance * +ep_session_get_next_event (EventPipeSession *session); + +EventPipeWaitHandle +ep_session_get_wait_event (EventPipeSession *session); + +uint64_t +ep_session_get_mask (const EventPipeSession *session); + +bool +ep_session_get_rundown_enabled (const EventPipeSession *session); + +void +ep_session_set_rundown_enabled ( + EventPipeSession *session, + bool enabled); + +bool +ep_session_get_ipc_streaming_enabled (const EventPipeSession *session); + +void +ep_session_set_ipc_streaming_enabled ( + EventPipeSession *session, + bool enabled); + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_SESSION_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-stack-contents.h b/src/mono/mono/eventpipe/ep-stack-contents.h new file mode 100644 index 0000000000000..6ffe98d657004 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-stack-contents.h @@ -0,0 +1,172 @@ +#ifndef __EVENTPIPE_STACKCONTENTS_H__ +#define __EVENTPIPE_STACKCONTENTS_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventPipeStackContents. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeStackContents { +#else +struct _EventPipeStackContents_Internal { +#endif + // Array of IP values from a stack crawl. + // Top of stack is at index 0. + uintptr_t stack_frames [EP_MAX_STACK_DEPTH]; +#ifdef EP_CHECKED_BUILD + // Parallel array of MethodDesc pointers. + // Used for debug-only stack printing. + ep_rt_method_desc_t *methods [EP_MAX_STACK_DEPTH]; +#endif + + // The next available slot in stack_frames. + uint32_t next_available_frame; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeStackContents { + uint8_t _internal [sizeof (struct _EventPipeStackContents_Internal)]; +}; +#endif + +EP_DEFINE_GETTER_ARRAY_REF(EventPipeStackContents *, stack_contents, uintptr_t *, const uintptr_t *, stack_frames, stack_frames[0]) +#ifdef EP_CHECKED_BUILD +EP_DEFINE_GETTER_ARRAY_REF(EventPipeStackContents *, stack_contents, ep_rt_method_desc_t **, ep_rt_method_desc_t *const*, methods, methods[0]) +#endif +EP_DEFINE_GETTER(EventPipeStackContents *, stack_contents, uint32_t, next_available_frame) +EP_DEFINE_SETTER(EventPipeStackContents *, stack_contents, uint32_t, next_available_frame) + +EventPipeStackContents * +ep_stack_contents_alloc (void); + +EventPipeStackContents * +ep_stack_contents_init (EventPipeStackContents *stack_contents); + +void +ep_stack_contents_fini (EventPipeStackContents *stack_contents); + +void +ep_stack_contents_free (EventPipeStackContents *stack_contents); + +static +inline +void +ep_stack_contents_copyto ( + EventPipeStackContents *stack_contents, + EventPipeStackContents *dest) +{ + memcpy ( + ep_stack_contents_get_stack_frames_ref (dest), + ep_stack_contents_get_stack_frames_ref (stack_contents), + ep_stack_contents_get_next_available_frame (stack_contents) * sizeof (uintptr_t)); + +#ifdef EP_CHECKED_BUILD + memcpy ( + ep_stack_contents_get_methods_ref (dest), + ep_stack_contents_get_methods_ref (stack_contents), + ep_stack_contents_get_next_available_frame (stack_contents) * sizeof (ep_rt_method_desc_t *)); +#endif + + ep_stack_contents_set_next_available_frame (dest, ep_stack_contents_get_next_available_frame (stack_contents)); +} + +static +inline +void +ep_stack_contents_reset (EventPipeStackContents *stack_contents) +{ + ep_stack_contents_set_next_available_frame (stack_contents, 0); +} + +static +inline +bool +ep_stack_contents_is_empty (EventPipeStackContents *stack_contents) +{ + return (ep_stack_contents_get_next_available_frame (stack_contents) == 0); +} + +static +inline +uint32_t +ep_stack_contents_get_length (EventPipeStackContents *stack_contents) +{ + return ep_stack_contents_get_next_available_frame (stack_contents); +} + +static +inline +uintptr_t +ep_stack_contents_get_ip ( + EventPipeStackContents *stack_contents, + uint32_t frame_index) +{ + EP_ASSERT (frame_index < EP_MAX_STACK_DEPTH); + if (frame_index >= EP_MAX_STACK_DEPTH) + return 0; + + return ep_stack_contents_get_stack_frames_cref (stack_contents)[frame_index]; +} + +#ifdef EP_CHECKED_BUILD +static +inline +ep_rt_method_desc_t * +ep_stack_contents_get_method ( + EventPipeStackContents *stack_contents, + uint32_t frame_index) +{ + EP_ASSERT (frame_index < EP_MAX_STACK_DEPTH); + if (frame_index >= EP_MAX_STACK_DEPTH) + return NULL; + + return ep_stack_contents_get_methods_cref (stack_contents)[frame_index]; +} +#endif + +static +inline +void +ep_stack_contents_append ( + EventPipeStackContents *stack_contents, + uintptr_t control_pc, + ep_rt_method_desc_t *method) +{ + EP_ASSERT (stack_contents != NULL); + uint32_t next_frame = ep_stack_contents_get_next_available_frame (stack_contents); + if (next_frame < EP_MAX_STACK_DEPTH) { + ep_stack_contents_get_stack_frames_ref (stack_contents)[next_frame] = control_pc; +#ifdef EP_CHECKED_BUILD + ep_stack_contents_get_methods_ref (stack_contents)[next_frame] = method; +#endif + next_frame++; + ep_stack_contents_set_next_available_frame (stack_contents, next_frame); + } +} + +static +inline +uint8_t * +ep_stack_contents_get_pointer (const EventPipeStackContents *stack_contents) +{ + EP_ASSERT (stack_contents != NULL); + return (uint8_t *)ep_stack_contents_get_stack_frames_cref (stack_contents); +} + +static +inline +uint32_t +ep_stack_contents_get_size (const EventPipeStackContents *stack_contents) +{ + EP_ASSERT (stack_contents != NULL); + return (ep_stack_contents_get_next_available_frame (stack_contents) * sizeof (uintptr_t)); +} + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_STACKCONTENTS_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-stream-internals.c b/src/mono/mono/eventpipe/ep-stream-internals.c new file mode 100644 index 0000000000000..c62c857552aec --- /dev/null +++ b/src/mono/mono/eventpipe/ep-stream-internals.c @@ -0,0 +1,392 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +/* + * Forward declares of all static functions. + */ + +static +void +file_stream_writer_free_func (void *stream); + +static +bool +file_stream_writer_write_func ( + void *stream, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written); + +static +void +file_write_end (EventPipeFile *file); + +static +void +ipc_stream_writer_free_func (void *stream); + +static +bool +ipc_stream_writer_write_func ( + void *stream, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written); + +/* + * FastSerializableObject. + */ + +FastSerializableObject * +ep_fast_serializable_object_init ( + FastSerializableObject *fast_serializable_object, + FastSerializableObjectVtable *vtable, + int32_t object_version, + int32_t min_reader_version, + bool is_private) +{ + EP_ASSERT (fast_serializable_object != NULL && vtable != NULL); + + fast_serializable_object->vtable = vtable; + fast_serializable_object->object_version = object_version; + fast_serializable_object->min_reader_version = min_reader_version; + fast_serializable_object->is_private = is_private; + + return fast_serializable_object; +} + +void +ep_fast_serializable_object_fini (FastSerializableObject *fast_serializable_ojbect) +{ + ; +} + +void +ep_fast_serializable_object_free_vcall (FastSerializableObject *fast_serializable_ojbect) +{ + ep_return_void_if_nok (fast_serializable_ojbect != NULL); + + EP_ASSERT (fast_serializable_ojbect->vtable != NULL); + FastSerializableObjectVtable *vtable = fast_serializable_ojbect->vtable; + + EP_ASSERT (vtable->free_func != NULL); + vtable->free_func (fast_serializable_ojbect); +} + +void +ep_fast_serializable_object_fast_serialize_vcall ( + FastSerializableObject *fast_serializable_ojbect, + FastSerializer *fast_serializer) +{ + EP_ASSERT (fast_serializable_ojbect != NULL && fast_serializable_ojbect->vtable != NULL); + FastSerializableObjectVtable *vtable = fast_serializable_ojbect->vtable; + + EP_ASSERT (vtable->fast_serialize_func != NULL); + vtable->fast_serialize_func (fast_serializable_ojbect, fast_serializer); +} + +const ep_char8_t * +ep_fast_serializable_object_get_type_name_vcall (FastSerializableObject *fast_serializable_ojbect) +{ + EP_ASSERT (fast_serializable_ojbect != NULL && fast_serializable_ojbect->vtable != NULL); + FastSerializableObjectVtable *vtable = fast_serializable_ojbect->vtable; + + EP_ASSERT (vtable->get_type_name_func != NULL); + return vtable->get_type_name_func (fast_serializable_ojbect); +} + +/* + * FastSerializer. + */ +FastSerializer * +ep_fast_serializer_alloc (StreamWriter *stream_writer) +{ + ep_return_null_if_nok (stream_writer != NULL); + + FastSerializer *instance = ep_rt_object_alloc (FastSerializer); + ep_raise_error_if_nok (instance != NULL); + + // Ownership transfered. + instance->stream_writer = stream_writer; + instance->required_padding = 0; + instance->write_error_encountered = false; + + const ep_char8_t signature[] = "!FastSerialization.1"; // the consumer lib expects exactly the same string, it must not be changed + uint32_t signature_len = EP_ARRAY_SIZE (signature) - 1; + ep_fast_serializer_write_string (instance, signature, signature_len); + +ep_on_exit: + return instance; + +ep_on_error: + ep_fast_serializer_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_fast_serializer_free (FastSerializer *fast_serializer) +{ + ep_return_void_if_nok (fast_serializer != NULL); + + EP_ASSERT (fast_serializer->stream_writer != NULL); + ep_stream_writer_free_vcall (fast_serializer->stream_writer); + + ep_rt_object_free (fast_serializer); +} + +/* + * FileStream. + */ + +FileStream * +ep_file_stream_alloc (void) +{ + return ep_rt_object_alloc (FileStream); +} + +void +ep_file_stream_free (FileStream *file_stream) +{ + ep_return_void_if_nok (file_stream != NULL); + + ep_file_stream_close (file_stream); + ep_rt_object_free (file_stream); +} + +/* + * FileStreamWriter. + */ + +static +void +file_stream_writer_free_func (void *stream) +{ + ep_file_stream_writer_free ((FileStreamWriter *)stream); +} + +static +bool +file_stream_writer_write_func ( + void *stream, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written) +{ + EP_ASSERT (stream != NULL); + + return ep_file_stream_writer_write ( + (FileStreamWriter *)stream, + buffer, + bytes_to_write, + bytes_written); +} + +static StreamWriterVtable file_stream_writer_vtable = { + file_stream_writer_free_func, + file_stream_writer_write_func }; + +FileStreamWriter * +ep_file_stream_writer_alloc (const ep_char8_t *output_file_path) +{ + ep_return_null_if_nok (output_file_path != NULL); + + FileStreamWriter *instance = ep_rt_object_alloc (FileStreamWriter); + ep_raise_error_if_nok (instance != NULL); + + ep_raise_error_if_nok (ep_stream_writer_init ( + &instance->stream_writer, + &file_stream_writer_vtable) != NULL); + + instance->file_stream = ep_file_stream_alloc (); + ep_raise_error_if_nok (instance->file_stream != NULL); + + if (!ep_file_stream_open_write (instance->file_stream, output_file_path)) { + EP_ASSERT (!"Unable to open file for write."); + ep_raise_error (); + } + +ep_on_exit: + return instance; + +ep_on_error: + ep_file_stream_writer_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_file_stream_writer_free (FileStreamWriter *file_stream_writer) +{ + ep_return_void_if_nok (file_stream_writer != NULL); + + ep_file_stream_free (file_stream_writer->file_stream); + ep_stream_writer_fini (&file_stream_writer->stream_writer); + ep_rt_object_free (file_stream_writer); +} + +/* + * IpcStream. + */ + +IpcStream * +ep_ipc_stream_alloc (ep_rt_ipc_handle_t rt_ipc) +{ + IpcStream *instance = ep_rt_object_alloc (IpcStream); + ep_raise_error_if_nok (instance != NULL); + + //Transfer ownership. + instance->rt_ipc = rt_ipc; + +ep_on_exit: + return instance; + +ep_on_error: + ep_ipc_stream_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_ipc_stream_free (IpcStream *ipc_stream) +{ + ep_return_void_if_nok (ipc_stream != NULL); + + ep_ipc_stream_flush (ipc_stream); + ep_ipc_stream_disconnect (ipc_stream); + ep_ipc_stream_close (ipc_stream); + + ep_rt_object_free (ipc_stream); +} + +/* + * IpcStreamWriter. + */ + +static +void +ipc_stream_writer_free_func (void *stream) +{ + ep_ipc_stream_writer_free ((IpcStreamWriter *)stream); +} + +static +bool +ipc_stream_writer_write_func ( + void *stream, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written) +{ + EP_ASSERT (stream != NULL); + + return ep_ipc_stream_writer_write ( + (IpcStreamWriter *)stream, + buffer, + bytes_to_write, + bytes_written); +} + +static StreamWriterVtable ipc_stream_writer_vtable = { + ipc_stream_writer_free_func, + ipc_stream_writer_write_func }; + +IpcStreamWriter * +ep_ipc_stream_writer_alloc ( + uint64_t id, + IpcStream *stream) +{ + IpcStreamWriter *instance = ep_rt_object_alloc (IpcStreamWriter); + ep_raise_error_if_nok (instance != NULL); + + ep_raise_error_if_nok (ep_stream_writer_init ( + &instance->stream_writer, + &ipc_stream_writer_vtable) != NULL); + + //Ownership transfered. + instance->ipc_stream = stream; + +ep_on_exit: + return instance; + +ep_on_error: + ep_ipc_stream_writer_free (instance); + + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_ipc_stream_writer_free (IpcStreamWriter *ipc_stream_writer) +{ + ep_return_void_if_nok (ipc_stream_writer != NULL); + + ep_ipc_stream_free (ipc_stream_writer->ipc_stream); + ep_stream_writer_fini (&ipc_stream_writer->stream_writer); + ep_rt_object_free (ipc_stream_writer); +} + +/* + * StreamWriter. + */ + +StreamWriter * +ep_stream_writer_init ( + StreamWriter *stream_writer, + StreamWriterVtable *vtable) +{ + EP_ASSERT (stream_writer != NULL && vtable != NULL); + + stream_writer->vtable = vtable; + + return stream_writer; +} + +void +ep_stream_writer_fini (StreamWriter *stream_writer) +{ + ; +} + +void +ep_stream_writer_free_vcall (StreamWriter *stream_writer) +{ + ep_return_void_if_nok (stream_writer != NULL); + + EP_ASSERT (stream_writer->vtable != NULL); + StreamWriterVtable *vtable = stream_writer->vtable; + + EP_ASSERT (vtable->free_func != NULL); + vtable->free_func (stream_writer); +} + +bool +ep_stream_writer_write_vcall ( + StreamWriter *stream_writer, + const uint8_t *buffer, + const uint32_t bytes_to_write, + uint32_t *bytes_written) +{ + EP_ASSERT (stream_writer != NULL && stream_writer->vtable != NULL); + StreamWriterVtable *vtable = stream_writer->vtable; + + EP_ASSERT (vtable->write_func != NULL); + return vtable->write_func (stream_writer, buffer, bytes_to_write, bytes_written); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_stream_internals; +const char quiet_linker_empty_file_warning_eventpipe_stream_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-stream.c b/src/mono/mono/eventpipe/ep-stream.c new file mode 100644 index 0000000000000..5d9ee0060aa38 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-stream.c @@ -0,0 +1,280 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#include "ep.h" + +/* + * Forward declares of all static functions. + */ + +static +void +fast_serializer_write_serialization_type ( + FastSerializer *fast_serializer, + FastSerializableObject *fast_serializable_ojbect); + +/* + * FastSerializableObject. + */ + +void +ep_fast_serializable_object_fast_serialize ( + FastSerializableObject *fast_serializable_ojbect, + FastSerializer *fast_serializer) +{ + ep_fast_serializable_object_fast_serialize_vcall (fast_serializable_ojbect, fast_serializer); +} + +const ep_char8_t * +ep_fast_serializable_object_get_type_name (FastSerializableObject *fast_serializable_ojbect) +{ + return ep_fast_serializable_object_get_type_name_vcall (fast_serializable_ojbect); +} + +/* + * FastSerializer. + */ + +static +void +fast_serializer_write_serialization_type ( + FastSerializer *fast_serializer, + FastSerializableObject *fast_serializable_ojbect) +{ + ep_return_void_if_nok (fast_serializable_ojbect != NULL); + + // Write the BeginObject tag. + ep_fast_serializer_write_tag (fast_serializer, ep_fast_serializable_object_get_is_private (fast_serializable_ojbect) ? FAST_SERIALIZER_TAGS_BEGIN_PRIVATE_OBJECT : FAST_SERIALIZER_TAGS_BEGIN_OBJECT, NULL, 0); + + // Write a NullReferenceTag, which implies that the following fields belong to SerializationType. + ep_fast_serializer_write_tag (fast_serializer, FAST_SERIALIZER_TAGS_NULL_REFERENCE, NULL, 0); + + // Write the SerializationType version fields. + int32_t serialization_type [2]; + serialization_type [0] = ep_fast_serializable_object_get_object_version (fast_serializable_ojbect); + serialization_type [1] = ep_fast_serializable_object_get_min_reader_version (fast_serializable_ojbect); + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)serialization_type, sizeof (serialization_type)); + + // Write the SerializationType TypeName field. + const ep_char8_t *type_name = ep_fast_serializable_object_get_type_name_vcall (fast_serializable_ojbect); + if (type_name) + ep_fast_serializer_write_string (fast_serializer, type_name, (uint32_t)ep_rt_utf8_string_len (type_name)); + + // Write the EndObject tag. + ep_fast_serializer_write_tag (fast_serializer, FAST_SERIALIZER_TAGS_END_OBJECT, NULL, 0); +} + +void +ep_fast_serializer_write_buffer ( + FastSerializer *fast_serializer, + const uint8_t *buffer, + uint32_t buffer_len) +{ + ep_return_void_if_nok (fast_serializer != NULL && buffer != NULL && buffer_len > 0); + ep_return_void_if_nok (ep_fast_serializer_get_write_error_encountered (fast_serializer) != true && ep_fast_serializer_get_stream_writer (fast_serializer) != NULL); + + uint32_t bytes_written = 0; + bool result = ep_stream_writer_write (ep_fast_serializer_get_stream_writer (fast_serializer), buffer, buffer_len, &bytes_written); + + uint32_t required_padding = ep_fast_serializer_get_required_padding (fast_serializer); + required_padding = (FAST_SERIALIZER_ALIGNMENT_SIZE + required_padding - (bytes_written & FAST_SERIALIZER_ALIGNMENT_SIZE)) % FAST_SERIALIZER_ALIGNMENT_SIZE; + ep_fast_serializer_set_required_padding (fast_serializer, required_padding); + + // This will cause us to stop writing to the file. + // The file will still remain open until shutdown so that we don't + // have to take a lock at this level when we touch the file stream. + ep_fast_serializer_set_write_error_encountered (fast_serializer, ((buffer_len != bytes_written) || !result)); +} + +void +ep_fast_serializer_write_object ( + FastSerializer *fast_serializer, + FastSerializableObject *fast_serializable_ojbect) +{ + ep_return_void_if_nok (fast_serializer != NULL && fast_serializable_ojbect != NULL); + + ep_fast_serializer_write_tag (fast_serializer, ep_fast_serializable_object_get_is_private (fast_serializable_ojbect) ? FAST_SERIALIZER_TAGS_BEGIN_PRIVATE_OBJECT : FAST_SERIALIZER_TAGS_BEGIN_OBJECT, NULL, 0); + + fast_serializer_write_serialization_type (fast_serializer, fast_serializable_ojbect); + + // Ask the object to serialize itself using the current serializer. + ep_fast_serializable_object_fast_serialize_vcall (fast_serializable_ojbect, fast_serializer); + + ep_fast_serializer_write_tag (fast_serializer, FAST_SERIALIZER_TAGS_END_OBJECT, NULL, 0); +} + +void +ep_fast_serializer_write_string ( + FastSerializer *fast_serializer, + const ep_char8_t *contents, + uint32_t contents_len) +{ + // Write teh string length. + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&contents_len, sizeof (contents_len)); + + //Wirte the string contents. + ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)contents, contents_len); +} + +void +ep_fast_serializer_write_tag ( + FastSerializer *fast_serializer, + FastSerializerTags tag, + const uint8_t *payload, + uint32_t payload_len) +{ + uint8_t tag_as_byte = tag; + ep_fast_serializer_write_buffer (fast_serializer, &tag_as_byte, sizeof (tag_as_byte)); + if (payload != NULL) { + EP_ASSERT (payload_len > 0); + ep_fast_serializer_write_buffer (fast_serializer, payload, payload_len); + } +} + +/* +* FileStream. +*/ + +bool +ep_file_stream_open_write ( + FileStream *file_stream, + const ep_char8_t *path) +{ + ep_return_false_if_nok (file_stream != NULL); + + ep_rt_file_handle_t rt_file = ep_rt_file_open_write (path); + ep_raise_error_if_nok (rt_file != NULL); + + ep_file_stream_set_rt_file (file_stream, rt_file); + return true; + +ep_on_error: + return false; +} + +bool +ep_file_stream_close (FileStream *file_stream) +{ + ep_return_false_if_nok (file_stream != NULL); + return ep_rt_file_close (ep_file_stream_get_rt_file (file_stream)); +} + +bool +ep_file_stream_write ( + FileStream *file_stream, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written) +{ + ep_return_false_if_nok (file_stream != NULL && buffer != NULL && bytes_to_write > 0 && bytes_written != NULL); + return ep_rt_file_write (ep_file_stream_get_rt_file (file_stream), buffer, bytes_to_write, bytes_written); +} + +/* + * FileStreamWriter. + */ + +bool +ep_file_stream_writer_write ( + FileStreamWriter *file_stream_writer, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written) +{ + ep_return_false_if_nok (file_stream_writer != NULL && buffer != NULL && bytes_to_write > 0 && bytes_written != NULL); + + ep_raise_error_if_nok (ep_file_stream_writer_get_file_stream (file_stream_writer) != NULL); + + return ep_file_stream_write (ep_file_stream_writer_get_file_stream (file_stream_writer), buffer, bytes_to_write, bytes_written); + +ep_on_error: + *bytes_written = 0; + return false; +} + +/* +* IpcStream. +*/ + +bool +ep_ipc_stream_flush (IpcStream *ipc_stream) +{ + //TODO: Implement. + return false; +} + +bool +ep_ipc_stream_disconnect (IpcStream *ipc_stream) +{ + //TODO: Implement. + return false; +} + +bool +ep_ipc_stream_close (IpcStream *ipc_stream) +{ + //TODO: Implement. + return false; +} + +bool +ep_ipc_stream_write ( + IpcStream *ipc_stream, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written) +{ + //TODO: Implement. + return false; +} + +/* + * IpcStreamWriter. + */ + +bool +ep_ipc_stream_writer_write ( + IpcStreamWriter *ipc_stream_writer, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written) +{ + ep_return_false_if_nok (ipc_stream_writer != NULL && buffer != NULL && bytes_to_write > 0 && bytes_written != NULL); + + ep_raise_error_if_nok (ep_ipc_stream_writer_get_ipc_stream (ipc_stream_writer) != NULL); + + return ep_ipc_stream_write (ep_ipc_stream_writer_get_ipc_stream (ipc_stream_writer), buffer, bytes_to_write, bytes_written); + +ep_on_error: + *bytes_written = 0; + return false; +} + +/* + * StreamWriter. + */ + +bool +ep_stream_writer_write ( + StreamWriter *stream_writer, + const uint8_t *buffer, + const uint32_t bytes_to_write, + uint32_t *bytes_written) +{ + return ep_stream_writer_write_vcall ( + stream_writer, + buffer, + bytes_to_write, + bytes_written); +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_stream; +const char quiet_linker_empty_file_warning_eventpipe_stream = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-stream.h b/src/mono/mono/eventpipe/ep-stream.h new file mode 100644 index 0000000000000..16d9c9e49b8e3 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-stream.h @@ -0,0 +1,364 @@ +#ifndef __EVENTPIPE_STREAM_H__ +#define __EVENTPIPE_STREAM_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +// the enumeration has a specific set of values to keep it compatible with consumer library +// it's sibling is defined in https://github.com/Microsoft/perfview/blob/10d1f92b242c98073b3817ac5ee6d98cd595d39b/src/FastSerialization/FastSerialization.cs#L2295 +typedef enum +{ + FAST_SERIALIZER_TAGS_ERROR = 0, // To improve debugabilty, 0 is an illegal tag. + FAST_SERIALIZER_TAGS_NULL_REFERENCE = 1, // Tag for a null object forwardReference. + FAST_SERIALIZER_TAGS_OBJECT_REFERENCE = 2, // Followed by StreamLabel + // 3 used to belong to ForwardReference, which got removed in V3 + FAST_SERIALIZER_TAGS_BEGIN_OBJECT = 4, // Followed by Type object, object data, tagged EndObject + FAST_SERIALIZER_TAGS_BEGIN_PRIVATE_OBJECT = 5, // Like beginObject, but not placed in interning table on deserialiation + FAST_SERIALIZER_TAGS_END_OBJECT = 6, // Placed after an object to mark its end. + // 7 used to belong to ForwardDefinition, which got removed in V3 + FAST_SERIALIZER_TAGS_BYTE = 8, + FAST_SERIALIZER_TAGS_INT16, + FAST_SERIALIZER_TAGS_INT32, + FAST_SERIALIZER_TAGS_INT64, + FAST_SERIALIZER_TAGS_SKIP_REGION, + FAST_SERIALIZER_TAGS_STRING, + FAST_SERIALIZER_TAGS_BLOB, + FAST_SERIALIZER_TAGS_LIMIT // Just past the last valid tag, used for asserts. +} FastSerializerTags; + +/* + * StreamWriter. + */ + +typedef void (*StreamWriterFreeFunc)(void *stream); +typedef bool (*StreamWriterWriteFunc)(void *stream, const uint8_t *buffer, const uint32_t bytes_to_write, uint32_t *bytes_written); + +struct _StreamWriterVtable { + StreamWriterFreeFunc free_func; + StreamWriterWriteFunc write_func; +}; + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _StreamWriter { +#else +struct _StreamWriter_Internal { +#endif + StreamWriterVtable *vtable; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _StreamWriter { + uint8_t _internal [sizeof (struct _StreamWriter_Internal)]; +}; +#endif + +StreamWriter * +ep_stream_writer_init ( + StreamWriter *stream_writer, + StreamWriterVtable *vtable); + +void +ep_stream_writer_fini (StreamWriter *stream_writer); + +bool +ep_stream_writer_write ( + StreamWriter *stream_writer, + const uint8_t *buffer, + const uint32_t bytes_to_write, + uint32_t *bytes_written); + +void +ep_stream_writer_free_vcall (StreamWriter *stream_writer); + +bool +ep_stream_writer_write_vcall ( + StreamWriter *stream_writer, + const uint8_t *buffer, + const uint32_t bytes_to_write, + uint32_t *bytes_written); + +/* + * FastSerializableObject. + */ + +typedef void (*FastSerializableObjectFreeFunc)(void *object); +typedef void (*FastSerializableObjectFastSerializeFunc)(void *object, FastSerializer *fast_serializer); +typedef const ep_char8_t * (*FastSerializableObjectGetTypeNameFunc)(void *object); + +struct _FastSerializableObjectVtable { + FastSerializableObjectFreeFunc free_func; + FastSerializableObjectFastSerializeFunc fast_serialize_func; + FastSerializableObjectGetTypeNameFunc get_type_name_func; +}; + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _FastSerializableObject { +#else +struct _FastSerializableObject_Internal { +#endif + FastSerializableObjectVtable *vtable; + int32_t object_version; + int32_t min_reader_version; + bool is_private; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _FastSerializableObject { + uint8_t _internal [sizeof (struct _FastSerializableObject_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(FastSerializableObject *, fast_serializable_object, int32_t, object_version) +EP_DEFINE_GETTER(FastSerializableObject *, fast_serializable_object, int32_t, min_reader_version) +EP_DEFINE_GETTER(FastSerializableObject *, fast_serializable_object, bool, is_private) + +FastSerializableObject * +ep_fast_serializable_object_init ( + FastSerializableObject *fast_serializable_object, + FastSerializableObjectVtable *vtable, + int32_t object_version, + int32_t min_reader_version, + bool is_private); + +void +ep_fast_serializable_object_fini (FastSerializableObject *fast_serializable_object); + +void +ep_fast_serializable_object_fast_serialize ( + FastSerializableObject *fast_serializable_ojbect, + FastSerializer *fast_serializer); + +const ep_char8_t * +ep_fast_serializable_object_get_type_name (FastSerializableObject *fast_serializable_ojbect); + +void +ep_fast_serializable_object_free_vcall (FastSerializableObject *fast_serializable_ojbect); + +const ep_char8_t * +ep_fast_serializable_object_get_type_name_vcall (FastSerializableObject *fast_serializable_ojbect); + +void +ep_fast_serializable_object_fast_serialize_vcall ( + FastSerializableObject *fast_serializable_ojbect, + FastSerializer *fast_serializer); + +/* + * FastSerializer. + */ + +#define FAST_SERIALIZER_ALIGNMENT_SIZE 4 + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _FastSerializer { +#else +struct _FastSerializer_Internal { +#endif + StreamWriter *stream_writer; + uint32_t required_padding; + bool write_error_encountered; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _FastSerializer { + uint8_t _internal [sizeof (struct _FastSerializer_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(FastSerializer *, fast_serializer, StreamWriter *, stream_writer) +EP_DEFINE_GETTER(FastSerializer *, fast_serializer, uint32_t, required_padding) +EP_DEFINE_SETTER(FastSerializer *, fast_serializer, uint32_t, required_padding) +EP_DEFINE_GETTER(FastSerializer *, fast_serializer, bool, write_error_encountered) +EP_DEFINE_SETTER(FastSerializer *, fast_serializer, bool, write_error_encountered) + +FastSerializer * +ep_fast_serializer_alloc (StreamWriter *stream_writer); + +void +ep_fast_serializer_free (FastSerializer *fast_serializer); + +void +ep_fast_serializer_write_buffer ( + FastSerializer *fast_serializer, + const uint8_t *buffer, + uint32_t buffer_len); + +void +ep_fast_serializer_write_object ( + FastSerializer *fast_serializer, + FastSerializableObject *fast_serializable_ojbect); + +void +ep_fast_serializer_write_string ( + FastSerializer *fast_serializer, + const ep_char8_t *contents, + uint32_t contents_len); + +void +ep_fast_serializer_write_tag ( + FastSerializer *fast_serializer, + FastSerializerTags tag, + const uint8_t *payload, + uint32_t payload_len); + +/* +* FileStream. +*/ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _FileStream { +#else +struct _FileStream_Internal { +#endif + ep_rt_file_handle_t rt_file; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _FileStream { + uint8_t _internal [sizeof (struct _FileStream_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(FileStream *, file_stream, ep_rt_file_handle_t, rt_file) +EP_DEFINE_SETTER(FileStream *, file_stream, ep_rt_file_handle_t, rt_file) + +FileStream * +ep_file_stream_alloc (void); + +void +ep_file_stream_free (FileStream *file_stream); + +bool +ep_file_stream_open_write ( + FileStream *file_stream, + const ep_char8_t *path); + +bool +ep_file_stream_close (FileStream *file_stream); + +bool +ep_file_stream_write ( + FileStream *file_stream, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written); + +/* + * FileStreamWriter. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _FileStreamWriter { +#else +struct _FileStreamWriter_Internal { +#endif + StreamWriter stream_writer; + FileStream *file_stream; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _FileStreamWriter { + uint8_t _internal [sizeof (struct _FileStreamWriter_Internal)]; +}; +#endif + +EP_DEFINE_GETTER_REF(FileStreamWriter *, file_stream_writer, StreamWriter *, stream_writer) +EP_DEFINE_GETTER(FileStreamWriter *, file_stream_writer, FileStream *, file_stream) + +FileStreamWriter * +ep_file_stream_writer_alloc (const ep_char8_t *output_file_path); + +void +ep_file_stream_writer_free (FileStreamWriter *file_stream_writer); + +bool +ep_file_stream_writer_write ( + FileStreamWriter *file_stream_writer, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written); + +/* + * IpcStream. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +//TODO: Implement. +struct _IpcStream { +#else +struct _IpcStream_Internal { +#endif + ep_rt_ipc_handle_t rt_ipc; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _IpcStream { + uint8_t _internal [sizeof (struct _IpcStream_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(IpcStream *, ipc_stream, ep_rt_ipc_handle_t, rt_ipc) + +IpcStream * +ep_ipc_stream_alloc (ep_rt_ipc_handle_t rt_ipc); + +void +ep_ipc_stream_free (IpcStream *ipc_stream); + +bool +ep_ipc_stream_flush (IpcStream *stream); + +bool +ep_ipc_stream_disconnect (IpcStream *stream); + +bool +ep_ipc_stream_close (IpcStream *stream); + +bool +ep_ipc_stream_write ( + IpcStream *stream, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written); + +/* + * IpcStreamWriter. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _IpcStreamWriter { +#else +struct _IpcStreamWriter_Internal { +#endif + StreamWriter stream_writer; + IpcStream *ipc_stream; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _IpcStreamWriter { + uint8_t _internal [sizeof (struct _IpcStreamWriter_Internal)]; +}; +#endif + +EP_DEFINE_GETTER_REF(IpcStreamWriter *, ipc_stream_writer, StreamWriter *, stream_writer) +EP_DEFINE_GETTER(IpcStreamWriter *, ipc_stream_writer, IpcStream *, ipc_stream) + +IpcStreamWriter * +ep_ipc_stream_writer_alloc ( + uint64_t id, + IpcStream *stream); + +void +ep_ipc_stream_writer_free (IpcStreamWriter *ipc_stream_writer); + +bool +ep_ipc_stream_writer_write ( + IpcStreamWriter *ipc_stream_writer, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written); + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_STREAM_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-thread-internals.c b/src/mono/mono/eventpipe/ep-thread-internals.c new file mode 100644 index 0000000000000..da2d7ad2b624f --- /dev/null +++ b/src/mono/mono/eventpipe/ep-thread-internals.c @@ -0,0 +1,219 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#define EP_IMPL_GETTER_SETTER +#include "ep.h" + +/* + * EventPipeThread. + */ + +EventPipeThread * +ep_thread_alloc (void) +{ + EventPipeThread *instance = ep_rt_object_alloc (EventPipeThread); + ep_raise_error_if_nok (instance != NULL); + + ep_rt_spin_lock_alloc (&instance->rt_lock); + ep_raise_error_if_nok (instance->rt_lock.lock != NULL); + + instance->os_thread_id = ep_rt_current_thread_get_id (); + memset (instance->session_state, 0, sizeof (instance->session_state)); + +ep_on_exit: + return instance; + +ep_on_error: + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_thread_free (EventPipeThread *thread) +{ + ep_return_void_if_nok (thread != NULL); + + EP_ASSERT (ep_rt_volatile_load_uint32_t ((const volatile uint32_t *)&thread->ref_count) == 0); + +#ifdef EP_CHECKED_BUILD + for (uint32_t i = 0; i < EP_MAX_NUMBER_OF_SESSIONS; ++i) { + EP_ASSERT (thread->session_state [i] == NULL); + } +#endif + + ep_rt_spin_lock_free (&thread->rt_lock); + ep_rt_object_free (thread); +} + +/* + * EventPipeThreadHolder. + */ + +EventPipeThreadHolder * +ep_thread_holder_alloc (EventPipeThread *thread) +{ + ep_return_null_if_nok (thread != NULL); + + EventPipeThreadHolder *instance = ep_rt_object_alloc (EventPipeThreadHolder); + ep_raise_error_if_nok (instance != NULL); + ep_raise_error_if_nok (ep_thread_holder_init (instance, thread) != NULL); + +ep_on_exit: + return instance; + +ep_on_error: + instance = NULL; + ep_exit_error_handler (); +} + +EventPipeThreadHolder * +ep_thread_holder_init ( + EventPipeThreadHolder *thread_holder, + EventPipeThread *thread) +{ + ep_return_null_if_nok (thread_holder != NULL && thread != NULL); + + thread_holder->thread = thread; + ep_thread_addref (thread_holder->thread); + + return thread_holder; +} + +void +ep_thread_holder_fini (EventPipeThreadHolder *thread_holder) +{ + ep_return_void_if_nok (thread_holder != NULL && thread_holder->thread); + ep_thread_release (thread_holder->thread); +} + +void +ep_thread_holder_free (EventPipeThreadHolder *thread_holder) +{ + ep_return_void_if_nok (thread_holder != NULL); + ep_thread_holder_fini (thread_holder); + ep_rt_object_free (thread_holder); +} + +/* + * EventPipeThreadSessionState. + */ + +EventPipeThreadSessionState * +ep_thread_session_state_alloc ( + EventPipeThread *thread, + EventPipeSession *session, + EventPipeBufferManager *buffer_manager) +{ + EventPipeThreadSessionState *instance = ep_rt_object_alloc (EventPipeThreadSessionState); + ep_raise_error_if_nok (instance != NULL); + + ep_raise_error_if_nok (ep_thread_holder_init (&instance->thread_holder, thread) != NULL); + + instance->session = session; + instance->sequence_number = 1; + +#ifdef EP_CHECKED_BUILD + instance->buffer_manager = buffer_manager; +#endif + +ep_on_exit: + return instance; + +ep_on_error: + instance = NULL; + ep_exit_error_handler (); +} + +void +ep_thread_session_state_free (EventPipeThreadSessionState *thread_session_state) +{ + ep_return_void_if_nok (thread_session_state != NULL); + ep_thread_holder_fini (&thread_session_state->thread_holder); + ep_rt_object_free (thread_session_state); +} + +EventPipeThread * +ep_thread_session_state_get_thread (const EventPipeThreadSessionState *thread_session_state) +{ + EP_ASSERT (thread_session_state != NULL); + return thread_session_state->thread_holder.thread; +} + +EventPipeBuffer * +ep_thread_session_state_get_write_buffer (const EventPipeThreadSessionState *thread_session_state) +{ + EP_ASSERT (thread_session_state != NULL); + ep_thread_requires_lock_held (thread_session_state->thread_holder.thread); + + EP_ASSERT ((thread_session_state->write_buffer == NULL) || (ep_rt_volatile_load_uint32_t (&thread_session_state->write_buffer->state) == EP_BUFFER_STATE_WRITABLE)); + return thread_session_state->write_buffer; +} + +void +ep_thread_session_state_set_write_buffer ( + EventPipeThreadSessionState *thread_session_state, + EventPipeBuffer *new_buffer) +{ + EP_ASSERT (thread_session_state != NULL); + ep_thread_requires_lock_held (thread_session_state->thread_holder.thread); + + EP_ASSERT ((new_buffer == NULL) || (ep_rt_volatile_load_uint32_t (&thread_session_state->write_buffer->state) == EP_BUFFER_STATE_WRITABLE)); + EP_ASSERT ((thread_session_state->write_buffer == NULL) || (ep_rt_volatile_load_uint32_t (&thread_session_state->write_buffer->state) == EP_BUFFER_STATE_WRITABLE)); + + if (thread_session_state->write_buffer) + ep_buffer_convert_to_read_only (thread_session_state->write_buffer); + + thread_session_state->write_buffer = new_buffer; +} + +EventPipeBufferList * +ep_thread_session_state_get_buffer_list (const EventPipeThreadSessionState *thread_session_state) +{ + EP_ASSERT (thread_session_state != NULL); + ep_buffer_manager_requires_lock_held (thread_session_state->buffer_manager); + return thread_session_state->buffer_list; +} + +void +ep_thread_session_state_set_buffer_list ( + EventPipeThreadSessionState *thread_session_state, + EventPipeBufferList *new_buffer_list) +{ + EP_ASSERT (thread_session_state != NULL); + ep_buffer_manager_requires_lock_held (thread_session_state->buffer_manager); + thread_session_state->buffer_list = new_buffer_list; +} + +uint32_t +ep_thread_session_state_get_volatile_sequence_number (const EventPipeThreadSessionState *thread_session_state) +{ + EP_ASSERT (thread_session_state != NULL); + return ep_rt_volatile_load_uint32_t_without_barrier (&thread_session_state->sequence_number); +} + +uint32_t +ep_thread_session_state_get_sequence_number (const EventPipeThreadSessionState *thread_session_state) +{ + EP_ASSERT (thread_session_state != NULL); + ep_thread_requires_lock_held (thread_session_state->thread_holder.thread); + return ep_rt_volatile_load_uint32_t_without_barrier (&thread_session_state->sequence_number); +} + +void +ep_thread_session_state_increment_sequence_number (EventPipeThreadSessionState *thread_session_state) +{ + EP_ASSERT (thread_session_state != NULL); + ep_thread_requires_lock_held (thread_session_state->thread_holder.thread); + thread_session_state->sequence_number++; +} + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_thread_internals; +const char quiet_linker_empty_file_warning_eventpipe_thread_internals = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-thread.c b/src/mono/mono/eventpipe/ep-thread.c new file mode 100644 index 0000000000000..68632bea401b0 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-thread.c @@ -0,0 +1,157 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) + +#include "ep.h" + +/* + * EventPipeThread. + */ + +void +ep_thread_addref (EventPipeThread *thread) +{ + EP_ASSERT (thread != NULL); + ep_rt_atomic_inc_int32_t (ep_thread_get_ref_count_ref (thread)); +} + +void +ep_thread_release (EventPipeThread *thread) +{ + EP_ASSERT (thread != NULL); + if (ep_rt_atomic_dec_int32_t (ep_thread_get_ref_count_ref (thread)) == 0) + ep_thread_free (thread); +} + +EventPipeThread * +ep_thread_get (void) +{ + return ep_rt_thread_get (); +} + +EventPipeThread * +ep_thread_get_or_create (void) +{ + return ep_rt_thread_get_or_create (); +} + +void +ep_thread_create_activity_id ( + uint8_t *activity_id, + uint32_t activity_id_len) +{ + ep_return_void_if_nok (activity_id != NULL); + ep_rt_create_activity_id (activity_id, activity_id_len); +} + +void +ep_thread_get_activity_id ( + EventPipeThread *thread, + uint8_t *activity_id, + uint32_t activity_id_len) +{ + ep_return_void_if_nok (thread != NULL && activity_id != NULL); + EP_ASSERT (activity_id_len == EP_ACTIVITY_ID_SIZE); + memcpy (activity_id, ep_thread_get_activity_id_cref (thread), EP_ACTIVITY_ID_SIZE); +} + +void +ep_thread_set_activity_id ( + EventPipeThread *thread, + const uint8_t *activity_id, + uint32_t activity_id_len) +{ + ep_return_void_if_nok (thread != NULL && activity_id != NULL); + EP_ASSERT (activity_id_len == EP_ACTIVITY_ID_SIZE); + memcpy (ep_thread_get_activity_id_ref (thread), activity_id, EP_ACTIVITY_ID_SIZE); +} + +void +ep_thread_set_session_write_in_progress ( + EventPipeThread *thread, + uint32_t session_index) +{ + ep_return_void_if_nok (thread != NULL); + ep_rt_volatile_store_uint32_t (ep_thread_get_writing_event_in_progress_ref (thread), session_index); +} + +uint32_t +ep_thread_get_session_write_in_progress (const EventPipeThread *thread) +{ + ep_return_zero_if_nok (thread != NULL); + return ep_rt_volatile_load_uint32_t (ep_thread_get_writing_event_in_progress_cref (thread)); +} + +EventPipeThreadSessionState * +ep_thread_get_or_create_session_state ( + EventPipeThread *thread, + EventPipeSession *session) +{ + ep_return_null_if_nok (thread != NULL && session != NULL); + EP_ASSERT (ep_session_get_index (session) < EP_MAX_NUMBER_OF_SESSIONS); + ep_thread_requires_lock_held (thread); + + EventPipeThreadSessionState *state = ep_thread_get_session_state_ref (thread)[ep_session_get_index (session)]; + if (!state) { + state = ep_thread_session_state_alloc (thread, session, ep_session_get_buffer_manager (session)); + ep_thread_get_session_state_ref (thread)[ep_session_get_index (session)] = state; + } + + return state; +} + +EventPipeThreadSessionState * +ep_thread_get_session_state ( + const EventPipeThread *thread, + EventPipeSession *session) +{ + ep_return_null_if_nok (thread != NULL && session != NULL); + EP_ASSERT (ep_session_get_index (session) < EP_MAX_NUMBER_OF_SESSIONS); + ep_thread_requires_lock_held (thread); + + EventPipeThreadSessionState *const state = ep_thread_get_session_state_cref (thread)[ep_session_get_index (session)]; + EP_ASSERT (state != NULL); + return state; +} + +void +ep_thread_delete_session_state ( + EventPipeThread *thread, + EventPipeSession *session) +{ + ep_return_void_if_nok (thread != NULL && session != NULL); + ep_thread_requires_lock_held (thread); + + uint32_t index = ep_session_get_index (session); + EP_ASSERT (index < EP_MAX_NUMBER_OF_SESSIONS); + EventPipeThreadSessionState *state = ep_thread_get_session_state_ref (thread)[index]; + EP_ASSERT (state != NULL); + ep_thread_session_state_free (state); + ep_thread_get_session_state_ref (thread)[index] = NULL; +} + +#ifdef EP_CHECKED_BUILD +void +ep_thread_requires_lock_held (const EventPipeThread *thread) +{ + EP_ASSERT (thread != NULL); + ep_rt_spin_lock_requires_lock_held (ep_thread_get_rt_lock_cref (thread)); +} + +void +ep_thread_requires_lock_not_held (const EventPipeThread *thread) +{ + EP_ASSERT (thread != NULL); + ep_rt_spin_lock_requires_lock_not_held (ep_thread_get_rt_lock_cref (thread)); +} +#endif + +#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */ +#endif /* ENABLE_PERFTRACING */ + +#ifndef EP_INCLUDE_SOURCE_FILES +extern const char quiet_linker_empty_file_warning_eventpipe_thread; +const char quiet_linker_empty_file_warning_eventpipe_thread = 0; +#endif diff --git a/src/mono/mono/eventpipe/ep-thread.h b/src/mono/mono/eventpipe/ep-thread.h new file mode 100644 index 0000000000000..23d0e5093f237 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-thread.h @@ -0,0 +1,233 @@ +#ifndef __EVENTPIPE_THREAD_H__ +#define __EVENTPIPE_THREAD_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" + +/* + * EventPipeThread. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeThread { +#else +struct _EventPipeThread_Internal { +#endif + EventPipeThreadSessionState *session_state [EP_MAX_NUMBER_OF_SESSIONS]; + uint8_t activity_id [EP_ACTIVITY_ID_SIZE]; + EventPipeSession *rundown_session; + size_t os_thread_id; + ep_rt_thread_handle_t rt_thread; + ep_rt_spin_lock_handle_t rt_lock; + int32_t ref_count; + volatile uint32_t writing_event_in_progress; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeThread { + uint8_t _internal [sizeof (struct _EventPipeThread_Internal)]; +}; +#endif + +EP_DEFINE_GETTER_ARRAY_REF(EventPipeThread *, thread, EventPipeThreadSessionState **, EventPipeThreadSessionState *const*, session_state, session_state[0]); +EP_DEFINE_GETTER_ARRAY_REF(EventPipeThread *, thread, uint8_t *, const uint8_t *, activity_id, activity_id[0]); +EP_DEFINE_GETTER(EventPipeThread *, thread, EventPipeSession *, rundown_session); +EP_DEFINE_SETTER(EventPipeThread *, thread, EventPipeSession *, rundown_session); +EP_DEFINE_GETTER(EventPipeThread *, thread, size_t, os_thread_id); +EP_DEFINE_GETTER_REF(EventPipeThread *, thread, ep_rt_spin_lock_handle_t *, rt_lock); +EP_DEFINE_GETTER_REF(EventPipeThread *, thread, int32_t *, ref_count); +EP_DEFINE_GETTER_REF(EventPipeThread *, thread, volatile uint32_t *, writing_event_in_progress); + +EventPipeThread * +ep_thread_alloc (void); + +void +ep_thread_free (EventPipeThread *thread); + +void +ep_thread_addref (EventPipeThread *thread); + +void +ep_thread_release (EventPipeThread *thread); + +EventPipeThread * +ep_thread_get (void); + +EventPipeThread * +ep_thread_get_or_create (void); + +void +ep_thread_create_activity_id ( + uint8_t *activity_id, + uint32_t activity_id_len); + +void +ep_thread_get_activity_id ( + EventPipeThread *thread, + uint8_t *activity_id, + uint32_t activity_id_len); + +void +ep_thread_set_activity_id ( + EventPipeThread *thread, + const uint8_t *activity_id, + uint32_t activity_id_len); + +static +inline +void +ep_thread_set_as_rundown_thread ( + EventPipeThread *thread, + EventPipeSession *session) +{ + EP_ASSERT (thread != NULL); + ep_thread_set_rundown_session (thread, session); +} + +static +inline +bool +ep_thread_is_rundown_thread (const EventPipeThread *thread) +{ + EP_ASSERT (thread != NULL); + return (ep_thread_get_rundown_session (thread) != NULL); +} + +#ifdef EP_CHECKED_BUILD +void +ep_thread_requires_lock_held (const EventPipeThread *thread); + +void +ep_thread_requires_lock_not_held (const EventPipeThread *thread); +#else +#define ep_thread_requires_lock_held(x) +#define ep_thread_requires_lock_not_held(x) +#endif + +void +ep_thread_set_session_write_in_progress ( + EventPipeThread *thread, + uint32_t session_index); + +uint32_t +ep_thread_get_session_write_in_progress (const EventPipeThread *thread); + +EventPipeThreadSessionState * +ep_thread_get_or_create_session_state ( + EventPipeThread *thread, + EventPipeSession *session); + +EventPipeThreadSessionState * +ep_thread_get_session_state ( + const EventPipeThread *thread, + EventPipeSession *session); + +void +ep_thread_delete_session_state ( + EventPipeThread *thread, + EventPipeSession *session); + +/* + * EventPipeThreadHolder. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeThreadHolder { +#else +struct _EventPipeThreadHolder_Internal { +#endif + EventPipeThread *thread; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeThreadHolder { + uint8_t _internal [sizeof (struct _EventPipeThreadHolder_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventPipeThreadHolder *, thread_holder, EventPipeThread *, thread) + +EventPipeThreadHolder * +ep_thread_holder_alloc (EventPipeThread *thread); + +EventPipeThreadHolder * +ep_thread_holder_init ( + EventPipeThreadHolder *thread_holder, + EventPipeThread *thread); + +void +ep_thread_holder_fini (EventPipeThreadHolder *thread_holder); + +void +ep_thread_holder_free (EventPipeThreadHolder *thread_holder); + +/* + * EventPipeThreadSessionState. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeThreadSessionState { +#else +struct _EventPipeThreadSessionState_Internal { +#endif + EventPipeThreadHolder thread_holder; + EventPipeSession *session; + EventPipeBuffer *write_buffer; + EventPipeBufferList *buffer_list; +#ifdef EP_CHECKED_BUILD + EventPipeBufferManager *buffer_manager; +#endif + volatile uint32_t sequence_number; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeThreadSessionState { + uint8_t _internal [sizeof (struct _EventPipeThreadSessionState_Internal)]; +}; +#endif + +EP_DEFINE_GETTER_REF(EventPipeThreadSessionState *, thread_session_state, EventPipeThreadHolder *, thread_holder) +EP_DEFINE_GETTER(EventPipeThreadSessionState *, thread_session_state, EventPipeSession *, session) + +EventPipeThreadSessionState * +ep_thread_session_state_alloc ( + EventPipeThread *thread, + EventPipeSession *session, + EventPipeBufferManager *buffer_manager); + +void +ep_thread_session_state_free (EventPipeThreadSessionState *thread_session_state); + +EventPipeThread * +ep_thread_session_state_get_thread (const EventPipeThreadSessionState *thread_session_state); + +EventPipeBuffer * +ep_thread_session_state_get_write_buffer (const EventPipeThreadSessionState *thread_session_state); + +void +ep_thread_session_state_set_write_buffer ( + EventPipeThreadSessionState *thread_session_state, + EventPipeBuffer *new_buffer); + +EventPipeBufferList * +ep_thread_session_state_get_buffer_list (const EventPipeThreadSessionState *thread_session_state); + +void +ep_thread_session_state_set_buffer_list ( + EventPipeThreadSessionState *thread_session_state, + EventPipeBufferList *new_buffer_list); + +uint32_t +ep_thread_session_state_get_volatile_sequence_number (const EventPipeThreadSessionState *thread_session_state); + +uint32_t +ep_thread_session_state_get_sequence_number (const EventPipeThreadSessionState *thread_session_state); + +void +ep_thread_session_state_increment_sequence_number (EventPipeThreadSessionState *thread_session_state); + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_THREAD_H__ **/ diff --git a/src/mono/mono/eventpipe/ep-types.h b/src/mono/mono/eventpipe/ep-types.h new file mode 100644 index 0000000000000..7e25f32016c96 --- /dev/null +++ b/src/mono/mono/eventpipe/ep-types.h @@ -0,0 +1,388 @@ +#ifndef __EVENTPIPE_TYPES_H__ +#define __EVENTPIPE_TYPES_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include +#include +#include "ep-rt-types.h" + +/* + * EventPipe Structs. + */ + +typedef struct _EventData EventData; +typedef struct _EventFilterDescriptor EventFilterDescriptor; +typedef struct _EventPipeBuffer EventPipeBuffer; +typedef struct _EventPipeBufferList EventPipeBufferList; +typedef struct _EventPipeBufferManager EventPipeBufferManager; +typedef struct _EventPipeBlock EventPipeBlock; +typedef struct _EventPipeBlockVtable EventPipeBlockVtable; +typedef struct _EventPipeConfiguration EventPipeConfiguration; +typedef struct _EventPipeEvent EventPipeEvent; +typedef struct _EventPipeEventBlockBase EventPipeEventBlockBase; +typedef struct _EventPipeEventBlock EventPipeEventBlock; +typedef struct _EventPipeEventHeader EventPipeEventHeader; +typedef struct _EventPipeEventInstance EventPipeEventInstance; +typedef struct _EventPipeEventMetadataEvent EventPipeEventMetadataEvent; +typedef struct _EventPipeEventSource EventPipeEventSource; +typedef struct _EventPipeFile EventPipeFile; +typedef struct _EventPipeMetadataBlock EventPipeMetadataBlock; +typedef struct _EventPipeParameterDesc EventPipeParameterDesc; +typedef struct _EventPipeProvider EventPipeProvider; +typedef struct _EventPipeProviderCallbackData EventPipeProviderCallbackData; +typedef struct _EventPipeProviderCallbackDataQueue EventPipeProviderCallbackDataQueue; +typedef struct _EventPipeProviderConfiguration EventPipeProviderConfiguration; +typedef struct _EventPipeSession EventPipeSession; +typedef struct _EventPipeSessionProvider EventPipeSessionProvider; +typedef struct _EventPipeSessionProviderList EventPipeSessionProviderList; +typedef struct _EventPipeSequencePoint EventPipeSequencePoint; +typedef struct _EventPipeSequencePointBlock EventPipeSequencePointBlock; +typedef struct _EventPipeStackBlock EventPipeStackBlock; +typedef struct _EventPipeStackContents EventPipeStackContents; +typedef struct _EventPipeThread EventPipeThread; +typedef struct _EventPipeThreadHolder EventPipeThreadHolder; +typedef struct _EventPipeThreadSessionState EventPipeThreadSessionState; +typedef struct _FastSerializableObject FastSerializableObject; +typedef struct _FastSerializableObjectVtable FastSerializableObjectVtable; +typedef struct _FastSerializer FastSerializer; +typedef struct _FileStream FileStream; +typedef struct _FileStreamWriter FileStreamWriter; +typedef struct _IpcStream IpcStream; +typedef struct _IpcStreamWriter IpcStreamWriter; +typedef struct _StackHashEntry StackHashEntry; +typedef struct _StackHashKey StackHashKey; +typedef struct _StreamWriter StreamWriter; +typedef struct _StreamWriterVtable StreamWriterVtable; + +#ifdef EP_INLINE_GETTER_SETTER +#ifndef EP_DEFINE_GETTER +#define EP_DEFINE_GETTER(instance_type, instance_type_name, return_type, instance_field_name) \ + static inline return_type ep_ ## instance_type_name ## _get_ ## instance_field_name (const instance_type instance) { return instance-> instance_field_name; } \ + static inline size_t ep_ ## instance_type_name ## _sizeof_ ## instance_field_name (const instance_type instance) { return sizeof (instance-> instance_field_name); } +#endif + +#ifndef EP_DEFINE_GETTER_REF +#define EP_DEFINE_GETTER_REF(instance_type, instance_type_name, return_type, instance_field_name) \ + static inline return_type ep_ ## instance_type_name ## _get_ ## instance_field_name ## _ref (instance_type instance) { return &(instance-> instance_field_name); } \ + static inline const return_type ep_ ## instance_type_name ## _get_ ## instance_field_name ## _cref (const instance_type instance) { return &(instance-> instance_field_name); } +#endif + +#ifndef EP_DEFINE_GETTER_ARRAY_REF +#define EP_DEFINE_GETTER_ARRAY_REF(instance_type, instance_type_name, return_type, const_return_type, instance_field_name, instance_field) \ + static inline return_type ep_ ## instance_type_name ## _get_ ## instance_field_name ## _ref (instance_type instance) { return &(instance-> instance_field); } \ + static inline const_return_type ep_ ## instance_type_name ## _get_ ## instance_field_name ## _cref (const instance_type instance) { return &(instance-> instance_field); } +#endif + +#ifndef EP_DEFINE_SETTER +#define EP_DEFINE_SETTER(instance_type, instance_type_name, instance_field_type, instance_field_name) static inline void ep_ ## instance_type_name ## _set_ ## instance_field_name (instance_type instance, instance_field_type instance_field_name) { instance-> instance_field_name = instance_field_name; } +#endif +#else +#ifndef EP_DEFINE_GETTER +#define EP_DEFINE_GETTER(instance_type, instance_type_name, return_type, instance_field_name) \ + return_type ep_ ## instance_type_name ## _get_ ## instance_field_name (const instance_type instance); \ + size_t ep_ ## instance_type_name ## _sizeof_ ## instance_field_name (const instance_type instance); +#endif + +#ifndef EP_DEFINE_GETTER_REF +#define EP_DEFINE_GETTER_REF(instance_type, instance_type_name, return_type, instance_field_name) \ + return_type ep_ ## instance_type_name ## _get_ ## instance_field_name ## _ref (instance_type instance); \ + const return_type ep_ ## instance_type_name ## _get_ ## instance_field_name ## _cref (const instance_type instance); +#endif + +#ifndef EP_DEFINE_GETTER_ARRAY_REF +#define EP_DEFINE_GETTER_ARRAY_REF(instance_type, instance_type_name, return_type, const_return_type, instance_field_name, instance_field) \ + return_type ep_ ## instance_type_name ## _get_ ## instance_field_name ## _ref (instance_type instance); \ + const_return_type ep_ ## instance_type_name ## _get_ ## instance_field_name ## _cref (const instance_type instance); +#endif + +#ifndef EP_DEFINE_SETTER +#define EP_DEFINE_SETTER(instance_type, instance_type_name, instance_field_type, instance_field_name) \ + void ep_ ## instance_type_name ## _set_ ## instance_field_name (instance_type instance, instance_field_type instance_field_name); +#endif +#endif + +#define EP_MAX_NUMBER_OF_SESSIONS 64 + +#define EP_ACTIVITY_ID_SIZE 16 + +#define EP_MAX_STACK_DEPTH 100 + +/* + * EventPipe Enums. + */ + +typedef enum { + EP_BUFFER_STATE_WRITABLE = 0, + EP_BUFFER_STATE_READ_ONLY = 1 +} EventPipeBufferState; + +typedef enum { + EP_EVENT_LEVEL_LOG_ALWAYS, + EP_EVENT_LEVEL_CRITICAL, + EP_EVENT_LEVEL_ERROR, + EP_EVENT_LEVEL_WARNING, + EP_EVENT_LEVEL_INFORMATIONAL, + EP_EVENT_LEVEL_VERBOSE +} EventPipeEventLevel; + +typedef enum { + EP_FILE_FLUSH_FLAGS_EVENT_BLOCK = 1, + EP_FILE_FLUSH_FLAGS_METADATA_BLOCK = 2, + EP_FILE_FLUSH_FLAGS_STACK_BLOCK = 4, + EP_FILE_FLUSH_FLAGS_ALL_BLOCKS = EP_FILE_FLUSH_FLAGS_EVENT_BLOCK | EP_FILE_FLUSH_FLAGS_METADATA_BLOCK | EP_FILE_FLUSH_FLAGS_STACK_BLOCK +} EventPipeFileFlushFlags; + +// Represents the type of an event parameter. +// This enum is derived from the managed TypeCode type, though +// not all of these values are available in TypeCode. +// For example, Guid does not exist in TypeCode. +// Keep this in sync with COR_PRF_EVENTPIPE_PARAM_TYPE defined in +// corprof.idl +typedef enum { + EP_PARAMETER_TYPE_EMPTY = 0, // Null reference + EP_PARAMETER_TYPE_OBJECT = 1, // Instance that isn't a value + EP_PARAMETER_TYPE_DB_NULL = 2, // Database null value + EP_PARAMETER_TYPE_BOOLEAN = 3, // Boolean + EP_PARAMETER_TYPE_CHAR = 4, // Unicode character + EP_PARAMETER_TYPE_SBYTE = 5, // Signed 8-bit integer + EP_PARAMETER_TYPE_BYTE = 6, // Unsigned 8-bit integer + EP_PARAMETER_TYPE_INT16 = 7, // Signed 16-bit integer + EP_PARAMETER_TYPE_UINT16 = 8, // Unsigned 16-bit integer + EP_PARAMETER_TYPE_INT32 = 9, // Signed 32-bit integer + EP_PARAMETER_TYPE_UINT32 = 10, // Unsigned 32-bit integer + EP_PARAMETER_TYPE_INT64 = 11, // Signed 64-bit integer + EP_PARAMETER_TYPE_UINT64 = 12, // Unsigned 64-bit integer + EP_PARAMETER_TYPE_SINGLE = 13, // IEEE 32-bit float + EP_PARAMETER_TYPE_DOUBLE = 14, // IEEE 64-bit double + EP_PARAMETER_TYPE_DECIMAL = 15, // Decimal + EP_PARAMETER_TYPE_DATE_TIME = 16, // DateTime + EP_PARAMETER_TYPE_GUID = 17, // Guid + EP_PARAMETER_TYPE_STRING = 18 // Unicode character string +} EventPipeParameterType; + +typedef enum { + EP_SERIALIZATION_FORMAT_NETPERF_V3, + EP_SERIALIZATION_FORMAT_NETTRACE_V4, + EP_SERIALIZATION_FORMAT_COUNT +} EventPipeSerializationFormat; + +typedef enum { + EP_SESSION_TYPE_FILE, + EP_SESSION_TYPE_LISTENER, + EP_SESSION_TYPE_IPCSTREAM +} EventPipeSessionType ; + +typedef enum { + EP_STATE_NOT_INITIALIZED, + EP_STATE_INITIALIZED, + EP_STATE_SHUTTING_DOWN +} EventPipeState; + +/* + * EventPipe Basic Types. + */ + +typedef intptr_t EventPipeWaitHandle; +typedef uint64_t EventPipeSessionID; +typedef char ep_char8_t; +typedef unsigned short ep_char16_t; + +/* + * EventPipe Callbacks. + */ + +// Define the event pipe callback to match the ETW callback signature. +typedef void (*EventPipeCallback)( + const uint8_t *source_id, + unsigned long is_enabled, + uint8_t level, + uint64_t match_any_keywords, + uint64_t match_all_keywords, + EventFilterDescriptor *filter_data, + void *callback_context); + +/* + * EventFilterDescriptor. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventFilterDescriptor { +#else +struct _EventFilterDescriptor_Internal { +#endif + uint64_t ptr; + uint32_t size; + uint32_t type; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventFilterDescriptor { + uint8_t _internal [sizeof (struct _EventFilterDescriptor_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventFilterDescriptor *, event_filter_desc, uint64_t, ptr) +EP_DEFINE_GETTER(EventFilterDescriptor *, event_filter_desc, uint32_t, size) +EP_DEFINE_GETTER(EventFilterDescriptor *, event_filter_desc, uint32_t, type) + +EventFilterDescriptor * +ep_event_filter_desc_alloc ( + uint64_t ptr, + uint32_t size, + uint32_t type); + +EventFilterDescriptor * +ep_event_filter_desc_init ( + EventFilterDescriptor *event_filter_desc, + uint64_t ptr, + uint32_t size, + uint32_t type +); + +void +ep_event_filter_desc_fini (EventFilterDescriptor * filter_desc); + +void +ep_event_filter_desc_free (EventFilterDescriptor * filter_desc); + +/* + * EventPipeProviderCallbackData. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeProviderCallbackData { +#else +struct _EventPipeProviderCallbackData_Internal { +#endif + const ep_char8_t *filter_data; + EventPipeCallback callback_function; + void *callback_data; + int64_t keywords; + EventPipeEventLevel provider_level; + bool enabled; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeProviderCallbackData { + uint8_t _internal [sizeof (struct _EventPipeProviderCallbackData_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventPipeProviderCallbackData *, provider_callback_data, const ep_char8_t *, filter_data) +EP_DEFINE_GETTER(EventPipeProviderCallbackData *, provider_callback_data, EventPipeCallback, callback_function) +EP_DEFINE_GETTER(EventPipeProviderCallbackData *, provider_callback_data, void *, callback_data) +EP_DEFINE_GETTER(EventPipeProviderCallbackData *, provider_callback_data, int64_t, keywords) +EP_DEFINE_GETTER(EventPipeProviderCallbackData *, provider_callback_data, EventPipeEventLevel, provider_level) +EP_DEFINE_GETTER(EventPipeProviderCallbackData *, provider_callback_data, bool, enabled) + +EventPipeProviderCallbackData * +ep_provider_callback_data_alloc ( + const ep_char8_t *filter_data, + EventPipeCallback callback_function, + void *callback_data, + int64_t keywords, + EventPipeEventLevel provider_level, + bool enabled); + +EventPipeProviderCallbackData * +ep_provider_callback_data_alloc_copy (EventPipeProviderCallbackData *provider_callback_data_src); + +EventPipeProviderCallbackData * +ep_provider_callback_data_init ( + EventPipeProviderCallbackData *provider_callback_data, + const ep_char8_t *filter_data, + EventPipeCallback callback_function, + void *callback_data, + int64_t keywords, + EventPipeEventLevel provider_level, + bool enabled); + +EventPipeProviderCallbackData * +ep_provider_callback_data_init_copy ( + EventPipeProviderCallbackData *provider_callback_data_dst, + EventPipeProviderCallbackData *provider_callback_data_src); + +void +ep_provider_callback_data_fini (EventPipeProviderCallbackData *provider_callback_data); + +void +ep_provider_callback_data_free (EventPipeProviderCallbackData *provider_callback_data); + +/* + * EventPipeProviderCallbackDataQueue. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeProviderCallbackDataQueue { +#else +struct _EventPipeProviderCallbackDataQueue_Internal { +#endif + ep_rt_provider_callback_data_queue_t queue; +}; + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeProviderCallbackDataQueue { + uint8_t _internal [sizeof (struct _EventPipeProviderCallbackDataQueue_Internal)]; +}; +#endif + +EP_DEFINE_GETTER_REF(EventPipeProviderCallbackDataQueue *, provider_callback_data_queue, ep_rt_provider_callback_data_queue_t *, queue) + +EventPipeProviderCallbackDataQueue * +ep_provider_callback_data_queue_init (EventPipeProviderCallbackDataQueue *provider_callback_data_queue); + +void +ep_provider_callback_data_queue_fini (EventPipeProviderCallbackDataQueue *provider_callback_data_queue); + +void +ep_provider_callback_data_queue_enqueue ( + EventPipeProviderCallbackDataQueue *provider_callback_data_queue, + EventPipeProviderCallbackData *provider_callback_data); + +bool +ep_provider_callback_data_queue_try_dequeue ( + EventPipeProviderCallbackDataQueue *provider_callback_data_queue, + EventPipeProviderCallbackData *provider_callback_data); + +/* + * EventPipeProviderConfiguration. + */ + +#if defined(EP_INLINE_GETTER_SETTER) || defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeProviderConfiguration { +#else +struct _EventPipeProviderConfiguration_Internal { +#endif + const ep_char8_t *provider_name; + uint64_t keywords; + EventPipeEventLevel logging_level; + const ep_char8_t *filter_data; +}; + + +#if !defined(EP_INLINE_GETTER_SETTER) && !defined(EP_IMPL_GETTER_SETTER) +struct _EventPipeProviderConfiguration { + uint8_t _internal [sizeof (struct _EventPipeProviderConfiguration_Internal)]; +}; +#endif + +EP_DEFINE_GETTER(EventPipeProviderConfiguration *, provider_config, const ep_char8_t *, provider_name) +EP_DEFINE_GETTER(EventPipeProviderConfiguration *, provider_config, uint64_t, keywords) +EP_DEFINE_GETTER(EventPipeProviderConfiguration *, provider_config, EventPipeEventLevel, logging_level) +EP_DEFINE_GETTER(EventPipeProviderConfiguration *, provider_config, const ep_char8_t *, filter_data) + +EventPipeProviderConfiguration * +ep_provider_config_init ( + EventPipeProviderConfiguration *provider_config, + const ep_char8_t *provider_name, + uint64_t keywords, + uint32_t logging_level, + const ep_char8_t *filter_data); + +void +ep_provider_config_fini (EventPipeProviderConfiguration *provider_config); + +#endif /* ENABLE_PERFTRACING */ +#endif /* __EVENTPIPE_TYPES_H__ */ diff --git a/src/mono/mono/eventpipe/ep.c b/src/mono/mono/eventpipe/ep.c new file mode 100644 index 0000000000000..3725a8281eb8f --- /dev/null +++ b/src/mono/mono/eventpipe/ep.c @@ -0,0 +1,711 @@ +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep.h" + +// Option to include all internal source files into ep.c. +#ifdef EP_INCLUDE_SOURCE_FILES +#define EP_FORCE_INCLUDE_SOURCE_FILES +#include "ep-block.c" +#include "ep-buffer-manager.c" +#include "ep-config.c" +#include "ep-event-instance.c" +#include "ep-event-source.c" +#include "ep-file.c" +#include "ep-metadata-generator.c" +#include "ep-provider.c" +#include "ep-session.c" +#include "ep-session-provider.c" +#include "ep-stream.c" +#include "ep-thread.c" +#endif + +/* + * Forward declares of all static functions. + */ + +static +bool +enabled_lock_held (void); + +static +uint32_t +generate_session_index_lock_held (void); + +static +bool +is_session_id_in_collection_lock_held (EventPipeSessionID id); + +static +EventPipeSessionID +enable_lock_held ( + const ep_char8_t *output_path, + uint32_t circular_buffer_size_in_mb, + const EventPipeProviderConfiguration *providers, + uint32_t providers_len, + EventPipeSessionType session_type, + EventPipeSerializationFormat format, + bool rundown_requested, + IpcStream *stream, + bool enable_sample_profiler, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue); + +static +void +log_process_info_event (EventPipeEventSource *event_source); + +static +void +disable_lock_held ( + EventPipeSessionID id, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue); + +static +void +disable ( + EventPipeSessionID id, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue); + +/* + * Global volatile varaibles, only to be accessed through inlined volatile access functions. + */ + +volatile EventPipeState _ep_state = EP_STATE_NOT_INITIALIZED; + +volatile uint32_t _ep_number_of_sessions = 0; + +volatile EventPipeSession *_ep_sessions [EP_MAX_NUMBER_OF_SESSIONS] = { 0 }; + +volatile uint64_t _ep_allow_write = 0; + +/* + * EventPipe. + */ + +static +bool +enabled_lock_held (void) +{ + ep_rt_config_requires_lock_held (); + return (ep_volatile_load_eventpipe_state_without_barrier () >= EP_STATE_INITIALIZED && + ep_volatile_load_number_of_sessions_without_barrier () > 0); +} + +static +uint32_t +generate_session_index_lock_held (void) +{ + ep_rt_config_requires_lock_held (); + + for (uint32_t i = 0; i < EP_MAX_NUMBER_OF_SESSIONS; ++i) + if (ep_volatile_load_session_without_barrier (i) == NULL) + return i; + return EP_MAX_NUMBER_OF_SESSIONS; +} + +static +bool +is_session_id_in_collection_lock_held (EventPipeSessionID session_id) +{ + ep_rt_config_requires_lock_held (); + EP_ASSERT (session_id != 0); + + const EventPipeSession *const session = (EventPipeSession *)session_id; + for (uint32_t i = 0; i < EP_MAX_NUMBER_OF_SESSIONS; ++i) { + if (ep_volatile_load_session (i) == session) { + EP_ASSERT (i == ep_session_get_index (session)); + return true; + } + } + + return false; +} + +static +EventPipeSessionID +enable_lock_held ( + const ep_char8_t *output_path, + uint32_t circular_buffer_size_in_mb, + const EventPipeProviderConfiguration *providers, + uint32_t providers_len, + EventPipeSessionType session_type, + EventPipeSerializationFormat format, + bool rundown_requested, + IpcStream *stream, + bool enable_sample_profiler, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue) +{ + ep_rt_config_requires_lock_held (); + EP_ASSERT (format < EP_SERIALIZATION_FORMAT_COUNT); + EP_ASSERT (circular_buffer_size_in_mb > 0); + EP_ASSERT (providers_len > 0 && providers != NULL); + EP_ASSERT ((session_type == EP_SESSION_TYPE_FILE && output_path != NULL) ||(session_type == EP_SESSION_TYPE_IPCSTREAM && stream != NULL)); + + EventPipeSession *session = NULL; + EventPipeSessionID session_id = 0; + + ep_raise_error_if_nok (ep_volatile_load_eventpipe_state () == EP_STATE_INITIALIZED); + + const uint32_t session_index = generate_session_index_lock_held (); + ep_raise_error_if_nok (session_index < EP_MAX_NUMBER_OF_SESSIONS); + + session = ep_session_alloc ( + session_index, + output_path, + stream, + session_type, + format, + rundown_requested, + circular_buffer_size_in_mb, + providers, + providers_len, + FALSE); + + ep_raise_error_if_nok (session != NULL && ep_session_is_valid (session) == true); + + session_id = (EventPipeSessionID)session; + + // Return if the index is invalid. + if (ep_session_get_index (session) >= EP_MAX_NUMBER_OF_SESSIONS) { + EP_ASSERT (!"Session index was out of range."); + ep_raise_error (); + } + + if (ep_volatile_load_number_of_sessions () >= EP_MAX_NUMBER_OF_SESSIONS) { + EP_ASSERT (!"max number of sessions reached."); + ep_raise_error (); + } + + // Register the SampleProfiler the very first time (if supported). + ep_rt_sample_profiler_init (provider_callback_data_queue); + + // Enable the EventPipe EventSource. + ep_event_source_enable (ep_event_source_get (), session); + + // Save the session. + if (ep_volatile_load_session_without_barrier (ep_session_get_index (session)) != NULL) { + EP_ASSERT (!"Attempting to override an existing session."); + ep_raise_error (); + } + + ep_volatile_store_session (ep_session_get_index (session), session); + + ep_volatile_store_allow_write (ep_volatile_load_allow_write () | ep_session_get_mask (session)); + ep_volatile_store_number_of_sessions (ep_volatile_load_number_of_sessions () + 1); + + // Enable tracing. + ep_config_enable_disable_lock_held (ep_config_get (), session, provider_callback_data_queue, true); + + session = NULL; + + // Enable the sample profiler (if supported). + if (enable_sample_profiler) + ep_rt_sample_profiler_enable (); + +ep_on_exit: + ep_rt_config_requires_lock_held (); + return session_id; + +ep_on_error: + ep_session_free (session); + + session_id = 0; + ep_exit_error_handler (); +} + +static +void +log_process_info_event (EventPipeEventSource *event_source) +{ + // Get the managed command line. + const ep_char8_t *cmd_line = ep_rt_managed_command_line_get (); + + if (cmd_line == NULL) + cmd_line = ep_rt_command_line_get (); + + // Log the process information event. + ep_char16_t *cmd_line_utf16 = ep_rt_utf8_to_utf16_string (cmd_line, -1); + if (cmd_line_utf16 != NULL) { + ep_event_source_send_process_info (event_source, cmd_line_utf16); + ep_rt_utf16_string_free (cmd_line_utf16); + } +} + +static +void +disable_lock_held ( + EventPipeSessionID id, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue) +{ + ep_rt_config_requires_lock_held (); + EP_ASSERT (id != 0); + EP_ASSERT (ep_volatile_load_number_of_sessions () > 0); + + if (is_session_id_in_collection_lock_held (id)) { + EventPipeSession *const session = (EventPipeSession *)id; + + // Disable the profiler. + ep_rt_sample_profiler_disable (); + + // Log the process information event. + log_process_info_event (ep_event_source_get ()); + + // Disable session tracing. + ep_config_enable_disable_lock_held (ep_config_get (), session, provider_callback_data_queue, false); + + ep_session_disable (session); // WriteAllBuffersToFile, and remove providers. + + // Do rundown before fully stopping the session unless rundown wasn't requested + if (ep_session_get_rundown_requested (session)) { + ep_session_enable_rundown_lock_held (session); // Set Rundown provider. + EventPipeThread *const thread = ep_thread_get (); + if (thread != NULL) { + ep_thread_set_as_rundown_thread (thread, session); + { + ep_config_enable_disable_lock_held (ep_config_get (), session, provider_callback_data_queue, true); + { + ep_session_execute_rundown_lock_held (session); + } + ep_config_enable_disable_lock_held (ep_config_get (), session, provider_callback_data_queue, false); + } + ep_thread_set_as_rundown_thread (thread, NULL); + } else { + EP_ASSERT (!"Failed to get or create the EventPipeThread for rundown events."); + } + } + + ep_volatile_store_allow_write (ep_volatile_load_allow_write () & ~(ep_session_get_mask (session))); + ep_session_suspend_write_event_lock_held (session); + + bool ignored; + ep_session_write_all_buffers_to_file (session, &ignored); // Flush the buffers to the stream/file + + ep_volatile_store_number_of_sessions (ep_volatile_load_number_of_sessions () - 1); + + // At this point, we should not be writing events to this session anymore + // This is a good time to remove the session from the array. + EP_ASSERT (ep_volatile_load_session (ep_session_get_index (session)) == session); + + // Remove the session from the array, and mask. + ep_volatile_store_session (ep_session_get_index (session), NULL); + + // Write a final sequence point to the file now that all events have + // been emitted. + ep_session_write_sequence_point_unbuffered_lock_held (session); + + ep_session_free (session); + + // Providers can't be deleted during tracing because they may be needed when serializing the file. + ep_config_delete_deferred_providers_lock_held (ep_config_get ()); + } + + ep_rt_config_requires_lock_held (); + return; +} + +static +void +disable ( + EventPipeSessionID id, + EventPipeProviderCallbackDataQueue *provider_callback_data_queue) +{ + ep_rt_config_requires_lock_not_held (); + + EP_CONFIG_LOCK_ENTER + disable_lock_held (id, provider_callback_data_queue); + EP_CONFIG_LOCK_EXIT + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return; + +ep_on_error: + ep_exit_error_handler (); +} + +EventPipeSessionID +ep_enable ( + const ep_char8_t *output_path, + uint32_t circular_buffer_size_in_mb, + const EventPipeProviderConfiguration *providers, + uint32_t providers_len, + EventPipeSessionType session_type, + EventPipeSerializationFormat format, + bool rundown_requested, + IpcStream *stream, + bool enable_sample_profiler) +{ + ep_rt_config_requires_lock_not_held (); + EP_ASSERT (format < EP_SERIALIZATION_FORMAT_COUNT); + EP_ASSERT (circular_buffer_size_in_mb > 0); + EP_ASSERT (providers_len > 0 && providers != NULL); + + // If the state or arguments are invalid, bail here. + if (session_type == EP_SESSION_TYPE_FILE && output_path == NULL) + return 0; + if (session_type == EP_SESSION_TYPE_IPCSTREAM && stream == NULL) + return 0; + + EventPipeSessionID session_id = 0; + EventPipeProviderCallbackDataQueue callback_data_queue; + EventPipeProviderCallbackData provider_callback_data; + EventPipeProviderCallbackDataQueue *provider_callback_data_queue = ep_provider_callback_data_queue_init (&callback_data_queue); + + EP_CONFIG_LOCK_ENTER + session_id = enable_lock_held ( + output_path, + circular_buffer_size_in_mb, + providers, + providers_len, + session_type, + format, + rundown_requested, + stream, + enable_sample_profiler, + provider_callback_data_queue); + EP_CONFIG_LOCK_EXIT + + while (ep_provider_callback_data_queue_try_dequeue (provider_callback_data_queue, &provider_callback_data)) + ep_provider_invoke_callback (&provider_callback_data); + +ep_on_exit: + ep_provider_callback_data_queue_fini (provider_callback_data_queue); + ep_rt_config_requires_lock_not_held (); + return session_id; + +ep_on_error: + session_id = 0; + ep_exit_error_handler (); +} + +void +ep_disable (EventPipeSessionID id) +{ + ep_rt_config_requires_lock_not_held (); + + //TODO: Why is this needed? Just to make sure thread is attached to runtime for + //EP_GCX_PREEMP_ENTER/EP_GCX_PREEMP_EXIT to work? + ep_rt_thread_setup (); + + if (id == 0) + return; + + // Don't block GC during clean-up. + EP_GCX_PREEMP_ENTER + + EventPipeProviderCallbackDataQueue callback_data_queue; + EventPipeProviderCallbackData provider_callback_data; + EventPipeProviderCallbackDataQueue *provider_callback_data_queue = ep_provider_callback_data_queue_init (&callback_data_queue); + + disable (id, provider_callback_data_queue); + + while (ep_provider_callback_data_queue_try_dequeue (provider_callback_data_queue, &provider_callback_data)) + ep_provider_invoke_callback (&provider_callback_data); + + ep_provider_callback_data_queue_fini (provider_callback_data_queue); + + EP_GCX_PREEMP_EXIT + + ep_rt_config_requires_lock_not_held (); + return; +} + +EventPipeSession * +ep_get_session (EventPipeSessionID session_id) +{ + ep_rt_config_requires_lock_not_held (); + + EP_CONFIG_LOCK_ENTER + + if (ep_volatile_load_eventpipe_state () == EP_STATE_NOT_INITIALIZED) { + EP_ASSERT (!"EventPipe::GetSession invoked before EventPipe was initialized."); + ep_raise_error_holding_lock (); + } + + ep_raise_error_if_nok_holding_lock (is_session_id_in_collection_lock_held (session_id) == true); + + EP_CONFIG_LOCK_EXIT + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return (EventPipeSession *)session_id; + +ep_on_error: + session_id = 0; + ep_exit_error_handler (); +} + +bool +ep_enabled (void) +{ + //TODO: Validate if ever called without holding lock, if so should check be atomic? + return (ep_volatile_load_eventpipe_state () >= EP_STATE_INITIALIZED && + ep_volatile_load_number_of_sessions () > 0); +} + +EventPipeProvider * +ep_create_provider ( + const ep_char8_t *provider_name, + EventPipeCallback callback_func, + void *callback_data) +{ + ep_rt_config_requires_lock_not_held (); + + ep_return_null_if_nok (provider_name != NULL); + + EventPipeProvider *provider = NULL; + EventPipeProviderCallbackDataQueue data_queue; + EventPipeProviderCallbackData provider_callback_data; + EventPipeProviderCallbackDataQueue *provider_callback_data_queue = ep_provider_callback_data_queue_init (&data_queue); + + EP_CONFIG_LOCK_ENTER + provider = ep_config_create_provider_lock_held (ep_config_get (), provider_name, callback_func, callback_data, provider_callback_data_queue); + ep_raise_error_if_nok_holding_lock (provider != NULL); + EP_CONFIG_LOCK_EXIT + + while (ep_provider_callback_data_queue_try_dequeue (provider_callback_data_queue, &provider_callback_data)) + ep_provider_invoke_callback (&provider_callback_data); + +ep_on_exit: + ep_provider_callback_data_queue_fini (provider_callback_data_queue); + ep_rt_config_requires_lock_not_held (); + return provider; + +ep_on_error: + ep_delete_provider (provider); + + provider = NULL; + ep_exit_error_handler (); +} + +void +ep_delete_provider (EventPipeProvider *provider) +{ + ep_rt_config_requires_lock_not_held (); + + ep_return_void_if_nok (provider != NULL); + + // Take the lock to make sure that we don't have a race + // between disabling tracing and deleting a provider + // where we hold a provider after tracing has been disabled. + EP_CONFIG_LOCK_ENTER + if (enabled_lock_held ()) { + // Save the provider until the end of the tracing session. + ep_provider_set_delete_deferred (provider, true); + } else { + ep_config_delete_provider_lock_held (ep_config_get (), provider); + } + EP_CONFIG_LOCK_EXIT + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return; + +ep_on_error: + ep_exit_error_handler (); +} + +EventPipeProvider * +ep_get_provider (const ep_char8_t *provider_name) +{ + ep_rt_config_requires_lock_not_held (); + + ep_return_null_if_nok (provider_name != NULL); + + EventPipeProvider *provider = NULL; + + EP_CONFIG_LOCK_ENTER + provider = ep_config_get_provider_lock_held (ep_config_get (), provider_name); + ep_raise_error_if_nok_holding_lock (provider != NULL); + EP_CONFIG_LOCK_EXIT + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return provider; + +ep_on_error: + provider = NULL; + ep_exit_error_handler (); +} + +void +ep_init (void) +{ + ep_rt_init (); + ep_rt_config_requires_lock_not_held (); + + //TODO: Implement. Locking pattern between init/shutdown is racy but same as CoreCLR. Needs to be revisited. + if (ep_volatile_load_eventpipe_state () != EP_STATE_NOT_INITIALIZED) { + EP_ASSERT (!"EventPipe already initialized."); + return; + } + + for (uint32_t i = 0; i < EP_MAX_NUMBER_OF_SESSIONS; ++i) + ep_volatile_store_session (i, NULL); + + if (ep_config_init (ep_config_get ())) { + EP_CONFIG_LOCK_ENTER + ep_volatile_store_eventpipe_state_without_barrier (EP_STATE_INITIALIZED); + EP_CONFIG_LOCK_EXIT + } + + //TODO: Implement. + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return; + +ep_on_error: + ep_exit_error_handler (); +} + +void +ep_finish_init (void) +{ + //TODO: Implement. +} + +void +ep_shutdown (void) +{ + ep_rt_config_requires_lock_not_held (); + + //TODO: Locking pattern between init/shutdown is racy but same as CoreCLR. Needs to be revisited. + ep_return_void_if_nok (ep_volatile_load_eventpipe_state () != EP_STATE_SHUTTING_DOWN); + ep_return_void_if_nok (!ep_rt_process_detach ()); + ep_return_void_if_nok (ep_volatile_load_eventpipe_state () == EP_STATE_INITIALIZED); + + EP_CONFIG_LOCK_ENTER + ep_volatile_store_eventpipe_state_without_barrier (EP_STATE_SHUTTING_DOWN); + EP_CONFIG_LOCK_EXIT + + for (uint32_t i = 0; i < EP_MAX_NUMBER_OF_SESSIONS; ++i) { + EventPipeSession *session = ep_volatile_load_session (i); + if (session) + ep_disable ((EventPipeSessionID)session); + } + + // dotnet/coreclr: issue 24850: EventPipe shutdown race conditions + // Deallocating providers/events here might cause AV if a WriteEvent + // was to occur. Thus, we are not doing this cleanup. + + // // Remove EventPipeEventSource first since it tries to use the data structures that we remove below. + // // We need to do this after disabling sessions since those try to write to EventPipeEventSource. + // delete s_pEventSource; + // s_pEventSource = nullptr; + // s_config.Shutdown(); + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + ep_rt_shutdown (); + return; + +ep_on_error: + ep_exit_error_handler (); +} + +EventPipeEventMetadataEvent * +ep_build_event_metadata_event ( + EventPipeEventInstance *event_instance, + uint32_t metadata_id) +{ + return ep_config_build_event_metadata_event (ep_config_get (), event_instance, metadata_id); +} + +void +ep_write_event ( + EventPipeEvent *ep_event, + EventData *event_data, + uint32_t event_data_len, + const uint8_t *activity_id, + const uint8_t *related_activity_id) +{ + //TODO: Implement. +} + +EventPipeEventInstance * +ep_get_next_event (EventPipeSessionID session_id) +{ + ep_rt_config_requires_lock_not_held (); + + // Only fetch the next event if a tracing session exists. + // The buffer manager is not disposed until the process is shutdown. + EventPipeSession *const session = ep_get_session (session_id); + return session ? ep_session_get_next_event (session) : NULL; +} + +EventPipeWaitHandle +ep_get_wait_handle (EventPipeSessionID session_id) +{ + EventPipeSession *const session = ep_get_session (session_id); + return session ? ep_session_get_wait_event (session) : 0; +} + +void +ep_start_streaming (EventPipeSessionID session_id) +{ + ep_rt_config_requires_lock_not_held (); + + EP_CONFIG_LOCK_ENTER + ep_raise_error_if_nok_holding_lock (is_session_id_in_collection_lock_held (session_id) == true); + EventPipeSession *const session = (EventPipeSession *)session_id; + ep_session_start_streaming_lock_held (session); + EP_CONFIG_LOCK_EXIT + +ep_on_exit: + ep_rt_config_requires_lock_not_held (); + return; + +ep_on_error: + ep_exit_error_handler (); +} + +/* + * EventPipePerf. + */ + +uint64_t +ep_perf_counter_query (void) +{ + return ep_rt_perf_counter_query (); +} + +uint64_t +ep_perf_frequency_query (void) +{ + return ep_rt_perf_frequency_query (); +} + +/* + * EventPipeProviderCallbackDataQueue. + */ + +void +ep_provider_callback_data_queue_enqueue ( + EventPipeProviderCallbackDataQueue *provider_callback_data_queue, + EventPipeProviderCallbackData *provider_callback_data) +{ + ep_return_void_if_nok (provider_callback_data_queue != NULL); + ep_rt_provider_callback_data_queue_push_tail (ep_provider_callback_data_queue_get_queue_ref (provider_callback_data_queue), ep_provider_callback_data_alloc_copy (provider_callback_data)); +} + +bool +ep_provider_callback_data_queue_try_dequeue ( + EventPipeProviderCallbackDataQueue *provider_callback_data_queue, + EventPipeProviderCallbackData *provider_callback_data) +{ + ep_return_false_if_nok (provider_callback_data_queue != NULL && ep_rt_provider_callback_data_queue_is_empty (ep_provider_callback_data_queue_get_queue_ref (provider_callback_data_queue)) != true); + + EventPipeProviderCallbackData *value = NULL; + ep_rt_provider_callback_data_queue_pop_head (ep_provider_callback_data_queue_get_queue_ref (provider_callback_data_queue), &value); + ep_provider_callback_data_init_copy (provider_callback_data, value); + ep_provider_callback_data_free (value); + + return true; +} + +#endif /* ENABLE_PERFTRACING */ + +extern const char quiet_linker_empty_file_warning_eventpipe; +const char quiet_linker_empty_file_warning_eventpipe = 0; diff --git a/src/mono/mono/eventpipe/ep.h b/src/mono/mono/eventpipe/ep.h new file mode 100644 index 0000000000000..ca11989aa415b --- /dev/null +++ b/src/mono/mono/eventpipe/ep.h @@ -0,0 +1,272 @@ +#ifndef __EVENTPIPE_H__ +#define __EVENTPIPE_H__ + +#include + +#ifdef ENABLE_PERFTRACING +#include "ep-rt-config.h" +#include "ep-types.h" +#include "ep-stream.h" +#include "ep-thread.h" +#include "ep-block.h" +#include "ep-event-payload.h" +#include "ep-buffer.h" +#include "ep-buffer-manager.h" +#include "ep-stack-contents.h" +#include "ep-event.h" +#include "ep-event-instance.h" +#include "ep-config.h" +#include "ep-event-source.h" +#include "ep-file.h" +#include "ep-metadata-generator.h" +#include "ep-provider.h" +#include "ep-session.h" +#include "ep-session-provider.h" +#include "ep-rt.h" + +/* + * Globals and volatile access functions. + */ + +static +inline +EventPipeState +ep_volatile_load_eventpipe_state (void) +{ + extern volatile EventPipeState _ep_state; + return (EventPipeState)ep_rt_volatile_load_uint32_t ((const volatile uint32_t *)&_ep_state); +} + +static +inline +EventPipeState +ep_volatile_load_eventpipe_state_without_barrier (void) +{ + extern volatile EventPipeState _ep_state; + return (EventPipeState)ep_rt_volatile_load_uint32_t_without_barrier ((const volatile uint32_t *)&_ep_state); +} + +static +inline +void +ep_volatile_store_eventpipe_state (EventPipeState state) +{ + extern volatile EventPipeState _ep_state; + ep_rt_volatile_store_uint32_t ((volatile uint32_t *)&_ep_state, state); +} + +static +inline +void +ep_volatile_store_eventpipe_state_without_barrier (EventPipeState state) +{ + extern volatile EventPipeState _ep_state; + ep_rt_volatile_store_uint32_t_without_barrier ((volatile uint32_t *)&_ep_state, state); +} + +static +inline +EventPipeSession * +ep_volatile_load_session (size_t index) +{ + extern volatile EventPipeSession *_ep_sessions [EP_MAX_NUMBER_OF_SESSIONS]; + return (EventPipeSession *)ep_rt_volatile_load_ptr ((volatile void **)(&_ep_sessions [index])); +} + +static +inline +EventPipeSession * +ep_volatile_load_session_without_barrier (size_t index) +{ + extern volatile EventPipeSession *_ep_sessions [EP_MAX_NUMBER_OF_SESSIONS]; + return (EventPipeSession *)ep_rt_volatile_load_ptr_without_barrier ((volatile void **)(&_ep_sessions [index])); +} + +static +inline +void +ep_volatile_store_session (size_t index, EventPipeSession *session) +{ + extern volatile EventPipeSession *_ep_sessions [EP_MAX_NUMBER_OF_SESSIONS]; + ep_rt_volatile_store_ptr ((volatile void **)(&_ep_sessions [index]), session); +} + +static +inline +void +ep_volatile_store_session_without_barrier (size_t index, EventPipeSession *session) +{ + extern volatile EventPipeSession *_ep_sessions [EP_MAX_NUMBER_OF_SESSIONS]; + ep_rt_volatile_store_ptr_without_barrier ((volatile void **)(&_ep_sessions [index]), session); +} + +static +inline +uint32_t +ep_volatile_load_number_of_sessions (void) +{ + extern volatile uint32_t _ep_number_of_sessions; + return ep_rt_volatile_load_uint32_t (&_ep_number_of_sessions); +} + +static +inline +uint32_t +ep_volatile_load_number_of_sessions_without_barrier (void) +{ + extern volatile uint32_t _ep_number_of_sessions; + return ep_rt_volatile_load_uint32_t_without_barrier (&_ep_number_of_sessions); +} + +static +inline +void +ep_volatile_store_number_of_sessions (uint32_t number_of_sessions) +{ + extern volatile uint32_t _ep_number_of_sessions; + ep_rt_volatile_store_uint32_t (&_ep_number_of_sessions, number_of_sessions); +} + +static +inline +void +ep_volatile_store_number_of_sessions_without_barrier (uint32_t number_of_sessions) +{ + extern volatile uint32_t _ep_number_of_sessions; + ep_rt_volatile_store_uint32_t_without_barrier (&_ep_number_of_sessions, number_of_sessions); +} + +static +inline +uint64_t +ep_volatile_load_allow_write (void) +{ + extern volatile uint64_t _ep_allow_write; + return ep_rt_volatile_load_uint64_t (&_ep_allow_write); +} + +static +inline +uint64_t +ep_volatile_load_allow_write_without_barrier (void) +{ + extern volatile uint64_t _ep_allow_write; + return ep_rt_volatile_load_uint64_t_without_barrier (&_ep_allow_write); +} + +static +inline +void +ep_volatile_store_allow_write (uint64_t allow_write) +{ + extern volatile uint64_t _ep_allow_write; + ep_rt_volatile_store_uint64_t (&_ep_allow_write, allow_write); +} + +static +inline +void +ep_volatile_store_allow_write_without_barrier (uint64_t allow_write) +{ + extern volatile uint64_t _ep_allow_write; + ep_rt_volatile_store_uint64_t_without_barrier (&_ep_allow_write, allow_write); +} + +/* + * EventPipe. + */ + +EventPipeSessionID +ep_enable ( + const ep_char8_t *output_path, + uint32_t circular_buffer_size_in_mb, + const EventPipeProviderConfiguration *providers, + uint32_t providers_len, + EventPipeSessionType session_type, + EventPipeSerializationFormat format, + bool rundown_requested, + IpcStream *stream, + bool enable_sample_profiler); + +void +ep_disable (EventPipeSessionID id); + +EventPipeSession * +ep_get_session (EventPipeSessionID session_id); + +bool +ep_enabled (void); + +EventPipeProvider * +ep_create_provider ( + const ep_char8_t *provider_name, + EventPipeCallback callback_func, + void *callback_data); + +void +ep_delete_provider (EventPipeProvider *provider); + +EventPipeProvider * +ep_get_provider (const ep_char8_t *provider_name); + +void +ep_init (void); + +void +ep_finish_init (void); + +void +ep_shutdown (void); + +EventPipeEventMetadataEvent * +ep_build_event_metadata_event ( + EventPipeEventInstance *event_instance, + uint32_t metadata_id); + +void +ep_write_event ( + EventPipeEvent *ep_event, + EventData *event_data, + uint32_t event_data_len, + const uint8_t *activity_id, + const uint8_t *related_activity_id); + +EventPipeEventInstance * +ep_get_next_event (EventPipeSessionID session_id); + +EventPipeWaitHandle +ep_get_wait_handle (EventPipeSessionID session_id); + +void +ep_start_streaming (EventPipeSessionID session_id); + +/* + * EventPipePerf. + */ + +uint64_t +ep_perf_counter_query (void); + +uint64_t +ep_perf_frequency_query (void); + +#else /* ENABLE_PERFTRACING */ + +static +inline +void +ep_init (void) +{ + ; +} + +static +inline +void +ep_shutdown (void) +{ + ; +} + +#endif /* ENABLE_PERFTRACING */ +#endif /** __EVENTPIPE_H__ **/ diff --git a/src/mono/mono/eventpipe/test/Directory.Build.props b/src/mono/mono/eventpipe/test/Directory.Build.props new file mode 100644 index 0000000000000..4de865b5f1e15 --- /dev/null +++ b/src/mono/mono/eventpipe/test/Directory.Build.props @@ -0,0 +1,3 @@ + + + diff --git a/src/mono/mono/eventpipe/test/Directory.Build.targets b/src/mono/mono/eventpipe/test/Directory.Build.targets new file mode 100644 index 0000000000000..c43cec29bd65d --- /dev/null +++ b/src/mono/mono/eventpipe/test/Directory.Build.targets @@ -0,0 +1,3 @@ + + + diff --git a/src/mono/mono/eventpipe/test/Makefile.am b/src/mono/mono/eventpipe/test/Makefile.am new file mode 100644 index 0000000000000..4513e50da6326 --- /dev/null +++ b/src/mono/mono/eventpipe/test/Makefile.am @@ -0,0 +1,56 @@ +MAKEFLAGS := $(MAKEFLAGS) --no-builtin-rules + +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/mono $(GLIB_CFLAGS) + +if HOST_DARWIN +test_ldflags = -framework CoreFoundation -framework Foundation +endif + +sgen_libs = \ + $(top_builddir)/mono/metadata/libmonoruntimesgen.la \ + $(top_builddir)/mono/sgen/libmonosgen.la \ + $(top_builddir)/mono/utils/libmonoutils.la \ + $(top_builddir)/mono/eglib/libeglib.la + +mini_libs = \ + $(top_builddir)/mono/mini/libmini.la + +if !DISABLE_INTERPRETER +mini_libs += $(top_builddir)/mono/mini/libmono-ee-interp.la +endif + +if !DISABLE_DEBUGGER_AGENT +mini_libs += $(top_builddir)/mono/mini/libmono-dbg.la +endif + +eventpipe_libs = \ + $(top_builddir)/mono/eventpipe/libeventpipe.la + +CFLAGS = $(filter-out @CXX_REMOVE_CFLAGS@, @CFLAGS@) + +if !HOST_WIN32 +if ENABLE_PERFTRACING + +test_eventpipe_SOURCES = \ +ep-test-runner.c \ +ep-test-driver.c \ +ep-fake-tests.c \ +ep-fastserializer-tests.c \ +ep-provider-callback-dataqueue-tests.c \ +ep-setup-tests.c \ +ep-tests.c \ +ep-file-tests.c \ +ep-session-tests.c \ +ep-teardown-tests.c \ +ep-thread-tests.c \ +ep-tests-debug.h \ +ep-tests.h + +test_eventpipe_CFLAGS = $(AM_CFLAGS) $(SGEN_DEFINES) +test_eventpipe_LDADD = $(mini_libs) $(sgen_libs) $(eventpipe_libs) +test_eventpipe_LDFLAGS = $(test_ldflags) + +noinst_PROGRAMS = test-eventpipe + +endif ENABLE_PERFTRACING +endif !HOST_WIN32 diff --git a/src/mono/mono/eventpipe/test/ep-fake-tests.c b/src/mono/mono/eventpipe/test/ep-fake-tests.c new file mode 100644 index 0000000000000..86bc252101893 --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-fake-tests.c @@ -0,0 +1 @@ +#include "mono/eglib/test/fake.c" diff --git a/src/mono/mono/eventpipe/test/ep-fastserializer-tests.c b/src/mono/mono/eventpipe/test/ep-fastserializer-tests.c new file mode 100644 index 0000000000000..0d39f7e6f294a --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-fastserializer-tests.c @@ -0,0 +1,346 @@ +#include "mono/eventpipe/ep.h" +#include "eglib/test/test.h" + +#define TEST_PROVIDER_NAME "MyTestProvider" + +typedef struct _MemoryStreamWriter { + StreamWriter stream_writer; + uint8_t buffer [1024]; + uint8_t *current_ptr; +} MemoryStreamWriter; + +static +void +memory_stream_writer_free_func (void *stream) +{ + g_free ((MemoryStreamWriter *)stream); +} + +static +bool +memory_stream_writer_write_func ( + void *stream, + const uint8_t *buffer, + uint32_t bytes_to_write, + uint32_t *bytes_written) +{ + *bytes_written = 0; + + MemoryStreamWriter *memory_stream = (MemoryStreamWriter *)stream; + if (!stream) + return false; + + if ((memory_stream->current_ptr + bytes_to_write) > (memory_stream->buffer + sizeof (memory_stream->buffer))) + return false; + + memcpy (memory_stream->current_ptr, buffer, bytes_to_write); + memory_stream->current_ptr += bytes_to_write; + *bytes_written = bytes_to_write; + + return true; +} + +static StreamWriterVtable memory_stream_writer_vtable = { + memory_stream_writer_free_func, + memory_stream_writer_write_func }; + +static RESULT +test_fast_serializer_object_fast_serialize (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + MemoryStreamWriter *stream_writer = NULL; + FastSerializer *fast_serializer = NULL; + EventPipeProvider *provider = NULL; + EventPipeEvent *ep_event = NULL; + EventPipeEventInstance *ep_event_instance = NULL; + EventPipeEventBlock *event_block = NULL; + + // Use memory stream for testing. + stream_writer = g_new0 (MemoryStreamWriter, 1); + ep_raise_error_if_nok (stream_writer != NULL); + + test_location = 1; + + stream_writer->current_ptr = stream_writer->buffer; + ep_stream_writer_init (&stream_writer->stream_writer, &memory_stream_writer_vtable); + + fast_serializer = ep_fast_serializer_alloc ((StreamWriter *)stream_writer); + ep_raise_error_if_nok (fast_serializer != NULL); + stream_writer = NULL; + + test_location = 2; + + provider = ep_create_provider (TEST_PROVIDER_NAME, NULL, NULL); + ep_raise_error_if_nok (provider != NULL); + + test_location = 3; + + ep_event = ep_event_alloc (provider, 1, 1, 1, EP_EVENT_LEVEL_VERBOSE, false, NULL, 0); + ep_raise_error_if_nok (ep_event != NULL); + + test_location = 4; + + ep_event_instance = ep_event_instance_alloc (ep_event, 0, 0, NULL, 0, NULL, NULL); + event_block = ep_event_block_alloc (1024, EP_SERIALIZATION_FORMAT_NETTRACE_V4); + ep_raise_error_if_nok (ep_event_instance != NULL && event_block != NULL); + + test_location = 5; + + ep_raise_error_if_nok (ep_event_block_base_write_event ((EventPipeEventBlockBase *)event_block, ep_event_instance, 0, 1, 0, false) == true); + + test_location = 6; + + ep_fast_serializable_object_fast_serialize ((FastSerializableObject *)event_block, fast_serializer); + + //Check memory stream results. + stream_writer = (MemoryStreamWriter *)ep_fast_serializer_get_stream_writer (fast_serializer); + if (stream_writer->buffer == stream_writer->current_ptr) { + result = FAILED ("fast_serialize for EventPipeEventBlock didn't write any data into MemoryStreamWriter"); + ep_raise_error (); + } + +ep_on_exit: + ep_event_instance_free (ep_event_instance); + ep_event_block_free (event_block); + ep_event_free (ep_event); + ep_delete_provider (provider); + ep_fast_serializer_free (fast_serializer); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_fast_serializer_event_block_free_vcall (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeEventBlock *event_block = ep_event_block_alloc (1024, EP_SERIALIZATION_FORMAT_NETTRACE_V4); + ep_raise_error_if_nok (event_block != NULL); + + test_location = 1; + + ep_fast_serializable_object_free_vcall ((FastSerializableObject *)event_block); + +ep_on_exit: + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_fast_serializer_metadata_block_free_vcall (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeMetadataBlock *metadata_block = ep_metadata_block_alloc (1024); + ep_raise_error_if_nok (metadata_block != NULL); + + test_location = 1; + + ep_fast_serializable_object_free_vcall ((FastSerializableObject *)metadata_block); + +ep_on_exit: + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_fast_serializer_sequence_point_block_free_vcall (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeSequencePoint sequence_point; + EventPipeSequencePointBlock *sequence_point_block = NULL; + + ep_raise_error_if_nok (ep_sequence_point_init (&sequence_point) != NULL); + + test_location = 1; + + sequence_point_block = ep_sequence_point_block_alloc (&sequence_point); + ep_raise_error_if_nok (sequence_point_block != NULL); + + test_location = 2; + + ep_fast_serializable_object_free_vcall ((FastSerializableObject *)sequence_point_block); + +ep_on_exit: + ep_sequence_point_fini (&sequence_point); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_fast_serializer_stack_block_free_vcall (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeStackBlock *stack_block = ep_stack_block_alloc (1024); + ep_raise_error_if_nok (stack_block != NULL); + + test_location = 1; + + ep_fast_serializable_object_free_vcall ((FastSerializableObject *)stack_block); + +ep_on_exit: + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_fast_serializer_event_block_get_type_name (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeEventBlock *event_block = ep_event_block_alloc (1024, EP_SERIALIZATION_FORMAT_NETTRACE_V4); + ep_raise_error_if_nok (event_block != NULL); + + test_location = 1; + + const char *type_name = (char *)ep_fast_serializable_object_get_type_name ((FastSerializableObject *)event_block); + if (strcmp (type_name, "EventBlock")) { + result = FAILED ("get_type_name for EventPipeEventBlock returned unexpected value, retrieved: %s, expected: %s", type_name, "EventBlock"); + ep_raise_error (); + } + +ep_on_exit: + ep_event_block_free (event_block); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_fast_serializer_metadata_block_get_type_name (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeMetadataBlock *metadata_block = ep_metadata_block_alloc (1024); + ep_raise_error_if_nok (metadata_block != NULL); + + test_location = 1; + + const char *type_name = (char *)ep_fast_serializable_object_get_type_name ((FastSerializableObject *)metadata_block); + if (strcmp (type_name, "MetadataBlock")) { + result = FAILED ("get_type_name for EventPipeMetadataBlock returned unexpected value, retrieved: %s, expected: %s", type_name, "MetadataBlock"); + ep_raise_error (); + } + +ep_on_exit: + ep_metadata_block_free (metadata_block); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_fast_serializer_sequence_point_block_get_type_name (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeSequencePoint sequence_point; + EventPipeSequencePointBlock *sequence_point_block = NULL; + + ep_raise_error_if_nok (ep_sequence_point_init (&sequence_point) != NULL); + + test_location = 1; + + sequence_point_block = ep_sequence_point_block_alloc (&sequence_point); + ep_raise_error_if_nok (sequence_point_block != NULL); + + test_location = 2; + + const char *type_name = (char *)ep_fast_serializable_object_get_type_name ((FastSerializableObject *)sequence_point_block); + if (strcmp (type_name, "SPBlock")) { + result = FAILED ("get_type_name for EventPipeSequencePointBlock returned unexpected value, retrieved: %s, expected: %s", type_name, "SPBlock"); + ep_raise_error (); + } + +ep_on_exit: + ep_sequence_point_block_free (sequence_point_block); + ep_sequence_point_fini (&sequence_point); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_fast_serializer_stack_block_get_type_name (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeStackBlock *stack_block = ep_stack_block_alloc (1024); + ep_raise_error_if_nok (stack_block != NULL); + + test_location = 1; + + const char *type_name = (char *)ep_fast_serializable_object_get_type_name ((FastSerializableObject *)stack_block); + if (strcmp (type_name, "StackBlock")) { + result = FAILED ("get_type_name for EventPipeStackBlock returned unexpected value, retrieved: %s, expected: %s", type_name, "StackBlock"); + ep_raise_error (); + } + +ep_on_exit: + ep_stack_block_free (stack_block); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +//TODO: Add perf test just doing write into fast serializer with different event types (no event alloc/instancing). Write into void +//stream but still write into same memory buffer to do something. + +static Test ep_fastserializer_tests [] = { + {"fast_serializer_object_fast_serialize", test_fast_serializer_object_fast_serialize}, + {"test_fast_serializer_event_block_free_vcall", test_fast_serializer_event_block_free_vcall}, + {"test_fast_serializer_metadata_block_free_vcall", test_fast_serializer_metadata_block_free_vcall}, + {"test_fast_serializer_sequence_point_block_free_vcall", test_fast_serializer_sequence_point_block_free_vcall}, + {"test_fast_serializer_stack_block_free_vcall", test_fast_serializer_stack_block_free_vcall}, + {"test_fast_serializer_event_block_get_type_name", test_fast_serializer_event_block_get_type_name}, + {"test_fast_serializer_metadata_block_get_type_name", test_fast_serializer_metadata_block_get_type_name}, + {"test_fast_serializer_sequence_point_block_get_type_name", test_fast_serializer_sequence_point_block_get_type_name}, + {"test_fast_serializer_stack_block_get_type_name", test_fast_serializer_stack_block_get_type_name}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(ep_fastserializer_tests_init, ep_fastserializer_tests) diff --git a/src/mono/mono/eventpipe/test/ep-file-tests.c b/src/mono/mono/eventpipe/test/ep-file-tests.c new file mode 100644 index 0000000000000..696d2442c9baf --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-file-tests.c @@ -0,0 +1,172 @@ +#include "mono/eventpipe/ep.h" +#include "eglib/test/test.h" + +#define TEST_PROVIDER_NAME "MyTestProvider" +#define TEST_FILE "./ep_test_create_file.txt" + +static RESULT +test_create_file (EventPipeSerializationFormat format) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeFile *file = NULL; + FileStreamWriter *file_stream_writer = NULL; + + file_stream_writer = ep_file_stream_writer_alloc (TEST_FILE); + ep_raise_error_if_nok (file_stream_writer != NULL); + + test_location = 1; + + file = ep_file_alloc ((StreamWriter *)file_stream_writer, format); + ep_raise_error_if_nok (file != NULL); + + file_stream_writer = NULL; + if (!ep_file_initialize_file (file)) { + result = FAILED ("ep_file_initialize_file failed"); + ep_raise_error (); + } + + test_location = 2; + + ep_file_flush (file, EP_FILE_FLUSH_FLAGS_ALL_BLOCKS); + + test_location = 3; + +ep_on_exit: + ep_file_free (file); + ep_file_stream_writer_free (file_stream_writer); + + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_file_write_event (EventPipeSerializationFormat format, bool write_event, bool write_sequence_point) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeFile *file = NULL; + FileStreamWriter *file_stream_writer = NULL; + EventPipeProvider *provider = NULL; + EventPipeEvent *ep_event = NULL; + EventPipeEventInstance *ep_event_instance = NULL; + EventPipeEventMetadataEvent *metadata_event = NULL; + + file_stream_writer = ep_file_stream_writer_alloc (TEST_FILE); + ep_raise_error_if_nok (file_stream_writer != NULL); + + test_location = 1; + + file = ep_file_alloc ((StreamWriter *)file_stream_writer, format); + ep_raise_error_if_nok (file != NULL); + + file_stream_writer = NULL; + if (!ep_file_initialize_file (file)) { + result = FAILED ("ep_file_initialize_file failed"); + ep_raise_error (); + } + + test_location = 2; + + if (write_event) { + provider = ep_create_provider (TEST_PROVIDER_NAME, NULL, NULL); + ep_raise_error_if_nok (provider != NULL); + + test_location = 3; + + ep_event = ep_event_alloc (provider, 1, 1, 1, EP_EVENT_LEVEL_VERBOSE, false, NULL, 0); + ep_raise_error_if_nok (ep_event != NULL); + + test_location = 4; + + ep_event_instance = ep_event_instance_alloc (ep_event, 0, 0, NULL, 0, NULL, NULL); + ep_raise_error_if_nok (ep_event_instance != NULL); + + test_location = 5; + + metadata_event = ep_build_event_metadata_event (ep_event_instance, 1); + ep_raise_error_if_nok (metadata_event != NULL); + + ep_file_write_event (file, (EventPipeEventInstance *)metadata_event, 1, 1 , true); + } + + if (write_sequence_point) { + EventPipeSequencePoint sequence_point; + ep_sequence_point_init (&sequence_point); + ep_file_write_sequence_point (file, &sequence_point); + ep_sequence_point_fini (&sequence_point); + } + + ep_file_flush (file, EP_FILE_FLUSH_FLAGS_ALL_BLOCKS); + + test_location = 6; + +ep_on_exit: + ep_delete_provider (provider); + ep_event_free (ep_event); + ep_event_instance_free (ep_event_instance); + ep_event_metdata_event_free (metadata_event); + ep_file_free (file); + ep_file_stream_writer_free (file_stream_writer); + + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_create_file_netperf_v3 (void) +{ + return test_create_file (EP_SERIALIZATION_FORMAT_NETPERF_V3); +} + +static RESULT +test_create_file_nettrace_v4 (void) +{ + return test_create_file (EP_SERIALIZATION_FORMAT_NETTRACE_V4); +} + +static RESULT +test_file_write_event_netperf_v3 (void) +{ + return test_file_write_event (EP_SERIALIZATION_FORMAT_NETPERF_V3, true, false); +} + +static RESULT +test_file_write_event_nettrace_v4 (void) +{ + return test_file_write_event (EP_SERIALIZATION_FORMAT_NETTRACE_V4, true, false); +} + +static RESULT +test_file_write_sequence_point_netperf_v3 (void) +{ + return test_file_write_event (EP_SERIALIZATION_FORMAT_NETPERF_V3, false, true); +} + +static RESULT +test_file_write_sequence_point_nettrace_v4 (void) +{ + return test_file_write_event (EP_SERIALIZATION_FORMAT_NETTRACE_V4, false, true); +} + +static Test ep_file_tests [] = { + {"test_create_file_netperf_v3", test_create_file_netperf_v3}, + {"test_create_file_nettrace_v4", test_create_file_nettrace_v4}, + {"test_file_write_event_netperf_v3", test_file_write_event_netperf_v3}, + {"test_file_write_event_nettrace_v4", test_file_write_event_nettrace_v4}, + {"test_file_write_sequence_point_netperf_v3", test_file_write_sequence_point_netperf_v3}, + {"test_file_write_sequence_point_nettrace_v4", test_file_write_sequence_point_nettrace_v4}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(ep_file_tests_init, ep_file_tests) diff --git a/src/mono/mono/eventpipe/test/ep-provider-callback-dataqueue-tests.c b/src/mono/mono/eventpipe/test/ep-provider-callback-dataqueue-tests.c new file mode 100644 index 0000000000000..06a45c4c6a5e7 --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-provider-callback-dataqueue-tests.c @@ -0,0 +1,98 @@ +#include "mono/eventpipe/ep.h" +#include "eglib/test/test.h" + +#define TEST_PROVIDER_NAME "MyTestProvider" +#define TEST_FILE "./ep_test_create_file.txt" + +#ifdef _CRTDBG_MAP_ALLOC +static _CrtMemState eventpipe_memory_start_snapshot; +static _CrtMemState eventpipe_memory_end_snapshot; +static _CrtMemState eventpipe_memory_diff_snapshot; +#endif + +static RESULT +test_provider_callback_data_queue_setup (void) +{ +#ifdef _CRTDBG_MAP_ALLOC + _CrtMemCheckpoint (&eventpipe_memory_start_snapshot); +#endif + return NULL; +} + +static +void +provider_callback ( + const uint8_t *source_id, + unsigned long is_enabled, + uint8_t level, + uint64_t match_any_keywords, + uint64_t match_all_keywords, + EventFilterDescriptor *filter_data, + void *callback_context) +{ + ; +} + +static RESULT +test_provider_callback_data_queue (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeProviderCallbackDataQueue callback_data_queue; + EventPipeProviderCallbackDataQueue *provider_callback_data_queue = ep_provider_callback_data_queue_init (&callback_data_queue); + + EventPipeProviderCallbackData enqueue_callback_data; + EventPipeProviderCallbackData *provider_enqueue_callback_data = ep_provider_callback_data_init ( + &enqueue_callback_data, + "", + provider_callback, + NULL, + 1, + EP_EVENT_LEVEL_LOG_ALWAYS, + true); + + for (uint32_t i = 0; i < 1000; ++i) + ep_provider_callback_data_queue_enqueue (provider_callback_data_queue, provider_enqueue_callback_data); + + EventPipeProviderCallbackData dequeue_callback_data; + uint32_t deque_counter = 0; + while (ep_provider_callback_data_queue_try_dequeue (provider_callback_data_queue, &dequeue_callback_data)) + deque_counter++; + + if (deque_counter != 1000) { + result = FAILED ("Unexpected number of provider callback invokes"); + ep_raise_error (); + } + +ep_on_exit: + ep_provider_callback_data_queue_fini (provider_callback_data_queue); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_provider_callback_data_queue_teardown (void) +{ +#ifdef _CRTDBG_MAP_ALLOC + _CrtMemCheckpoint (&eventpipe_memory_end_snapshot); + if ( _CrtMemDifference( &eventpipe_memory_diff_snapshot, &eventpipe_memory_start_snapshot, &eventpipe_memory_end_snapshot) ) { + _CrtMemDumpStatistics( &eventpipe_memory_diff_snapshot ); + return FAILED ("Memory leak detected!"); + } +#endif + return NULL; +} + +static Test ep_provider_callback_data_queue_tests [] = { + {"test_provider_callback_data_queue_setup", test_provider_callback_data_queue_setup}, + {"test_provider_callback_data_queue", test_provider_callback_data_queue}, + {"test_provider_callback_data_queue_teardown", test_provider_callback_data_queue_teardown}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(ep_provider_callback_data_queue_tests_init, ep_provider_callback_data_queue_tests) diff --git a/src/mono/mono/eventpipe/test/ep-session-tests.c b/src/mono/mono/eventpipe/test/ep-session-tests.c new file mode 100644 index 0000000000000..c9ef8fa79acfe --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-session-tests.c @@ -0,0 +1,244 @@ +#include "mono/eventpipe/ep.h" +#include "eglib/test/test.h" + +#define TEST_PROVIDER_NAME "MyTestProvider" +#define TEST_FILE "./ep_test_create_file.txt" + +#ifdef _CRTDBG_MAP_ALLOC +static _CrtMemState eventpipe_memory_start_snapshot; +static _CrtMemState eventpipe_memory_end_snapshot; +static _CrtMemState eventpipe_memory_diff_snapshot; +#endif + +static RESULT +test_session_setup (void) +{ +#ifdef _CRTDBG_MAP_ALLOC + _CrtMemCheckpoint (&eventpipe_memory_start_snapshot); +#endif + return NULL; +} + +static RESULT +test_create_delete_session (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + EventPipeSession *test_session = NULL; + + EventPipeProviderConfiguration provider_config; + ep_raise_error_if_nok (ep_provider_config_init (&provider_config, TEST_PROVIDER_NAME, 1, EP_EVENT_LEVEL_LOG_ALWAYS, "") != NULL); + + test_location = 1; + + EP_CONFIG_LOCK_ENTER + test_session = ep_session_alloc ( + 1, + TEST_FILE, + NULL, + EP_SESSION_TYPE_FILE, + EP_SERIALIZATION_FORMAT_NETTRACE_V4, + false, + 1, + &provider_config, + 1, + false); + EP_CONFIG_LOCK_EXIT + + ep_raise_error_if_nok (test_session != NULL); + +ep_on_exit: + ep_session_free (test_session); + if (test_location != 0) + ep_provider_config_fini (&provider_config); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_add_session_providers (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + EventPipeSession *test_session = NULL; + EventPipeSessionProvider *test_session_provider = NULL; + + EventPipeProviderConfiguration provider_config; + ep_raise_error_if_nok (ep_provider_config_init (&provider_config, TEST_PROVIDER_NAME, 1, EP_EVENT_LEVEL_LOG_ALWAYS, "") != NULL); + + test_location = 1; + + EP_CONFIG_LOCK_ENTER + test_session = ep_session_alloc ( + 1, + TEST_FILE, + NULL, + EP_SESSION_TYPE_FILE, + EP_SERIALIZATION_FORMAT_NETTRACE_V4, + false, + 1, + &provider_config, + 1, + false); + EP_CONFIG_LOCK_EXIT + + ep_raise_error_if_nok (test_session != NULL); + + test_location = 2; + + if (!ep_session_is_valid (test_session)) { + result = FAILED ("ep_session_is_valid returned false with session providers"); + ep_raise_error (); + } + + test_location = 3; + + test_session_provider = ep_session_provider_alloc (TEST_PROVIDER_NAME, 1, EP_EVENT_LEVEL_LOG_ALWAYS, ""); + ep_raise_error_if_nok (test_session_provider != NULL); + + test_location = 4; + + ep_session_add_session_provider (test_session, test_session_provider); + test_session_provider = NULL; + + if (!ep_session_is_valid (test_session)) { + result = FAILED ("ep_session_is_valid returned false with session providers"); + ep_raise_error (); + } + + test_location = 5; + + ep_session_disable (test_session); + + if (ep_session_is_valid (test_session)) { + result = FAILED ("ep_session_is_valid returned true without session providers"); + ep_raise_error (); + } + +ep_on_exit: + ep_session_free (test_session); + if (test_location != 0) + ep_provider_config_fini (&provider_config); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_session_special_get_set (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + EventPipeSession *test_session = NULL; + + EventPipeProviderConfiguration provider_config; + EventPipeProviderConfiguration *current_provider_config = ep_provider_config_init (&provider_config, TEST_PROVIDER_NAME, 1, EP_EVENT_LEVEL_LOG_ALWAYS, ""); + ep_raise_error_if_nok (current_provider_config != NULL); + + test_location = 1; + + EP_CONFIG_LOCK_ENTER + test_session = ep_session_alloc ( + 1, + TEST_FILE, + NULL, + EP_SESSION_TYPE_FILE, + EP_SERIALIZATION_FORMAT_NETTRACE_V4, + false, + 1, + current_provider_config, + 1, + false); + EP_CONFIG_LOCK_EXIT + + ep_raise_error_if_nok (test_session != NULL); + + test_location = 2; + + if (ep_session_get_rundown_enabled (test_session)) { + result = FAILED ("ep_session_get_rundown_enabled returned true, should be false"); + ep_raise_error (); + } + + test_location = 3; + + ep_session_set_rundown_enabled (test_session, true); + + if (!ep_session_get_rundown_enabled (test_session)) { + result = FAILED ("ep_session_get_rundown_enabled returned false, should be true"); + ep_raise_error (); + } + + test_location = 4; + + if (ep_session_get_ipc_streaming_enabled (test_session)) { + result = FAILED ("ep_session_get_ipc_streaming_enabled returned true, should be false"); + ep_raise_error (); + } + + test_location = 5; + + ep_session_set_ipc_streaming_enabled (test_session, true); + + if (!ep_session_get_ipc_streaming_enabled (test_session)) { + result = FAILED ("ep_session_set_ipc_streaming_enabled returned false, should be true"); + ep_raise_error (); + } + + ep_session_set_ipc_streaming_enabled (test_session, false); + + test_location = 6; + + if (!ep_session_get_wait_event (test_session)) { + result = FAILED ("ep_session_get_wait_event failed"); + ep_raise_error (); + } + + test_location = 7; + + if (!ep_session_get_mask (test_session)) { + result = FAILED ("Unexpected session mask"); + ep_raise_error (); + } + +ep_on_exit: + ep_session_free (test_session); + ep_provider_config_fini (current_provider_config); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_session_teardown (void) +{ +#ifdef _CRTDBG_MAP_ALLOC + _CrtMemCheckpoint (&eventpipe_memory_end_snapshot); + if ( _CrtMemDifference( &eventpipe_memory_diff_snapshot, &eventpipe_memory_start_snapshot, &eventpipe_memory_end_snapshot) ) { + _CrtMemDumpStatistics( &eventpipe_memory_diff_snapshot ); + return FAILED ("Memory leak detected!"); + } +#endif + return NULL; +} + +static Test ep_session_tests [] = { + {"test_session_setup", test_session_setup}, + {"test_create_delete_session", test_create_delete_session}, + {"test_add_session_providers", test_add_session_providers}, + {"test_session_special_get_set", test_session_special_get_set}, + {"test_session_teardown", test_session_teardown}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(ep_session_tests_init, ep_session_tests) diff --git a/src/mono/mono/eventpipe/test/ep-setup-tests.c b/src/mono/mono/eventpipe/test/ep-setup-tests.c new file mode 100644 index 0000000000000..30e51463bc169 --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-setup-tests.c @@ -0,0 +1,27 @@ +#include "mono/eventpipe/ep.h" +#include "eglib/test/test.h" +#include +#include + +MonoDomain *eventpipe_test_domain; + +static RESULT +test_setup (void) +{ + char *core_root = g_getenv ("CORE_ROOT"); + if (core_root) { + mono_set_assemblies_path (core_root); + g_free (core_root); + } + + eventpipe_test_domain = mono_jit_init_version_for_test_only ("eventpipe-tests", "v4.0.30319"); + + return NULL; +} + +static Test ep_setup_tests [] = { + {"test_setup", test_setup}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(ep_setup_tests_init, ep_setup_tests) diff --git a/src/mono/mono/eventpipe/test/ep-teardown-tests.c b/src/mono/mono/eventpipe/test/ep-teardown-tests.c new file mode 100644 index 0000000000000..3800f9360e725 --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-teardown-tests.c @@ -0,0 +1,25 @@ +#include "mono/eventpipe/ep.h" +#include "eglib/test/test.h" +#include + +#define TEST_FILE "./ep_test_create_file.txt" + +extern MonoDomain *eventpipe_test_domain; + +static RESULT +test_teardown (void) +{ + if (eventpipe_test_domain) + mono_jit_cleanup (eventpipe_test_domain); + + unlink (TEST_FILE); + + return NULL; +} + +static Test ep_teardown_tests [] = { + {"test_teardown", test_teardown}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(ep_teardown_tests_init, ep_teardown_tests) diff --git a/src/mono/mono/eventpipe/test/ep-test-driver.c b/src/mono/mono/eventpipe/test/ep-test-driver.c new file mode 100644 index 0000000000000..a1aa730b814c7 --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-test-driver.c @@ -0,0 +1,5 @@ +#define DRIVER_EXTERNAL_TESTS +#define DRIVER_NAME "eventpipe-tests" + +#include "ep-tests.h" +#include "mono/eglib/test/driver.c" diff --git a/src/mono/mono/eventpipe/test/ep-test-runner.c b/src/mono/mono/eventpipe/test/ep-test-runner.c new file mode 100644 index 0000000000000..7e9072000f921 --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-test-runner.c @@ -0,0 +1 @@ +#include "mono/eglib/test/test.c" diff --git a/src/mono/mono/eventpipe/test/ep-test.sln b/src/mono/mono/eventpipe/test/ep-test.sln new file mode 100644 index 0000000000000..4431637a8dbb8 --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-test.sln @@ -0,0 +1,127 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30011.22 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ep-test", "ep-test.vcxproj", "{AF48E883-A558-4027-8934-32CFD2750D04}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eglib", "..\..\..\msvc\eglib.vcxproj", "{158073ED-99AE-4196-9EDC-DDB2344F8466}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmonoutils", "..\..\..\msvc\libmonoutils.vcxproj", "{8FC2B0C8-51AD-49DF-851F-5D01A77A75E4}" + ProjectSection(ProjectDependencies) = postProject + {C36612BD-22D3-4B95-85E2-7FDC4FC5D740} = {C36612BD-22D3-4B95-85E2-7FDC4FC5D740} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmonoruntime", "..\..\..\msvc\libmonoruntime.vcxproj", "{C36612BD-22D3-4B95-85E2-7FDC4FC5D739}" + ProjectSection(ProjectDependencies) = postProject + {C36612BD-22D3-4B95-85E2-7FDC4FC5D740} = {C36612BD-22D3-4B95-85E2-7FDC4FC5D740} + {8FC2B0C8-51AD-49DF-851F-5D01A77A75E4} = {8FC2B0C8-51AD-49DF-851F-5D01A77A75E4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgcmonosgen", "..\..\..\msvc\libgcmonosgen.vcxproj", "{C36612BD-22D3-4B95-85E2-7FDC4FC5D740}" + ProjectSection(ProjectDependencies) = postProject + {158073ED-99AE-4196-9EDC-DDB2344F8466} = {158073ED-99AE-4196-9EDC-DDB2344F8466} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmini", "..\..\..\msvc\libmini.vcxproj", "{88D2EB79-592D-45F8-B849-AE021C1D983A}" + ProjectSection(ProjectDependencies) = postProject + {C36612BD-22D3-4B95-85E2-7FDC4FC5D739} = {C36612BD-22D3-4B95-85E2-7FDC4FC5D739} + {C36612BD-22D3-4B95-85E2-7FDC4FC5D740} = {C36612BD-22D3-4B95-85E2-7FDC4FC5D740} + {8FC2B0C8-51AD-49DF-851F-5D01A77A75E4} = {8FC2B0C8-51AD-49DF-851F-5D01A77A75E4} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "static-mono-runtime", "static-mono-runtime", "{B46B84C3-14C4-4C81-B4A3-CE5292663515}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmono-static", "..\..\..\msvc\libmono-static.vcxproj", "{CB0D9E92-293C-439C-9AC7-C5F59B6E0772}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "build-init", "..\..\..\msvc\build-init.vcxproj", "{92AE7622-5F58-4234-9A26-9EC71876B3F4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AF48E883-A558-4027-8934-32CFD2750D04}.Debug|Win32.ActiveCfg = Debug|Win32 + {AF48E883-A558-4027-8934-32CFD2750D04}.Debug|Win32.Build.0 = Debug|Win32 + {AF48E883-A558-4027-8934-32CFD2750D04}.Debug|x64.ActiveCfg = Debug|x64 + {AF48E883-A558-4027-8934-32CFD2750D04}.Debug|x64.Build.0 = Debug|x64 + {AF48E883-A558-4027-8934-32CFD2750D04}.Release|Win32.ActiveCfg = Release|Win32 + {AF48E883-A558-4027-8934-32CFD2750D04}.Release|Win32.Build.0 = Release|Win32 + {AF48E883-A558-4027-8934-32CFD2750D04}.Release|x64.ActiveCfg = Release|x64 + {AF48E883-A558-4027-8934-32CFD2750D04}.Release|x64.Build.0 = Release|x64 + {158073ED-99AE-4196-9EDC-DDB2344F8466}.Debug|Win32.ActiveCfg = Debug|Win32 + {158073ED-99AE-4196-9EDC-DDB2344F8466}.Debug|Win32.Build.0 = Debug|Win32 + {158073ED-99AE-4196-9EDC-DDB2344F8466}.Debug|x64.ActiveCfg = Debug|x64 + {158073ED-99AE-4196-9EDC-DDB2344F8466}.Debug|x64.Build.0 = Debug|x64 + {158073ED-99AE-4196-9EDC-DDB2344F8466}.Release|Win32.ActiveCfg = Release|Win32 + {158073ED-99AE-4196-9EDC-DDB2344F8466}.Release|Win32.Build.0 = Release|Win32 + {158073ED-99AE-4196-9EDC-DDB2344F8466}.Release|x64.ActiveCfg = Release|x64 + {158073ED-99AE-4196-9EDC-DDB2344F8466}.Release|x64.Build.0 = Release|x64 + {8FC2B0C8-51AD-49DF-851F-5D01A77A75E4}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FC2B0C8-51AD-49DF-851F-5D01A77A75E4}.Debug|Win32.Build.0 = Debug|Win32 + {8FC2B0C8-51AD-49DF-851F-5D01A77A75E4}.Debug|x64.ActiveCfg = Debug|x64 + {8FC2B0C8-51AD-49DF-851F-5D01A77A75E4}.Debug|x64.Build.0 = Debug|x64 + {8FC2B0C8-51AD-49DF-851F-5D01A77A75E4}.Release|Win32.ActiveCfg = Release|Win32 + {8FC2B0C8-51AD-49DF-851F-5D01A77A75E4}.Release|Win32.Build.0 = Release|Win32 + {8FC2B0C8-51AD-49DF-851F-5D01A77A75E4}.Release|x64.ActiveCfg = Release|x64 + {8FC2B0C8-51AD-49DF-851F-5D01A77A75E4}.Release|x64.Build.0 = Release|x64 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D739}.Debug|Win32.ActiveCfg = Debug|Win32 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D739}.Debug|Win32.Build.0 = Debug|Win32 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D739}.Debug|x64.ActiveCfg = Debug|x64 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D739}.Debug|x64.Build.0 = Debug|x64 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D739}.Release|Win32.ActiveCfg = Release|Win32 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D739}.Release|Win32.Build.0 = Release|Win32 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D739}.Release|x64.ActiveCfg = Release|x64 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D739}.Release|x64.Build.0 = Release|x64 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D740}.Debug|Win32.ActiveCfg = Debug|Win32 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D740}.Debug|Win32.Build.0 = Debug|Win32 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D740}.Debug|x64.ActiveCfg = Debug|x64 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D740}.Debug|x64.Build.0 = Debug|x64 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D740}.Release|Win32.ActiveCfg = Release|Win32 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D740}.Release|Win32.Build.0 = Release|Win32 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D740}.Release|x64.ActiveCfg = Release|x64 + {C36612BD-22D3-4B95-85E2-7FDC4FC5D740}.Release|x64.Build.0 = Release|x64 + {88D2EB79-592D-45F8-B849-AE021C1D983A}.Debug|Win32.ActiveCfg = Debug|Win32 + {88D2EB79-592D-45F8-B849-AE021C1D983A}.Debug|Win32.Build.0 = Debug|Win32 + {88D2EB79-592D-45F8-B849-AE021C1D983A}.Debug|x64.ActiveCfg = Debug|x64 + {88D2EB79-592D-45F8-B849-AE021C1D983A}.Debug|x64.Build.0 = Debug|x64 + {88D2EB79-592D-45F8-B849-AE021C1D983A}.Release|Win32.ActiveCfg = Release|Win32 + {88D2EB79-592D-45F8-B849-AE021C1D983A}.Release|Win32.Build.0 = Release|Win32 + {88D2EB79-592D-45F8-B849-AE021C1D983A}.Release|x64.ActiveCfg = Release|x64 + {88D2EB79-592D-45F8-B849-AE021C1D983A}.Release|x64.Build.0 = Release|x64 + {CB0D9E92-293C-439C-9AC7-C5F59B6E0772}.Debug|Win32.ActiveCfg = Debug|Win32 + {CB0D9E92-293C-439C-9AC7-C5F59B6E0772}.Debug|Win32.Build.0 = Debug|Win32 + {CB0D9E92-293C-439C-9AC7-C5F59B6E0772}.Debug|x64.ActiveCfg = Debug|x64 + {CB0D9E92-293C-439C-9AC7-C5F59B6E0772}.Debug|x64.Build.0 = Debug|x64 + {CB0D9E92-293C-439C-9AC7-C5F59B6E0772}.Release|Win32.ActiveCfg = Release|Win32 + {CB0D9E92-293C-439C-9AC7-C5F59B6E0772}.Release|Win32.Build.0 = Release|Win32 + {CB0D9E92-293C-439C-9AC7-C5F59B6E0772}.Release|x64.ActiveCfg = Release|x64 + {CB0D9E92-293C-439C-9AC7-C5F59B6E0772}.Release|x64.Build.0 = Release|x64 + {92AE7622-5F58-4234-9A26-9EC71876B3F4}.Debug|Win32.ActiveCfg = Debug|Win32 + {92AE7622-5F58-4234-9A26-9EC71876B3F4}.Debug|Win32.Build.0 = Debug|Win32 + {92AE7622-5F58-4234-9A26-9EC71876B3F4}.Debug|x64.ActiveCfg = Debug|x64 + {92AE7622-5F58-4234-9A26-9EC71876B3F4}.Debug|x64.Build.0 = Debug|x64 + {92AE7622-5F58-4234-9A26-9EC71876B3F4}.Release|Win32.ActiveCfg = Release|Win32 + {92AE7622-5F58-4234-9A26-9EC71876B3F4}.Release|Win32.Build.0 = Release|Win32 + {92AE7622-5F58-4234-9A26-9EC71876B3F4}.Release|x64.ActiveCfg = Release|x64 + {92AE7622-5F58-4234-9A26-9EC71876B3F4}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {158073ED-99AE-4196-9EDC-DDB2344F8466} = {B46B84C3-14C4-4C81-B4A3-CE5292663515} + {8FC2B0C8-51AD-49DF-851F-5D01A77A75E4} = {B46B84C3-14C4-4C81-B4A3-CE5292663515} + {C36612BD-22D3-4B95-85E2-7FDC4FC5D739} = {B46B84C3-14C4-4C81-B4A3-CE5292663515} + {C36612BD-22D3-4B95-85E2-7FDC4FC5D740} = {B46B84C3-14C4-4C81-B4A3-CE5292663515} + {88D2EB79-592D-45F8-B849-AE021C1D983A} = {B46B84C3-14C4-4C81-B4A3-CE5292663515} + {CB0D9E92-293C-439C-9AC7-C5F59B6E0772} = {B46B84C3-14C4-4C81-B4A3-CE5292663515} + {92AE7622-5F58-4234-9A26-9EC71876B3F4} = {B46B84C3-14C4-4C81-B4A3-CE5292663515} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CE83F76A-FA5A-4DF0-B015-5D802539DEFC} + EndGlobalSection +EndGlobal diff --git a/src/mono/mono/eventpipe/test/ep-test.vcxproj b/src/mono/mono/eventpipe/test/ep-test.vcxproj new file mode 100644 index 0000000000000..6687c5d70819c --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-test.vcxproj @@ -0,0 +1,186 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + ..\..\.. + + + + + + + + + + + + + + + + + + + + + {cb0d9e92-293c-439c-9ac7-c5f59b6e0772} + + + + {AF48E883-A558-4027-8934-32CFD2750D04} + eventpipe + Win32Proj + 10.0 + + + + Application + false + $(DefaultPlatformToolset) + Unicode + + + Application + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + + + + + + + + + + + + + + + + + + + + + false + $(ProjectName)$(MONO_TARGET_SUFFIX) + $(MONO_BUILD_DIR_PREFIX)$(Platform)\bin\$(Configuration)\ + $(MONO_BUILD_DIR_PREFIX)$(Platform)\obj\$(ProjectName)$(MONO_TARGET_SUFFIX)\$(Configuration)\ + + + false + $(ProjectName)$(MONO_TARGET_SUFFIX) + $(MONO_BUILD_DIR_PREFIX)$(Platform)\bin\$(Configuration)\ + $(MONO_BUILD_DIR_PREFIX)$(Platform)\obj\$(ProjectName)$(MONO_TARGET_SUFFIX)\$(Configuration)\ + + + true + $(ProjectName)$(MONO_TARGET_SUFFIX) + $(MONO_BUILD_DIR_PREFIX)$(Platform)\bin\$(Configuration)\ + $(MONO_BUILD_DIR_PREFIX)$(Platform)\obj\$(ProjectName)$(MONO_TARGET_SUFFIX)\$(Configuration)\ + + + true + $(ProjectName)$(MONO_TARGET_SUFFIX) + $(MONO_BUILD_DIR_PREFIX)$(Platform)\bin\$(Configuration)\ + $(MONO_BUILD_DIR_PREFIX)$(Platform)\obj\$(ProjectName)$(MONO_TARGET_SUFFIX)\$(Configuration)\ + + + + $(MONO_DIR);$(MONO_INCLUDE_DIR);$(MONO_EGLIB_SOURCE_DIR);%(AdditionalIncludeDirectories) + Level4 + Disabled + $(ProjectDir)ep-tests-debug.h + + + %(AdditionalDependencies) + %(AdditionalLibraryDirectories) + Console + + + + + Level4 + $(MONO_DIR);$(MONO_INCLUDE_DIR);$(MONO_EGLIB_SOURCE_DIR);%(AdditionalIncludeDirectories) + true + true + true + + + %(AdditionalLibraryDirectories) + Console + %(AdditionalDependencies) + UseLinkTimeCodeGeneration + + + + + X64 + + + $(MONO_DIR);$(MONO_INCLUDE_DIR);$(MONO_EGLIB_SOURCE_DIR);%(AdditionalIncludeDirectories) + Level4 + Disabled + $(ProjectDir)ep-tests-debug.h + + + %(AdditionalDependencies) + %(AdditionalLibraryDirectories) + Console + + + + + X64 + + + Level4 + $(MONO_DIR);$(MONO_INCLUDE_DIR);$(MONO_EGLIB_SOURCE_DIR);%(AdditionalIncludeDirectories) + true + true + true + + + %(AdditionalLibraryDirectories) + Console + %(AdditionalDependencies) + UseLinkTimeCodeGeneration + + + + + + \ No newline at end of file diff --git a/src/mono/mono/eventpipe/test/ep-test.vcxproj.filters b/src/mono/mono/eventpipe/test/ep-test.vcxproj.filters new file mode 100644 index 0000000000000..e9d41287b865a --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-test.vcxproj.filters @@ -0,0 +1,63 @@ + + + + + Source Files\tests + + + Source Files\tests + + + Source Files\tests + + + Source Files\tests + + + Source Files\tests + + + Source Files\tests + + + Source Files\tests + + + Source Files\tests + + + Source Files\testframework + + + Source Files\testframework + + + Source Files\testframework + + + + + {d0fb7679-6e47-42a8-bd98-9c31c4bb065a} + + + {ee850408-9c60-43ab-8845-133cdd03c67a} + + + {0bf8953c-e42a-464e-b422-a451238f319f} + + + {29232fda-0808-499c-9d29-f079a62967e7} + + + {e0fbc587-715b-4470-be21-7645cfe77e5a} + + + + + Header Files\tests + + + Header Files\tests + + + \ No newline at end of file diff --git a/src/mono/mono/eventpipe/test/ep-tests-debug.h b/src/mono/mono/eventpipe/test/ep-tests-debug.h new file mode 100644 index 0000000000000..e86795ea3ff5f --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-tests-debug.h @@ -0,0 +1,8 @@ +#ifndef __EVENTPIPE_TESTS_DEBUG_H__ +#define __EVENTPIPE_TESTS_DEBUG_H__ + +#define _CRTDBG_MAP_ALLOC +#include +#include + +#endif /* __EVENTPIPE_TESTS_DEBUG_H__ */ diff --git a/src/mono/mono/eventpipe/test/ep-tests.c b/src/mono/mono/eventpipe/test/ep-tests.c new file mode 100644 index 0000000000000..2cc0ddb1bad87 --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-tests.c @@ -0,0 +1,399 @@ +#include "mono/eventpipe/ep.h" +#include "eglib/test/test.h" + +#define TEST_PROVIDER_NAME "MyTestProvider" +#define TEST_FILE "./ep_test_create_file.txt" + +#ifdef _CRTDBG_MAP_ALLOC +static _CrtMemState eventpipe_memory_start_snapshot; +static _CrtMemState eventpipe_memory_end_snapshot; +static _CrtMemState eventpipe_memory_diff_snapshot; +#endif + +static RESULT +test_eventpipe_setup (void) +{ +#ifdef _CRTDBG_MAP_ALLOC + _CrtMemCheckpoint (&eventpipe_memory_start_snapshot); +#endif + return NULL; +} + +static RESULT +test_create_delete_provider (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeProvider *test_provider = ep_create_provider (TEST_PROVIDER_NAME, NULL, NULL); + if (!test_provider) { + result = FAILED ("Failed to create provider %s, ep_create_provider returned NULL", TEST_PROVIDER_NAME); + ep_raise_error (); + } + +ep_on_exit: + ep_delete_provider (test_provider); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_stress_create_delete_provider (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeProvider *test_providers [1000] = {0}; + + for (uint32_t i = 0; i < 1000; ++i) { + char *provider_name = g_strdup_printf (TEST_PROVIDER_NAME "_%i", i); + test_providers [i] = ep_create_provider (provider_name, NULL, NULL); + g_free (provider_name); + + if (!test_providers [i]) { + result = FAILED ("Failed to create provider %s_%i, ep_create_provider returned NULL", TEST_PROVIDER_NAME, i); + ep_raise_error (); + } + } + +ep_on_exit: + for (uint32_t i = 0; i < 1000; ++i) { + if (test_providers [i]) + ep_delete_provider (test_providers [i]); + } + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_get_provider (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeProvider *test_provider = ep_create_provider (TEST_PROVIDER_NAME, NULL, NULL); + if (!test_provider) { + result = FAILED ("Failed to create provider %s, ep_create_provider returned NULL", TEST_PROVIDER_NAME); + ep_raise_error (); + } + + test_location = 1; + + EventPipeProvider *returned_test_provider = ep_get_provider (TEST_PROVIDER_NAME); + if (!returned_test_provider) { + result = FAILED ("Failed to get provider %s, ep_get_provider returned NULL", TEST_PROVIDER_NAME); + ep_raise_error (); + } + + test_location = 2; + + ep_delete_provider (test_provider); + test_provider = NULL; + + returned_test_provider = ep_get_provider (TEST_PROVIDER_NAME); + if (returned_test_provider) { + result = FAILED ("Provider %s, still returned from ep_get_provider after deleted", TEST_PROVIDER_NAME); + ep_raise_error (); + } + +ep_on_exit: + ep_delete_provider (test_provider); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_create_same_provider_twice (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeProvider *test_provider = ep_create_provider (TEST_PROVIDER_NAME, NULL, NULL); + if (!test_provider) { + result = FAILED ("Failed to create provider %s, ep_create_provider returned NULL", TEST_PROVIDER_NAME); + ep_raise_error (); + } + + test_location = 1; + + EventPipeProvider *returned_test_provider = ep_get_provider (TEST_PROVIDER_NAME); + if (!returned_test_provider) { + result = FAILED ("Failed to get provider %s, ep_get_provider returned NULL", TEST_PROVIDER_NAME); + ep_raise_error (); + } + + test_location = 2; + + EventPipeProvider *test_provider2 = ep_create_provider (TEST_PROVIDER_NAME, NULL, NULL); + if (test_provider2) { + result = FAILED ("Creating an already existing provider %s, succeeded", TEST_PROVIDER_NAME); + ep_raise_error (); + } + + test_location = 3; + + returned_test_provider = ep_get_provider (TEST_PROVIDER_NAME); + if (!returned_test_provider) { + result = FAILED ("Failed to get provider %s, ep_get_provider returned NULL", TEST_PROVIDER_NAME); + ep_raise_error (); + } + +ep_on_exit: + ep_delete_provider (test_provider); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + + +static RESULT +test_enable_disable (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeSessionID session_id = 0; + EventPipeProviderConfiguration provider_config; + EventPipeProviderConfiguration *current_provider_config =ep_provider_config_init (&provider_config, TEST_PROVIDER_NAME, 1, EP_EVENT_LEVEL_LOG_ALWAYS, ""); + ep_raise_error_if_nok (current_provider_config != NULL); + + test_location = 1; + + session_id = ep_enable ( + TEST_FILE, + 1, + current_provider_config, + 1, + EP_SESSION_TYPE_FILE, + EP_SERIALIZATION_FORMAT_NETTRACE_V4, + false, + NULL, + false); + + if (!session_id) { + result = FAILED ("Failed to enable session"); + ep_raise_error (); + } + + test_location = 2; + + if (!ep_enabled ()) { + result = FAILED ("event pipe disabled"); + ep_raise_error (); + } + +ep_on_exit: + ep_disable (session_id); + ep_provider_config_fini (current_provider_config); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static bool provider_callback_data; + +static +void +provider_callback ( + const uint8_t *source_id, + unsigned long is_enabled, + uint8_t level, + uint64_t match_any_keywords, + uint64_t match_all_keywords, + EventFilterDescriptor *filter_data, + void *callback_context) +{ + *(bool *)callback_context = true; +} + +static RESULT +test_create_delete_provider_with_callback (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeSessionID session_id = 0; + EventPipeProvider *test_provider = NULL; + EventPipeProviderConfiguration provider_config; + + EventPipeProviderConfiguration *current_provider_config =ep_provider_config_init (&provider_config, TEST_PROVIDER_NAME, 1, EP_EVENT_LEVEL_LOG_ALWAYS, ""); + ep_raise_error_if_nok (current_provider_config != NULL); + + test_location = 1; + + session_id = ep_enable ( + TEST_FILE, + 1, + current_provider_config, + 1, + EP_SESSION_TYPE_FILE, + EP_SERIALIZATION_FORMAT_NETTRACE_V4, + false, + NULL, + false); + + if (!session_id) { + result = FAILED ("Failed to enable session"); + ep_raise_error (); + } + + test_location = 2; + + test_provider = ep_create_provider (TEST_PROVIDER_NAME, provider_callback, &provider_callback_data); + ep_raise_error_if_nok (test_provider != NULL); + + test_location = 3; + + if (!provider_callback_data) { + result = FAILED ("Provider callback not called"); + ep_raise_error (); + } + +ep_on_exit: + ep_delete_provider (test_provider); + ep_disable (session_id); + ep_provider_config_fini (current_provider_config); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_build_event_metadata (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeProvider *provider = NULL; + EventPipeEvent *ep_event = NULL; + EventPipeEventInstance *ep_event_instance = NULL; + EventPipeEventMetadataEvent *metadata_event = NULL; + + provider = ep_create_provider (TEST_PROVIDER_NAME, NULL, NULL); + ep_raise_error_if_nok (provider != NULL); + + test_location = 1; + + ep_event = ep_event_alloc (provider, 1, 1, 1, EP_EVENT_LEVEL_VERBOSE, false, NULL, 0); + ep_raise_error_if_nok (ep_event != NULL); + + test_location = 2; + + ep_event_instance = ep_event_instance_alloc (ep_event, 0, 0, NULL, 0, NULL, NULL); + ep_raise_error_if_nok (ep_event_instance != NULL); + + test_location = 3; + + metadata_event = ep_build_event_metadata_event (ep_event_instance, 1); + ep_raise_error_if_nok (metadata_event != NULL); + + test_location = 4; + +ep_on_exit: + ep_delete_provider (provider); + ep_event_free (ep_event); + ep_event_instance_free (ep_event_instance); + ep_event_metdata_event_free (metadata_event); + + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_start_session_streaming (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeSessionID session_id = 0; + EventPipeProviderConfiguration provider_config; + + EventPipeProviderConfiguration *current_provider_config =ep_provider_config_init (&provider_config, TEST_PROVIDER_NAME, 1, EP_EVENT_LEVEL_LOG_ALWAYS, ""); + ep_raise_error_if_nok (current_provider_config != NULL); + + test_location = 1; + + session_id = ep_enable ( + TEST_FILE, + 1, + current_provider_config, + 1, + EP_SESSION_TYPE_FILE, + EP_SERIALIZATION_FORMAT_NETTRACE_V4, + false, + NULL, + false); + + if (!session_id) { + result = FAILED ("Failed to enable session"); + ep_raise_error (); + } + + test_location = 2; + + ep_start_streaming (session_id); + +ep_on_exit: + ep_disable (session_id); + ep_provider_config_fini (current_provider_config); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_eventpipe_teardown (void) +{ +#ifdef _CRTDBG_MAP_ALLOC + _CrtMemCheckpoint (&eventpipe_memory_end_snapshot); + if ( _CrtMemDifference( &eventpipe_memory_diff_snapshot, &eventpipe_memory_start_snapshot, &eventpipe_memory_end_snapshot) ) { + _CrtMemDumpStatistics( &eventpipe_memory_diff_snapshot ); + return FAILED ("Memory leak detected!"); + } +#endif + return NULL; +} + +static Test ep_tests [] = { + {"test_eventpipe_setup", test_eventpipe_setup}, + {"test_create_delete_provider", test_create_delete_provider}, + {"test_stress_create_delete_provider", test_stress_create_delete_provider}, + {"test_get_provider", test_get_provider}, + {"test_create_same_provider_twice", test_create_same_provider_twice}, + {"test_enable_disable", test_enable_disable}, + {"test_create_delete_provider_with_callback", test_create_delete_provider_with_callback}, + {"test_build_event_metadata", test_build_event_metadata}, + {"test_start_session_streaming", test_start_session_streaming}, + {"test_eventpipe_teardown", test_eventpipe_teardown}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(ep_tests_init, ep_tests) diff --git a/src/mono/mono/eventpipe/test/ep-tests.h b/src/mono/mono/eventpipe/test/ep-tests.h new file mode 100644 index 0000000000000..c8e56be313a6e --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-tests.h @@ -0,0 +1,30 @@ +#ifndef _EVENTPIPE_TESTS_H +#define _EVENTPIPE_TESTS_H + +#include "eglib/test/test.h" + +DEFINE_TEST_GROUP_INIT_H(ep_setup_tests_init); +DEFINE_TEST_GROUP_INIT_H(ep_fastserializer_tests_init); +DEFINE_TEST_GROUP_INIT_H(ep_provider_callback_data_queue_tests_init); +DEFINE_TEST_GROUP_INIT_H(ep_file_tests_init); +DEFINE_TEST_GROUP_INIT_H(ep_session_tests_init); +DEFINE_TEST_GROUP_INIT_H(ep_thread_tests_init); +DEFINE_TEST_GROUP_INIT_H(ep_tests_init); +DEFINE_TEST_GROUP_INIT_H(fake_tests_init); +DEFINE_TEST_GROUP_INIT_H(ep_teardown_tests_init); + +const +static Group test_groups [] = { + {"setup", ep_setup_tests_init}, + {"fastserialzier", ep_fastserializer_tests_init}, + {"provider-callback-dataqueue", ep_provider_callback_data_queue_tests_init}, + {"file", ep_file_tests_init}, + {"session", ep_session_tests_init}, + {"thread", ep_thread_tests_init}, + {"eventpipe", ep_tests_init}, + {"fake", fake_tests_init}, + {"teardown", ep_teardown_tests_init}, + {NULL, NULL} +}; + +#endif /* _EVENTPIPE_TESTS_H */ diff --git a/src/mono/mono/eventpipe/test/ep-thread-tests.c b/src/mono/mono/eventpipe/test/ep-thread-tests.c new file mode 100644 index 0000000000000..9f68befe532a0 --- /dev/null +++ b/src/mono/mono/eventpipe/test/ep-thread-tests.c @@ -0,0 +1,478 @@ +#include "mono/eventpipe/ep.h" +#include "eglib/test/test.h" + +#define TEST_FILE "./ep_test_create_file.txt" + +#ifdef _CRTDBG_MAP_ALLOC +static _CrtMemState eventpipe_memory_start_snapshot; +static _CrtMemState eventpipe_memory_end_snapshot; +static _CrtMemState eventpipe_memory_diff_snapshot; +#endif + +static RESULT +test_thread_setup (void) +{ +#ifdef _CRTDBG_MAP_ALLOC + _CrtMemCheckpoint (&eventpipe_memory_start_snapshot); +#endif + return NULL; +} + +static RESULT +test_create_free_thread (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeThread *thread = ep_thread_alloc (); + if (!thread) { + result = FAILED ("Failed to create thread"); + ep_raise_error (); + } + +ep_on_exit: + ep_thread_free (thread); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_addref_release_thread (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeThread *thread = ep_thread_alloc (); + if (!thread) { + result = FAILED ("Failed to create thread"); + ep_raise_error (); + } + + test_location = 1; + + if (ep_rt_volatile_load_uint32_t ((const volatile uint32_t *)ep_thread_get_ref_count_ref (thread)) != 0) { + result = FAILED ("Ref count should start at 0"); + ep_raise_error (); + } + + test_location = 2; + + ep_thread_addref (thread); + + if (ep_rt_volatile_load_uint32_t ((const volatile uint32_t *)ep_thread_get_ref_count_ref (thread)) != 1) { + result = FAILED ("addref should increment 1"); + ep_raise_error (); + } + + test_location = 3; + + ep_thread_release (thread); + thread = NULL; + +ep_on_exit: + ep_thread_free (thread); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_get_or_create_thread (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeThread *thread = ep_thread_get (); + if (thread) { + result = FAILED ("ep_thread_get should return NULL"); + ep_raise_error (); + } + + test_location = 1; + + thread = ep_thread_get_or_create (); + if (!thread) { + result = FAILED ("ep_thread_get_or_create should not return NULL"); + ep_raise_error (); + } + + test_location = 2; + + thread = ep_thread_get (); + if (!thread) { + result = FAILED ("ep_thread_get should not return NULL"); + ep_raise_error (); + } + + test_location = 3; + + if (ep_rt_volatile_load_uint32_t ((const volatile uint32_t *)ep_thread_get_ref_count_ref (thread)) != 1) { + result = FAILED ("thread ref count should be 1"); + ep_raise_error (); + } + + test_location = 4; + + // Need to emulate a thread exit to make sure TLS gets cleaned up for current thread + // or we will get memory leaks reported. + ep_rt_mono_thread_exited (); + + thread = ep_thread_get (); + if (thread) { + result = FAILED ("ep_thread_get should return NULL"); + ep_raise_error (); + } + +ep_on_exit: + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_thread_activity_id (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + uint8_t empty_id [EP_ACTIVITY_ID_SIZE] = {0}; + uint8_t current_activity_id [EP_ACTIVITY_ID_SIZE]; + uint8_t new_activity_id [EP_ACTIVITY_ID_SIZE]; + + ep_thread_create_activity_id (new_activity_id, sizeof (new_activity_id)); + if (!memcmp (empty_id, new_activity_id, sizeof (new_activity_id))) { + result = FAILED ("Created activity id is empty"); + ep_raise_error (); + } + + test_location = 1; + + EventPipeThread *thread = ep_thread_get (); + if (thread) { + result = FAILED ("ep_thread_get should return NULL"); + ep_raise_error (); + } + + test_location = 2; + + thread = ep_thread_get_or_create (); + if (!thread) { + result = FAILED ("ep_thread_get_or_create should not return NULL"); + ep_raise_error (); + } + + test_location = 3; + + ep_thread_get_activity_id (thread, current_activity_id, sizeof (current_activity_id)); + if (memcmp (empty_id, current_activity_id, sizeof (current_activity_id))) { + result = FAILED ("Current activity id is not empty"); + ep_raise_error (); + } + + test_location = 4; + + ep_thread_set_activity_id (thread, new_activity_id, sizeof (new_activity_id)); + + ep_thread_get_activity_id (thread, current_activity_id, sizeof (current_activity_id)); + if (memcmp (new_activity_id, current_activity_id, sizeof (current_activity_id))) { + result = FAILED ("Current activity id doesn't match previously set activity id"); + ep_raise_error (); + } + + test_location = 5; + + // Need to emulate a thread exit to make sure TLS gets cleaned up for current thread + // or we will get memory leaks reported. + ep_rt_mono_thread_exited (); + + thread = ep_thread_get (); + if (thread) { + result = FAILED ("ep_thread_get should return NULL"); + ep_raise_error (); + } + +ep_on_exit: + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_thread_is_rundown_thread (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeThread *thread = ep_thread_alloc (); + if (!thread) { + result = FAILED ("Failed to create thread"); + ep_raise_error (); + } + + test_location = 1; + + if (ep_thread_is_rundown_thread (thread)) { + result = FAILED ("Thread is a rundown thread"); + ep_raise_error (); + } + + test_location = 2; + + EventPipeSession dummy_session; + ep_thread_set_as_rundown_thread (thread, &dummy_session); + if (!ep_thread_is_rundown_thread (thread)) { + result = FAILED ("Thread is not a rundown thread"); + ep_raise_error (); + } + + test_location = 3; + + if (ep_thread_get_rundown_session (thread) != &dummy_session) { + result = FAILED ("Unexpected rundown session"); + ep_raise_error (); + } + + test_location = 4; + + ep_thread_set_as_rundown_thread (thread, NULL); + + if (ep_thread_is_rundown_thread (thread)) { + result = FAILED ("Thread is a rundown thread"); + ep_raise_error (); + } + +ep_on_exit: + ep_thread_free (thread); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_thread_lock (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeThread *thread = ep_thread_alloc (); + if (!thread) { + result = FAILED ("Failed to create thread"); + ep_raise_error (); + } + + test_location = 1; + + ep_thread_requires_lock_not_held (thread); + + ep_rt_spin_lock_aquire (ep_thread_get_rt_lock_ref (thread)); + + ep_thread_requires_lock_held (thread); + + ep_rt_spin_lock_release (ep_thread_get_rt_lock_ref (thread)); + + ep_thread_requires_lock_not_held (thread); + +ep_on_exit: + ep_thread_free (thread); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_thread_session_write (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + + EventPipeThread *thread = ep_thread_alloc (); + if (!thread) { + result = FAILED ("Failed to create thread"); + ep_raise_error (); + } + + test_location = 1; + + uint32_t session_write = ep_thread_get_session_write_in_progress (thread); + if (session_write) { + result = FAILED ("Session write is in progress"); + ep_raise_error (); + } + + test_location = 2; + + ep_thread_set_session_write_in_progress (thread, 1); + + session_write = ep_thread_get_session_write_in_progress (thread); + if (session_write != 1) { + result = FAILED ("Wrong session id in write progress"); + ep_raise_error (); + } + + test_location = 3; + + ep_thread_set_session_write_in_progress (thread, 0); + + session_write = ep_thread_get_session_write_in_progress (thread); + if (session_write) { + result = FAILED ("Session write is in progress"); + ep_raise_error (); + } + +ep_on_exit: + ep_thread_free (thread); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_thread_session_state (void) +{ + RESULT result = NULL; + uint32_t test_location = 0; + EventPipeThread *thread = NULL; + EventPipeProviderConfiguration *provider_config = NULL; + EventPipeSession *session = NULL; + EventPipeThreadSessionState *session_state = NULL; + + thread = ep_thread_alloc (); + if (!thread) { + result = FAILED ("Failed to create thread"); + ep_raise_error (); + } + + ep_thread_addref (thread); + + test_location = 1; + + { + EventPipeProviderConfiguration dummy_config; + if (!ep_provider_config_init (&dummy_config, "DummyProvider", 0, 0, "")) { + result = FAILED ("Failed to init provider config"); + ep_raise_error (); + } + provider_config = &dummy_config; + } + + test_location = 2; + + EP_CONFIG_LOCK_ENTER + session = ep_session_alloc ( + 1, + TEST_FILE, + NULL, + EP_SESSION_TYPE_FILE, + EP_SERIALIZATION_FORMAT_NETTRACE_V4, + false, + 1, + provider_config, + 1, + false); + EP_CONFIG_LOCK_EXIT + + if (!session) { + result = FAILED ("Failed to alloc session"); + ep_raise_error (); + } + + test_location = 3; + + ep_rt_spin_lock_aquire (ep_thread_get_rt_lock_ref (thread)); + session_state = ep_thread_get_or_create_session_state (thread, session); + ep_rt_spin_lock_release (ep_thread_get_rt_lock_ref (thread)); + + if (!session_state) { + result = FAILED ("Failed to alloc session state"); + ep_raise_error (); + } + + test_location = 4; + + ep_rt_spin_lock_aquire (ep_thread_get_rt_lock_ref (thread)); + EventPipeThreadSessionState *current_session_state = ep_thread_get_or_create_session_state (thread, session); + ep_rt_spin_lock_release (ep_thread_get_rt_lock_ref (thread)); + + if (current_session_state != session_state) { + result = FAILED ("Second call to get_or_create_session_state allocated new session_state"); + ep_raise_error (); + } + + test_location = 5; + + ep_rt_spin_lock_aquire (ep_thread_get_rt_lock_ref (thread)); + current_session_state = ep_thread_get_session_state (thread, session); + ep_rt_spin_lock_release (ep_thread_get_rt_lock_ref (thread)); + + if (current_session_state != session_state) { + result = FAILED ("Call to get_session_state allocated returned unexpected session"); + ep_raise_error (); + } + +ep_on_exit: + if (thread && session_state) { + ep_rt_spin_lock_aquire (ep_thread_get_rt_lock_ref (thread)); + ep_thread_delete_session_state (thread, session); + ep_rt_spin_lock_release (ep_thread_get_rt_lock_ref (thread)); + } + ep_session_free (session); + ep_provider_config_fini (provider_config); + ep_thread_release (thread); + return result; + +ep_on_error: + if (!result) + result = FAILED ("Failed at test location=%i", test_location); + ep_exit_error_handler (); +} + +static RESULT +test_thread_teardown (void) +{ +#ifdef _CRTDBG_MAP_ALLOC + _CrtMemCheckpoint (&eventpipe_memory_end_snapshot); + if ( _CrtMemDifference( &eventpipe_memory_diff_snapshot, &eventpipe_memory_start_snapshot, &eventpipe_memory_end_snapshot) ) { + _CrtMemDumpStatistics( &eventpipe_memory_diff_snapshot ); + return FAILED ("Memory leak detected!"); + } +#endif + return NULL; +} + +static Test ep_thread_tests [] = { + {"test_thread_setup", test_thread_setup}, + {"test_create_free_thread", test_create_free_thread}, + {"test_addref_release_thread", test_addref_release_thread}, + {"test_get_or_create_thread", test_get_or_create_thread}, + {"test_thread_activity_id", test_thread_activity_id}, + {"test_thread_is_rundown_thread", test_thread_is_rundown_thread}, + {"test_thread_lock", test_thread_lock}, + {"test_thread_session_write", test_thread_session_write}, + {"test_thread_session_state", test_thread_session_state}, + {"test_thread_teardown", test_thread_teardown}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(ep_thread_tests_init, ep_thread_tests) diff --git a/src/mono/mono/metadata/Makefile.am b/src/mono/mono/metadata/Makefile.am index 2ba687b890e2b..d9ad09f5cca39 100644 --- a/src/mono/mono/metadata/Makefile.am +++ b/src/mono/mono/metadata/Makefile.am @@ -91,6 +91,10 @@ if !ENABLE_ILGEN ilgen_libraries = libmono-ilgen.la endif +if ENABLE_PERFTRACING +eventpipe_libs = $(top_builddir)/mono/eventpipe/libeventpipe.la +endif + BUNDLE_ZLIB_PATH=$(top_builddir)/mono/zlib/libz.la if HAVE_STATIC_ZLIB @@ -169,7 +173,7 @@ if BITCODE if WASM libmono_icall_table_la_LIBADD = # empty to avoid duplicate symbols when enabling dynamic linking else -libmono_icall_table_la_LIBADD = $(glib_libs) ../utils/libmonoutils.la ../sgen/libmonosgen.la libmonoruntimesgen.la +libmono_icall_table_la_LIBADD = $(glib_libs) ../utils/libmonoutils.la ../sgen/libmonosgen.la $(eventpipe_libs) libmonoruntimesgen.la endif endif endif @@ -193,7 +197,7 @@ if BITCODE if WASM libmono_ilgen_la_LIBADD = # empty to avoid duplicate symbols when enabling dynamic linking else -libmono_ilgen_la_LIBADD = $(glib_libs) ../utils/libmonoutils.la ../sgen/libmonosgen.la libmonoruntimesgen.la +libmono_ilgen_la_LIBADD = $(glib_libs) ../utils/libmonoutils.la ../sgen/libmonosgen.la $(eventpipe_libs) libmonoruntimesgen.la endif endif endif @@ -260,6 +264,7 @@ common_sources = \ domain-internals.h \ environment.c \ environment.h \ + icall-eventpipe.c \ exception.c \ exception.h \ exception-internals.h \ diff --git a/src/mono/mono/metadata/icall-eventpipe.c b/src/mono/mono/metadata/icall-eventpipe.c new file mode 100644 index 0000000000000..9f64e90cc44db --- /dev/null +++ b/src/mono/mono/metadata/icall-eventpipe.c @@ -0,0 +1,489 @@ +#include +#include +#include + +#ifdef ENABLE_NETCORE +#include + +#ifdef ENABLE_PERFTRACING +#include +#include + +#include +#include +#include +#include +#include +#include + +typedef enum _EventPipeActivityControlCode { + EP_ACTIVITY_CONTROL_GET_ID = 1, + EP_ACTIVITY_CONTROL_SET_ID = 2, + EP_ACTIVITY_CONTROL_CREATE_ID = 3, + EP_ACTIVITY_CONTROL_GET_SET_ID = 4, + EP_ACTIVITY_CONTROL_CREATE_SET_ID = 5 +} EventPipeActivityControlCode; + +typedef struct _EventPipeProviderConfigurationNative { + gunichar2 *provider_name; + uint64_t keywords; + uint32_t logging_level; + gunichar2 *filter_data; +} EventPipeProviderConfigurationNative; + +typedef struct _EventProviderEventData { + uint64_t ptr; + uint32_t size; + uint32_t reserved; +} EventProviderEventData; + +typedef struct _EventPipeSessionInfo { + int64_t starttime_as_utc_filetime; + int64_t start_timestamp; + int64_t timestamp_frequency; +} EventPipeSessionInfo; + +typedef struct _EventPipeEventInstanceData { + intptr_t provider_id; + uint32_t event_id; + uint32_t thread_id; + int64_t timestamp; + uint8_t activity_id [EP_ACTIVITY_ID_SIZE]; + uint8_t related_activity_id [EP_ACTIVITY_ID_SIZE]; + const uint8_t *payload; + uint32_t payload_len; +} EventPipeEventInstanceData; + +gboolean ep_rt_mono_initialized; +MonoNativeTlsKey ep_rt_mono_thread_holder_tls_id; +gpointer ep_rt_mono_rand_provider; + +static ep_rt_thread_holder_alloc_func thread_holder_alloc_callback_func; +static ep_rt_thread_holder_free_func thread_holder_free_callback_func; + +void +mono_eventpipe_raise_thread_exited (uint64_t); + +static +gboolean +rand_try_get_bytes_func (guchar *buffer, gssize buffer_size, MonoError *error) +{ + g_assert (ep_rt_mono_rand_provider != NULL); + return mono_rand_try_get_bytes (&ep_rt_mono_rand_provider, buffer, buffer_size, error); +} + +static +EventPipeThread * +eventpipe_thread_get (void) +{ + EventPipeThreadHolder *thread_holder = mono_native_tls_get_value (ep_rt_mono_thread_holder_tls_id); + return thread_holder ? ep_thread_holder_get_thread (thread_holder) : NULL; +} + +static +EventPipeThread * +eventpipe_thread_get_or_create (void) +{ + EventPipeThreadHolder *thread_holder = (EventPipeThreadHolder *)mono_native_tls_get_value (ep_rt_mono_thread_holder_tls_id); + if (!thread_holder && thread_holder_alloc_callback_func) { + thread_holder = thread_holder_alloc_callback_func (); + mono_native_tls_set_value (ep_rt_mono_thread_holder_tls_id, thread_holder); + } + return ep_thread_holder_get_thread (thread_holder); +} + +static +void +eventpipe_thread_exited (void) +{ + if (ep_rt_mono_initialized) { + EventPipeThreadHolder *thread_holder = (EventPipeThreadHolder *)mono_native_tls_get_value (ep_rt_mono_thread_holder_tls_id); + if (thread_holder && thread_holder_free_callback_func) + thread_holder_free_callback_func (thread_holder); + mono_native_tls_set_value (ep_rt_mono_thread_holder_tls_id, NULL); + } +} + +static +void +profiler_eventpipe_thread_exited (MonoProfiler *prof, uintptr_t tid) +{ + eventpipe_thread_exited (); +} + +void +mono_eventpipe_init ( + EventPipeMonoFuncTable *table, + ep_rt_thread_holder_alloc_func thread_holder_alloc_func, + ep_rt_thread_holder_free_func thread_holder_free_func) +{ + g_assert (table != NULL); + table->ep_rt_mono_100ns_datetime = mono_100ns_datetime; + table->ep_rt_mono_100ns_ticks = mono_100ns_ticks; + table->ep_rt_mono_cpu_count = mono_cpu_count; + table->ep_rt_mono_process_current_pid = mono_process_current_pid; + table->ep_rt_mono_native_thread_id_get = mono_native_thread_id_get; + table->ep_rt_mono_native_thread_id_equals = mono_native_thread_id_equals; + table->ep_rt_mono_runtime_is_shutting_down = mono_runtime_is_shutting_down; + table->ep_rt_mono_rand_try_get_bytes = rand_try_get_bytes_func; + table->ep_rt_mono_thread_get = eventpipe_thread_get; + table->ep_rt_mono_thread_get_or_create = eventpipe_thread_get_or_create; + table->ep_rt_mono_thread_exited = eventpipe_thread_exited; + table->ep_rt_mono_w32file_close = mono_w32file_close; + table->ep_rt_mono_w32file_create = mono_w32file_create; + table->ep_rt_mono_w32file_write = mono_w32file_write; + + thread_holder_alloc_callback_func = thread_holder_alloc_func; + thread_holder_free_callback_func = thread_holder_free_func; + mono_native_tls_alloc (&ep_rt_mono_thread_holder_tls_id, NULL); + + mono_100ns_ticks (); + mono_rand_open (); + ep_rt_mono_rand_provider = mono_rand_init (NULL, 0); + + ep_rt_mono_initialized = TRUE; + + MonoProfilerHandle profiler = mono_profiler_create (NULL); + mono_profiler_set_thread_stopped_callback (profiler, profiler_eventpipe_thread_exited); +} + +void +mono_eventpipe_fini (void) +{ + if (ep_rt_mono_initialized) + mono_rand_close (ep_rt_mono_rand_provider); + + ep_rt_mono_rand_provider = NULL; + thread_holder_alloc_callback_func = NULL; + thread_holder_free_callback_func = NULL; + ep_rt_mono_initialized = FALSE; +} + +gconstpointer +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_CreateProvider ( + MonoStringHandle provider_name, + MonoDelegateHandle callback_func, + MonoError *error) +{ + EventPipeProvider *provider = NULL; + + if (MONO_HANDLE_IS_NULL (provider_name)) { + mono_error_set_argument_null (error, "providerName", ""); + return NULL; + } + + char *provider_name_utf8 = mono_string_handle_to_utf8 (provider_name, error); + + //TODO: Need to pin delegate if we switch to safe mode or maybe we should get funcptr in icall? + provider = ep_create_provider (provider_name_utf8, MONO_HANDLE_GETVAL (callback_func, delegate_trampoline), NULL); + + g_free (provider_name_utf8); + return provider; +} + +intptr_t +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_DefineEvent ( + intptr_t provider_handle, + uint32_t event_id, + int64_t keywords, + uint32_t event_version, + uint32_t level, + const uint8_t *metadata, + uint32_t metadata_len) +{ + g_assert (provider_handle != 0); + + EventPipeProvider *provider = (EventPipeProvider *)provider_handle; + EventPipeEvent *ep_event = ep_provider_add_event (provider, event_id, (uint64_t)keywords, event_version, (EventPipeEventLevel)level, /* needStack = */ true, metadata, metadata_len); + + g_assert (ep_event != NULL); + return (intptr_t)ep_event; +} + +void +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_DeleteProvider (intptr_t provider_handle) +{ + if (provider_handle) { + ep_delete_provider ((EventPipeProvider *)provider_handle); + } +} + +void +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_Disable (uint64_t session_id) +{ + ep_disable (session_id); +} + +uint64_t +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_Enable ( + const gunichar2 *output_file, + /* EventPipeSerializationFormat */int32_t format, + uint32_t circular_buffer_size_mb, + /* EventPipeProviderConfigurationNative[] */const void *providers, + uint32_t providers_len) +{ + ERROR_DECL (error); + EventPipeSessionID session_id = 0; + + if (circular_buffer_size_mb == 0 || format > EP_SERIALIZATION_FORMAT_COUNT || providers_len == 0 || providers == NULL) + return 0; + + char *output_file_utf8 = mono_utf16_to_utf8 (output_file, g_utf16_len (output_file), error); + + session_id = ep_enable ( + output_file_utf8, + circular_buffer_size_mb, + providers, + providers_len, + output_file != NULL ? EP_SESSION_TYPE_FILE : EP_SESSION_TYPE_LISTENER, + (EventPipeSerializationFormat)format, + true, + NULL, + true); + ep_start_streaming (session_id); + + g_free (output_file_utf8); + return session_id; +} + +int32_t +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_EventActivityIdControl ( + uint32_t control_code, + /* GUID * */uint8_t *activity_id) +{ + int32_t result = 0; + EventPipeThread *thread = ep_thread_get (); + + if (thread == NULL) + return 1; + + uint8_t current_activity_id [EP_ACTIVITY_ID_SIZE]; + EventPipeActivityControlCode activity_control_code = (EventPipeActivityControlCode)control_code; + switch (activity_control_code) { + case EP_ACTIVITY_CONTROL_GET_ID: + ep_thread_get_activity_id (thread, activity_id, EP_ACTIVITY_ID_SIZE); + break; + case EP_ACTIVITY_CONTROL_SET_ID: + ep_thread_set_activity_id (thread, activity_id, EP_ACTIVITY_ID_SIZE); + break; + case EP_ACTIVITY_CONTROL_CREATE_ID: + ep_thread_create_activity_id (activity_id, EP_ACTIVITY_ID_SIZE); + break; + case EP_ACTIVITY_CONTROL_GET_SET_ID: + ep_thread_get_activity_id (thread, activity_id, EP_ACTIVITY_ID_SIZE); + ep_thread_create_activity_id (current_activity_id, G_N_ELEMENTS (current_activity_id)); + ep_thread_set_activity_id (thread, current_activity_id, G_N_ELEMENTS (current_activity_id)); + break; + default: + result = 1; + break; + } + + return result; +} + +MonoBoolean +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetNextEvent ( + uint64_t session_id, + /* EventPipeEventInstanceData * */void *instance) +{ + g_assert (instance != NULL); + + EventPipeEventInstance *const next_instance = ep_get_next_event (session_id); + EventPipeEventInstanceData *const data = (EventPipeEventInstanceData *)instance; + if (next_instance && data) { + const EventPipeEvent *const ep_event = ep_event_instance_get_ep_event (next_instance); + if (ep_event) { + data->provider_id = (intptr_t)ep_event_get_provider (ep_event); + data->event_id = ep_event_get_event_id (ep_event); + } + data->thread_id = ep_event_instance_get_thread_id (next_instance); + data->timestamp = ep_event_instance_get_timestamp (next_instance); + memcpy (&data->activity_id, ep_event_instance_get_activity_id_cref (next_instance), EP_ACTIVITY_ID_SIZE); + memcpy (&data->related_activity_id, ep_event_instance_get_related_activity_id_cref (next_instance), EP_ACTIVITY_ID_SIZE); + data->payload = ep_event_instance_get_data (next_instance); + data->payload_len = ep_event_instance_get_data_len (next_instance); + } + + return next_instance != NULL; +} + +intptr_t +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetProvider (const gunichar2 *provider_name) +{ + ERROR_DECL (error); + char * provider_name_utf8 = NULL; + EventPipeProvider *provider = NULL; + + if (provider_name) { + provider_name_utf8 = mono_utf16_to_utf8 (provider_name, g_utf16_len (provider_name), error); + provider = ep_get_provider (provider_name_utf8); + } + + g_free (provider_name_utf8); + return (intptr_t)provider; +} + +MonoBoolean +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetSessionInfo ( + uint64_t session_id, + /* EventPipeSessionInfo * */void *session_info) +{ + bool result = false; + if (session_info) { + EventPipeSession *session = ep_get_session ((EventPipeSessionID)session_id); + if (session) { + EventPipeSessionInfo *instance = (EventPipeSessionInfo *)session_info; + instance->starttime_as_utc_filetime = ep_session_get_session_start_time (session); + instance->start_timestamp = ep_session_get_session_start_timestamp (session); + instance->timestamp_frequency = ep_perf_frequency_query (); + result = true; + } + } + + return result; +} + +intptr_t +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetWaitHandle (uint64_t session_id) +{ + return (intptr_t)ep_get_wait_handle (session_id); +} + +void +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_WriteEventData ( + intptr_t event_handle, + /* EventProviderEventData[] */const void *event_data, + uint32_t data_len, + /* GUID * */const uint8_t *activity_id, + /* GUID * */const uint8_t *related_activity_id) +{ + ; +} + +#else /* ENABLE_PERFTRACING */ + +gconstpointer +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_CreateProvider ( + MonoStringHandle provider_name, + MonoDelegateHandle callback_func, + MonoError *error) +{ + mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.CreateProvider"); + return NULL; +} + +intptr_t +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_DefineEvent ( + intptr_t provider_handle, + uint32_t event_id, + int64_t keywords, + uint32_t event_version, + uint32_t level, + const uint8_t *metadata, + uint32_t metadata_len) +{ + ERROR_DECL (error); + mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.DefineEvent"); + mono_error_set_pending_exception (error); + return 0; +} + +void +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_DeleteProvider (intptr_t provider_handle) +{ + ERROR_DECL (error); + mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.DeleteProvider"); + mono_error_set_pending_exception (error); +} + +void +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_Disable (uint64_t session_id) +{ + ERROR_DECL (error); + mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.Disable"); + mono_error_set_pending_exception (error); +} + +uint64_t +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_Enable ( + const gunichar2 *output_file, + /* EventPipeSerializationFormat */int32_t format, + uint32_t circular_buffer_size_mb, + /* EventPipeProviderConfigurationNative[] */const void *providers, + uint32_t providers_len) +{ + ERROR_DECL (error); + mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.Enable"); + mono_error_set_pending_exception (error); + return 0; +} + +int32_t +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_EventActivityIdControl ( + uint32_t control_code, + /* GUID * */uint8_t *activity_id) +{ + ERROR_DECL (error); + mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.EventActivityIdControl"); + mono_error_set_pending_exception (error); + return 0; +} + +MonoBoolean +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetNextEvent ( + uint64_t session_id, + /* EventPipeEventInstanceData * */void *instance) +{ + ERROR_DECL (error); + mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.GetNextEvent"); + mono_error_set_pending_exception (error); + return FALSE; +} + +intptr_t +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetProvider (const gunichar2 *provider_name) +{ + ERROR_DECL (error); + mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.GetProvider"); + mono_error_set_pending_exception (error); + return 0; +} + +MonoBoolean +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetSessionInfo ( + uint64_t session_id, + /* EventPipeSessionInfo * */void *session_info) +{ + ERROR_DECL (error); + mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.GetSessionInfo"); + mono_error_set_pending_exception (error); + return FALSE; +} + +intptr_t +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetWaitHandle (uint64_t session_id) +{ + ERROR_DECL (error); + mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.GetWaitHandle"); + mono_error_set_pending_exception (error); + return 0; +} + +void +ves_icall_System_Diagnostics_Tracing_EventPipeInternal_WriteEventData ( + intptr_t event_handle, + /* EventProviderEventData[] */const void *event_data, + uint32_t data_len, + /* GUID * */const uint8_t *activity_id, + /* GUID * */const uint8_t *related_activity_id) +{ + ERROR_DECL (error); + mono_error_set_not_implemented (error, "System.Diagnostics.Tracing.EventPipeInternal.WriteEventData"); + mono_error_set_pending_exception (error); +} + +#endif /* ENABLE_PERFTRACING */ +#endif /* ENABLE_NETCORE */ + +MONO_EMPTY_SOURCE_FILE (eventpipe_rt_mono); diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index 0fa8444117d9a..c51006c362ed1 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -8427,115 +8427,6 @@ ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *volatile* cate mono_get_runtime_callbacks ()->debug_log (level, *category, *message); } -#ifdef ENABLE_NETCORE -#define EVENT_PIPE_DUMMY_PROVIDER_ID 1 -#define EVENT_PIPE_DUMMY_SESSION_ID 1 -#define EVENT_PIPE_DUMMY_EVENT_ID 1 -#define EVENT_PIPE_ERROR_SUCCESS 0 -#define EVENT_PIPE_INVALID_WAIT_HANDLE 0 - -typedef enum _EventPipeSerializationFormat{ - NetPerf, - NetTrace -} EventPipeSerializationFormat; - -typedef struct _EventPipeProviderConfigurationNative { - gunichar2 *provider_name; - uint64_t keywords; - uint32_t logging_level; - gunichar2 *filter_data; -} EventPipeProviderConfigurationNative; - -typedef struct _EventProviderEventData { - uint64_t ptr; - uint32_t size; - uint32_t reserved; -} EventProviderEventData; - -typedef struct _EventPipeSessionInfo { - int64_t starttime_as_utc_filetime; - int64_t start_timestamp; - int64_t timestamp_frequency; -} EventPipeSessionInfo; - -typedef struct _EventPipeEventInstanceData { - intptr_t provider_id; - uint32_t event_id; - uint32_t thread_id; - int64_t timestamp; - uint8_t activity_id[16]; - uint8_t related_activity_id[16]; - const uint8_t *payload; - uint32_t payload_length; -} EventPipeEventInstanceData; - -gconstpointer -ves_icall_System_Diagnostics_Tracing_EventPipeInternal_CreateProvider (MonoStringHandle provider_name, MonoDelegateHandle callback_func, MonoError *error) -{ - return GUINT_TO_POINTER (EVENT_PIPE_DUMMY_PROVIDER_ID); -} - -intptr_t -ves_icall_System_Diagnostics_Tracing_EventPipeInternal_DefineEvent (intptr_t prov_handle, uint32_t event_id, int64_t keywords, uint32_t event_version, uint32_t level, const uint8_t *metadata, uint32_t metadata_len) -{ - return EVENT_PIPE_DUMMY_EVENT_ID; -} - -void -ves_icall_System_Diagnostics_Tracing_EventPipeInternal_DeleteProvider (intptr_t prov_handle) -{ - ; -} - -void -ves_icall_System_Diagnostics_Tracing_EventPipeInternal_Disable (uint64_t session_id) -{ - ; -} - -uint64_t -ves_icall_System_Diagnostics_Tracing_EventPipeInternal_Enable (const_gunichar2_ptr output_file, /* EventPipeSerializationFormat */int32_t format, uint32_t circular_buffer_size_mb, /* EventPipeProviderConfigurationNative[] */const void *providers, uint32_t num_providers) -{ - return EVENT_PIPE_DUMMY_SESSION_ID; -} - -int32_t -ves_icall_System_Diagnostics_Tracing_EventPipeInternal_EventActivityIdControl (uint32_t control_code, /* GUID * */uint8_t *activity_id) -{ - return EVENT_PIPE_ERROR_SUCCESS; -} - -MonoBoolean -ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetNextEvent (uint64_t session_id, /* EventPipeEventInstanceData * */void *instance) -{ - return FALSE; -} - -intptr_t -ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetProvider (const_gunichar2_ptr provider_name) -{ - return EVENT_PIPE_DUMMY_PROVIDER_ID; -} - -MonoBoolean -ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetSessionInfo (uint64_t session_id, /* EventPipeSessionInfo * */void *session_info) -{ - return FALSE; -} - -intptr_t -ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetWaitHandle (uint64_t session_id) -{ - return EVENT_PIPE_INVALID_WAIT_HANDLE; -} - -void -ves_icall_System_Diagnostics_Tracing_EventPipeInternal_WriteEventData (intptr_t event_handle, /* EventProviderEventData[] */const void *event_data, uint32_t data_count, /* GUID * */const uint8_t *activity_id, /* GUID * */const uint8_t *related_activity_id) -{ - ; -} -#endif /* ENABLE_NETCORE */ - #ifndef HOST_WIN32 static inline void mono_icall_write_windows_debug_string (const gunichar2 *message) diff --git a/src/mono/mono/mini/Makefile.am.in b/src/mono/mono/mini/Makefile.am.in index 4fa894984cc16..a8e9891def5b7 100755 --- a/src/mono/mono/mini/Makefile.am.in +++ b/src/mono/mono/mini/Makefile.am.in @@ -29,6 +29,10 @@ endif glib_libs = $(monodir)/mono/eglib/libeglib.la +if ENABLE_PERFTRACING +eventpipe_libs = $(monodir)/mono/eventpipe/libeventpipe.la +endif + boehm_libs= \ $(monodir)/mono/metadata/libmonoruntime.la \ $(monodir)/mono/utils/libmonoutils.la \ @@ -39,6 +43,7 @@ sgen_libs = \ $(monodir)/mono/metadata/libmonoruntimesgen.la \ $(monodir)/mono/sgen/libmonosgen.la \ $(monodir)/mono/utils/libmonoutils.la \ + $(eventpipe_libs) \ $(glib_libs) if ENABLE_LLVM diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index e76f06f4186a0..ca2a59cf11a20 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -74,6 +74,10 @@ #include #include +#ifdef ENABLE_PERFTRACING +#include +#endif + #include "mini.h" #include "seq-points.h" #include "tasklets.h" @@ -4531,6 +4535,10 @@ mini_init (const char *filename, const char *runtime_version) mono_install_get_class_from_name (mono_aot_get_class_from_name); mono_install_jit_info_find_in_aot (mono_aot_find_jit_info); +#ifdef ENABLE_PERFTRACING + ep_init (); +#endif + mono_profiler_state.context_enable = mini_profiler_context_enable; mono_profiler_state.context_get_this = mini_profiler_context_get_this; mono_profiler_state.context_get_argument = mini_profiler_context_get_argument; @@ -4992,6 +5000,9 @@ mini_cleanup (MonoDomain *domain) mono_runtime_print_stats (); jit_stats_cleanup (); mono_jit_dump_cleanup (); +#ifdef ENABLE_PERFTRACING + ep_shutdown (); +#endif } #else void diff --git a/src/mono/msvc/build-init.vcxproj b/src/mono/msvc/build-init.vcxproj index 8d15e191ac40d..8b36028ea476c 100644 --- a/src/mono/msvc/build-init.vcxproj +++ b/src/mono/msvc/build-init.vcxproj @@ -142,6 +142,7 @@ <_EnableDefines Condition="'$(MONO_ENABLE_LLVM)' == 'true'">$(_EnableDefines);ENABLE_LLVM;ENABLE_LLVM_RUNTIME <_EnableDefines Condition="'$(MONO_ENABLE_NETCORE)' == 'true'">$(_EnableDefines);ENABLE_NETCORE + <_EnableDefines Condition="'$(MONO_ENABLE_PERFTRACING)' == 'true'">$(_EnableDefines);ENABLE_PERFTRACING <_HaveDefines Condition="'$(MONO_ENABLE_BTLS)' == 'true'">$(_HaveDefines);HAVE_BTLS <_EnableDefines>$(_EnableDefines.Trim(';')) <_HaveDefines>$(_HaveDefines.Trim(';')) diff --git a/src/mono/msvc/libeventpipe.targets b/src/mono/msvc/libeventpipe.targets new file mode 100644 index 0000000000000..9758f292b376c --- /dev/null +++ b/src/mono/msvc/libeventpipe.targets @@ -0,0 +1,149 @@ + + + + false + true + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + $(ExcludeEventPipeFromBuild) + CompileAsC + + + + diff --git a/src/mono/msvc/libeventpipe.targets.filters b/src/mono/msvc/libeventpipe.targets.filters new file mode 100644 index 0000000000000..1bb9dcffc7bc3 --- /dev/null +++ b/src/mono/msvc/libeventpipe.targets.filters @@ -0,0 +1,172 @@ + + + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Source Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + Header Files$(MonoRuntimeFilterSubFolder)\eventpipe + + + + + {D6D64FF2-7951-44D8-B965-4593893CEF35} + + + {B372B1CF-F13A-43B8-97E0-DF7A9563D4AE} + + + diff --git a/src/mono/msvc/libmono-dynamic.vcxproj b/src/mono/msvc/libmono-dynamic.vcxproj index c63be2c85ad72..cd120b7cfb16f 100644 --- a/src/mono/msvc/libmono-dynamic.vcxproj +++ b/src/mono/msvc/libmono-dynamic.vcxproj @@ -94,7 +94,6 @@ - /D /NODEFAULTLIB:LIBCD" " %(AdditionalOptions) Disabled $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories) WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);$(SHIM_GLOBALIZATION_DEFINES);_DEBUG;%(PreprocessorDefinitions) @@ -121,7 +120,6 @@ X64 - /D /NODEFAULTLIB:LIBCD" " %(AdditionalOptions) Disabled $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories) WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);$(SHIM_GLOBALIZATION_DEFINES);WIN64;_DEBUG;%(PreprocessorDefinitions) @@ -145,7 +143,6 @@ - /D /NODEFAULTLIB:LIBCD" " %(AdditionalOptions) true $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories) WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);$(SHIM_GLOBALIZATION_DEFINES);NDEBUG;%(PreprocessorDefinitions) @@ -174,7 +171,6 @@ X64 - /D /NODEFAULTLIB:LIBCD" " %(AdditionalOptions) true $(MONO_DIR);$(MONO_INCLUDE_DIR);$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE);$(MONO_LLVM_DEFAULT_INCLUDE_DIR);$(SHIM_GLOBALIZATION_INCLUDE_DIR);%(AdditionalIncludeDirectories) WIN32;WIN32_LEAN_AND_MEAN;$(GC_DEFINES);MONO_DLL_EXPORT;LLVM_API_VERSION=$(MONO_LLVM_DEFAULT_API_VERSION);$(SHIM_GLOBALIZATION_DEFINES);WIN64;NDEBUG;%(PreprocessorDefinitions) diff --git a/src/mono/msvc/libmonoruntime-common.targets b/src/mono/msvc/libmonoruntime-common.targets index 3e6f62e64d155..316efc8a4fc23 100644 --- a/src/mono/msvc/libmonoruntime-common.targets +++ b/src/mono/msvc/libmonoruntime-common.targets @@ -36,6 +36,7 @@ + diff --git a/src/mono/msvc/libmonoruntime-common.targets.filters b/src/mono/msvc/libmonoruntime-common.targets.filters index d614b6bcc49f7..fb4a4e3c84060 100644 --- a/src/mono/msvc/libmonoruntime-common.targets.filters +++ b/src/mono/msvc/libmonoruntime-common.targets.filters @@ -97,6 +97,9 @@ Source Files$(MonoRuntimeFilterSubFolder)\common + + Source Files$(MonoRuntimeFilterSubFolder)\common + Source Files$(MonoRuntimeFilterSubFolder)\common diff --git a/src/mono/msvc/libmonoruntime.targets b/src/mono/msvc/libmonoruntime.targets index 7b797ee766ddc..ef506c56f4555 100644 --- a/src/mono/msvc/libmonoruntime.targets +++ b/src/mono/msvc/libmonoruntime.targets @@ -2,6 +2,7 @@ + diff --git a/src/mono/msvc/libmonoruntime.targets.filters b/src/mono/msvc/libmonoruntime.targets.filters index d59ba5b295cee..6add73fc2df6d 100644 --- a/src/mono/msvc/libmonoruntime.targets.filters +++ b/src/mono/msvc/libmonoruntime.targets.filters @@ -2,6 +2,7 @@ + diff --git a/src/mono/msvc/mono.props b/src/mono/msvc/mono.props index 502c5398527d2..dbfed0b19f4a2 100644 --- a/src/mono/msvc/mono.props +++ b/src/mono/msvc/mono.props @@ -28,8 +28,11 @@ false + false true - false + + false + true .. @@ -124,6 +127,9 @@ $(MONO_ENABLE_NETCORE) + + $(MONO_ENABLE_PERFTRACING) + HAVE_CONFIG_H diff --git a/src/mono/msvc/mono.winconfig.targets b/src/mono/msvc/mono.winconfig.targets index d8e39ca7ad2dc..62e92339ee266 100644 --- a/src/mono/msvc/mono.winconfig.targets +++ b/src/mono/msvc/mono.winconfig.targets @@ -124,7 +124,8 @@ "ENABLE_LLVM_RUNTIME", "ENABLE_HYBRID_SUSPEND", "ENABLE_COOP_SUSPEND", - "ENABLE_NETCORE" }; + "ENABLE_NETCORE", + "ENABLE_PERFTRACING" }; var enableFeatures = GetConfigFeatures(path, ".*#define.*ENABLE_.*1"); if (enableDefines != null) From 639f06df970c6772a0cad5dbde9cb71335b61ab5 Mon Sep 17 00:00:00 2001 From: Erhan Atesoglu <47518605+eanova@users.noreply.github.com> Date: Tue, 26 May 2020 07:51:23 -0700 Subject: [PATCH 383/420] Add SIMD acceleration for Matrix4x4.Invert #34394 (#36323) * Add SIMD acceleration for Matrix4x4.Invert #34394 Fix for #34394. Added SIMD hardware acceleration support to the Matrix4x4.Invert function. * Add link to source and update THIRD-PARTY-NOTICES.TXT Added the link to Microsoft/DirectXMath source code and appended license to THIRD-PARTY-NOTICES.TXT * Add test for non-invertable matrix. Given a Matrix4x4 of only rank 3 test to see the matrix is non-invertable. * Typo fixed in new test case * Fixed formating for test matrix. * Fix for missing return statement. * Add suggested fixes to Matrix4x4.Invert Update containing all suggested fixes. * Added missing using statement Added missing using statement for Internal.Runtime.CompilerServices.Unknown static object. * Use abbreviated constructor for Vector128 * Moved implementations into local functions Moved the SSE implementation and SoftwareFallback to local functions of Invert. --- THIRD-PARTY-NOTICES.TXT | 27 + .../tests/Matrix4x4Tests.cs | 17 + .../src/System/Numerics/Matrix4x4.cs | 497 ++++++++++++------ 3 files changed, 388 insertions(+), 153 deletions(-) diff --git a/THIRD-PARTY-NOTICES.TXT b/THIRD-PARTY-NOTICES.TXT index db9304008a31d..707bd024f8f86 100644 --- a/THIRD-PARTY-NOTICES.TXT +++ b/THIRD-PARTY-NOTICES.TXT @@ -821,6 +821,32 @@ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +License notice for DirectX Math Library +--------------------------------------- + +https://github.com/microsoft/DirectXMath/blob/master/LICENSE + + The MIT License (MIT) + +Copyright (c) 2011-2020 Microsoft Corp + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies +or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + License notice for ldap4net --------------------------- @@ -833,3 +859,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/src/libraries/System.Numerics.Vectors/tests/Matrix4x4Tests.cs b/src/libraries/System.Numerics.Vectors/tests/Matrix4x4Tests.cs index 4c6fa0c0637d3..fc82fb83850f0 100644 --- a/src/libraries/System.Numerics.Vectors/tests/Matrix4x4Tests.cs +++ b/src/libraries/System.Numerics.Vectors/tests/Matrix4x4Tests.cs @@ -219,6 +219,23 @@ public void Matrix4x4InvertAffineTest() Assert.True(MathHelper.Equal(i, Matrix4x4.Identity)); } + // A test for Invert (Matrix4x4) + [Fact] + public void Matrix4x4InvertRank3() + { + // A 4x4 Matrix having a rank of 3 + Matrix4x4 mtx = new Matrix4x4(1.0f, 2.0f, 3.0f, 0.0f, + 5.0f, 1.0f, 6.0f, 0.0f, + 8.0f, 9.0f, 1.0f, 0.0f, + 4.0f, 7.0f, 3.0f, 0.0f); + + Matrix4x4 actual; + Assert.False(Matrix4x4.Invert(mtx, out actual)); + + Matrix4x4 i = mtx * actual; + Assert.False(MathHelper.Equal(i, Matrix4x4.Identity)); + } + void DecomposeTest(float yaw, float pitch, float roll, Vector3 expectedTranslation, Vector3 expectedScales) { Quaternion expectedRotation = Quaternion.CreateFromYawPitchRoll(MathHelper.ToRadians(yaw), diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs index c49c02c18dd20..7323ba23e3dd7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs @@ -1,8 +1,10 @@ // 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. - +using Internal.Runtime.CompilerServices; +using System.Diagnostics; using System.Globalization; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; @@ -1305,171 +1307,360 @@ public static Matrix4x4 CreateReflection(Plane value) d * (e * jo_kn - f * io_km + g * in_jm); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector128 Permute(Vector128 value, byte control) + { + if (Avx.IsSupported) + { + return Avx.Permute(value, control); + } + + Debug.Assert(Sse.IsSupported); + return Sse.Shuffle(value, value, control); + } + /// /// Attempts to calculate the inverse of the given matrix. If successful, result will contain the inverted matrix. /// /// The source matrix to invert. /// If successful, contains the inverted matrix. /// True if the source matrix could be inverted; False otherwise. - public static bool Invert(Matrix4x4 matrix, out Matrix4x4 result) + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool Invert(Matrix4x4 matrix, out Matrix4x4 result) { - // -1 - // If you have matrix M, inverse Matrix M can compute - // - // -1 1 - // M = --------- A - // det(M) - // - // A is adjugate (adjoint) of M, where, - // - // T - // A = C - // - // C is Cofactor matrix of M, where, - // i + j - // C = (-1) * det(M ) - // ij ij - // - // [ a b c d ] - // M = [ e f g h ] - // [ i j k l ] - // [ m n o p ] - // - // First Row - // 2 | f g h | - // C = (-1) | j k l | = + ( f ( kp - lo ) - g ( jp - ln ) + h ( jo - kn ) ) - // 11 | n o p | - // - // 3 | e g h | - // C = (-1) | i k l | = - ( e ( kp - lo ) - g ( ip - lm ) + h ( io - km ) ) - // 12 | m o p | - // - // 4 | e f h | - // C = (-1) | i j l | = + ( e ( jp - ln ) - f ( ip - lm ) + h ( in - jm ) ) - // 13 | m n p | - // - // 5 | e f g | - // C = (-1) | i j k | = - ( e ( jo - kn ) - f ( io - km ) + g ( in - jm ) ) - // 14 | m n o | - // - // Second Row - // 3 | b c d | - // C = (-1) | j k l | = - ( b ( kp - lo ) - c ( jp - ln ) + d ( jo - kn ) ) - // 21 | n o p | - // - // 4 | a c d | - // C = (-1) | i k l | = + ( a ( kp - lo ) - c ( ip - lm ) + d ( io - km ) ) - // 22 | m o p | - // - // 5 | a b d | - // C = (-1) | i j l | = - ( a ( jp - ln ) - b ( ip - lm ) + d ( in - jm ) ) - // 23 | m n p | - // - // 6 | a b c | - // C = (-1) | i j k | = + ( a ( jo - kn ) - b ( io - km ) + c ( in - jm ) ) - // 24 | m n o | - // - // Third Row - // 4 | b c d | - // C = (-1) | f g h | = + ( b ( gp - ho ) - c ( fp - hn ) + d ( fo - gn ) ) - // 31 | n o p | - // - // 5 | a c d | - // C = (-1) | e g h | = - ( a ( gp - ho ) - c ( ep - hm ) + d ( eo - gm ) ) - // 32 | m o p | - // - // 6 | a b d | - // C = (-1) | e f h | = + ( a ( fp - hn ) - b ( ep - hm ) + d ( en - fm ) ) - // 33 | m n p | - // - // 7 | a b c | - // C = (-1) | e f g | = - ( a ( fo - gn ) - b ( eo - gm ) + c ( en - fm ) ) - // 34 | m n o | - // - // Fourth Row - // 5 | b c d | - // C = (-1) | f g h | = - ( b ( gl - hk ) - c ( fl - hj ) + d ( fk - gj ) ) - // 41 | j k l | - // - // 6 | a c d | - // C = (-1) | e g h | = + ( a ( gl - hk ) - c ( el - hi ) + d ( ek - gi ) ) - // 42 | i k l | - // - // 7 | a b d | - // C = (-1) | e f h | = - ( a ( fl - hj ) - b ( el - hi ) + d ( ej - fi ) ) - // 43 | i j l | - // - // 8 | a b c | - // C = (-1) | e f g | = + ( a ( fk - gj ) - b ( ek - gi ) + c ( ej - fi ) ) - // 44 | i j k | - // - // Cost of operation - // 53 adds, 104 muls, and 1 div. - float a = matrix.M11, b = matrix.M12, c = matrix.M13, d = matrix.M14; - float e = matrix.M21, f = matrix.M22, g = matrix.M23, h = matrix.M24; - float i = matrix.M31, j = matrix.M32, k = matrix.M33, l = matrix.M34; - float m = matrix.M41, n = matrix.M42, o = matrix.M43, p = matrix.M44; + if (Sse.IsSupported) + { + return SseImpl(matrix, out result); + } - float kp_lo = k * p - l * o; - float jp_ln = j * p - l * n; - float jo_kn = j * o - k * n; - float ip_lm = i * p - l * m; - float io_km = i * o - k * m; - float in_jm = i * n - j * m; + return SoftwareFallback(matrix, out result); - float a11 = +(f * kp_lo - g * jp_ln + h * jo_kn); - float a12 = -(e * kp_lo - g * ip_lm + h * io_km); - float a13 = +(e * jp_ln - f * ip_lm + h * in_jm); - float a14 = -(e * jo_kn - f * io_km + g * in_jm); + static unsafe bool SseImpl(Matrix4x4 matrix, out Matrix4x4 result) + { + // This implementation is based on the DirectX Math Library XMMInverse method + // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathMatrix.inl - float det = a * a11 + b * a12 + c * a13 + d * a14; + // Load the matrix values into rows + Vector128 row1 = Sse.LoadVector128(&matrix.M11); + Vector128 row2 = Sse.LoadVector128(&matrix.M21); + Vector128 row3 = Sse.LoadVector128(&matrix.M31); + Vector128 row4 = Sse.LoadVector128(&matrix.M41); - if (MathF.Abs(det) < float.Epsilon) - { - result = new Matrix4x4(float.NaN, float.NaN, float.NaN, float.NaN, - float.NaN, float.NaN, float.NaN, float.NaN, - float.NaN, float.NaN, float.NaN, float.NaN, - float.NaN, float.NaN, float.NaN, float.NaN); - return false; + // Transpose the matrix + Vector128 vTemp1 = Sse.Shuffle(row1, row2, 0x44); //_MM_SHUFFLE(1, 0, 1, 0) + Vector128 vTemp3 = Sse.Shuffle(row1, row2, 0xEE); //_MM_SHUFFLE(3, 2, 3, 2) + Vector128 vTemp2 = Sse.Shuffle(row3, row4, 0x44); //_MM_SHUFFLE(1, 0, 1, 0) + Vector128 vTemp4 = Sse.Shuffle(row3, row4, 0xEE); //_MM_SHUFFLE(3, 2, 3, 2) + + row1 = Sse.Shuffle(vTemp1, vTemp2, 0x88); //_MM_SHUFFLE(2, 0, 2, 0) + row2 = Sse.Shuffle(vTemp1, vTemp2, 0xDD); //_MM_SHUFFLE(3, 1, 3, 1) + row3 = Sse.Shuffle(vTemp3, vTemp4, 0x88); //_MM_SHUFFLE(2, 0, 2, 0) + row4 = Sse.Shuffle(vTemp3, vTemp4, 0xDD); //_MM_SHUFFLE(3, 1, 3, 1) + + Vector128 V00 = Permute(row3, 0x50); //_MM_SHUFFLE(1, 1, 0, 0) + Vector128 V10 = Permute(row4, 0xEE); //_MM_SHUFFLE(3, 2, 3, 2) + Vector128 V01 = Permute(row1, 0x50); //_MM_SHUFFLE(1, 1, 0, 0) + Vector128 V11 = Permute(row2, 0xEE); //_MM_SHUFFLE(3, 2, 3, 2) + Vector128 V02 = Sse.Shuffle(row3, row1, 0x88); //_MM_SHUFFLE(2, 0, 2, 0) + Vector128 V12 = Sse.Shuffle(row4, row2, 0xDD); //_MM_SHUFFLE(3, 1, 3, 1) + + Vector128 D0 = Sse.Multiply(V00, V10); + Vector128 D1 = Sse.Multiply(V01, V11); + Vector128 D2 = Sse.Multiply(V02, V12); + + V00 = Permute(row3, 0xEE); //_MM_SHUFFLE(3, 2, 3, 2) + V10 = Permute(row4, 0x50); //_MM_SHUFFLE(1, 1, 0, 0) + V01 = Permute(row1, 0xEE); //_MM_SHUFFLE(3, 2, 3, 2) + V11 = Permute(row2, 0x50); //_MM_SHUFFLE(1, 1, 0, 0) + V02 = Sse.Shuffle(row3, row1, 0xDD); //_MM_SHUFFLE(3, 1, 3, 1) + V12 = Sse.Shuffle(row4, row2, 0x88); //_MM_SHUFFLE(2, 0, 2, 0) + + // Note: We use this expansion pattern instead of Fused Multiply Add + // in order to support older hardware + D0 = Sse.Subtract(D0, Sse.Multiply(V00, V10)); + D1 = Sse.Subtract(D1, Sse.Multiply(V01, V11)); + D2 = Sse.Subtract(D2, Sse.Multiply(V02, V12)); + + // V11 = D0Y,D0W,D2Y,D2Y + V11 = Sse.Shuffle(D0, D2, 0x5D); //_MM_SHUFFLE(1, 1, 3, 1) + V00 = Permute(row2, 0x49); //_MM_SHUFFLE(1, 0, 2, 1) + V10 = Sse.Shuffle(V11, D0, 0x32); //_MM_SHUFFLE(0, 3, 0, 2) + V01 = Permute(row1, 0x12); //_MM_SHUFFLE(0, 1, 0, 2) + V11 = Sse.Shuffle(V11, D0, 0x99); //_MM_SHUFFLE(2, 1, 2, 1) + + // V13 = D1Y,D1W,D2W,D2W + Vector128 V13 = Sse.Shuffle(D1, D2, 0xFD); //_MM_SHUFFLE(3, 3, 3, 1) + V02 = Permute(row4, 0x49); //_MM_SHUFFLE(1, 0, 2, 1) + V12 = Sse.Shuffle(V13, D1, 0x32); //_MM_SHUFFLE(0, 3, 0, 2) + Vector128 V03 = Permute(row3, 0x12); //_MM_SHUFFLE(0, 1, 0, 2) + V13 = Sse.Shuffle(V13, D1, 0x99); //_MM_SHUFFLE(2, 1, 2, 1) + + Vector128 C0 = Sse.Multiply(V00, V10); + Vector128 C2 = Sse.Multiply(V01, V11); + Vector128 C4 = Sse.Multiply(V02, V12); + Vector128 C6 = Sse.Multiply(V03, V13); + + // V11 = D0X,D0Y,D2X,D2X + V11 = Sse.Shuffle(D0, D2, 0x4); //_MM_SHUFFLE(0, 0, 1, 0) + V00 = Permute(row2, 0x9e); //_MM_SHUFFLE(2, 1, 3, 2) + V10 = Sse.Shuffle(D0, V11, 0x93); //_MM_SHUFFLE(2, 1, 0, 3) + V01 = Permute(row1, 0x7b); //_MM_SHUFFLE(1, 3, 2, 3) + V11 = Sse.Shuffle(D0, V11, 0x26); //_MM_SHUFFLE(0, 2, 1, 2) + + // V13 = D1X,D1Y,D2Z,D2Z + V13 = Sse.Shuffle(D1, D2, 0xa4); //_MM_SHUFFLE(2, 2, 1, 0) + V02 = Permute(row4, 0x9e); //_MM_SHUFFLE(2, 1, 3, 2) + V12 = Sse.Shuffle(D1, V13, 0x93); //_MM_SHUFFLE(2, 1, 0, 3) + V03 = Permute(row3, 0x7b); //_MM_SHUFFLE(1, 3, 2, 3) + V13 = Sse.Shuffle(D1, V13, 0x26); //_MM_SHUFFLE(0, 2, 1, 2) + + C0 = Sse.Subtract(C0, Sse.Multiply(V00, V10)); + C2 = Sse.Subtract(C2, Sse.Multiply(V01, V11)); + C4 = Sse.Subtract(C4, Sse.Multiply(V02, V12)); + C6 = Sse.Subtract(C6, Sse.Multiply(V03, V13)); + + V00 = Permute(row2, 0x33); //_MM_SHUFFLE(0, 3, 0, 3) + + // V10 = D0Z,D0Z,D2X,D2Y + V10 = Sse.Shuffle(D0, D2, 0x4A); //_MM_SHUFFLE(1, 0, 2, 2) + V10 = Permute(V10, 0x2C); //_MM_SHUFFLE(0, 2, 3, 0) + V01 = Permute(row1, 0x8D); //_MM_SHUFFLE(2, 0, 3, 1) + + // V11 = D0X,D0W,D2X,D2Y + V11 = Sse.Shuffle(D0, D2, 0x4C); //_MM_SHUFFLE(1, 0, 3, 0) + V11 = Permute(V11, 0x93); //_MM_SHUFFLE(2, 1, 0, 3) + V02 = Permute(row4, 0x33); //_MM_SHUFFLE(0, 3, 0, 3) + + // V12 = D1Z,D1Z,D2Z,D2W + V12 = Sse.Shuffle(D1, D2, 0xEA); //_MM_SHUFFLE(3, 2, 2, 2) + V12 = Permute(V12, 0x2C); //_MM_SHUFFLE(0, 2, 3, 0) + V03 = Permute(row3, 0x8D); //_MM_SHUFFLE(2, 0, 3, 1) + + // V13 = D1X,D1W,D2Z,D2W + V13 = Sse.Shuffle(D1, D2, 0xEC); //_MM_SHUFFLE(3, 2, 3, 0) + V13 = Permute(V13, 0x93); //_MM_SHUFFLE(2, 1, 0, 3) + + V00 = Sse.Multiply(V00, V10); + V01 = Sse.Multiply(V01, V11); + V02 = Sse.Multiply(V02, V12); + V03 = Sse.Multiply(V03, V13); + + Vector128 C1 = Sse.Subtract(C0, V00); + C0 = Sse.Add(C0, V00); + Vector128 C3 = Sse.Add(C2, V01); + C2 = Sse.Subtract(C2, V01); + Vector128 C5 = Sse.Subtract(C4, V02); + C4 = Sse.Add(C4, V02); + Vector128 C7 = Sse.Add(C6, V03); + C6 = Sse.Subtract(C6, V03); + + C0 = Sse.Shuffle(C0, C1, 0xD8); //_MM_SHUFFLE(3, 1, 2, 0) + C2 = Sse.Shuffle(C2, C3, 0xD8); //_MM_SHUFFLE(3, 1, 2, 0) + C4 = Sse.Shuffle(C4, C5, 0xD8); //_MM_SHUFFLE(3, 1, 2, 0) + C6 = Sse.Shuffle(C6, C7, 0xD8); //_MM_SHUFFLE(3, 1, 2, 0) + + C0 = Permute(C0, 0xD8); //_MM_SHUFFLE(3, 1, 2, 0) + C2 = Permute(C2, 0xD8); //_MM_SHUFFLE(3, 1, 2, 0) + C4 = Permute(C4, 0xD8); //_MM_SHUFFLE(3, 1, 2, 0) + C6 = Permute(C6, 0xD8); //_MM_SHUFFLE(3, 1, 2, 0) + + // Get the determinant + vTemp2 = row1; + float det = Vector4.Dot(C0.AsVector4(), vTemp2.AsVector4()); + + // Check determinate is not zero + if (MathF.Abs(det) < float.Epsilon) + { + result = new Matrix4x4(float.NaN, float.NaN, float.NaN, float.NaN, + float.NaN, float.NaN, float.NaN, float.NaN, + float.NaN, float.NaN, float.NaN, float.NaN, + float.NaN, float.NaN, float.NaN, float.NaN); + return false; + } + + // Create Vector128 copy of the determinant and invert them. + Vector128 ones = Vector128.Create(1.0f); + Vector128 vTemp = Vector128.Create(det); + vTemp = Sse.Divide(ones, vTemp); + + row1 = Sse.Multiply(C0, vTemp); + row2 = Sse.Multiply(C2, vTemp); + row3 = Sse.Multiply(C4, vTemp); + row4 = Sse.Multiply(C6, vTemp); + + Unsafe.SkipInit(out result); + ref Vector128 vResult = ref Unsafe.As>(ref result); + + vResult = row1; + Unsafe.Add(ref vResult, 1) = row2; + Unsafe.Add(ref vResult, 2) = row3; + Unsafe.Add(ref vResult, 3) = row4; + + return true; } - float invDet = 1.0f / det; - - result.M11 = a11 * invDet; - result.M21 = a12 * invDet; - result.M31 = a13 * invDet; - result.M41 = a14 * invDet; - - result.M12 = -(b * kp_lo - c * jp_ln + d * jo_kn) * invDet; - result.M22 = +(a * kp_lo - c * ip_lm + d * io_km) * invDet; - result.M32 = -(a * jp_ln - b * ip_lm + d * in_jm) * invDet; - result.M42 = +(a * jo_kn - b * io_km + c * in_jm) * invDet; - - float gp_ho = g * p - h * o; - float fp_hn = f * p - h * n; - float fo_gn = f * o - g * n; - float ep_hm = e * p - h * m; - float eo_gm = e * o - g * m; - float en_fm = e * n - f * m; - - result.M13 = +(b * gp_ho - c * fp_hn + d * fo_gn) * invDet; - result.M23 = -(a * gp_ho - c * ep_hm + d * eo_gm) * invDet; - result.M33 = +(a * fp_hn - b * ep_hm + d * en_fm) * invDet; - result.M43 = -(a * fo_gn - b * eo_gm + c * en_fm) * invDet; - - float gl_hk = g * l - h * k; - float fl_hj = f * l - h * j; - float fk_gj = f * k - g * j; - float el_hi = e * l - h * i; - float ek_gi = e * k - g * i; - float ej_fi = e * j - f * i; - - result.M14 = -(b * gl_hk - c * fl_hj + d * fk_gj) * invDet; - result.M24 = +(a * gl_hk - c * el_hi + d * ek_gi) * invDet; - result.M34 = -(a * fl_hj - b * el_hi + d * ej_fi) * invDet; - result.M44 = +(a * fk_gj - b * ek_gi + c * ej_fi) * invDet; - - return true; + static bool SoftwareFallback(Matrix4x4 matrix, out Matrix4x4 result) + { + // -1 + // If you have matrix M, inverse Matrix M can compute + // + // -1 1 + // M = --------- A + // det(M) + // + // A is adjugate (adjoint) of M, where, + // + // T + // A = C + // + // C is Cofactor matrix of M, where, + // i + j + // C = (-1) * det(M ) + // ij ij + // + // [ a b c d ] + // M = [ e f g h ] + // [ i j k l ] + // [ m n o p ] + // + // First Row + // 2 | f g h | + // C = (-1) | j k l | = + ( f ( kp - lo ) - g ( jp - ln ) + h ( jo - kn ) ) + // 11 | n o p | + // + // 3 | e g h | + // C = (-1) | i k l | = - ( e ( kp - lo ) - g ( ip - lm ) + h ( io - km ) ) + // 12 | m o p | + // + // 4 | e f h | + // C = (-1) | i j l | = + ( e ( jp - ln ) - f ( ip - lm ) + h ( in - jm ) ) + // 13 | m n p | + // + // 5 | e f g | + // C = (-1) | i j k | = - ( e ( jo - kn ) - f ( io - km ) + g ( in - jm ) ) + // 14 | m n o | + // + // Second Row + // 3 | b c d | + // C = (-1) | j k l | = - ( b ( kp - lo ) - c ( jp - ln ) + d ( jo - kn ) ) + // 21 | n o p | + // + // 4 | a c d | + // C = (-1) | i k l | = + ( a ( kp - lo ) - c ( ip - lm ) + d ( io - km ) ) + // 22 | m o p | + // + // 5 | a b d | + // C = (-1) | i j l | = - ( a ( jp - ln ) - b ( ip - lm ) + d ( in - jm ) ) + // 23 | m n p | + // + // 6 | a b c | + // C = (-1) | i j k | = + ( a ( jo - kn ) - b ( io - km ) + c ( in - jm ) ) + // 24 | m n o | + // + // Third Row + // 4 | b c d | + // C = (-1) | f g h | = + ( b ( gp - ho ) - c ( fp - hn ) + d ( fo - gn ) ) + // 31 | n o p | + // + // 5 | a c d | + // C = (-1) | e g h | = - ( a ( gp - ho ) - c ( ep - hm ) + d ( eo - gm ) ) + // 32 | m o p | + // + // 6 | a b d | + // C = (-1) | e f h | = + ( a ( fp - hn ) - b ( ep - hm ) + d ( en - fm ) ) + // 33 | m n p | + // + // 7 | a b c | + // C = (-1) | e f g | = - ( a ( fo - gn ) - b ( eo - gm ) + c ( en - fm ) ) + // 34 | m n o | + // + // Fourth Row + // 5 | b c d | + // C = (-1) | f g h | = - ( b ( gl - hk ) - c ( fl - hj ) + d ( fk - gj ) ) + // 41 | j k l | + // + // 6 | a c d | + // C = (-1) | e g h | = + ( a ( gl - hk ) - c ( el - hi ) + d ( ek - gi ) ) + // 42 | i k l | + // + // 7 | a b d | + // C = (-1) | e f h | = - ( a ( fl - hj ) - b ( el - hi ) + d ( ej - fi ) ) + // 43 | i j l | + // + // 8 | a b c | + // C = (-1) | e f g | = + ( a ( fk - gj ) - b ( ek - gi ) + c ( ej - fi ) ) + // 44 | i j k | + // + // Cost of operation + // 53 adds, 104 muls, and 1 div. + float a = matrix.M11, b = matrix.M12, c = matrix.M13, d = matrix.M14; + float e = matrix.M21, f = matrix.M22, g = matrix.M23, h = matrix.M24; + float i = matrix.M31, j = matrix.M32, k = matrix.M33, l = matrix.M34; + float m = matrix.M41, n = matrix.M42, o = matrix.M43, p = matrix.M44; + + float kp_lo = k * p - l * o; + float jp_ln = j * p - l * n; + float jo_kn = j * o - k * n; + float ip_lm = i * p - l * m; + float io_km = i * o - k * m; + float in_jm = i * n - j * m; + + float a11 = +(f * kp_lo - g * jp_ln + h * jo_kn); + float a12 = -(e * kp_lo - g * ip_lm + h * io_km); + float a13 = +(e * jp_ln - f * ip_lm + h * in_jm); + float a14 = -(e * jo_kn - f * io_km + g * in_jm); + + float det = a * a11 + b * a12 + c * a13 + d * a14; + + if (MathF.Abs(det) < float.Epsilon) + { + result = new Matrix4x4(float.NaN, float.NaN, float.NaN, float.NaN, + float.NaN, float.NaN, float.NaN, float.NaN, + float.NaN, float.NaN, float.NaN, float.NaN, + float.NaN, float.NaN, float.NaN, float.NaN); + return false; + } + + float invDet = 1.0f / det; + + result.M11 = a11 * invDet; + result.M21 = a12 * invDet; + result.M31 = a13 * invDet; + result.M41 = a14 * invDet; + + result.M12 = -(b * kp_lo - c * jp_ln + d * jo_kn) * invDet; + result.M22 = +(a * kp_lo - c * ip_lm + d * io_km) * invDet; + result.M32 = -(a * jp_ln - b * ip_lm + d * in_jm) * invDet; + result.M42 = +(a * jo_kn - b * io_km + c * in_jm) * invDet; + + float gp_ho = g * p - h * o; + float fp_hn = f * p - h * n; + float fo_gn = f * o - g * n; + float ep_hm = e * p - h * m; + float eo_gm = e * o - g * m; + float en_fm = e * n - f * m; + + result.M13 = +(b * gp_ho - c * fp_hn + d * fo_gn) * invDet; + result.M23 = -(a * gp_ho - c * ep_hm + d * eo_gm) * invDet; + result.M33 = +(a * fp_hn - b * ep_hm + d * en_fm) * invDet; + result.M43 = -(a * fo_gn - b * eo_gm + c * en_fm) * invDet; + + float gl_hk = g * l - h * k; + float fl_hj = f * l - h * j; + float fk_gj = f * k - g * j; + float el_hi = e * l - h * i; + float ek_gi = e * k - g * i; + float ej_fi = e * j - f * i; + + result.M14 = -(b * gl_hk - c * fl_hj + d * fk_gj) * invDet; + result.M24 = +(a * gl_hk - c * el_hi + d * ek_gi) * invDet; + result.M34 = -(a * fl_hj - b * el_hi + d * ej_fi) * invDet; + result.M44 = +(a * fk_gj - b * ek_gi + c * ej_fi) * invDet; + + return true; + } } From c08d909893625a11d91cfc9100e53291af373780 Mon Sep 17 00:00:00 2001 From: Swaroop Sridhar Date: Sun, 24 May 2020 02:40:17 -0700 Subject: [PATCH 384/420] Address futher review feedback * Fix Assembly.ni.dll and Assembly.dll path usage. * Remove unused full-path computation for corelib when loading from bundle. * Add tracing when loading from bundle. * Add bundle-probing for satellite assemblies. * Adapt the BundleRename test to the .net5 scenario where assemblies are loaded from bundle. --- src/coreclr/src/binder/assemblybinder.cpp | 251 ++++++++++++------ src/coreclr/src/binder/inc/bindertracing.h | 3 +- src/coreclr/src/binder/utils.cpp | 2 +- .../TestProjects/AppWithWait/Program.cs | 5 + .../AppHost.Bundle.Tests/BundleRename.cs | 29 +- 5 files changed, 191 insertions(+), 99 deletions(-) diff --git a/src/coreclr/src/binder/assemblybinder.cpp b/src/coreclr/src/binder/assemblybinder.cpp index 0f8c782867107..362c2b867802f 100644 --- a/src/coreclr/src/binder/assemblybinder.cpp +++ b/src/coreclr/src/binder/assemblybinder.cpp @@ -381,27 +381,34 @@ namespace BINDER_SPACE ReleaseHolder pSystemAssembly; - StackSString sCoreLibDir(systemDirectory); - if (!sCoreLibDir.EndsWith(DIRECTORY_SEPARATOR_CHAR_W)) - { - sCoreLibDir.Append(DIRECTORY_SEPARATOR_CHAR_W); - } - - StackSString sCoreLib(sCoreLibDir); - StackSString coreLibName(CoreLibName_IL_W); - sCoreLib.Append(coreLibName); - // At run-time, System.Private.CoreLib.dll is expected to be the NI image. // System.Private.CoreLib.dll is expected to be found at one of the following locations: // * Non-single-file app: In systemDirectory, beside coreclr.dll // * Framework-dependent single-file app: In systemDirectory, beside coreclr.dll // * Self-contained single-file app: Within the single-file bundle. + // + // CoreLib path (sCoreLib): + // * Absolute path when looking for a file on disk + // * Bundle-relative path when looking within the single-file bundle. + + StackSString sCoreLibName(CoreLibName_IL_W); + StackSString sCoreLib; + BinderTracing::PathSource pathSource = BinderTracing::PathSource::Bundle; + BundleFileLocation bundleFileLocation = Bundle::ProbeAppBundle(sCoreLibName, /*pathIsBundleRelative */ true); + if (!bundleFileLocation.IsValid()) + { + sCoreLib.Set(systemDirectory); + pathSource = BinderTracing::PathSource::ApplicationAssemblies; + } + CombinePath(sCoreLib, sCoreLibName, sCoreLib); + IF_FAIL_GO(AssemblyBinder::GetAssembly(sCoreLib, - TRUE /* fIsInGAC */, - fBindToNativeImage, - &pSystemAssembly, - NULL /* szMDAssemblyPath */, - Bundle::ProbeAppBundle(coreLibName, /*pathIsBundleRelative */ true))); + TRUE /* fIsInGAC */, + fBindToNativeImage, + &pSystemAssembly, + NULL /* szMDAssemblyPath */, + bundleFileLocation)); + BinderTracing::PathProbed(sCoreLib, pathSource, hr); *ppSystemAssembly = pSystemAssembly.Extract(); @@ -411,10 +418,10 @@ namespace BINDER_SPACE /* static */ - HRESULT AssemblyBinder::BindToSystemSatellite(SString &systemDirectory, - SString &simpleName, - SString &cultureName, - Assembly **ppSystemAssembly) + HRESULT AssemblyBinder::BindToSystemSatellite(SString& systemDirectory, + SString& simpleName, + SString& cultureName, + Assembly** ppSystemAssembly) { // Indirect check that binder was initialized. _ASSERTE(g_BinderVariables != NULL); @@ -438,8 +445,18 @@ namespace BINDER_SPACE // append extension relativePath.Append(W(".dll")); - // Satellite assembly's absolute path - StackSString sMscorlibSatellite(systemDirectory); + // Satellite assembly's path: + // * Absolute path when looking for a file on disk + // * Bundle-relative path when looking within the single-file bundle. + StackSString sMscorlibSatellite; + + BinderTracing::PathSource pathSource = BinderTracing::PathSource::Bundle; + BundleFileLocation bundleFileLocation = Bundle::ProbeAppBundle(relativePath, /*pathIsBundleRelative */ true); + if (!bundleFileLocation.IsValid()) + { + sMscorlibSatellite.Set(systemDirectory); + pathSource = BinderTracing::PathSource::ApplicationAssemblies; + } CombinePath(sMscorlibSatellite, relativePath, sMscorlibSatellite); ReleaseHolder pSystemAssembly; @@ -448,7 +465,8 @@ namespace BINDER_SPACE FALSE /* fExplicitBindToNativeImage */, &pSystemAssembly, NULL /* szMDAssemblyPath */, - Bundle::ProbeAppBundle(relativePath, /*pathIsBundleRelative */ true))); + bundleFileLocation)); + BinderTracing::PathProbed(sMscorlibSatellite, pathSource, hr); *ppSystemAssembly = pSystemAssembly.Extract(); @@ -735,36 +753,75 @@ namespace BINDER_SPACE namespace { - typedef void (*OnPathProbed)(const WCHAR *path, HRESULT hr); - - HRESULT BindSatelliteResourceByProbingPaths( - const StringArrayList *pResourceRoots, - AssemblyName *pRequestedAssemblyName, - BindResult *pBindResult, - OnPathProbed onPathProbed) + HRESULT BindSatelliteResourceFromBundle( + AssemblyName* pRequestedAssemblyName, + SString &relativePath, + BindResult* pBindResult) { HRESULT hr = S_OK; - SString &simpleNameRef = pRequestedAssemblyName->GetSimpleName(); - SString &cultureRef = pRequestedAssemblyName->GetCulture(); + BundleFileLocation bundleFileLocation = Bundle::ProbeAppBundle(relativePath, /* pathIsBundleRelative */ true); + if (!bundleFileLocation.IsValid()) + { + return hr; + } - _ASSERTE(!cultureRef.IsEmpty() && !cultureRef.EqualsCaseInsensitive(g_BinderVariables->cultureNeutral)); + ReleaseHolder pAssembly; + hr = AssemblyBinder::GetAssembly(relativePath, + FALSE /* fIsInGAC */, + FALSE /* fExplicitBindToNativeImage */, + &pAssembly, + NULL, // szMDAssemblyPath + bundleFileLocation); + + BinderTracing::PathProbed(relativePath, BinderTracing::PathSource::Bundle, hr); + + // Missing files are okay and expected when probing + if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) + { + return S_OK; + } + + pBindResult->SetAttemptResult(hr, pAssembly); + if (FAILED(hr)) + return hr; + + AssemblyName* pBoundAssemblyName = pAssembly->GetAssemblyName(); + if (TestCandidateRefMatchesDef(pRequestedAssemblyName, pBoundAssemblyName, false /*tpaListAssembly*/)) + { + pBindResult->SetResult(pAssembly); + hr = S_OK; + } + else + { + hr = FUSION_E_REF_DEF_MISMATCH; + } + + pBindResult->SetAttemptResult(hr, pAssembly); + return hr; + } + + HRESULT BindSatelliteResourceByProbingPaths( + const StringArrayList *pResourceRoots, + AssemblyName *pRequestedAssemblyName, + SString &relativePath, + BindResult *pBindResult, + BinderTracing::PathSource pathSource) + { + HRESULT hr = S_OK; for (UINT i = 0; i < pResourceRoots->GetCount(); i++) { ReleaseHolder pAssembly; SString &wszBindingPath = (*pResourceRoots)[i]; SString fileName(wszBindingPath); - - CombinePath(fileName, cultureRef, fileName); - CombinePath(fileName, simpleNameRef, fileName); - fileName.Append(W(".dll")); + CombinePath(fileName, relativePath, fileName); hr = AssemblyBinder::GetAssembly(fileName, FALSE /* fIsInGAC */, FALSE /* fExplicitBindToNativeImage */, &pAssembly); - onPathProbed(fileName, hr); + BinderTracing::PathProbed(fileName, pathSource, hr); // Missing files are okay and expected when probing if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) @@ -795,6 +852,59 @@ namespace BINDER_SPACE return S_OK; } + HRESULT BindSatelliteResource( + ApplicationContext* pApplicationContext, + AssemblyName* pRequestedAssemblyName, + BindResult* pBindResult) + { + // Satellite resource probing strategy is to look: + // * First within the single-file bundle + // * Then under each of the Platform Resource Roots + // * Then under each of the App Paths. + // + // During each search, if we find a platform resource file with matching file name, but whose ref-def didn't match, + // fall back to application resource lookup to handle case where a user creates resources with the same + // names as platform ones. + + HRESULT hr = S_OK; + SString& simpleNameRef = pRequestedAssemblyName->GetSimpleName(); + SString& cultureRef = pRequestedAssemblyName->GetCulture(); + + _ASSERTE(!cultureRef.IsEmpty() && !cultureRef.EqualsCaseInsensitive(g_BinderVariables->cultureNeutral)); + + ReleaseHolder pAssembly; + SString fileName; + CombinePath(fileName, cultureRef, fileName); + CombinePath(fileName, simpleNameRef, fileName); + fileName.Append(W(".dll")); + + hr = BindSatelliteResourceFromBundle(pRequestedAssemblyName, fileName, pBindResult); + + if (pBindResult->HaveResult() || (FAILED(hr) && hr != FUSION_E_CONFIGURATION_ERROR)) + { + return hr; + } + + hr = BindSatelliteResourceByProbingPaths(pApplicationContext->GetPlatformResourceRoots(), + pRequestedAssemblyName, + fileName, + pBindResult, + BinderTracing::PathSource::PlatformResourceRoots); + + if (pBindResult->HaveResult() || (FAILED(hr) && hr != FUSION_E_CONFIGURATION_ERROR)) + { + return hr; + } + + hr = BindSatelliteResourceByProbingPaths(pApplicationContext->GetAppPaths(), + pRequestedAssemblyName, + fileName, + pBindResult, + BinderTracing::PathSource::AppPaths); + + return hr; + } + HRESULT BindAssemblyByProbingPaths( const StringArrayList *pBindingPaths, AssemblyName *pRequestedAssemblyName, @@ -802,7 +912,6 @@ namespace BINDER_SPACE Assembly **ppAssembly) { SString &simpleName = pRequestedAssemblyName->GetSimpleName(); - BinderTracing::PathSource pathSource = useNativeImages ? BinderTracing::PathSource::AppNativeImagePaths : BinderTracing::PathSource::AppPaths; // Loop through the binding paths looking for a matching assembly for (DWORD i = 0; i < pBindingPaths->GetCount(); i++) @@ -896,31 +1005,7 @@ namespace BINDER_SPACE if (!culture.IsEmpty() && !culture.EqualsCaseInsensitive(g_BinderVariables->cultureNeutral)) { - // - // Satellite resource probing strategy is to look under each of the Platform Resource Roots - // followed by App Paths. - // - - hr = BindSatelliteResourceByProbingPaths(pApplicationContext->GetPlatformResourceRoots(), - pRequestedAssemblyName, - pBindResult, - [](const WCHAR *path, HRESULT res) { BinderTracing::PathProbed(path, BinderTracing::PathSource::PlatformResourceRoots, res); }); - - // We found a platform resource file with matching file name, but whose ref-def didn't match. Fall - // back to application resource lookup to handle case where a user creates resources with the same - // names as platform ones. - if (hr != FUSION_E_CONFIGURATION_ERROR) - { - IF_FAIL_GO(hr); - } - - if (!pBindResult->HaveResult()) - { - IF_FAIL_GO(BindSatelliteResourceByProbingPaths(pApplicationContext->GetAppPaths(), - pRequestedAssemblyName, - pBindResult, - [](const WCHAR *path, HRESULT res) { BinderTracing::PathProbed(path, BinderTracing::PathSource::AppPaths, res); })); - } + IF_FAIL_GO(BindSatelliteResource(pApplicationContext, pRequestedAssemblyName, pBindResult)); } else { @@ -934,7 +1019,9 @@ namespace BINDER_SPACE // If found, the assembly is loaded from the bundle. if (Bundle::AppIsBundle()) { - SString candidates[] = { W(".dll"), W(".ni.dll") }; + // Search Assembly.ni.dll, then Assembly.dll + // The Assembly.ni.dll paths are rare, and intended for supporting managed C++ R2R assemblies. + SString candidates[] = { W(".ni.dll"), W(".dll") }; // Loop through the binding paths looking for a matching assembly for (int i = 0; i < 2; i++) @@ -945,24 +1032,30 @@ namespace BINDER_SPACE SString assemblyFilePath(Bundle::AppBundle->BasePath()); assemblyFilePath.Append(assemblyFileName); - hr = GetAssembly(assemblyFilePath, - TRUE, // fIsInGAC - FALSE, // fExplicitBindToNativeImage - &pTPAAssembly, - NULL, // szMDAssemblyPath - Bundle::ProbeAppBundle(assemblyFileName, /* pathIsBundleRelative */ true)); - - if (hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) + BundleFileLocation bundleFileLocation = Bundle::ProbeAppBundle(assemblyFileName, /* pathIsBundleRelative */ true); + if (bundleFileLocation.IsValid()) { - // Any other error is fatal - IF_FAIL_GO(hr); + hr = GetAssembly(assemblyFilePath, + TRUE, // fIsInGAC + FALSE, // fExplicitBindToNativeImage + &pTPAAssembly, + NULL, // szMDAssemblyPath + bundleFileLocation); + + BinderTracing::PathProbed(assemblyFilePath, BinderTracing::PathSource::Bundle, hr); - if (TestCandidateRefMatchesDef(pRequestedAssemblyName, pTPAAssembly->GetAssemblyName(), true /*tpaListAssembly*/)) + if (hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { - // We have found the requested assembly match in the bundle with validation of the full-qualified name. - // Bind to it. - pBindResult->SetResult(pTPAAssembly); - GO_WITH_HRESULT(S_OK); + // Any other error is fatal + IF_FAIL_GO(hr); + + if (TestCandidateRefMatchesDef(pRequestedAssemblyName, pTPAAssembly->GetAssemblyName(), true /*tpaListAssembly*/)) + { + // We have found the requested assembly match in the bundle with validation of the full-qualified name. + // Bind to it. + pBindResult->SetResult(pTPAAssembly); + GO_WITH_HRESULT(S_OK); + } } } } diff --git a/src/coreclr/src/binder/inc/bindertracing.h b/src/coreclr/src/binder/inc/bindertracing.h index 472197bf5b4e3..6fb5137349e02 100644 --- a/src/coreclr/src/binder/inc/bindertracing.h +++ b/src/coreclr/src/binder/inc/bindertracing.h @@ -180,7 +180,8 @@ namespace BinderTracing AppNativeImagePaths, AppPaths, PlatformResourceRoots, - SatelliteSubdirectory + SatelliteSubdirectory, + Bundle }; void PathProbed(const WCHAR *path, PathSource source, HRESULT hr); diff --git a/src/coreclr/src/binder/utils.cpp b/src/coreclr/src/binder/utils.cpp index 27f1d4c6b3f6d..953da35d8ffa3 100644 --- a/src/coreclr/src/binder/utils.cpp +++ b/src/coreclr/src/binder/utils.cpp @@ -80,7 +80,7 @@ namespace BINDER_SPACE SString platformPathSeparator(SString::Literal, GetPlatformPathSeparator()); combinedPath.Set(pathA); - if (!combinedPath.EndsWith(platformPathSeparator)) + if (!combinedPath.IsEmpty() && !combinedPath.EndsWith(platformPathSeparator)) { combinedPath.Append(platformPathSeparator); } diff --git a/src/installer/test/Assets/TestProjects/AppWithWait/Program.cs b/src/installer/test/Assets/TestProjects/AppWithWait/Program.cs index f6f9749cb03b3..3c1c12a346958 100644 --- a/src/installer/test/Assets/TestProjects/AppWithWait/Program.cs +++ b/src/installer/test/Assets/TestProjects/AppWithWait/Program.cs @@ -5,6 +5,7 @@ using System; using System.IO; using System.Threading; +using System.Reflection; namespace AppWithSubDirs { @@ -21,6 +22,10 @@ public static void Main(string[] args) string waitFile = args[0]; string resumeFile = args[1]; + // Once this app creates the waitFile and yeilds control, the test-harness renames this single-file app bundle. + // Therefore, any assemblies loaded directly from the bundle, should be loaded before creating the waitFile. + Assembly.Load("System.Memory"); + File.Create(waitFile).Close(); Thread.Sleep(200); diff --git a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleRename.cs b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleRename.cs index 581a1155c98f9..8decb64146690 100644 --- a/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleRename.cs +++ b/src/installer/test/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleRename.cs @@ -7,6 +7,7 @@ using Xunit; using Microsoft.DotNet.Cli.Build.Framework; using Microsoft.DotNet.CoreSetup.Test; +using Microsoft.NET.HostModel.Bundle; using BundleTests.Helpers; using System.Threading; @@ -22,38 +23,30 @@ public BundleRename(SharedTestState fixture) } [Theory] - [InlineData(true)] // Test renaming the single-exe during the initial run, when contents are extracted - [InlineData(false)] // Test renaming the single-exe during subsequent runs, when contents are reused - private void Bundle_can_be_renamed_while_running(bool renameFirstRun) + [InlineData(true)] // Test renaming the single-exe when contents are extracted + [InlineData(false)] // Test renaming the single-exe when contents are not extracted + private void Bundle_can_be_renamed_while_running(bool testExtraction) { var fixture = sharedTestState.TestFixture.Copy(); - string singleFile = BundleHelper.BundleApp(fixture); + BundleOptions options = testExtraction ? BundleOptions.BundleAllContent : BundleOptions.None; + string singleFile = BundleHelper.BundleApp(fixture, options); string outputDir = Path.GetDirectoryName(singleFile); string renameFile = Path.Combine(outputDir, Path.GetRandomFileName()); string waitFile = Path.Combine(outputDir, "wait"); string resumeFile = Path.Combine(outputDir, "resume"); - if (!renameFirstRun) - { - Command.Create(singleFile) - .CaptureStdErr() - .CaptureStdOut() - .Execute() - .Should() - .Pass() - .And - .HaveStdOutContaining("Hello World!"); - } - // Once the App starts running, it creates the waitFile, and waits until resumeFile file is created. var singleExe = Command.Create(singleFile, waitFile, resumeFile) .CaptureStdErr() .CaptureStdOut() .Start(); - while (!File.Exists(waitFile) && !singleExe.Process.HasExited) + const int twoMitutes = 120000 /*milliseconds*/; + int waitTime = 0; + while (!File.Exists(waitFile) && !singleExe.Process.HasExited && waitTime < twoMitutes) { Thread.Sleep(100); + waitTime += 100; } Assert.True(File.Exists(waitFile)); @@ -61,7 +54,7 @@ private void Bundle_can_be_renamed_while_running(bool renameFirstRun) File.Move(singleFile, renameFile); File.Create(resumeFile).Close(); - var result = singleExe.WaitForExit(fExpectedToFail: false); + var result = singleExe.WaitForExit(fExpectedToFail: false, twoMitutes); result .Should() From df1045720c8e8e626310be6cf6e5e09dfe2c2266 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Tue, 26 May 2020 18:43:13 +0300 Subject: [PATCH 385/420] Switch to getCacheDir if getExternalFilesDir is not available (#37009) --- .../AndroidAppBuilder/Templates/MonoRunner.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/MonoRunner.java b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/MonoRunner.java index 6cbf3147a0a91..6acedccf6ac2e 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/MonoRunner.java +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Templates/MonoRunner.java @@ -48,7 +48,11 @@ public void onStart() { Context context = getContext(); String filesDir = context.getFilesDir().getAbsolutePath(); String cacheDir = context.getCacheDir().getAbsolutePath(); - String docsDir = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath(); + File docsPath = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS); + if (docsPath == null) { + docsPath = context.getCacheDir(); + } + String docsDir = docsPath.getAbsolutePath(); // unzip libs and test files to filesDir unzipAssets(context, filesDir, "assets.zip"); From a90124ffaadf551fc5d35ea4f42bbcfcb8a0300a Mon Sep 17 00:00:00 2001 From: Matt Mitchell Date: Tue, 26 May 2020 09:06:45 -0700 Subject: [PATCH 386/420] Update hosted pools for publish to BAR (#36832) Reduce contention on the internal build pools --- eng/pipelines/official/stages/publish.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/eng/pipelines/official/stages/publish.yml b/eng/pipelines/official/stages/publish.yml index 260931d01cb43..48171955c3709 100644 --- a/eng/pipelines/official/stages/publish.yml +++ b/eng/pipelines/official/stages/publish.yml @@ -18,8 +18,7 @@ stages: publishUsingPipelines: true dependsOn: PrepareSignedArtifacts pool: - name: NetCoreInternal-Pool - queue: buildpool.windows.10.amd64.vs2017 + vmImage: vs2017-win2016 # Stages-based publishing entry point - template: /eng/common/templates/post-build/post-build.yml From 1692e34e4161fa8ee9d3f92ba0abb2aae93a8b1a Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Tue, 26 May 2020 17:50:18 +0100 Subject: [PATCH 387/420] Document disabling ApiCompat checks (#37011) * Document disabling ApiCompat checks --- docs/coding-guidelines/updating-ref-source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/coding-guidelines/updating-ref-source.md b/docs/coding-guidelines/updating-ref-source.md index b6bcd1ed686fa..6ca0e56cc2629 100644 --- a/docs/coding-guidelines/updating-ref-source.md +++ b/docs/coding-guidelines/updating-ref-source.md @@ -2,7 +2,7 @@ This document provides the steps you need to take to update the reference assemb ## For most assemblies within libraries -1. Implement the API in the source assembly and [build it](../workflow/building/libraries/README.md#building-individual-libraries). +1. Implement the API in the source assembly and [build it](../workflow/building/libraries/README.md#building-individual-libraries). Note that when adding new public types, this might fail with a `TypeMustExist` error. The deadlock can be worked around by disabling the `RunApiCompat` property: `dotnet build /p:RunApiCompat=false`. 2. Run the following command (from the src directory) `msbuild /t:GenerateReferenceAssemblySource` to update the reference assembly**. 3. Navigate to the ref directory and build the reference assembly. 4. Add, build, and run tests. From 0bbdc8e2fefd52bdae62a071ec1b4fdf952f425f Mon Sep 17 00:00:00 2001 From: Josh Schreuder Date: Wed, 27 May 2020 03:15:51 +1000 Subject: [PATCH 388/420] Improve System.Text.Json coverage (#32341) (#36919) * Remove unused method on JsonClassInfo (#32341) * Add test coverage for a couple of validation branches in JsonWriterHelper (#32341) Co-authored-by: Josh Schreuder --- .../Json/Serialization/JsonClassInfo.Cache.cs | 16 ---------------- .../tests/Utf8JsonWriterTests.cs | 10 ++++++++++ 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Cache.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Cache.cs index e9b99527cbc9f..0e88b3fb048c3 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Cache.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Cache.cs @@ -48,22 +48,6 @@ internal sealed partial class JsonClassInfo // Use an array (instead of List) for highest performance. private volatile PropertyRef[]? _propertyRefsSorted; - private Dictionary CreatePropertyCache(int capacity) - { - StringComparer comparer; - - if (Options.PropertyNameCaseInsensitive) - { - comparer = StringComparer.OrdinalIgnoreCase; - } - else - { - comparer = StringComparer.Ordinal; - } - - return new Dictionary(capacity, comparer); - } - public Dictionary CreateParameterCache(int capacity, JsonSerializerOptions options) { if (options.PropertyNameCaseInsensitive) diff --git a/src/libraries/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/libraries/System.Text.Json/tests/Utf8JsonWriterTests.cs index 82ab722487415..5ead06b20c4bc 100644 --- a/src/libraries/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/libraries/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -2982,6 +2982,16 @@ public void WritingTooLargeBase64Bytes(bool formatted, bool skipValidation) Assert.Throws(() => jsonUtf8.WriteBase64StringValue(value.AsSpan(0, 125_000_001))); } + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + Assert.Throws(() => jsonUtf8.WriteBase64String(value.AsSpan(0, 166_666_667), value.AsSpan(0, 1))); + } + + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) + { + Assert.Throws(() => jsonUtf8.WriteBase64String(Encoding.UTF8.GetString(value).ToCharArray().AsSpan(0, 166_666_667), value.AsSpan(0, 1))); + } + using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { Assert.Throws(() => jsonUtf8.WriteBase64StringValue(value)); From 68fd4fbdd448e5bfb8a1bfc70da0fe7fdb5a6864 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Tue, 26 May 2020 11:09:17 -0700 Subject: [PATCH 389/420] Tracking how much memory is committed per object heap (#36731) --- src/coreclr/src/gc/gc.cpp | 149 +++++++++++++++++++++++------------- src/coreclr/src/gc/gcpriv.h | 47 +++++++++++- 2 files changed, 140 insertions(+), 56 deletions(-) diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index c3e52c7540bee..3c26bd5b60e2e 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -192,6 +192,25 @@ BOOL is_induced_blocking (gc_reason reason) (reason == reason_lowmemory_host_blocking)); } +gc_oh_num gen_to_oh(int gen) +{ + switch (gen) + { + case soh_gen0: + return gc_oh_num::soh; + case soh_gen1: + return gc_oh_num::soh; + case soh_gen2: + return gc_oh_num::soh; + case loh_generation: + return gc_oh_num::loh; + case poh_generation: + return gc_oh_num::poh; + default: + return gc_oh_num::none; + } +} + #ifndef DACCESS_COMPILE int64_t qpf; size_t start_time; @@ -2067,7 +2086,6 @@ void qsort1(uint8_t** low, uint8_t** high, unsigned int depth); void* virtual_alloc (size_t size); void* virtual_alloc (size_t size, bool use_large_pages_p); -void virtual_free (void* add, size_t size); /* per heap static initialization */ #if defined(BACKGROUND_GC) && !defined(MULTIPLE_HEAPS) @@ -2151,6 +2169,8 @@ CLRCriticalSection gc_heap::check_commit_cs; size_t gc_heap::current_total_committed = 0; +size_t gc_heap::committed_by_oh[total_oh_count] = {0, 0, 0, 0}; + size_t gc_heap::current_total_committed_bookkeeping = 0; #ifdef SHORT_PLUGS @@ -3950,7 +3970,7 @@ struct initial_memory_details initial_memory_details memory_details; -BOOL reserve_initial_memory (size_t normal_size, size_t large_size, size_t pinned_size, int num_heaps, bool use_large_pages_p) +BOOL gc_heap::reserve_initial_memory (size_t normal_size, size_t large_size, size_t pinned_size, int num_heaps, bool use_large_pages_p) { BOOL reserve_success = FALSE; @@ -4089,7 +4109,7 @@ BOOL reserve_initial_memory (size_t normal_size, size_t large_size, size_t pinne return reserve_success; } -void destroy_initial_memory() +void gc_heap::destroy_initial_memory() { if (memory_details.initial_memory != NULL) { @@ -4109,7 +4129,7 @@ void destroy_initial_memory() virtual_free (memory_details.initial_pinned_heap[0].memory_base, memory_details.block_count*memory_details.block_size_pinned); - } + } else { assert (memory_details.allocation_pattern == initial_memory_details::EACH_BLOCK); @@ -4136,7 +4156,8 @@ heap_segment* make_initial_segment (int gen, int h_number) { void* mem = memory_details.get_initial_memory (gen, h_number); size_t size = memory_details.get_initial_size (gen); - heap_segment* res = gc_heap::make_heap_segment ((uint8_t*)mem, size , h_number); + gc_oh_num oh = gen_to_oh (gen); + heap_segment* res = gc_heap::make_heap_segment ((uint8_t*)mem, size, oh, h_number); return res; } @@ -4203,14 +4224,6 @@ void* virtual_alloc (size_t size, bool use_large_pages_p) return aligned_mem; } -void virtual_free (void* add, size_t size) -{ - GCToOSInterface::VirtualRelease (add, size); - gc_heap::reserved_memory -= size; - dprintf (2, ("Virtual Free size %Id: [%Ix, %Ix[", - size, (size_t)add, (size_t)((uint8_t*)add+size))); -} - static size_t get_valid_segment_size (BOOL large_seg=FALSE) { size_t seg_size, initial_seg_size; @@ -4384,7 +4397,7 @@ gc_heap::soh_get_segment_to_expand() } } - heap_segment* result = get_segment (size, FALSE); + heap_segment* result = get_segment (size, gc_oh_num::soh); if(result) { @@ -4425,8 +4438,10 @@ gc_heap::soh_get_segment_to_expand() //returns 0 in case of allocation failure heap_segment* -gc_heap::get_segment (size_t size, BOOL loh_p) +gc_heap::get_segment (size_t size, gc_oh_num oh) { + assert(oh != gc_oh_num::none); + BOOL uoh_p = (oh == gc_oh_num::loh) || (oh == gc_oh_num::poh); if (heap_hard_limit) return NULL; @@ -4495,11 +4510,11 @@ gc_heap::get_segment (size_t size, BOOL loh_p) void* mem = virtual_alloc (size); if (!mem) { - fgm_result.set_fgm (fgm_reserve_segment, size, loh_p); + fgm_result.set_fgm (fgm_reserve_segment, size, uoh_p); return 0; } - result = gc_heap::make_heap_segment ((uint8_t*)mem, size, heap_number); + result = gc_heap::make_heap_segment ((uint8_t*)mem, size, oh, heap_number); if (result) { @@ -4523,7 +4538,7 @@ gc_heap::get_segment (size_t size, BOOL loh_p) end = (uint8_t*)g_gc_highest_address; } - if (gc_heap::grow_brick_card_tables (start, end, size, result, __this, loh_p) != 0) + if (gc_heap::grow_brick_card_tables (start, end, size, result, __this, uoh_p) != 0) { virtual_free (mem, size); return 0; @@ -4531,7 +4546,7 @@ gc_heap::get_segment (size_t size, BOOL loh_p) } else { - fgm_result.set_fgm (fgm_commit_segment_beg, SEGMENT_INITIAL_COMMIT, loh_p); + fgm_result.set_fgm (fgm_commit_segment_beg, SEGMENT_INITIAL_COMMIT, uoh_p); virtual_free (mem, size); } @@ -4555,11 +4570,11 @@ gc_heap::get_segment (size_t size, BOOL loh_p) return result; } -void release_segment (heap_segment* sg) +void gc_heap::release_segment (heap_segment* sg) { ptrdiff_t delta = 0; FIRE_EVENT(GCFreeSegment_V1, heap_segment_mem(sg)); - virtual_free (sg, (uint8_t*)heap_segment_reserved (sg)-(uint8_t*)sg); + virtual_free (sg, (uint8_t*)heap_segment_reserved (sg)-(uint8_t*)sg, sg); } heap_segment* gc_heap::get_segment_for_uoh (int gen_number, size_t size @@ -4571,7 +4586,8 @@ heap_segment* gc_heap::get_segment_for_uoh (int gen_number, size_t size #ifndef MULTIPLE_HEAPS gc_heap* hp = 0; #endif //MULTIPLE_HEAPS - heap_segment* res = hp->get_segment (size, TRUE); + gc_oh_num oh = gen_to_oh (gen_number); + heap_segment* res = hp->get_segment (size, oh); if (res != 0) { #ifdef MULTIPLE_HEAPS @@ -5541,7 +5557,7 @@ bool gc_heap::virtual_alloc_commit_for_heap (void* addr, size_t size, int h_numb return GCToOSInterface::VirtualCommit(addr, size); } -bool gc_heap::virtual_commit (void* address, size_t size, int h_number, bool* hard_limit_exceeded_p) +bool gc_heap::virtual_commit (void* address, size_t size, gc_oh_num oh, int h_number, bool* hard_limit_exceeded_p) { #ifndef HOST_64BIT assert (heap_hard_limit == 0); @@ -5549,9 +5565,9 @@ bool gc_heap::virtual_commit (void* address, size_t size, int h_number, bool* ha if (heap_hard_limit) { - bool exceeded_p = false; - check_commit_cs.Enter(); + committed_by_oh[oh] += size; + bool exceeded_p = false; if ((current_total_committed + size) > heap_hard_limit) { @@ -5590,6 +5606,8 @@ bool gc_heap::virtual_commit (void* address, size_t size, int h_number, bool* ha if (!commit_succeeded_p && heap_hard_limit) { check_commit_cs.Enter(); + committed_by_oh[oh] -= size; + dprintf (1, ("commit failed, updating %Id to %Id", current_total_committed, (current_total_committed - size))); current_total_committed -= size; @@ -5598,11 +5616,10 @@ bool gc_heap::virtual_commit (void* address, size_t size, int h_number, bool* ha check_commit_cs.Leave(); } - return commit_succeeded_p; } -bool gc_heap::virtual_decommit (void* address, size_t size, int h_number) +bool gc_heap::virtual_decommit (void* address, size_t size, gc_oh_num oh, int h_number) { #ifndef HOST_64BIT assert (heap_hard_limit == 0); @@ -5613,6 +5630,7 @@ bool gc_heap::virtual_decommit (void* address, size_t size, int h_number) if (decommit_succeeded_p && heap_hard_limit) { check_commit_cs.Enter(); + committed_by_oh[oh] -= size; current_total_committed -= size; if (h_number < 0) current_total_committed_bookkeeping -= size; @@ -5622,6 +5640,18 @@ bool gc_heap::virtual_decommit (void* address, size_t size, int h_number) return decommit_succeeded_p; } +void gc_heap::virtual_free (void* add, size_t allocated_size, heap_segment* sg) +{ + assert(!heap_hard_limit); + bool release_succeeded_p = GCToOSInterface::VirtualRelease (add, allocated_size); + if (release_succeeded_p) + { + reserved_memory -= allocated_size; + dprintf (2, ("Virtual Free size %Id: [%Ix, %Ix[", + allocated_size, (size_t)add, (size_t)((uint8_t*)add + allocated_size))); + } +} + class mark { public: @@ -7225,7 +7255,7 @@ uint32_t* gc_heap::make_card_table (uint8_t* start, uint8_t* end) // mark array will be committed separately (per segment). size_t commit_size = alloc_size - ms; - if (!virtual_commit (mem, commit_size)) + if (!virtual_commit (mem, commit_size, gc_oh_num::none)) { dprintf (1, ("Card table commit failed")); GCToOSInterface::VirtualRelease (mem, alloc_size); @@ -7295,7 +7325,7 @@ int gc_heap::grow_brick_card_tables (uint8_t* start, size_t size, heap_segment* new_seg, gc_heap* hp, - BOOL loh_p) + BOOL uoh_p) { uint8_t* la = g_gc_lowest_address; uint8_t* ha = g_gc_highest_address; @@ -7420,7 +7450,7 @@ int gc_heap::grow_brick_card_tables (uint8_t* start, if (!mem) { - set_fgm_result (fgm_grow_table, alloc_size, loh_p); + set_fgm_result (fgm_grow_table, alloc_size, uoh_p); goto fail; } @@ -7431,10 +7461,10 @@ int gc_heap::grow_brick_card_tables (uint8_t* start, // mark array will be committed separately (per segment). size_t commit_size = alloc_size - ms; - if (!virtual_commit (mem, commit_size)) + if (!virtual_commit (mem, commit_size, gc_oh_num::none)) { dprintf (GC_TABLE_LOG, ("Table commit failed")); - set_fgm_result (fgm_commit_table, commit_size, loh_p); + set_fgm_result (fgm_commit_table, commit_size, uoh_p); goto fail; } } @@ -7501,14 +7531,14 @@ int gc_heap::grow_brick_card_tables (uint8_t* start, if (!commit_new_mark_array_global (new_mark_array)) { dprintf (GC_TABLE_LOG, ("failed to commit portions in the mark array for existing segments")); - set_fgm_result (fgm_commit_table, logging_ma_commit_size, loh_p); + set_fgm_result (fgm_commit_table, logging_ma_commit_size, uoh_p); goto fail; } if (!commit_mark_array_new_seg (hp, new_seg, translated_ct, saved_g_lowest_address)) { dprintf (GC_TABLE_LOG, ("failed to commit mark array for the new seg")); - set_fgm_result (fgm_commit_table, logging_ma_commit_size, loh_p); + set_fgm_result (fgm_commit_table, logging_ma_commit_size, uoh_p); goto fail; } } @@ -7625,7 +7655,7 @@ int gc_heap::grow_brick_card_tables (uint8_t* start, if (!commit_mark_array_new_seg (hp, new_seg)) { dprintf (GC_TABLE_LOG, ("failed to commit mark array for the new seg in range")); - set_fgm_result (fgm_commit_table, logging_ma_commit_size, loh_p); + set_fgm_result (fgm_commit_table, logging_ma_commit_size, uoh_p); return -1; } } @@ -9158,11 +9188,12 @@ int gc_heap::object_gennum_plan (uint8_t* o) #pragma optimize("", on) // Go back to command line default optimizations #endif //_MSC_VER && TARGET_X86 -heap_segment* gc_heap::make_heap_segment (uint8_t* new_pages, size_t size, int h_number) +heap_segment* gc_heap::make_heap_segment (uint8_t* new_pages, size_t size, gc_oh_num oh, int h_number) { + assert(oh != gc_oh_num::none); size_t initial_commit = SEGMENT_INITIAL_COMMIT; - if (!virtual_commit (new_pages, initial_commit, h_number)) + if (!virtual_commit (new_pages, initial_commit, oh, h_number)) { return 0; } @@ -9277,15 +9308,22 @@ size_t gc_heap::decommit_heap_segment_pages_worker (heap_segment* seg, size_t size = heap_segment_committed (seg) - page_start; if (size > 0) { - virtual_decommit (page_start, size, heap_number); - dprintf (3, ("Decommitting heap segment [%Ix, %Ix[(%d)", - (size_t)page_start, - (size_t)(page_start + size), - size)); - heap_segment_committed (seg) = page_start; - if (heap_segment_used (seg) > heap_segment_committed (seg)) + bool decommit_succeeded_p = virtual_decommit (page_start, size, heap_segment_oh (seg), heap_number); + if (decommit_succeeded_p) { - heap_segment_used (seg) = heap_segment_committed (seg); + dprintf (3, ("Decommitting heap segment [%Ix, %Ix[(%d)", + (size_t)page_start, + (size_t)(page_start + size), + size)); + heap_segment_committed (seg) = page_start; + if (heap_segment_used (seg) > heap_segment_committed (seg)) + { + heap_segment_used (seg) = heap_segment_committed (seg); + } + } + else + { + dprintf (3, ("Decommitting heap segment failed")); } } return size; @@ -9303,13 +9341,16 @@ void gc_heap::decommit_heap_segment (heap_segment* seg) #endif //BACKGROUND_GC size_t size = heap_segment_committed (seg) - page_start; - virtual_decommit (page_start, size, heap_number); + bool decommit_succeeded_p = virtual_decommit (page_start, size, heap_segment_oh (seg), heap_number); - //re-init the segment object - heap_segment_committed (seg) = page_start; - if (heap_segment_used (seg) > heap_segment_committed (seg)) + if (decommit_succeeded_p) { - heap_segment_used (seg) = heap_segment_committed (seg); + //re-init the segment object + heap_segment_committed (seg) = page_start; + if (heap_segment_used (seg) > heap_segment_committed (seg)) + { + heap_segment_used (seg) = heap_segment_committed (seg); + } } } @@ -10935,7 +10976,7 @@ BOOL gc_heap::grow_heap_segment (heap_segment* seg, uint8_t* high_address, bool* "Growing heap_segment: %Ix high address: %Ix\n", (size_t)seg, (size_t)high_address); - bool ret = virtual_commit (heap_segment_committed (seg), c_size, heap_number, hard_limit_exceeded_p); + bool ret = virtual_commit (heap_segment_committed (seg), c_size, heap_segment_oh (seg), heap_number, hard_limit_exceeded_p); if (ret) { heap_segment_committed (seg) += c_size; @@ -17010,7 +17051,9 @@ BOOL gc_heap::expand_soh_with_minimal_gc() return TRUE; } else + { return FALSE; + } } // Only to be done on the thread that calls restart in a join for server GC @@ -25826,7 +25869,7 @@ BOOL gc_heap::commit_mark_array_by_range (uint8_t* begin, uint8_t* end, uint32_t size)); #endif //SIMPLE_DPRINTF - if (virtual_commit (commit_start, size)) + if (virtual_commit (commit_start, size, gc_oh_num::none)) { // We can only verify the mark array is cleared from begin to end, the first and the last // page aren't necessarily all cleared 'cause they could be used by other segments or @@ -26050,7 +26093,7 @@ void gc_heap::decommit_mark_array_by_seg (heap_segment* seg) if (decommit_start < decommit_end) { - if (!virtual_decommit (decommit_start, size)) + if (!virtual_decommit (decommit_start, size, gc_oh_num::none)) { dprintf (GC_TABLE_LOG, ("decommit on %Ix for %Id bytes failed", decommit_start, size)); diff --git a/src/coreclr/src/gc/gcpriv.h b/src/coreclr/src/gc/gcpriv.h index e9ac7a7bfd15f..ac6e746317889 100644 --- a/src/coreclr/src/gc/gcpriv.h +++ b/src/coreclr/src/gc/gcpriv.h @@ -223,6 +223,7 @@ const int policy_expand = 2; #define JOIN_LOG (MIN_CUSTOM_LOG_LEVEL + 6) #define SPINLOCK_LOG (MIN_CUSTOM_LOG_LEVEL + 7) #define SNOOP_LOG (MIN_CUSTOM_LOG_LEVEL + 8) +#define COMMIT_ACCOUNTING_LOG (MIN_CUSTOM_LOG_LEVEL + 9) // NOTE! This is for HEAP_BALANCE_INSTRUMENTATION // This particular one is special and needs to be well formatted because we @@ -398,6 +399,17 @@ enum gc_tuning_point tuning_deciding_short_on_seg = 5 }; +enum gc_oh_num +{ + soh = 0, + loh = 1, + poh = 2, + none = 3, + total_oh_count = 4 +}; + +gc_oh_num gen_to_oh (int gen); + #if defined(TRACE_GC) && defined(BACKGROUND_GC) static const char * const str_bgc_state[] = { @@ -1138,6 +1150,7 @@ class gc_heap static heap_segment* make_heap_segment (uint8_t* new_pages, size_t size, + gc_oh_num oh, int h_number); static @@ -1269,6 +1282,11 @@ class gc_heap #endif // FEATURE_BASICFREEZE protected: + PER_HEAP_ISOLATED + BOOL reserve_initial_memory (size_t normal_size, size_t large_size, size_t pinned_size, int num_heaps, bool use_large_pages_p); + + PER_HEAP_ISOLATED + void destroy_initial_memory(); PER_HEAP_ISOLATED void walk_heap (walk_fn fn, void* context, int gen_number, BOOL walk_large_object_heap_p); @@ -1631,7 +1649,9 @@ class gc_heap PER_HEAP heap_segment* soh_get_segment_to_expand(); PER_HEAP - heap_segment* get_segment (size_t size, BOOL loh_p); + heap_segment* get_segment (size_t size, gc_oh_num oh); + PER_HEAP_ISOLATED + void release_segment (heap_segment* sg); PER_HEAP_ISOLATED void seg_mapping_table_add_segment (heap_segment* seg, gc_heap* hp); PER_HEAP_ISOLATED @@ -1661,9 +1681,11 @@ class gc_heap PER_HEAP_ISOLATED bool virtual_alloc_commit_for_heap (void* addr, size_t size, int h_number); PER_HEAP_ISOLATED - bool virtual_commit (void* address, size_t size, int h_number=-1, bool* hard_limit_exceeded_p=NULL); + bool virtual_commit (void* address, size_t size, gc_oh_num oh, int h_number=-1, bool* hard_limit_exceeded_p=NULL); + PER_HEAP_ISOLATED + bool virtual_decommit (void* address, size_t size, gc_oh_num oh, int h_number=-1); PER_HEAP_ISOLATED - bool virtual_decommit (void* address, size_t size, int h_number=-1); + void virtual_free (void* add, size_t size, heap_segment* sg=NULL); PER_HEAP void clear_gen0_bricks(); #ifdef BACKGROUND_GC @@ -3367,6 +3389,9 @@ class gc_heap PER_HEAP_ISOLATED size_t current_total_committed; + PER_HEAP_ISOLATED + size_t committed_by_oh[total_oh_count]; + // This is what GC uses for its own bookkeeping. PER_HEAP_ISOLATED size_t current_total_committed_bookkeeping; @@ -4790,6 +4815,22 @@ BOOL heap_segment_uoh_p (heap_segment * inst) return !!(inst->flags & (heap_segment_flags_loh | heap_segment_flags_poh)); } +inline gc_oh_num heap_segment_oh (heap_segment * inst) +{ + if ((inst->flags & heap_segment_flags_loh) != 0) + { + return gc_oh_num::loh; + } + else if ((inst->flags & heap_segment_flags_poh) != 0) + { + return gc_oh_num::poh; + } + else + { + return gc_oh_num::soh; + } +} + #ifdef BACKGROUND_GC inline BOOL heap_segment_decommitted_p (heap_segment * inst) From eef01694a727a20cf1c0999922a164caa728c466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 26 May 2020 20:19:02 +0200 Subject: [PATCH 390/420] Fix binplacing WASM files for in-tree runtime pack (#36985) It got broken by https://github.com/dotnet/runtime/pull/36781. --- eng/liveBuilds.targets | 18 ++++++++++++------ .../projects/netcoreapp/src/netcoreapp.depproj | 7 +------ src/libraries/Native/native-binplace.proj | 6 ++++++ src/libraries/pretest.proj | 1 - src/libraries/restore/runtime/runtime.depproj | 3 --- src/libraries/src.proj | 6 +++++- src/mono/wasm/Makefile | 4 ++-- src/mono/wasm/{wasm.proj => wasm.targets} | 13 ++++--------- .../WasmAppBuilder/WasmAppBuilder.cs | 2 +- 9 files changed, 31 insertions(+), 29 deletions(-) rename src/mono/wasm/{wasm.proj => wasm.targets} (76%) diff --git a/eng/liveBuilds.targets b/eng/liveBuilds.targets index 38755cc50ae19..42cae8568797a 100644 --- a/eng/liveBuilds.targets +++ b/eng/liveBuilds.targets @@ -138,8 +138,6 @@ Include="$(MonoArtifactsPath)\cross\*.*" /> - @@ -176,7 +174,7 @@ $(LibrariesAllBinArtifactsPath)*.dll; $(LibrariesAllBinArtifactsPath)*.pdb" IsNative="" /> - - + $(LibrariesNativeArtifactsPath)wasm\runtimes\debug\dotnet.js; + $(LibrariesNativeArtifactsPath)wasm\runtimes\debug\dotnet.wasm;" + IsNative="true" + NativeSubDirectory="wasm/runtimes/debug/" /> + diff --git a/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj b/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj index 863f359bf3700..f49103041893e 100644 --- a/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj +++ b/src/installer/pkg/projects/netcoreapp/src/netcoreapp.depproj @@ -76,11 +76,6 @@ runtimes/$(PackageRID)/native/include/%(RecursiveDir) - - runtimes/$(PackageRID)/native/wasm/runtimes/%(RecursiveDir) - - runtimes/$(CoreCLRCrossTargetComponentDirName)_$(TargetArchitecture)/native @@ -105,7 +100,7 @@ - + diff --git a/src/libraries/Native/native-binplace.proj b/src/libraries/Native/native-binplace.proj index a17aab30baef9..2cd59c4856f44 100644 --- a/src/libraries/Native/native-binplace.proj +++ b/src/libraries/Native/native-binplace.proj @@ -20,6 +20,12 @@ + + wasm\runtimes\debug\ + + + wasm\runtimes\release\ + diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj index 01ff1b776e79a..94141031b8b85 100644 --- a/src/libraries/pretest.proj +++ b/src/libraries/pretest.proj @@ -18,7 +18,6 @@ - include/%(RecursiveDir) - - wasm/%(RecursiveDir) - diff --git a/src/libraries/src.proj b/src/libraries/src.proj index 35120f01101ee..91225466df011 100644 --- a/src/libraries/src.proj +++ b/src/libraries/src.proj @@ -2,6 +2,7 @@ BuildAllProjects=true + BuildWasmRuntimes @@ -24,8 +25,11 @@ + + + AfterTargets="Build" + DependsOnTargets="$(NativeBinPlaceDependsOnTargets)"> diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile index e652422d1aef3..412ec94a18578 100644 --- a/src/mono/wasm/Makefile +++ b/src/mono/wasm/Makefile @@ -10,7 +10,8 @@ BINDIR?=$(TOP)/artifacts/bin OBJDIR?=$(TOP)/artifacts/obj PINVOKE_TABLE?=$(TOP)/artifacts/obj/mono/Browser.wasm.$(CONFIG)/wasm/pinvoke-table.h MONO_BIN_DIR?=$(BINDIR)/mono/Browser.wasm.$(CONFIG) -SYS_NATIVE_DIR?=$(BINDIR)/native/net5.0-Browser-$(CONFIG)-wasm/ +SYS_NATIVE_DIR?=$(OBJDIR)/native/net5.0-Browser-$(CONFIG)-wasm/System.Native +BUILDS_BIN_DIR?=$(BINDIR)/native/net5.0-Browser-$(CONFIG)-wasm/wasm/runtimes all: build-native @@ -44,7 +45,6 @@ emsdk_env.sh: | provision-wasm MONO_OBJ_DIR=$(OBJDIR)/mono/Browser.wasm.$(CONFIG) MONO_INCLUDE_DIR=$(MONO_BIN_DIR)/include/mono-2.0 -BUILDS_BIN_DIR=$(SYS_NATIVE_DIR)/wasm/runtimes BUILDS_OBJ_DIR=$(MONO_OBJ_DIR)/wasm/runtimes MONO_LIBS = \ $(MONO_BIN_DIR)/{libmono-ee-interp.a,libmonosgen-2.0.a,libmono-ilgen.a,libmono-icall-table.a} \ diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.targets similarity index 76% rename from src/mono/wasm/wasm.proj rename to src/mono/wasm/wasm.targets index 4da46637398e5..0e088e5cb0751 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.targets @@ -1,14 +1,10 @@ - - - $(NetCoreAppCurrent) - + - $(MonoObjDir)wasm/pinvoke-table.h - $(ArtifactsDir)bin\lib-runtime-packs\runtimes\browser-wasm\lib\$(NetCoreAppCurrent) + $(ArtifactsObjDir)wasm/pinvoke-table.h @@ -29,7 +25,7 @@ - + - + diff --git a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs index e2b76bdf4ca11..5261f4c08b276 100644 --- a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -68,7 +68,7 @@ public class WasmAppBuilder : Task foreach (var assembly in Assemblies!.Values) File.Copy (assembly.Location, Path.Join (AppDir, "managed", Path.GetFileName (assembly.Location)), true); foreach (var f in new string [] { "dotnet.wasm", "dotnet.js" }) - File.Copy (Path.Join (RuntimePackDir, "native", "wasm", "release", f), Path.Join (AppDir, f), true); + File.Copy (Path.Join (RuntimePackDir, "native", "wasm", "runtimes", "release", f), Path.Join (AppDir, f), true); File.Copy (MainJS!, Path.Join (AppDir, Path.GetFileName (MainJS!)), true); using (var sw = File.CreateText (Path.Join (AppDir, "mono-config.js"))) { From 076b6c107e088e1b3d138d8761faafab40065a89 Mon Sep 17 00:00:00 2001 From: Anirudh Agnihotry Date: Tue, 26 May 2020 11:44:48 -0700 Subject: [PATCH 391/420] Building coreclr and installer with true sourceBuildFlag (#36854) * Building coreclr and installer with true sourceBuildFlag * removing the old ci leg --- eng/pipelines/global-build.yml | 15 ++++++++++++++- eng/pipelines/libraries/base-job.yml | 12 ++---------- eng/pipelines/libraries/build-job.yml | 4 +--- eng/pipelines/runtime.yml | 18 ------------------ 4 files changed, 17 insertions(+), 32 deletions(-) diff --git a/eng/pipelines/global-build.yml b/eng/pipelines/global-build.yml index 0c75cd5020622..ff9600d83fea6 100644 --- a/eng/pipelines/global-build.yml +++ b/eng/pipelines/global-build.yml @@ -92,4 +92,17 @@ jobs: jobParameters: testGroup: innerloop nameSuffix: Mono_Libraries - buildArgs: -subset mono+libs /p:RuntimeFlavor=Mono \ No newline at end of file + buildArgs: -subset mono+libs /p:RuntimeFlavor=Mono + +# +# SourceBuild Build +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: release + platforms: + - Linux_x64 + jobParameters: + nameSuffix: SourceBuild + buildArgs: /p:DotNetBuildFromSource=true \ No newline at end of file diff --git a/eng/pipelines/libraries/base-job.yml b/eng/pipelines/libraries/base-job.yml index 575f23f31bc4c..b1a801f965789 100644 --- a/eng/pipelines/libraries/base-job.yml +++ b/eng/pipelines/libraries/base-job.yml @@ -5,7 +5,6 @@ parameters: osSubgroup: '' crossrootfsDir: '' framework: '' - isOfficialBuild: false isOfficialAllConfigurations: false isSourceBuild: false liveRuntimeBuildConfig: '' @@ -25,12 +24,8 @@ jobs: - template: /eng/common/templates/job/job.yml parameters: ${{ if notIn(parameters.framework, 'allConfigurations', 'net472') }}: - ${{ if eq(parameters.isSourceBuild, false) }}: - displayName: ${{ format('Libraries {0} {1}{2} {3} {4}', parameters.displayName, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - name: ${{ format('libraries_{0}_{1}{2}_{3}_{4}', parameters.name, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - ${{ if eq(parameters.isSourceBuild, true) }}: - displayName: ${{ format('Libraries {0} {1}{2} {3} {4}', 'Source Build', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - name: ${{ format('libraries_{0}_{1}{2}_{3}_{4}', 'sourcebuild', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + displayName: ${{ format('Libraries {0} {1}{2} {3} {4}', parameters.displayName, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + name: ${{ format('libraries_{0}_{1}{2}_{3}_{4}', parameters.name, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} ${{ if in(parameters.framework, 'allConfigurations', 'net472') }}: displayName: ${{ format('Libraries {0} {1} {2} {3} {4}', parameters.displayName, parameters.osGroup, parameters.framework, parameters.archType, parameters.buildConfig) }} name: ${{ format('libraries_{0}_{1}_{2}{3}_{4}_{5}', parameters.name, parameters.framework, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} @@ -80,9 +75,6 @@ jobs: - _finalFrameworkArg: -allConfigurations - _extraHelixArguments: /p:BuildAllConfigurations=true - - ${{ if eq(parameters.isSourceBuild, true) }}: - - _finalFrameworkArg: /p:DotnetBuildFromSource=true - - ${{ if eq(parameters.isOfficialAllConfigurations, true) }}: - librariesBuildArtifactName: 'libraries_bin_official_allconfigurations' diff --git a/eng/pipelines/libraries/build-job.yml b/eng/pipelines/libraries/build-job.yml index 94df7e9469e34..f33f413f457ee 100644 --- a/eng/pipelines/libraries/build-job.yml +++ b/eng/pipelines/libraries/build-job.yml @@ -5,7 +5,6 @@ parameters: archType: '' crossrootfsDir: '' framework: '' - isSourceBuild: false isOfficialBuild: false isOfficialAllConfigurations: false runtimeVariant: '' @@ -38,7 +37,6 @@ jobs: framework: ${{ parameters.framework }} isOfficialBuild: ${{ parameters.isOfficialBuild }} isOfficialAllConfigurations: ${{ parameters.isOfficialAllConfigurations }} - isSourceBuild: ${{ parameters.isSourceBuild }} liveRuntimeBuildConfig: ${{ parameters.liveRuntimeBuildConfig }} runtimeFlavor: ${{ parameters.runtimeFlavor }} timeoutInMinutes: ${{ parameters.timeoutInMinutes }} @@ -98,7 +96,7 @@ jobs: df -h displayName: Disk Usage after Build - - ${{ if and(eq(parameters.runTests, false), ne(parameters.isSourceBuild, true)) }}: + - ${{ if eq(parameters.runTests, false) }}: - ${{ if ne(parameters.isOfficialBuild, true) }}: - task: CopyFiles@2 displayName: Prepare testhost folder to publish diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index b490d0deeed24..8d69c7586b860 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -550,24 +550,6 @@ jobs: eq(dependencies.checkout.outputs['SetPathVars_libraries.containsChange'], true), eq(variables['isFullMatrix'], true)) -# -# Libraries Sourcebuild Build -# -- template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/libraries/build-job.yml - buildConfig: Release - platforms: - - Linux_x64 - jobParameters: - runTests: false - liveRuntimeBuildConfig: release - isSourceBuild: true - condition: >- - or( - eq(dependencies.checkout.outputs['SetPathVars_libraries.containsChange'], true), - eq(variables['isFullMatrix'], true)) - # # Installer Build and Test # These are always built since they only take like 15 minutes From 1bc70f26fb4b78068b00643df34f836250b3f0ab Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Tue, 26 May 2020 22:52:33 +0300 Subject: [PATCH 392/420] [mono] Remove unaligned apk after Sign step (#37018) We don't need two *.apk files in the output dir --- tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs index 511483a4bcb4d..1833c950c17f6 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs @@ -218,6 +218,8 @@ public class ApkBuilder string alignedApk = Path.Combine(OutputDir, "bin", $"{ProjectName}.apk"); Utils.RunProcess(zipalign, $"-v 4 {apkFile} {alignedApk}", workingDir: OutputDir); + // we don't need the unaligned one any more + File.Delete(apkFile); // 5. Generate key From df3f5d1e3b04280fa312f1ad2fdffd7169c78b58 Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Tue, 26 May 2020 14:03:22 -0700 Subject: [PATCH 393/420] Fix incorrect filtering operation in EventPipeHelper::IsEnabled (#36933) --- src/coreclr/src/vm/eventtrace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/vm/eventtrace.cpp b/src/coreclr/src/vm/eventtrace.cpp index d5099e498c2a6..0725580dc0f23 100644 --- a/src/coreclr/src/vm/eventtrace.cpp +++ b/src/coreclr/src/vm/eventtrace.cpp @@ -7612,7 +7612,7 @@ bool EventPipeHelper::IsEnabled(DOTNET_TRACE_CONTEXT Context, UCHAR Level, ULONG } CONTRACTL_END - if (Level <= Context.EventPipeProvider.Level || Context.EventPipeProvider.Level == 0) + if (Level <= Context.EventPipeProvider.Level) { return (Keyword == (ULONGLONG)0) || (Keyword & Context.EventPipeProvider.EnabledKeywordsBitmask) != 0; } From e899d1106f7154fe4c7a6dfadf0e4f521711f5ef Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 26 May 2020 14:12:51 -0700 Subject: [PATCH 394/420] Bump crossgen2 dependencies (#37017) Unify on the latest version of System.CommandLine --- eng/Versions.props | 1 + .../ILCompiler.Reflection.ReadyToRun.csproj | 4 +- .../ILCompiler.TypeSystem.ReadyToRun.csproj | 4 +- .../crossgen2/crossgen2/crossgen2.csproj | 4 +- .../src/tools/dotnet-pgo/dotnet-pgo.csproj | 6 +- .../src/tools/r2rdump/CommandLineOptions.cs | 52 ++++----- src/coreclr/src/tools/r2rdump/R2RDump.cs | 1 + src/coreclr/src/tools/r2rdump/R2RDump.csproj | 4 +- .../src/tools/r2rtest/CommandLineOptions.cs | 107 ++++++++++-------- src/coreclr/src/tools/r2rtest/Program.cs | 3 +- src/coreclr/src/tools/r2rtest/R2RTest.csproj | 8 +- 11 files changed, 105 insertions(+), 89 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index ef6bf8f04a664..2b3d55fa56220 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -92,6 +92,7 @@ 1.0.5 1.7.0 + 2.0.0-beta1.20253.1 - + diff --git a/src/installer/pkg/projects/netcoreappRIDs.props b/src/installer/pkg/projects/netcoreappRIDs.props index 6826d6cd71c22..706135723a29c 100644 --- a/src/installer/pkg/projects/netcoreappRIDs.props +++ b/src/installer/pkg/projects/netcoreappRIDs.props @@ -36,6 +36,7 @@ + armel From 2586a5c7e5e37ab150f51b3819e2aebefeedee27 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 26 May 2020 15:03:11 -0700 Subject: [PATCH 398/420] Fix bad refcount management in ComWrappers WeakReference test. (#37022) --- .../COM/ComWrappers/WeakReference/WeakReferenceTest.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs b/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs index acde6f6415802..f85138f72c1da 100644 --- a/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs +++ b/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.cs @@ -65,6 +65,7 @@ class TestComWrappers : ComWrappers protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flag) { + Marshal.AddRef(externalComObject); return new WeakReferencableWrapper(externalComObject); } @@ -87,11 +88,6 @@ static void ValidateNativeWeakReference() var obj = (WeakReferencableWrapper)cw.GetOrCreateObjectForComInstance(objRaw, CreateObjectFlags.None); - // The returned WeakReferencableWrapper from ComWrappers takes ownership - // of the ref returned from CreateWeakReferencableObject. - // Call Marshal.AddRef to ensure that objRaw owns a reference. - Marshal.AddRef(objRaw); - return (new WeakReference(obj), objRaw); } From a559a1c3686387efbe3ee14173f85b967a054a73 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Tue, 26 May 2020 16:13:15 -0700 Subject: [PATCH 399/420] Add dotnet.js to sign exclusion list (#37033) --- eng/SignCheckExclusionsFile.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/SignCheckExclusionsFile.txt b/eng/SignCheckExclusionsFile.txt index fd2b824540457..dc77ca3e4603c 100644 --- a/eng/SignCheckExclusionsFile.txt +++ b/eng/SignCheckExclusionsFile.txt @@ -12,3 +12,4 @@ *apphosttemplateapphostexe.exe;;Template, https://github.com/dotnet/core-setup/pull/7549 *comhosttemplatecomhostdll.dll;;Template, https://github.com/dotnet/core-setup/pull/7549 *staticapphosttemplateapphostexe.exe;;Template, https://github.com/dotnet/core-setup/pull/7549 +*dotnet.js;;Workaround, https://github.com/dotnet/core-eng/issues/9933 From f987b3bc8f8a4d49ca1fc8821a48a7614dfee7cd Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Tue, 26 May 2020 16:26:53 -0700 Subject: [PATCH 400/420] Simple sideloaded profile guided optimization support (#36887) 1. Add code so the runtime can read profile data from a text file and then make this data available to the jit, so it will be easier to test the jit's behavior when profile data is available. 2. Add code so the runtime can create profile text files by telling the jit to insert probes into jitted code that write into a persistent buffer, which is saved to text at shutdown. This is mainly intended to make creation of the sideloaded profile data files easier, since their internal structure must exactly match artifacts from jitted methods. 3. Add a mode where jit-instrumented Tier0 code can feed counts into Tier1 jitting. This is an experiment to see what benefit, if any, might accrue from having profile data available for Tier1 jitting. External format is text so it can be edited by hand or checked into the repo alongside tests. Binary format would be more compact but opaque. In all cases the jit internally sees a profile buffer identical to the one it sees with IBC; the only minor changes in the jit are to initialize the count field of each probe entry to zero and to only emit the entry helper call for prejitted IBC. Only root methods are instrumented, and only root method blocks are given profile weights. Broadening to handle inlinees is future work, facilitated by the new capabilites added here. --- .../templates/runtimes/run-test-job.yml | 1 + src/coreclr/clrdefinitions.cmake | 1 + src/coreclr/src/inc/clrconfigvalues.h | 10 + src/coreclr/src/jit/flowgraph.cpp | 82 ++-- src/coreclr/src/vm/CMakeLists.txt | 2 + src/coreclr/src/vm/ceemain.cpp | 9 + src/coreclr/src/vm/jitinterface.cpp | 85 +++- src/coreclr/src/vm/pgo.cpp | 368 ++++++++++++++++++ src/coreclr/src/vm/pgo.h | 72 ++++ src/coreclr/tests/testenvironment.proj | 2 + 10 files changed, 584 insertions(+), 48 deletions(-) create mode 100644 src/coreclr/src/vm/pgo.cpp create mode 100644 src/coreclr/src/vm/pgo.h diff --git a/eng/pipelines/common/templates/runtimes/run-test-job.yml b/eng/pipelines/common/templates/runtimes/run-test-job.yml index d93d842be6598..a98e8cd1c57cf 100644 --- a/eng/pipelines/common/templates/runtimes/run-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/run-test-job.yml @@ -453,6 +453,7 @@ jobs: - jitguardeddevirtualization - jitehwritethru - jitobjectstackallocation + - jitpgo # Publish Logs - task: PublishPipelineArtifact@1 diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index aa071ea69fe3d..469e009027109 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -195,6 +195,7 @@ add_compile_definitions($<$>>:F if (CLR_CMAKE_TARGET_ARCH_AMD64) add_compile_definitions($<$>>:FEATURE_ON_STACK_REPLACEMENT>) endif (CLR_CMAKE_TARGET_ARCH_AMD64) +add_compile_definitions($<$>>:FEATURE_PGO>) if (CLR_CMAKE_TARGET_WIN32) add_definitions(-DFEATURE_TYPEEQUIVALENCE) endif(CLR_CMAKE_TARGET_WIN32) diff --git a/src/coreclr/src/inc/clrconfigvalues.h b/src/coreclr/src/inc/clrconfigvalues.h index bd1b8d18d4958..109c3c8355301 100644 --- a/src/coreclr/src/inc/clrconfigvalues.h +++ b/src/coreclr/src/inc/clrconfigvalues.h @@ -619,6 +619,16 @@ CONFIG_DWORD_INFO(INTERNAL_OSR_LowId, W("OSR_LowId"), (DWORD)-1, "Low end of ena CONFIG_DWORD_INFO(INTERNAL_OSR_HighId, W("OSR_HighId"), 10000000, "High end of enabled patchpoint range (inclusive)"); #endif +/// +/// Profile Guided Opts +/// +#ifdef FEATURE_PGO +RETAIL_CONFIG_STRING_INFO_EX(INTERNAL_PGODataPath, W("PGODataPath"), "Read/Write PGO data from/to the indicated file.", CLRConfig::EEConfig_default) +RETAIL_CONFIG_DWORD_INFO(INTERNAL_ReadPGOData, W("ReadPGOData"), 0, "Read PGO data") +RETAIL_CONFIG_DWORD_INFO(INTERNAL_WritePGOData, W("WritePGOData"), 0, "Write PGO data") +RETAIL_CONFIG_DWORD_INFO(INTERNAL_TieredPGO, W("TieredPGO"), 0, "Instrument Tier0 code and make counts available to Tier1") +#endif + /// /// Entry point slot backpatch /// diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index 8f66842649037..778962636fb0a 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -271,23 +271,16 @@ void Compiler::fgInstrumentMethod() HRESULT res = info.compCompHnd->allocMethodBlockCounts(countOfBlocks, &profileBlockCountsStart); - Statement* stmt; - if (!SUCCEEDED(res)) { // The E_NOTIMPL status is returned when we are profiling a generic method from a different assembly if (res == E_NOTIMPL) { - // In such cases we still want to add the method entry callback node - - GenTreeCall::Use* args = gtNewCallArgs(gtNewIconEmbMethHndNode(info.compMethodHnd)); - GenTree* call = gtNewHelperCallNode(CORINFO_HELP_BBT_FCN_ENTER, TYP_VOID, args); - - stmt = gtNewStmt(call); + // expected failure... } else { - noway_assert(!"Error: failed to allocate profileBlockCounts"); + noway_assert(!"Error: failed to allocate profileBlockCounts"); return; } } @@ -310,8 +303,8 @@ void Compiler::fgInstrumentMethod() } // Assign the current block's IL offset into the profile data - currentBlockCounts->ILOffset = block->bbCodeOffs; - assert(currentBlockCounts->ExecutionCount == 0); // This value should already be zero-ed out + currentBlockCounts->ILOffset = block->bbCodeOffs; + currentBlockCounts->ExecutionCount = 0; size_t addrOfCurrentExecutionCount = (size_t)¤tBlockCounts->ExecutionCount; @@ -337,50 +330,51 @@ void Compiler::fgInstrumentMethod() // Check that we allocated and initialized the same number of BlockCounts tuples noway_assert(countOfBlocks == 0); - // Add the method entry callback node - - GenTree* arg; + // When prejitting, add the method entry callback node + if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) + { + GenTree* arg; #ifdef FEATURE_READYTORUN_COMPILER - if (opts.IsReadyToRun()) - { - mdMethodDef currentMethodToken = info.compCompHnd->getMethodDefFromMethod(info.compMethodHnd); + if (opts.IsReadyToRun()) + { + mdMethodDef currentMethodToken = info.compCompHnd->getMethodDefFromMethod(info.compMethodHnd); - CORINFO_RESOLVED_TOKEN resolvedToken; - resolvedToken.tokenContext = MAKE_METHODCONTEXT(info.compMethodHnd); - resolvedToken.tokenScope = info.compScopeHnd; - resolvedToken.token = currentMethodToken; - resolvedToken.tokenType = CORINFO_TOKENKIND_Method; + CORINFO_RESOLVED_TOKEN resolvedToken; + resolvedToken.tokenContext = MAKE_METHODCONTEXT(info.compMethodHnd); + resolvedToken.tokenScope = info.compScopeHnd; + resolvedToken.token = currentMethodToken; + resolvedToken.tokenType = CORINFO_TOKENKIND_Method; - info.compCompHnd->resolveToken(&resolvedToken); + info.compCompHnd->resolveToken(&resolvedToken); - arg = impTokenToHandle(&resolvedToken); - } - else + arg = impTokenToHandle(&resolvedToken); + } + else #endif - { - arg = gtNewIconEmbMethHndNode(info.compMethodHnd); - } - - GenTreeCall::Use* args = gtNewCallArgs(arg); - GenTree* call = gtNewHelperCallNode(CORINFO_HELP_BBT_FCN_ENTER, TYP_VOID, args); + { + arg = gtNewIconEmbMethHndNode(info.compMethodHnd); + } - // Get the address of the first blocks ExecutionCount - size_t addrOfFirstExecutionCount = (size_t)&profileBlockCountsStart->ExecutionCount; + GenTreeCall::Use* args = gtNewCallArgs(arg); + GenTree* call = gtNewHelperCallNode(CORINFO_HELP_BBT_FCN_ENTER, TYP_VOID, args); - // Read Basic-Block count value - GenTree* valueNode = gtNewIndOfIconHandleNode(TYP_INT, addrOfFirstExecutionCount, GTF_ICON_BBC_PTR, false); + // Get the address of the first blocks ExecutionCount + size_t addrOfFirstExecutionCount = (size_t)&profileBlockCountsStart->ExecutionCount; - // Compare Basic-Block count value against zero - GenTree* relop = gtNewOperNode(GT_NE, TYP_INT, valueNode, gtNewIconNode(0, TYP_INT)); - GenTree* colon = new (this, GT_COLON) GenTreeColon(TYP_VOID, gtNewNothingNode(), call); - GenTree* cond = gtNewQmarkNode(TYP_VOID, relop, colon); - stmt = gtNewStmt(cond); - } + // Read Basic-Block count value + GenTree* valueNode = gtNewIndOfIconHandleNode(TYP_INT, addrOfFirstExecutionCount, GTF_ICON_BBC_PTR, false); - fgEnsureFirstBBisScratch(); + // Compare Basic-Block count value against zero + GenTree* relop = gtNewOperNode(GT_NE, TYP_INT, valueNode, gtNewIconNode(0, TYP_INT)); + GenTree* colon = new (this, GT_COLON) GenTreeColon(TYP_VOID, gtNewNothingNode(), call); + GenTree* cond = gtNewQmarkNode(TYP_VOID, relop, colon); + Statement* stmt = gtNewStmt(cond); - fgInsertStmtAtEnd(fgFirstBB, stmt); + fgEnsureFirstBBisScratch(); + fgInsertStmtAtEnd(fgFirstBB, stmt); + } + } } /***************************************************************************** diff --git a/src/coreclr/src/vm/CMakeLists.txt b/src/coreclr/src/vm/CMakeLists.txt index c04d5f6219e03..dedb57d041475 100644 --- a/src/coreclr/src/vm/CMakeLists.txt +++ b/src/coreclr/src/vm/CMakeLists.txt @@ -107,6 +107,7 @@ set(VM_SOURCES_DAC_AND_WKS_COMMON peimagelayout.cpp perfmap.cpp perfinfo.cpp + pgo.cpp precode.cpp prestub.cpp profilerdiagnosticprotocolhelper.cpp @@ -218,6 +219,7 @@ set(VM_HEADERS_DAC_AND_WKS_COMMON peimagelayout.inl perfmap.h perfinfo.h + pgo.h precode.h rejit.h rejit.inl diff --git a/src/coreclr/src/vm/ceemain.cpp b/src/coreclr/src/vm/ceemain.cpp index 2d5f4f25b01ff..f80dc4601043b 100644 --- a/src/coreclr/src/vm/ceemain.cpp +++ b/src/coreclr/src/vm/ceemain.cpp @@ -164,6 +164,7 @@ #include "threadsuspend.h" #include "disassembler.h" #include "jithost.h" +#include "pgo.h" #ifndef TARGET_UNIX #include "dwreport.h" @@ -719,6 +720,10 @@ void EEStartupHelper() PerfMap::Initialize(); #endif +#ifdef FEATURE_PGO + PgoManager::Initialize(); +#endif + STRESS_LOG0(LF_STARTUP, LL_ALWAYS, "===================EEStartup Starting==================="); #ifndef CROSSGEN_COMPILE @@ -1313,6 +1318,10 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading) PerfMap::Destroy(); #endif +#ifdef FEATURE_PGO + PgoManager::Shutdown(); +#endif + { // If we're doing basic block profiling, we need to write the log files to disk. static BOOL fIBCLoggingDone = FALSE; diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index 98150ad8e2c47..94f3d1865754d 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -66,6 +66,10 @@ #include "perfmap.h" #endif +#ifdef FEATURE_PGO +#include "pgo.h" +#endif + #include "tailcallhelp.h" // The Stack Overflow probe takes place in the COOPERATIVE_TRANSITION_BEGIN() macro @@ -11807,8 +11811,6 @@ HRESULT CEEJitInfo::allocMethodBlockCounts ( JIT_TO_EE_TRANSITION(); -#ifdef FEATURE_PREJIT - // We need to know the code size. Typically we can get the code size // from m_ILHeader. For dynamic methods, m_ILHeader will be NULL, so // for that case we need to use DynamicResolver to get the code size. @@ -11826,11 +11828,16 @@ HRESULT CEEJitInfo::allocMethodBlockCounts ( codeSize = m_ILHeader->GetCodeSize(); } +#ifdef FEATURE_PREJIT *pBlockCounts = m_pMethodBeingCompiled->GetLoaderModule()->AllocateMethodBlockCounts(m_pMethodBeingCompiled->GetMemberDef(), count, codeSize); hr = (*pBlockCounts != nullptr) ? S_OK : E_OUTOFMEMORY; #else // FEATURE_PREJIT +#ifdef FEATURE_PGO + hr = PgoManager::allocMethodBlockCounts(m_pMethodBeingCompiled, count, pBlockCounts, codeSize); +#else _ASSERTE(!"allocMethodBlockCounts not implemented on CEEJitInfo!"); hr = E_NOTIMPL; +#endif // !FEATURE_PGO #endif // !FEATURE_PREJIT EE_TO_JIT_TRANSITION(); @@ -11847,9 +11854,55 @@ HRESULT CEEJitInfo::getMethodBlockCounts ( UINT32 * pNumRuns ) { - LIMITED_METHOD_CONTRACT; + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + HRESULT hr = E_FAIL; + *pCount = 0; + *pBlockCounts = NULL; + *pNumRuns = 0; + + JIT_TO_EE_TRANSITION(); + +#ifdef FEATURE_PGO + + // For now, only return the info for the method being jitted. + // Will need to fix this to gain access to pgo data for inlinees. + MethodDesc* pMD = (MethodDesc*)ftnHnd; + + if (pMD == m_pMethodBeingCompiled) + { + unsigned codeSize = 0; + if (pMD->IsDynamicMethod()) + { + unsigned stackSize, ehSize; + CorInfoOptions options; + DynamicResolver * pResolver = m_pMethodBeingCompiled->AsDynamicMethodDesc()->GetResolver(); + pResolver->GetCodeInfo(&codeSize, &stackSize, &options, &ehSize); + } + else + { + codeSize = m_ILHeader->GetCodeSize(); + } + + hr = PgoManager::getMethodBlockCounts(pMD, codeSize, pCount, pBlockCounts, pNumRuns); + } + else + { + hr = E_NOTIMPL; + } + +#else _ASSERTE(!"getMethodBlockCounts not implemented on CEEJitInfo!"); - return E_NOTIMPL; + hr = E_NOTIMPL; +#endif + + EE_TO_JIT_TRANSITION(); + + return hr; } void CEEJitInfo::allocMem ( @@ -12572,6 +12625,30 @@ CORJIT_FLAGS GetCompileFlags(MethodDesc * ftn, CORJIT_FLAGS flags, CORINFO_METHO flags.Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO); } +#ifdef FEATURE_PGO + + if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_WritePGOData) > 0) + { + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR); + } + else if ((CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TieredPGO) > 0) + && flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_TIER0)) + { + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR); + } + + if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_ReadPGOData) > 0) + { + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_BBOPT); + } + else if ((CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TieredPGO) > 0) + && flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_TIER1)) + { + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_BBOPT); + } + +#endif + return flags; } diff --git a/src/coreclr/src/vm/pgo.cpp b/src/coreclr/src/vm/pgo.cpp new file mode 100644 index 0000000000000..3d1826b7eba3b --- /dev/null +++ b/src/coreclr/src/vm/pgo.cpp @@ -0,0 +1,368 @@ +// 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. + +#include "common.h" +#include "log.h" +#include "pgo.h" + +#ifdef FEATURE_PGO + +ICorJitInfo::BlockCounts* PgoManager::s_PgoData; +unsigned PgoManager::s_PgoIndex; +const char* const PgoManager::s_FileHeaderString = "*** START PGO Data, max index = %u ***\n"; +const char* const PgoManager::s_FileTrailerString = "*** END PGO Data ***\n"; +const char* const PgoManager::s_MethodHeaderString = "@@@ token 0x%08X hash 0x%08X ilSize 0x%08X records 0x%08X index %u\n"; +const char* const PgoManager::s_RecordString = "ilOffs %u count %u\n"; + +void PgoManager::Initialize() +{ + LIMITED_METHOD_CONTRACT; + + // If any PGO mode is active, allocate the slab + if ((CLRConfig::GetConfigValue(CLRConfig::INTERNAL_ReadPGOData) > 0) || + (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_WritePGOData) > 0) || + (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TieredPGO) > 0)) + { + s_PgoData = new ICorJitInfo::BlockCounts[BUFFER_SIZE]; + s_PgoIndex = 0; + } + + // If we're reading in counts, do that now + ReadPgoData(); +} + +void PgoManager::Shutdown() +{ + WritePgoData(); +} + +void PgoManager::WritePgoData() +{ + if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_WritePGOData) == 0) + { + return; + } + + if (s_PgoData == NULL) + { + return; + } + + CLRConfigStringHolder fileName(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_PGODataPath)); + + if (fileName == NULL) + { + return; + } + + FILE* const pgoDataFile = _wfopen(fileName, W("w")); + + if (pgoDataFile == NULL) + { + return; + } + + fprintf(pgoDataFile, s_FileHeaderString, s_PgoIndex); + unsigned index = 0; + const unsigned maxIndex = s_PgoIndex; + + while (index < maxIndex) + { + const Header* const header = (Header*)&s_PgoData[index]; + + if ((header->recordCount < MIN_RECORD_COUNT) || (header->recordCount > MAX_RECORD_COUNT)) + { + fprintf(pgoDataFile, "Unreasonable record count %u at index %u\n", header->recordCount, index); + break; + } + + fprintf(pgoDataFile, s_MethodHeaderString, header->token, header->hash, header->ilSize, header->recordCount, index); + + index += 2; + + ICorJitInfo::BlockCounts* records = &s_PgoData[index]; + unsigned recordCount = header->recordCount - 2; + unsigned lastOffset = 0; + for (unsigned i = 0; i < recordCount; i++) + { + const unsigned thisOffset = records[i].ILOffset; + assert((thisOffset > lastOffset) || (lastOffset == 0)); + lastOffset = thisOffset; + fprintf(pgoDataFile, s_RecordString, records[i].ILOffset, records[i].ExecutionCount); + } + + index += recordCount; + } + + fprintf(pgoDataFile, s_FileTrailerString); + fclose(pgoDataFile); +} + +void PgoManager::ReadPgoData() +{ + // Skip, if we're not reading, or we're writing profile data, or doing tiered pgo + // + if ((CLRConfig::GetConfigValue(CLRConfig::INTERNAL_WritePGOData) > 0) || + (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TieredPGO) > 0) || + (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_ReadPGOData) == 0)) + { + return; + } + + // PGO data slab should already be set up, if not, just bail + // + if (s_PgoData == NULL) + { + return; + } + + CLRConfigStringHolder fileName(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_PGODataPath)); + + if (fileName == NULL) + { + return; + } + + FILE* const pgoDataFile = _wfopen(fileName, W("r")); + + if (pgoDataFile == NULL) + { + return; + } + + char buffer[256]; + unsigned maxIndex = 0; + + // Header must be first line + // + if (fgets(buffer, sizeof(buffer), pgoDataFile) == nullptr) + { + return; + } + + if (sscanf_s(buffer, s_FileHeaderString, &maxIndex) != 1) + { + return; + } + + // Sanity check data will fit into the slab + // + if ((maxIndex == 0) || (maxIndex >= MAX_RECORD_COUNT)) + { + return; + } + + // Fill in the data + // + unsigned index = 0; + unsigned methods = 0; + unsigned probes = 0; + + bool failed = false; + while (!failed) + { + if (fgets(buffer, sizeof(buffer), pgoDataFile) == nullptr) + { + break; + } + + // Find the next method entry line + // + unsigned recordCount = 0; + unsigned token = 0; + unsigned hash = 0; + unsigned ilSize = 0; + unsigned rIndex = 0; + + if (sscanf_s(buffer, s_MethodHeaderString, &token, &hash, &ilSize, &recordCount, &rIndex) != 5) + { + continue; + } + + assert(index == rIndex); + methods++; + + // If there's not enough room left, bail + if ((index + recordCount) > maxIndex) + { + failed = true; + break; + } + + Header* const header = (Header*)&s_PgoData[index]; + + header->recordCount = recordCount; + header->token = token; + header->hash = hash; + header->ilSize = ilSize; + + // Sanity check + // + if ((recordCount < MIN_RECORD_COUNT) || (recordCount > MAX_RECORD_COUNT)) + { + failed = true; + break; + } + + index += 2; + + // Read il data + // + for (unsigned i = 0; i < recordCount - 2; i++) + { + if (fgets(buffer, sizeof(buffer), pgoDataFile) == nullptr) + { + failed = true; + break; + } + + if (sscanf_s(buffer, s_RecordString, &s_PgoData[index].ILOffset, &s_PgoData[index].ExecutionCount) != 2) + { + failed = true; + break; + } + + index++; + } + + probes += recordCount - 2; + } + + s_PgoIndex = maxIndex; +} + +HRESULT PgoManager::allocMethodBlockCounts(MethodDesc* pMD, UINT32 count, + ICorJitInfo::BlockCounts** pBlockCounts, unsigned ilSize) +{ + // Initialize our out param + *pBlockCounts = NULL; + + if (s_PgoData == nullptr) + { + return E_NOTIMPL; + } + + unsigned methodIndex = 0; + unsigned recordCount = count + 2; + + // Look for space in the profile buffer for this method. + // Note other jit invocations may be vying for space concurrently. + // + while (true) + { + const unsigned oldIndex = s_PgoIndex; + const unsigned newIndex = oldIndex + recordCount; + + // If there is no room left for this method, + // that's ok, we just won't profile this method. + // + if (newIndex >= BUFFER_SIZE) + { + return E_NOTIMPL; + } + + const unsigned updatedIndex = InterlockedCompareExchangeT(&s_PgoIndex, newIndex, oldIndex); + + if (updatedIndex == oldIndex) + { + // Found space + methodIndex = oldIndex; + break; + } + } + + // Fill in the header + Header* const header = (Header*)&s_PgoData[methodIndex]; + header->recordCount = recordCount; + header->token = pMD->IsDynamicMethod() ? 0 : pMD->GetMemberDef(); + header->hash = pMD->GetStableHash(); + header->ilSize = ilSize; + + // Return pointer to start of count records + *pBlockCounts = &s_PgoData[methodIndex + 2]; + return S_OK; +} + +HRESULT PgoManager::getMethodBlockCounts(MethodDesc* pMD, unsigned ilSize, UINT32* pCount, + ICorJitInfo::BlockCounts** pBlockCounts, UINT32* pNumRuns) +{ + // Initialize our out params + *pCount = 0; + *pBlockCounts = NULL; + *pNumRuns = 0; + + // Bail if there's no profile data. + // + if (s_PgoData == NULL) + { + return E_NOTIMPL; + } + + // See if we can find counts for this method in the profile buffer. + // + const unsigned maxIndex = s_PgoIndex; + const unsigned token = pMD->IsDynamicMethod() ? 0 : pMD->GetMemberDef(); + const unsigned hash = pMD->GetStableHash(); + + + unsigned index = 0; + unsigned methodsChecked = 0; + + while (index < maxIndex) + { + // The first two "records" of each entry are actually header data + // to identify the method. + // + Header* const header = (Header*)&s_PgoData[index]; + + // Sanity check that header data looks reasonable. If not, just + // fail the lookup. + // + if ((header->recordCount < MIN_RECORD_COUNT) || (header->recordCount > MAX_RECORD_COUNT)) + { + break; + } + + // See if the header info matches the current method. + // + if ((header->token == token) && (header->hash == hash) && (header->ilSize == ilSize)) + { + // Yep, found data. + // + *pBlockCounts = &s_PgoData[index + 2]; + *pCount = header->recordCount - 2; + *pNumRuns = 1; + return S_OK; + } + + index += header->recordCount; + methodsChecked++; + } + + return E_NOTIMPL; +} + +#else + +// Stub version for !FEATURE_PGO builds +// +HRESULT PgoManager::allocMethodBlockCounts(MethodDesc* pMD, UINT32 count, + ICorJitInfo::BlockCounts** pBlockCounts, unsigned ilSize) +{ + pBlockCounts = NULL; + return E_NOTIMPL; +} + +// Stub version for !FEATURE_PGO builds +// +HRESULT PgoManager::getMethodBlockCounts(MethodDesc* pMD, unsigned ilSize, UINT32* pCount, + ICorJitInfo::BlockCounts** pBlockCounts, UINT32* pNumRuns) +{ + pBlockCounts = NULL; + pCount = 0; + pNumRuns = 0; + return E_NOTIMPL; +} + +#endif // FEATURE_PGO diff --git a/src/coreclr/src/vm/pgo.h b/src/coreclr/src/vm/pgo.h new file mode 100644 index 0000000000000..acaf74712c867 --- /dev/null +++ b/src/coreclr/src/vm/pgo.h @@ -0,0 +1,72 @@ +// 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. + +#ifndef PGO_H +#define PGO_H + +// PgoManager handles in-process and out of band profile data for jitted code. +class PgoManager +{ +#ifdef FEATURE_PGO + +public: + + static void Initialize(); + static void Shutdown(); + +#endif // FEATURE_PGO + +public: + + // Allocate a profile block count buffer for a method + static HRESULT allocMethodBlockCounts(MethodDesc* pMD, UINT32 count, + ICorJitInfo::BlockCounts** pBlockCounts, unsigned ilSize); + + // Retreive the profile block count buffer for a method + static HRESULT getMethodBlockCounts(MethodDesc* pMD, unsigned ilSize, UINT32* pCount, + ICorJitInfo::BlockCounts** pBlockCounts, UINT32* pNumRuns); + +#ifdef FEATURE_PGO + +private: + + enum + { + // Number of ICorJitInfo::BlockCount records in the global slab + BUFFER_SIZE = 64 * 1024, + MIN_RECORD_COUNT = 3, + MAX_RECORD_COUNT = BUFFER_SIZE + }; + + struct Header + { + unsigned recordCount; + unsigned token; + unsigned hash; + unsigned ilSize; + }; + +private: + + static void ReadPgoData(); + static void WritePgoData(); + +private: + + // Global slab holding all pgo data + static ICorJitInfo::BlockCounts* s_PgoData; + + // Index of next free entry in the global slab + static unsigned s_PgoIndex; + + // Formatting strings for file input/output + static const char* const s_FileHeaderString; + static const char* const s_FileTrailerString; + static const char* const s_MethodHeaderString; + static const char* const s_RecordString; + +#endif // FEATURE_PGO +}; + +#endif // PGO_H diff --git a/src/coreclr/tests/testenvironment.proj b/src/coreclr/tests/testenvironment.proj index 6bb7dda56ddbb..199382c46df9b 100644 --- a/src/coreclr/tests/testenvironment.proj +++ b/src/coreclr/tests/testenvironment.proj @@ -45,6 +45,7 @@ COMPlus_TC_QuickJitForLoops; COMPlus_TC_OnStackReplacement_InitialCounter; COMPlus_OSR_HitLimit; + COMPlus_TieredPGO; COMPlus_JitEnableGuardedDevirtualization; COMPlus_EnableEHWriteThru; COMPlus_JitObjectStackAllocation @@ -135,6 +136,7 @@ + From 08e04457baeb8cb1aa96687425d1ff4855d925aa Mon Sep 17 00:00:00 2001 From: Anirudh Agnihotry Date: Tue, 26 May 2020 17:43:37 -0700 Subject: [PATCH 401/420] rearrange tfms for intellisense (#37027) --- .../src/Microsoft.Extensions.Hosting.Abstractions.csproj | 2 +- .../src/Microsoft.Extensions.Hosting.csproj | 2 +- src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj | 2 +- .../src/System.Diagnostics.EventLog.csproj | 2 +- .../System.Drawing.Common/src/System.Drawing.Common.csproj | 2 +- src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj | 2 +- .../src/System.Windows.Extensions.csproj | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj index 1996b8d4effcb..2194698876f88 100644 --- a/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/Microsoft.Extensions.Hosting.Abstractions.csproj @@ -1,7 +1,7 @@ - netstandard2.0;$(NetCoreAppCurrent) + $(NetCoreAppCurrent);netstandard2.0 $(NoWarn);CS1591 Microsoft.Extensions.Hosting true diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj index 0333fb952b461..7dc68b6e59196 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj +++ b/src/libraries/Microsoft.Extensions.Hosting/src/Microsoft.Extensions.Hosting.csproj @@ -1,7 +1,7 @@ - netstandard2.0;netstandard2.1;$(NetCoreAppCurrent) + $(NetCoreAppCurrent);netstandard2.0;netstandard2.1 $(NoWarn);CS1591 true diff --git a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj index 33138aca3cfab..553fdae9adbd9 100644 --- a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj +++ b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj @@ -1,7 +1,7 @@ true - netcoreapp2.0-FreeBSD;netcoreapp2.0-Linux;netcoreapp2.0-OSX;netcoreapp2.0-Windows_NT;net461-Windows_NT;netstandard2.0;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;netcoreapp2.0-FreeBSD;netcoreapp2.0-Linux;netcoreapp2.0-OSX;netcoreapp2.0-Windows_NT;net461-Windows_NT;netstandard2.0;$(NetCoreAppCurrent)-FreeBSD;$(NetCoreAppCurrent)-Linux;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS;$(NetCoreAppCurrent)-tvOS;$(NetFrameworkCurrent)-Windows_NT true true diff --git a/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj b/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj index 6a43e6e8dee0d..db056eb6bf984 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj +++ b/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj @@ -1,7 +1,7 @@ true - netcoreapp2.0-Windows_NT;net461;netstandard2.0;$(NetCoreAppCurrent)-Windows_NT;$(NetFrameworkCurrent) + $(NetCoreAppCurrent)-Windows_NT;netcoreapp2.0-Windows_NT;net461;netstandard2.0;$(NetFrameworkCurrent) true true diff --git a/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj b/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj index b165ae7c6e4de..0291615e11c0b 100644 --- a/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj +++ b/src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj @@ -5,7 +5,7 @@ CS0618 $(DefineConstants);FEATURE_WINDOWS_SYSTEM_COLORS;FEATURE_SYSTEM_EVENTS true - netcoreapp3.0-Windows_NT;netcoreapp3.0-Unix;$(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;netcoreapp3.0-Windows_NT;netcoreapp3.0-Unix true enable diff --git a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj index 8cda15170f21e..ae41d45e7d897 100644 --- a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj +++ b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj @@ -2,7 +2,7 @@ System.Net.Sockets true - $(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Windows_NT + $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix enable diff --git a/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj b/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj index 43c366dda9fac..ea77d6793f77f 100644 --- a/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj +++ b/src/libraries/System.Windows.Extensions/src/System.Windows.Extensions.csproj @@ -2,7 +2,7 @@ SR.PlatformNotSupported_System_Windows_Extensions true - netcoreapp3.0-Windows_NT;netcoreapp3.0;$(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent) + $(NetCoreAppCurrent)-Windows_NT;netcoreapp3.0-Windows_NT;netcoreapp3.0;$(NetCoreAppCurrent) true From d3db91a5ef7fb2e8fd976db4c0dc7960c5a791b1 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 26 May 2020 21:55:46 -0500 Subject: [PATCH 402/420] Use nint instead of IntPtr in _RegisterFrozenSegment. (#37029) --- src/coreclr/src/System.Private.CoreLib/src/System/GC.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs index e3e1b54373fa5..a44047cc4d8e9 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs @@ -353,7 +353,7 @@ public static long GetTotalMemory(bool forceFullCollection) } [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] - private static extern IntPtr _RegisterFrozenSegment(IntPtr sectionAddress, IntPtr sectionSize); + private static extern IntPtr _RegisterFrozenSegment(IntPtr sectionAddress, nint sectionSize); [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] private static extern void _UnregisterFrozenSegment(IntPtr segmentHandle); From 4855a4cb67717c15e377a42c450750b769ce0601 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Tue, 26 May 2020 20:02:09 -0700 Subject: [PATCH 403/420] Disable AddThresholdTest in all archs (#37032) --- src/coreclr/tests/issues.targets | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index 0ab601012716a..263b7a1c8d3cd 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -79,7 +79,6 @@ 19441;22020 - https://github.com/dotnet/runtime/issues/3893 @@ -116,9 +115,12 @@ https://github.com/dotnet/runtime/issues/3893 - + + https://github.com/dotnet/runtime/issues/36850 + + This test is to verify we are running mono, and therefore only makes sense on mono. - + @@ -333,9 +335,6 @@ https://github.com/dotnet/runtime/issues/13355 - - https://github.com/dotnet/runtime/issues/36850 - From e2d4ab778ba7dd1c7d85006a3f1579ca3fcc7926 Mon Sep 17 00:00:00 2001 From: Anton Lapounov Date: Tue, 26 May 2020 20:44:23 -0700 Subject: [PATCH 404/420] Align assembler mnemonics and operands in R2RDump (#37034) * Align assembler mnemonics and operands in R2RDump. * For ARM64 images dump instruction bytes as 4-byte hexadecimal integers. * Fix incorrect usage of _methods.Count. * Fix the corrupted R2RFormat.png file. --- .../ReadyToRunMethod.cs | 7 - .../ReadyToRunReader.cs | 3 +- src/coreclr/src/tools/r2rdump/CoreDisTools.cs | 185 +++++++++++++++--- src/coreclr/src/tools/r2rdump/R2RFormat.png | Bin 152543 -> 152550 bytes src/coreclr/src/tools/r2rdump/TextDumper.cs | 8 +- 5 files changed, 158 insertions(+), 45 deletions(-) diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs index c59f99cbd1b3c..ee4290a80ef53 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs @@ -207,11 +207,6 @@ public class ReadyToRunMethod /// public MetadataReader MetadataReader { get; private set; } - /// - /// An unique index for the method - /// - public int Index { get; set; } - /// /// The name of the method /// @@ -288,7 +283,6 @@ public IReadOnlyList Fixups /// public ReadyToRunMethod( ReadyToRunReader readyToRunReader, - int index, MetadataReader metadataReader, EntityHandle methodHandle, int entryPointId, @@ -299,7 +293,6 @@ public IReadOnlyList Fixups { _readyToRunReader = readyToRunReader; _fixupOffset = fixupOffset; - Index = index; MethodHandle = methodHandle; EntryPointRuntimeFunctionId = entryPointId; diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index 3537d6429374a..2da57b2b7b538 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -708,7 +708,7 @@ private void ParseMethodDefEntrypointsSection(ReadyToRunSection section, Metadat int runtimeFunctionId; int? fixupOffset; GetRuntimeFunctionIndexFromOffset(offset, out runtimeFunctionId, out fixupOffset); - ReadyToRunMethod method = new ReadyToRunMethod(this, _methods.Count, metadataReader, methodHandle, runtimeFunctionId, owningType: null, constrainedType: null, instanceArgs: null, fixupOffset: fixupOffset); + ReadyToRunMethod method = new ReadyToRunMethod(this, metadataReader, methodHandle, runtimeFunctionId, owningType: null, constrainedType: null, instanceArgs: null, fixupOffset: fixupOffset); if (method.EntryPointRuntimeFunctionId < 0 || method.EntryPointRuntimeFunctionId >= isEntryPoint.Length) { @@ -793,7 +793,6 @@ private void ParseInstanceMethodEntrypoints(bool[] isEntryPoint) GetRuntimeFunctionIndexFromOffset((int)decoder.Offset, out runtimeFunctionId, out fixupOffset); ReadyToRunMethod method = new ReadyToRunMethod( this, - _methods.Count, mdReader, methodHandle, runtimeFunctionId, diff --git a/src/coreclr/src/tools/r2rdump/CoreDisTools.cs b/src/coreclr/src/tools/r2rdump/CoreDisTools.cs index bbaf801ad3cb6..1f41eab41af66 100644 --- a/src/coreclr/src/tools/r2rdump/CoreDisTools.cs +++ b/src/coreclr/src/tools/r2rdump/CoreDisTools.cs @@ -45,7 +45,7 @@ public enum TargetArch public unsafe static int GetInstruction(IntPtr Disasm, RuntimeFunction rtf, int imageOffset, int rtfOffset, byte[] image, out string instr) { - int instrSize = 1; + int instrSize; fixed (byte* p = image) { IntPtr ptr = (IntPtr)(p + imageOffset + rtfOffset); @@ -58,7 +58,7 @@ public unsafe static int GetInstruction(IntPtr Disasm, RuntimeFunction rtf, int public static IntPtr GetDisasm(Machine machine) { - TargetArch target = TargetArch.Target_Host; + TargetArch target; switch (machine) { case Machine.Amd64: @@ -86,6 +86,16 @@ public static IntPtr GetDisasm(Machine machine) /// public class Disassembler : IDisposable { + /// + /// Indentation of instruction mnemonics in naked mode with no offsets. + /// + private const int NakedNoOffsetIndentation = 4; + + /// + /// Indentation of instruction mnemonics in naked mode with offsets. + /// + private const int NakedWithOffsetIndentation = 11; + /// /// R2R reader is used to access architecture info, the PE image data and symbol table. /// @@ -101,6 +111,16 @@ public class Disassembler : IDisposable /// private readonly IntPtr _disasm; + /// + /// Indentation of instruction mnemonics. + /// + public int MnemonicIndentation { get; private set; } + + /// + /// Indentation of instruction mnemonics. + /// + public int OperandsIndentation { get; private set; } + /// /// Store the R2R reader and construct the disassembler for the appropriate architecture. /// @@ -110,6 +130,7 @@ public Disassembler(ReadyToRunReader reader, DumpOptions options) _reader = reader; _options = options; _disasm = CoreDisTools.GetDisasm(_reader.Machine); + SetIndentations(); } /// @@ -124,7 +145,52 @@ public void Dispose() } /// - /// Parse a single instruction and return the RVA of the next instruction. + /// Set indentations for mnemonics and operands. + /// + private void SetIndentations() + { + if (_options.Naked) + { + MnemonicIndentation = _options.HideOffsets ? NakedNoOffsetIndentation : NakedWithOffsetIndentation; + } + else + { + // The length of the byte dump starting with the first hexadecimal digit and ending with the final space + int byteDumpLength = _reader.Machine switch + { + // Most instructions are no longer than 7 bytes. CorDisasm::dumpInstruction always pads byte dumps + // to 7 * 3 characters; see https://github.com/dotnet/llilc/blob/master/lib/CoreDisTools/coredistools.cpp. + Machine.I386 => 7 * 3, + Machine.Amd64 => 7 * 3, + + // Instructions are either 2 or 4 bytes long + Machine.ArmThumb2 => 4 * 3, + + // Instructions are dumped as 4-byte hexadecimal integers + Machine.Arm64 => 4 * 2 + 1, + + _ => throw new NotImplementedException() + }; + + MnemonicIndentation = NakedWithOffsetIndentation + byteDumpLength; + } + + // This leaves 7 characters for the mnemonic + OperandsIndentation = MnemonicIndentation + 8; + } + + /// + /// Append spaces to the string builder to achieve at least the given indentation. + /// + private static void EnsureIndentation(StringBuilder builder, int lineStartIndex, int desiredIndentation) + { + int currentIndentation = builder.Length - lineStartIndex; + int spacesToAppend = Math.Max(desiredIndentation - currentIndentation, 1); + builder.Append(' ', spacesToAppend); + } + + /// + /// Parse and dump a single instruction and return its size in bytes. /// /// Runtime function to parse /// Offset within the PE image byte array @@ -142,47 +208,108 @@ public int GetInstruction(RuntimeFunction rtf, int imageOffset, int rtfOffset, o int instrSize = CoreDisTools.GetInstruction(_disasm, rtf, imageOffset, rtfOffset, _reader.Image, out instruction); CoreDisTools.ClearOutputBuffer(); - instruction = instruction.Replace('\t', ' '); + // CoreDisTools dumps instructions in the following format: + // + // address: bytes [padding] \t mnemonic [\t operands] \n + // + // However, due to an LLVM issue regarding instruction prefixes (https://bugs.llvm.org/show_bug.cgi?id=7709), + // multiple lines may be returned for a single x86/x64 instruction. - if (_options.Naked) + var builder = new StringBuilder(); + int lineNum = 0; + // The start index of the last line in builder + int lineStartIndex = 0; + + // Remove this foreach wrapper and line* variables after the aforementioned LLVM issue is fixed + foreach (string line in instruction.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)) { - StringBuilder nakedInstruction = new StringBuilder(); - foreach (string line in instruction.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)) + int colonIndex = line.IndexOf(':'); + int tab1Index = line.IndexOf('\t'); + + if ((0 < colonIndex) && (colonIndex < tab1Index)) { - int colon = line.IndexOf(':'); - if (colon >= 0) + // First handle the address and the byte dump + if (_options.Naked) { - colon += 2; - while (colon + 3 <= line.Length && - IsXDigit(line[colon]) && - IsXDigit(line[colon + 1]) && - line[colon + 2] == ' ') + if (!_options.HideOffsets) { - colon += 3; + // All lines but the last one must represent single-byte prefixes, so add lineNum to the offset + builder.Append($"{rtf.CodeOffset + rtfOffset + lineNum,8:x4}:"); } - - if (!_options.HideOffsets) + } + else + { + if (_reader.Machine == Machine.Arm64) { - nakedInstruction.Append($"{(rtfOffset + rtf.CodeOffset),8:x4}:"); - nakedInstruction.Append(" "); + // Replace " hh hh hh hh " byte dump with " hhhhhhhh ". + // CoreDisTools should be fixed to dump bytes this way for ARM64. + uint instructionBytes = BitConverter.ToUInt32(_reader.Image, imageOffset + rtfOffset); + builder.Append(line, 0, colonIndex + 1); + builder.Append(' '); + builder.Append(instructionBytes.ToString("x8")); } else { - nakedInstruction.Append(" "); + // Copy the offset and the byte dump + int byteDumpEndIndex = tab1Index; + do + { + byteDumpEndIndex--; + } + while (line[byteDumpEndIndex] == ' '); + builder.Append(line, 0, byteDumpEndIndex + 1); + } + builder.Append(' '); + } + + // Now handle the mnemonic and operands. Ensure proper indentation for the mnemonic. + EnsureIndentation(builder, lineStartIndex, MnemonicIndentation); + + int tab2Index = line.IndexOf('\t', tab1Index + 1); + if (tab2Index >= 0) + { + // Copy everything between the first and the second tabs + builder.Append(line, tab1Index + 1, tab2Index - tab1Index - 1); + // Ensure proper indentation for the operands + EnsureIndentation(builder, lineStartIndex, OperandsIndentation); + int afterTab2Index = tab2Index + 1; + + // Work around an LLVM issue causing an extra space to be output before operands; + // see https://reviews.llvm.org/D35946. + if ((afterTab2Index < line.Length) && + ((line[afterTab2Index] == ' ') || (line[afterTab2Index] == '\t'))) + { + afterTab2Index++; + } + + // Copy everything after the second tab + int savedLength = builder.Length; + builder.Append(line, afterTab2Index, line.Length - afterTab2Index); + // There should be no extra tabs. Should we encounter them, replace them with a single space. + if (line.IndexOf('\t', afterTab2Index) >= 0) + { + builder.Replace('\t', ' ', savedLength, builder.Length - savedLength); } - nakedInstruction.Append(line.Substring(colon).TrimStart()); - nakedInstruction.Append('\n'); } else { - nakedInstruction.Append(' ', 7); - nakedInstruction.Append(line.TrimStart()); - nakedInstruction.Append('\n'); + // Copy everything after the first tab + builder.Append(line, tab1Index + 1, line.Length - tab1Index - 1); } } - instruction = nakedInstruction.ToString(); + else + { + // Should not happen. Just replace tabs with spaces. + builder.Append(line.Replace('\t', ' ')); + } + + builder.Append('\n'); + lineNum++; + lineStartIndex = builder.Length; } + instruction = builder.ToString(); + switch (_reader.Machine) { case Machine.Amd64: @@ -194,7 +321,6 @@ public int GetInstruction(RuntimeFunction rtf, int imageOffset, int rtfOffset, o break; case Machine.ArmThumb2: - case Machine.Thumb: break; case Machine.Arm64: @@ -208,11 +334,6 @@ public int GetInstruction(RuntimeFunction rtf, int imageOffset, int rtfOffset, o return instrSize; } - private static bool IsXDigit(char c) - { - return Char.IsDigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); - } - const string RelIPTag = "[rip "; /// diff --git a/src/coreclr/src/tools/r2rdump/R2RFormat.png b/src/coreclr/src/tools/r2rdump/R2RFormat.png index f989086c61f7fc0a82de96e47a57ef5632df9634..60b84b6cdbeea8dd99ff096dbc87272b18338c6d 100644 GIT binary patch delta 59 zcmcb=ob%aoPS(x;}jSN delta 46 zcmV+}0MY;ErwQMu2?U8yPDil?-=?$WrkD$}ezNuwvvtK^I diff --git a/src/coreclr/src/tools/r2rdump/TextDumper.cs b/src/coreclr/src/tools/r2rdump/TextDumper.cs index 8491639798ec4..84ff8cc968685 100644 --- a/src/coreclr/src/tools/r2rdump/TextDumper.cs +++ b/src/coreclr/src/tools/r2rdump/TextDumper.cs @@ -134,7 +134,7 @@ internal override void DumpEntryPoints() internal override void DumpAllMethods() { WriteDivider("R2R Methods"); - _writer.WriteLine($"{_r2r.Methods.Count} methods"); + _writer.WriteLine($"{_r2r.Methods.Sum(kvp => kvp.Value.Count)} methods"); SkipLine(); foreach (ReadyToRunMethod method in NormalizedMethods()) { @@ -207,10 +207,10 @@ internal override void DumpRuntimeFunction(RuntimeFunction rtf) /// internal override void DumpDisasm(RuntimeFunction rtf, int imageOffset) { - int indent = (_options.Naked ? _options.HideOffsets ? 4 : 11 : 32); - string indentString = new string(' ', indent); - int rtfOffset = 0; + string indentString = new string(' ', _disassembler.MnemonicIndentation); int codeOffset = rtf.CodeOffset; + int rtfOffset = 0; + while (rtfOffset < rtf.Size) { string instr; From 67a809bac8564fa72f759b549c18427df8262028 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 26 May 2020 20:48:14 -0700 Subject: [PATCH 405/420] Ensure Vector3 inequality doesn't use the hidden 4th element (#36953) * Renable Vector3InequalityTest * Fixing ARM64 LowerHWIntrinsicCmpOp to always treat the extra element of a TYP_SIMD12 as equivalent * Adding a regression test for Vector3InequalityTest * Update src/coreclr/src/jit/lowerarmarch.cpp Co-authored-by: Carol Eidt * Applying formatting patch Co-authored-by: Carol Eidt --- src/coreclr/src/jit/lowerarmarch.cpp | 6 ++-- .../JitBlue/GitHub_36905/GitHub_36905.cs | 35 +++++++++++++++++++ .../JitBlue/GitHub_36905/GitHub_36905.csproj | 10 ++++++ .../tests/Vector3Tests.cs | 1 - 4 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_36905/GitHub_36905.cs create mode 100644 src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_36905/GitHub_36905.csproj diff --git a/src/coreclr/src/jit/lowerarmarch.cpp b/src/coreclr/src/jit/lowerarmarch.cpp index 827645576ec35..c3ac6513e9546 100644 --- a/src/coreclr/src/jit/lowerarmarch.cpp +++ b/src/coreclr/src/jit/lowerarmarch.cpp @@ -706,12 +706,14 @@ void Lowering::LowerHWIntrinsicCmpOp(GenTreeHWIntrinsic* node, genTreeOps cmpOp) if ((baseType == TYP_FLOAT) && (simdSize == 12)) { - // For TYP_SIMD12 we need to clear the upper bits and can't assume their value + // For TYP_SIMD12 we don't want the upper bits to participate in the comparison. So, we will insert all ones + // into those bits of the result, "as if" the upper bits are equal. Then if all lower bits are equal, we get the + // expected all-ones result, and will get the expected 0's only where there are non-matching bits. GenTree* idxCns = comp->gtNewIconNode(3, TYP_INT); BlockRange().InsertAfter(cmp, idxCns); - GenTree* insCns = comp->gtNewIconNode(cmpOp == GT_EQ ? -1 : 0, TYP_INT); + GenTree* insCns = comp->gtNewIconNode(-1, TYP_INT); BlockRange().InsertAfter(idxCns, insCns); GenTree* tmp = diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_36905/GitHub_36905.cs b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_36905/GitHub_36905.cs new file mode 100644 index 0000000000000..eb28530e54270 --- /dev/null +++ b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_36905/GitHub_36905.cs @@ -0,0 +1,35 @@ +// 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. + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; + +public class GitHub_36905 +{ + public static int Main() + { + bool success = true; + + Vector3 a = new Vector3(1.0f, 2.0f, 3.0f); + Vector3 b = new Vector3(1.0f, 2.0f, 3.0f); + + success &= ValidateResult(a == b, expected: true); + success &= ValidateResult(a != b, expected: false); + + Vector3 c = new Vector3(1.0f, 2.0f, 3.0f); + Vector3 d = new Vector3(10.0f, 2.0f, 3.0f); + + success &= ValidateResult(c == d, expected: false); + success &= ValidateResult(c != d, expected: true); + + return success ? 100 : 0; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static bool ValidateResult(bool actual, bool expected) + { + return actual == expected; + } +} diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_36905/GitHub_36905.csproj b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_36905/GitHub_36905.csproj new file mode 100644 index 0000000000000..19781e26c20d8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_36905/GitHub_36905.csproj @@ -0,0 +1,10 @@ + + + Exe + + True + + + + + diff --git a/src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs b/src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs index be50353cc2d06..ec930798c362d 100644 --- a/src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs +++ b/src/libraries/System.Numerics.Vectors/tests/Vector3Tests.cs @@ -967,7 +967,6 @@ public void Vector3NegateTest() // A test for operator != (Vector3f, Vector3f) [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/36905", typeof(PlatformDetection), nameof(PlatformDetection.IsNotArm64Process))] public void Vector3InequalityTest() { Vector3 a = new Vector3(1.0f, 2.0f, 3.0f); From 08ca98da3303ed87bd38b093de682fedd45d0df5 Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Tue, 26 May 2020 21:56:16 -0700 Subject: [PATCH 406/420] Fix a couple of bugs in multi-reg stores (#36994) * Fix a couple of bugs in multi-reg stores Fix #36912 --- src/coreclr/src/jit/codegenarmarch.cpp | 15 ++++++--------- src/coreclr/src/jit/codegencommon.cpp | 2 +- src/coreclr/src/jit/codegenxarch.cpp | 15 ++++++--------- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index c305408485fb5..cacfb1a6182db 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -1373,7 +1373,7 @@ void CodeGen::genMultiRegStoreToLocal(GenTree* treeNode) GenTree* op1 = treeNode->gtGetOp1(); GenTree* actualOp1 = op1->gtSkipReloadOrCopy(); assert(op1->IsMultiRegNode()); - unsigned regCount = op1->GetMultiRegCount(); + unsigned regCount = actualOp1->GetMultiRegCount(); // Assumption: current implementation requires that a multi-reg // var in 'var = call' is flagged as lvIsMultiRegRet to prevent it from @@ -1444,17 +1444,14 @@ void CodeGen::genMultiRegStoreToLocal(GenTree* treeNode) { for (unsigned i = 0; i < regCount; ++i) { - var_types type = op1->gtSkipReloadOrCopy()->GetRegTypeByIndex(i); + var_types type = actualOp1->GetRegTypeByIndex(i); regNumber reg = op1->GetRegByIndex(i); - if (op1->IsCopyOrReload()) + if (reg == REG_NA) { - // GT_COPY/GT_RELOAD will have valid reg for those positions + // GT_COPY/GT_RELOAD will have valid reg only for those positions // that need to be copied or reloaded. - regNumber reloadReg = op1->AsCopyOrReload()->GetRegNumByIdx(i); - if (reloadReg != REG_NA) - { - reg = reloadReg; - } + assert(op1->IsCopyOrReload()); + reg = actualOp1->GetRegByIndex(i); } assert(reg != REG_NA); diff --git a/src/coreclr/src/jit/codegencommon.cpp b/src/coreclr/src/jit/codegencommon.cpp index a89e24e217d51..3c4f9efc947af 100644 --- a/src/coreclr/src/jit/codegencommon.cpp +++ b/src/coreclr/src/jit/codegencommon.cpp @@ -11752,7 +11752,7 @@ void CodeGen::genRegCopy(GenTree* treeNode) GenTreeCopyOrReload* copyNode = treeNode->AsCopyOrReload(); unsigned regCount = copyNode->GetRegCount(); // GenTreeCopyOrReload only reports the number of registers that are valid. - assert(regCount <= 2); + assert(regCount <= MAX_MULTIREG_COUNT); // First set the source registers as busy if they haven't been spilled. // (Note that this is just for verification that we don't have circular dependencies.) diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index 2d2d92fde1a81..4d8d2fbf9e217 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -1868,7 +1868,7 @@ void CodeGen::genMultiRegStoreToLocal(GenTree* treeNode) GenTree* op1 = treeNode->gtGetOp1(); GenTree* actualOp1 = op1->gtSkipReloadOrCopy(); assert(op1->IsMultiRegNode()); - unsigned regCount = op1->GetMultiRegCount(); + unsigned regCount = actualOp1->GetMultiRegCount(); // Assumption: The current implementation requires that a multi-reg // var in 'var = call' is flagged as lvIsMultiRegRet to prevent it from @@ -1968,17 +1968,14 @@ void CodeGen::genMultiRegStoreToLocal(GenTree* treeNode) int offset = 0; for (unsigned i = 0; i < regCount; ++i) { - var_types type = op1->gtSkipReloadOrCopy()->GetRegTypeByIndex(i); + var_types type = actualOp1->GetRegTypeByIndex(i); regNumber reg = op1->GetRegByIndex(i); - if (op1->IsCopyOrReload()) + if (reg == REG_NA) { - // GT_COPY/GT_RELOAD will have valid reg for those positions + // GT_COPY/GT_RELOAD will have valid reg only for those positions // that need to be copied or reloaded. - regNumber reloadReg = op1->AsCopyOrReload()->GetRegNumByIdx(i); - if (reloadReg != REG_NA) - { - reg = reloadReg; - } + assert(op1->IsCopyOrReload()); + reg = actualOp1->GetRegByIndex(i); } assert(reg != REG_NA); From 20a01d299e838d86b4eb4f2294eac95a35d62be4 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Wed, 27 May 2020 08:52:18 +0300 Subject: [PATCH 407/420] RuyJIT: `Array.Length / cns` can be converted to unsigned div (mod) (#32368) * Optimize `array.Length / cns` and `array.Length % cns` if cns is positive * Address feedback --- src/coreclr/src/jit/morph.cpp | 21 +++ .../ArrayLengthArithmetic.cs | 143 ++++++++++++++++++ .../ArrayLengthArithmetic.csproj | 12 ++ 3 files changed, 176 insertions(+) create mode 100644 src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.cs create mode 100644 src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.csproj diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 6b76648e0c074..4fcaa51aa6173 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -11650,6 +11650,17 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) op2->AsDblCon()->gtDconVal = 1.0 / divisor; } } + + // array.Length is always positive so GT_DIV can be changed to GT_UDIV + // if op2 is a positive cns + if (!optValnumCSE_phase && op1->OperIs(GT_ARR_LENGTH) && op2->IsIntegralConst() && + op2->AsIntCon()->IconValue() >= 2) // for 0 and 1 it doesn't matter if it's UDIV or DIV + { + assert(tree->OperIs(GT_DIV)); + tree->ChangeOper(GT_UDIV); + return fgMorphSmpOp(tree, mac); + } + #ifndef TARGET_64BIT if (typ == TYP_LONG) { @@ -11714,6 +11725,16 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) goto USE_HELPER_FOR_ARITH; } + // array.Length is always positive so GT_DIV can be changed to GT_UDIV + // if op2 is a positive cns + if (!optValnumCSE_phase && op1->OperIs(GT_ARR_LENGTH) && op2->IsIntegralConst() && + op2->AsIntCon()->IconValue() >= 2) // for 0 and 1 it doesn't matter if it's UMOD or MOD + { + assert(tree->OperIs(GT_MOD)); + tree->ChangeOper(GT_UMOD); + return fgMorphSmpOp(tree, mac); + } + // Do not use optimizations (unlike UMOD's idiv optimizing during codegen) for signed mod. // A similar optimization for signed mod will not work for a negative perfectly divisible // HI-word. To make it correct, we would need to divide without the sign and then flip the diff --git a/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.cs b/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.cs new file mode 100644 index 0000000000000..4ac6ef069a3dd --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.cs @@ -0,0 +1,143 @@ +// 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. + +using System; +using System.Runtime.CompilerServices; + +public class ArrayLengthArithmeticTests +{ + private static int returnCode = 100; + + public static int Main(string[] args) + { + for (int arrayLength = 0; arrayLength < 100; arrayLength++) + { + var array = new int[arrayLength]; + + if (arrayLength == 0) + { + Expect(() => ArrayLengthDiv_cns0(array)); + Expect(() => ArrayLengthDiv_var0(array)); + Expect(() => ArrayLengthMod_cns0(array)); + Expect(() => ArrayLengthMod_var0(array)); + } + + // Array.Length / cns == Array.Length / ToVar(cns) + CompareResults(ArrayLengthDiv_cns1(array), ArrayLengthDiv_var1(array)); + CompareResults(ArrayLengthDiv_cns2(array), ArrayLengthDiv_var2(array)); + CompareResults(ArrayLengthDiv_cns3(array), ArrayLengthDiv_var3(array)); + CompareResults(ArrayLengthDiv_cns4(array), ArrayLengthDiv_var4(array)); + CompareResults(ArrayLengthDiv_cns5(array), ArrayLengthDiv_var5(array)); + CompareResults(ArrayLengthDiv_cns8(array), ArrayLengthDiv_var8(array)); + CompareResults(ArrayLengthDiv_cns10(array), ArrayLengthDiv_var10(array)); + CompareResults(ArrayLengthDiv_cnsMaxValuen1(array), ArrayLengthDiv_varMaxValuen1(array)); + CompareResults(ArrayLengthDiv_cnsMaxValue(array), ArrayLengthDiv_varMaxValue(array)); + CompareResults(ArrayLengthDiv_cnsn1(array), ArrayLengthDiv_varn1(array)); + CompareResults(ArrayLengthDiv_cnsn2(array), ArrayLengthDiv_varn2(array)); + CompareResults(ArrayLengthDiv_cnsMinValue(array), ArrayLengthDiv_varMinValue(array)); + + // Array.Length % cns == Array.Length % ToVar(cns) + CompareResults(ArrayLengthMod_cns1(array), ArrayLengthMod_var1(array)); + CompareResults(ArrayLengthMod_cns2(array), ArrayLengthMod_var2(array)); + CompareResults(ArrayLengthMod_cns3(array), ArrayLengthMod_var3(array)); + CompareResults(ArrayLengthMod_cns4(array), ArrayLengthMod_var4(array)); + CompareResults(ArrayLengthMod_cns5(array), ArrayLengthMod_var5(array)); + CompareResults(ArrayLengthMod_cns8(array), ArrayLengthMod_var8(array)); + CompareResults(ArrayLengthMod_cns10(array), ArrayLengthMod_var10(array)); + CompareResults(ArrayLengthMod_cnsMaxValuen1(array), ArrayLengthMod_varMaxValuen1(array)); + CompareResults(ArrayLengthMod_cnsMaxValue(array), ArrayLengthMod_varMaxValue(array)); + CompareResults(ArrayLengthMod_cnsn1(array), ArrayLengthMod_varn1(array)); + CompareResults(ArrayLengthMod_cnsn2(array), ArrayLengthMod_varn2(array)); + CompareResults(ArrayLengthMod_cnsMinValue(array), ArrayLengthMod_varMinValue(array)); + } + + return returnCode; + } + + // Array.Length / cns + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns0(int[] array) => array.Length / 0; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns1(int[] array) => array.Length / 1; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns2(int[] array) => array.Length / 2; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns3(int[] array) => array.Length / 3; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns4(int[] array) => array.Length / 4; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns5(int[] array) => array.Length / 5; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns8(int[] array) => array.Length / 8; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cns10(int[] array) => array.Length / 10; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cnsMaxValuen1(int[] array) => array.Length / (int.MaxValue - 1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cnsMaxValue(int[] array) => array.Length / int.MaxValue; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cnsn1(int[] array) => array.Length / -1; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cnsn2(int[] array) => array.Length / -2; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_cnsMinValue(int[] array) => array.Length / int.MinValue; + + // Array.Length / variable + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var0(int[] array) => array.Length / ToVar(0); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var1(int[] array) => array.Length / ToVar(1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var2(int[] array) => array.Length / ToVar(2); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var3(int[] array) => array.Length / ToVar(3); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var4(int[] array) => array.Length / ToVar(4); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var5(int[] array) => array.Length / ToVar(5); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var8(int[] array) => array.Length / ToVar(8); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_var10(int[] array) => array.Length / ToVar(10); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_varMaxValuen1(int[] array) => array.Length / ToVar(int.MaxValue - 1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_varMaxValue(int[] array) => array.Length / ToVar(int.MaxValue); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_varn1(int[] array) => array.Length / ToVar(-1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_varn2(int[] array) => array.Length / ToVar(-2); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthDiv_varMinValue(int[] array) => array.Length / ToVar(int.MinValue); + + // Array.Length % cns + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns0(int[] array) => array.Length % 0; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns1(int[] array) => array.Length % 1; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns2(int[] array) => array.Length % 2; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns3(int[] array) => array.Length % 3; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns4(int[] array) => array.Length % 4; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns5(int[] array) => array.Length % 5; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns8(int[] array) => array.Length % 8; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cns10(int[] array) => array.Length % 10; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cnsMaxValuen1(int[] array) => array.Length % (int.MaxValue - 1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cnsMaxValue(int[] array) => array.Length % int.MaxValue; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cnsn1(int[] array) => array.Length % -1; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cnsn2(int[] array) => array.Length % -2; + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_cnsMinValue(int[] array) => array.Length % int.MinValue; + + // Array.Length % variable + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var0(int[] array) => array.Length % ToVar(0); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var1(int[] array) => array.Length % ToVar(1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var2(int[] array) => array.Length % ToVar(2); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var3(int[] array) => array.Length % ToVar(3); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var4(int[] array) => array.Length % ToVar(4); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var5(int[] array) => array.Length % ToVar(5); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var8(int[] array) => array.Length % ToVar(8); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_var10(int[] array) => array.Length % ToVar(10); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_varMaxValuen1(int[] array) => array.Length % ToVar(int.MaxValue - 1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_varMaxValue(int[] array) => array.Length % ToVar(int.MaxValue); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_varn1(int[] array) => array.Length % ToVar(-1); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_varn2(int[] array) => array.Length % ToVar(-2); + [MethodImpl(MethodImplOptions.NoInlining)] private static int ArrayLengthMod_varMinValue(int[] array) => array.Length % ToVar(int.MinValue); + + private static void Expect(Action action, [CallerLineNumber] int line = 0) where T : Exception + { + try + { + action(); + } + catch (T) + { + return; + } + Console.WriteLine($"{typeof(T).Name} was expected, L{line}"); + returnCode++; + } + + private static void CompareResults(int a, int b, [CallerLineNumber] int line = 0) + { + if (a != b) + { + Console.WriteLine($"{a} != {b}, L{line}"); + returnCode++; + } + } + + // cns to var + [MethodImpl(MethodImplOptions.NoInlining)] private static T ToVar(T t) => t; +} \ No newline at end of file diff --git a/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.csproj b/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.csproj new file mode 100644 index 0000000000000..10e5a51b6a338 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/InstructionCombining/ArrayLengthArithmetic.csproj @@ -0,0 +1,12 @@ + + + Exe + + + None + True + + + + + From ae1c5fecd9517690a7efeb9a09967cb3be88c1f0 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Wed, 27 May 2020 04:29:11 -0400 Subject: [PATCH 408/420] Avoid HttpClientHandler.ServerCertificateCustomValidationCallback keeping first request message alive (#37021) --- .../System/Net/Http/SocketsHttpHandler/ConnectHelper.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs index 7f88b005bfdfd..288022837e832 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs @@ -136,7 +136,12 @@ public static ValueTask EstablishSslConnectionAsync(SslClientAuthenti Func localFromHttpClientHandler = mapper.FromHttpClientHandler; HttpRequestMessage localRequest = request; sslOptions.RemoteCertificateValidationCallback = (object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors) => - localFromHttpClientHandler(localRequest, certificate as X509Certificate2, chain, sslPolicyErrors); + { + Debug.Assert(localRequest != null); + bool result = localFromHttpClientHandler(localRequest, certificate as X509Certificate2, chain, sslPolicyErrors); + localRequest = null!; // ensure the SslOptions and this callback don't keep the first HttpRequestMessage alive indefinitely + return result; + }; } // Create the SslStream, authenticate, and return it. From feb16af4398a18277f1a114b8968afc6ade34615 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Wed, 27 May 2020 11:57:58 +0300 Subject: [PATCH 409/420] [interp] Remove return value indirection (#37004) * [interp] Remove return value indirection When returning from a method we used to save the return value into frame->retval. We would then have separate opcodes for normal and void call and, depending on the type of call, we would access the retval and push it on the stack. In case of valuetype returns, the value is not returned in the proper space so we have an additional MINT_VTRESULT that copies the return around in the caller frame. In addition to this we had retval, is_void locals, saved as part of the current frame state which just make things confusing and are not needed. This commit simplifies the call procedure by completely moving the responsability of the return to the called method. Simply put, once a method is ready for the call, it will leave its stack and vtstack to the state after pop-ing the arguments. The called method will then directly push the result to the parent frame's stack/vtstack. This means the calling code doesn't care about the type of the return anymore, the IL instructions after the call will just expect the return on the stack, if any, and use it naturally. We still make use of frame->retval for interp entry frames (since we don't have a parent frame to push to), for pinvoke and jit_call frames out of convenience, but we should consider removing this variable to further trim down InterpFrame. * [interp] Remove call opcodes that are no longer necessary * [interp] Split up CALL and CALLVIRT opcodes MINT_CALLVIRT is soon to be removed while MINT_CALL is the most common call opcode. * [interp] Fix jit calls done through MINT_CALLVIRT The callee should push the vt stack if there is a vt return, except when we are calling out of the interpreter, in which case the calling opcodes handle the push explicitly. We weren't handling the case of exiting the interpreter when doing a jit call through MINT_CALLVIRT. In order to keep the same structure for MINT_CALLVIRT, which doesn't need to know about the vt_res_size, we handle the vtstack change when doing a jit call by caching the return size in the InterpMethod, together with other jit_call information. Maybe we can refactor this later. * [interp] Cleanup call opcode emitting Add the opcode and set its data in the same place, making the code easier to follow. * [interp] Split up MINT_CALL_NAT in 2 opcodes This opcode had two different cases embedded in it. Clean up the code, split the opcode in two, removing also a dirty recursive call. * [tests] Disable a few tests that fail with this PR due to false pinning There are over a hundred tests calling GC.WaitForPendingFinalizers and potentially flaky with mono. We might have to disable all of them or tweak them to be mono friendly. --- src/coreclr/tests/issues.targets | 6 + src/mono/mono/mini/interp/interp-internals.h | 2 +- src/mono/mono/mini/interp/interp.c | 249 ++++++++++--------- src/mono/mono/mini/interp/mintops.def | 20 +- src/mono/mono/mini/interp/transform.c | 112 ++++----- 5 files changed, 199 insertions(+), 190 deletions(-) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index 263b7a1c8d3cd..a4717f3035c12 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -962,6 +962,12 @@ + + PlatformDetection.IsPreciseGcSupported false on mono + + + PlatformDetection.IsPreciseGcSupported false on mono + needs triage diff --git a/src/mono/mono/mini/interp/interp-internals.h b/src/mono/mono/mini/interp/interp-internals.h index 049de513fcd5f..b88e969bab9d6 100644 --- a/src/mono/mono/mini/interp/interp-internals.h +++ b/src/mono/mono/mini/interp/interp-internals.h @@ -151,6 +151,7 @@ struct InterpMethod { gpointer jit_wrapper; gpointer jit_addr; MonoMethodSignature *jit_sig; + gint32 jit_vt_res_size; gpointer jit_entry; gpointer llvmonly_unbox_entry; MonoType *rtype; @@ -205,7 +206,6 @@ typedef struct { const unsigned short *ip; GSList *finally_ips; FrameClauseArgs *clause_args; - gboolean is_void : 1; } InterpState; struct InterpFrame { diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 62c06d10bc099..4ac1b20a67f18 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -221,12 +221,11 @@ frame_stack_free (FrameStack *stack) * Reinitialize a frame. */ static void -reinit_frame (InterpFrame *frame, InterpFrame *parent, InterpMethod *imethod, stackval *stack_args, stackval *retval) +reinit_frame (InterpFrame *frame, InterpFrame *parent, InterpMethod *imethod, stackval *stack_args) { frame->parent = parent; frame->imethod = imethod; frame->stack_args = stack_args; - frame->retval = retval; frame->stack = NULL; frame->ip = NULL; frame->state.ip = NULL; @@ -2302,6 +2301,21 @@ do_jit_call (stackval *sp, unsigned char *vt_sp, ThreadContext *context, InterpF rmethod->jit_addr = addr; rmethod->jit_sig = sig; + + if (sig->ret->type != MONO_TYPE_VOID) { + int mt = mint_type (sig->ret); + if (mt == MINT_TYPE_VT) { + MonoClass *klass = mono_class_from_mono_type_internal (sig->ret); + /* + * We cache this size here, instead of the instruction stream of the + * calling instruction, to save space for common callvirt instructions + * that could end up doing a jit call. + */ + gint32 size = mono_class_value_size (klass, NULL); + rmethod->jit_vt_res_size = ALIGN_TO (size, MINT_VT_ALIGNMENT); + } + } + mono_memory_barrier (); rmethod->jit_wrapper = jit_wrapper; @@ -2489,7 +2503,7 @@ do_transform_method (InterpFrame *frame, ThreadContext *context) return mono_error_convert_to_exception (error); } -static guchar* +static void copy_varargs_vtstack (MonoMethodSignature *csig, stackval *sp, guchar *vt_sp_start) { stackval *first_arg = sp - csig->param_count; @@ -2498,8 +2512,9 @@ copy_varargs_vtstack (MonoMethodSignature *csig, stackval *sp, guchar *vt_sp_sta /* * We need to have the varargs linearly on the stack so the ArgIterator * can iterate over them. We pass the signature first and then copy them - * one by one on the vtstack. At the end we pass the original vt_stack - * so the callee (MINT_ARGLIST) can find the varargs space. + * one by one on the vtstack. The callee (MINT_ARGLIST) will be able to + * find this space by adding the current vt_sp pointer in the parent frame + * with the amount of vtstack space used by the parameters. */ *(gpointer*)vt_sp = csig; vt_sp += sizeof (gpointer); @@ -2512,13 +2527,6 @@ copy_varargs_vtstack (MonoMethodSignature *csig, stackval *sp, guchar *vt_sp_sta stackval_to_data (csig->params [i], &first_arg [i], vt_sp, FALSE); vt_sp += arg_size; } - - vt_sp += sizeof (gpointer); - vt_sp = (guchar*)ALIGN_PTR_TO (vt_sp, MINT_VT_ALIGNMENT); - - ((gpointer*)vt_sp) [-1] = vt_sp_start; - - return vt_sp; } /* @@ -3132,25 +3140,10 @@ mono_interp_isinst (MonoObject* object, MonoClass* klass) return isinst; } -// Do not inline use of alloca. -// Do not inline in case order of frame addresses matters. -static MONO_NEVER_INLINE void -mono_interp_calli_nat_dynamic_pinvoke ( - // Parameters are sorted by name. - guchar* code, - ThreadContext* context, - MonoMethodSignature* csignature, - MonoError* error, - InterpFrame *parent_frame, - stackval *retval, - stackval *sp) +static MONO_NEVER_INLINE InterpMethod* +mono_interp_get_native_func_wrapper (InterpMethod* imethod, MonoMethodSignature* csignature, guchar* code) { - InterpFrame frame = {parent_frame, NULL, sp, retval}; - - // Recompute to limit parameters, which can also contribute to caller stack. - InterpMethod* const imethod = parent_frame->imethod; - - g_assert (imethod->method->dynamic && csignature->pinvoke); + ERROR_DECL(error); /* Pinvoke call is missing the wrapper. See mono_get_native_calli_wrapper */ MonoMarshalSpec** mspecs = g_newa0 (MonoMarshalSpec*, csignature->param_count + 1); @@ -3164,13 +3157,10 @@ mono_interp_calli_nat_dynamic_pinvoke ( if (mspecs [i]) mono_metadata_free_marshal_spec (mspecs [i]); - { - ERROR_DECL (error); - frame.imethod = mono_interp_get_imethod (imethod->domain, m, error); - mono_error_cleanup (error); /* FIXME: don't swallow the error */ - } + InterpMethod *cmethod = mono_interp_get_imethod (imethod->domain, m, error); + mono_error_cleanup (error); /* FIXME: don't swallow the error */ - interp_exec_method (&frame, context, NULL, error); + return cmethod; } // Do not inline in case order of frame addresses matters. @@ -3340,7 +3330,6 @@ method_entry (ThreadContext *context, InterpFrame *frame, frame->state.ip = ip; \ frame->state.sp = sp; \ frame->state.vt_sp = vt_sp; \ - frame->state.is_void = is_void; \ frame->state.finally_ips = finally_ips; \ frame->state.clause_args = clause_args; \ } while (0) @@ -3349,7 +3338,6 @@ method_entry (ThreadContext *context, InterpFrame *frame, #define LOAD_INTERP_STATE(frame) do { \ ip = frame->state.ip; \ sp = frame->state.sp; \ - is_void = frame->state.is_void; \ vt_sp = frame->state.vt_sp; \ finally_ips = frame->state.finally_ips; \ clause_args = frame->state.clause_args; \ @@ -3377,8 +3365,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs { InterpMethod *cmethod; MonoException *ex; - gboolean is_void; - stackval *retval; /* Interpreter main loop state (InterpState) */ const guint16 *ip = NULL; @@ -3464,7 +3450,12 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs MINT_IN_BREAK; MINT_IN_CASE(MINT_ARGLIST) sp->data.p = vt_sp; - *(gpointer*)sp->data.p = ((gpointer*)frame->retval->data.p) [-1]; + /* + * We know we have been called by an MINT_CALL_VARARG and the amount of vtstack + * used by the parameters is at ip [-1] (the last argument to MINT_CALL_VARARG that + * is embedded in the instruction stream). + */ + *(gpointer*)sp->data.p = frame->parent->state.vt_sp + frame->parent->state.ip [-1]; vt_sp += ALIGN_TO (sizeof (gpointer), MINT_VT_ALIGNMENT); ++ip; ++sp; @@ -3619,7 +3610,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs } MINT_IN_CASE(MINT_CALL_DELEGATE) { MonoMethodSignature *csignature = (MonoMethodSignature*)frame->imethod->data_items [ip [1]]; - is_void = csignature->ret->type == MONO_TYPE_VOID; int param_count = csignature->param_count; MonoDelegate *del = (MonoDelegate*) sp [-param_count - 1].data.o; gboolean is_multicast = del->method == NULL; @@ -3658,8 +3648,7 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs } } cmethod = del_imethod; - retval = sp; - sp->data.p = vt_sp; + vt_sp -= ip [2]; sp -= param_count + 1; if (!is_multicast) { if (cmethod->param_count == param_count + 1) { @@ -3683,7 +3672,7 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs memmove (sp, sp + 1, param_count * sizeof (stackval)); } } - ip += 2; + ip += 3; goto call; } @@ -3693,7 +3682,6 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs frame->ip = ip; csignature = (MonoMethodSignature*)frame->imethod->data_items [ip [1]]; - ip += 2; --sp; cmethod = (InterpMethod*)sp->data.p; @@ -3702,14 +3690,11 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs mono_interp_error_cleanup (error); /* FIXME: don't swallow the error */ } - is_void = csignature->ret->type == MONO_TYPE_VOID; - retval = is_void ? NULL : sp; - - sp->data.p = vt_sp; /* decrement by the actual number of args */ sp -= csignature->param_count; if (csignature->hasthis) --sp; + vt_sp -= ip [2]; if (csignature->hasthis) { MonoObject *this_arg = (MonoObject*)sp->data.p; @@ -3719,6 +3704,7 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs sp [0].data.p = unboxed; } } + ip += 3; goto call; } @@ -3737,58 +3723,73 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs ip += 4; MINT_IN_BREAK; } - MINT_IN_CASE(MINT_CALLI_NAT) { + MINT_IN_CASE(MINT_CALLI_NAT_DYNAMIC) { MonoMethodSignature* csignature; frame->ip = ip; csignature = (MonoMethodSignature*)frame->imethod->data_items [ip [1]]; + --sp; + guchar* code = (guchar*)sp->data.p; + + /* decrement by the actual number of args */ + sp -= csignature->param_count; + if (csignature->hasthis) + --sp; + vt_sp -= ip [2]; + + cmethod = mono_interp_get_native_func_wrapper (frame->imethod, csignature, code); + ip += 3; + goto call; + } + MINT_IN_CASE(MINT_CALLI_NAT) { + MonoMethodSignature* csignature; + stackval retval; + + frame->ip = ip; + + csignature = (MonoMethodSignature*)frame->imethod->data_items [ip [1]]; + --sp; guchar* const code = (guchar*)sp->data.p; - retval = sp; - sp->data.p = vt_sp; /* decrement by the actual number of args */ sp -= csignature->param_count; if (csignature->hasthis) --sp; + vt_sp -= ip [2]; + /* If this is a vt return, the pinvoke will write the result directly to vt_sp */ + retval.data.p = vt_sp; - if (frame->imethod->method->dynamic && csignature->pinvoke) { - mono_interp_calli_nat_dynamic_pinvoke (code, context, csignature, error, frame, retval, sp); - } else { - const gboolean save_last_error = ip [-3 + 2]; - ves_pinvoke_method (csignature, (MonoFuncV)code, context, frame, retval, save_last_error, sp); - } + gboolean save_last_error = ip [4]; + ves_pinvoke_method (csignature, (MonoFuncV)code, context, frame, &retval, save_last_error, sp); CHECK_RESUME_STATE (context); if (csignature->ret->type != MONO_TYPE_VOID) { - *sp = *retval; + *sp = retval; + vt_sp += ip [3]; sp++; } + ip += 5; MINT_IN_BREAK; } - MINT_IN_CASE(MINT_CALLVIRT_FAST) - MINT_IN_CASE(MINT_VCALLVIRT_FAST) { + MINT_IN_CASE(MINT_CALLVIRT_FAST) { MonoObject *this_arg; - is_void = *ip == MINT_VCALLVIRT_FAST; int slot; frame->ip = ip; cmethod = (InterpMethod*)frame->imethod->data_items [ip [1]]; slot = (gint16)ip [2]; - ip += 3; - sp->data.p = vt_sp; - - retval = is_void ? NULL : sp; /* decrement by the actual number of args */ sp -= cmethod->param_count + cmethod->hasthis; - + vt_sp -= ip [3]; this_arg = (MonoObject*)sp->data.p; + ip += 4; cmethod = get_virtual_method_fast (cmethod, this_arg->vtable, slot); if (m_class_is_valuetype (this_arg->vtable->klass) && m_class_is_valuetype (cmethod->method->klass)) { @@ -3826,8 +3827,10 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs CHECK_RESUME_STATE (context); - if (cmethod->rtype->type != MONO_TYPE_VOID) + if (cmethod->rtype->type != MONO_TYPE_VOID) { sp++; + vt_sp += cmethod->jit_vt_res_size; + } } MINT_IN_BREAK; @@ -3841,59 +3844,56 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs csig = (MonoMethodSignature*) frame->imethod->data_items [ip [2]]; frame->ip = ip; - - // Retval must be set unconditionally due to MINT_ARGLIST. - // is_void guides exit_frame instead of retval nullness. - retval = sp; - is_void = csig->ret->type == MONO_TYPE_VOID; - /* Push all vararg arguments from normal sp to vt_sp together with the signature */ - vt_sp = copy_varargs_vtstack (csig, sp, vt_sp); - - ip += 3; - sp->data.p = vt_sp; + copy_varargs_vtstack (csig, sp, vt_sp); + vt_sp -= ip [3]; /* decrement by the actual number of args */ // FIXME This seems excessive: frame and csig param_count. sp -= cmethod->param_count + cmethod->hasthis + csig->param_count - csig->sentinelpos; + ip += 4; goto call; } - MINT_IN_CASE(MINT_VCALL) - MINT_IN_CASE(MINT_CALL) - MINT_IN_CASE(MINT_CALLVIRT) - MINT_IN_CASE(MINT_VCALLVIRT) { + MINT_IN_CASE(MINT_CALLVIRT) { // FIXME CALLVIRT opcodes are not used on netcore. We should kill them. - // FIXME braces from here until call: label. - is_void = *ip == MINT_VCALL || *ip == MINT_VCALLVIRT; - gboolean is_virtual; - is_virtual = *ip == MINT_CALLVIRT || *ip == MINT_VCALLVIRT; - cmethod = (InterpMethod*)frame->imethod->data_items [ip [1]]; - sp->data.p = vt_sp; - retval = is_void ? NULL : sp; /* decrement by the actual number of args */ sp -= ip [2]; + vt_sp -= ip [3]; - if (is_virtual) { - MonoObject *this_arg = (MonoObject*)sp->data.p; + MonoObject *this_arg = (MonoObject*)sp->data.p; - cmethod = get_virtual_method (cmethod, this_arg->vtable); - if (m_class_is_valuetype (this_arg->vtable->klass) && m_class_is_valuetype (cmethod->method->klass)) { - /* unbox */ - gpointer unboxed = mono_object_unbox_internal (this_arg); - sp [0].data.p = unboxed; - } + cmethod = get_virtual_method (cmethod, this_arg->vtable); + if (m_class_is_valuetype (this_arg->vtable->klass) && m_class_is_valuetype (cmethod->method->klass)) { + /* unbox */ + gpointer unboxed = mono_object_unbox_internal (this_arg); + sp [0].data.p = unboxed; } frame->ip = ip; #ifdef ENABLE_EXPERIMENT_TIERED ip += 5; #else - ip += 3; + ip += 4; +#endif + goto call; + } + MINT_IN_CASE(MINT_CALL) { + cmethod = (InterpMethod*)frame->imethod->data_items [ip [1]]; + + /* decrement by the actual number of args */ + sp -= ip [2]; + vt_sp -= ip [3]; + + frame->ip = ip; +#ifdef ENABLE_EXPERIMENT_TIERED + ip += 5; +#else + ip += 4; #endif -call:; +call: /* * Make a non-recursive call by loading the new interpreter state based on child frame, * and going back to the main loop. @@ -3909,7 +3909,7 @@ call:; // Not free currently, but will be when allocation attempted. frame->next_free = child_frame; } - reinit_frame (child_frame, frame, cmethod, sp, retval); + reinit_frame (child_frame, frame, cmethod, sp); frame = child_frame; } if (method_entry (context, frame, @@ -3932,18 +3932,21 @@ call:; error_init_reuse (error); frame->ip = ip; sp -= rmethod->param_count + rmethod->hasthis; + vt_sp -= ip [2]; do_jit_call (sp, vt_sp, context, frame, rmethod, error); if (!is_ok (error)) { MonoException *ex = mono_error_convert_to_exception (error); THROW_EX (ex, ip); } - ip += 2; CHECK_RESUME_STATE (context); - if (rmethod->rtype->type != MONO_TYPE_VOID) + if (rmethod->rtype->type != MONO_TYPE_VOID) { sp++; + vt_sp += rmethod->jit_vt_res_size; + } + ip += 3; MINT_IN_BREAK; } MINT_IN_CASE(MINT_JIT_CALL2) { @@ -3976,7 +3979,7 @@ call:; MonoMethodSignature *sig = (MonoMethodSignature*) frame->imethod->data_items [ip [2]]; sp->data.p = vt_sp; - retval = sp; + stackval *retval = sp; sp -= sig->param_count; if (sig->hasthis) @@ -3998,7 +4001,13 @@ call:; } MINT_IN_CASE(MINT_RET) --sp; - *frame->retval = *sp; + if (frame->parent) { + frame->parent->state.sp [0] = *sp; + frame->parent->state.sp++; + } else { + // FIXME This can only happen in a few wrappers. Add separate opcode for it + *frame->retval = *sp; + } if (sp > frame->stack) g_warning_d ("ret: more values on stack: %d", sp - frame->stack); goto exit_frame; @@ -4007,9 +4016,19 @@ call:; g_warning_ds ("ret.void: more values on stack: %d %s", sp - frame->stack, mono_method_full_name (frame->imethod->method, TRUE)); goto exit_frame; MINT_IN_CASE(MINT_RET_VT) { + gpointer dest_vt; int const i32 = READ32 (ip + 1); --sp; - memcpy(frame->retval->data.p, sp->data.p, i32); + if (frame->parent) { + dest_vt = frame->parent->state.vt_sp; + /* Push the valuetype in the parent frame */ + frame->parent->state.sp [0].data.p = dest_vt; + frame->parent->state.sp++; + frame->parent->state.vt_sp += ALIGN_TO (i32, MINT_VT_ALIGNMENT); + } else { + dest_vt = frame->retval->data.p; + } + memcpy (dest_vt, sp->data.p, i32); if (sp > frame->stack) g_warning_d ("ret.vt: more values on stack: %d", sp - frame->stack); goto exit_frame; @@ -4987,13 +5006,11 @@ call:; const int param_count = ip [2]; if (param_count) { sp -= param_count; - memmove (sp + 2, sp, param_count * sizeof (stackval)); + memmove (sp + 1, sp, param_count * sizeof (stackval)); } - - retval = sp; - ++sp; - sp->data.p = NULL; // first parameter - is_void = TRUE; + // `this` is implicit null. The created string will be returned + // by the call, even though the call has void return (?!). + sp->data.p = NULL; ip += 3; goto call; } @@ -5080,8 +5097,6 @@ call:; // on the stack before the call, instead of the call forming it. call_newobj: ++sp; // Point sp at added extra param, after return value. - is_void = TRUE; - retval = NULL; goto call; MINT_IN_CASE(MINT_NEWOBJ) { @@ -7184,8 +7199,6 @@ call:; if (!clause_args && frame->parent && frame->parent->state.ip) { /* Return to the main loop after a non-recursive interpreter call */ //printf ("R: %s -> %s %p\n", mono_method_get_full_name (frame->imethod->method), mono_method_get_full_name (frame->parent->imethod->method), frame->parent->state.ip); - stackval *retval = frame->retval; - InterpFrame* const child_frame = frame; frame = frame->parent; @@ -7195,10 +7208,6 @@ call:; CHECK_RESUME_STATE (context); - if (!is_void) { - *sp = *retval; - sp ++; - } goto main_loop; } diff --git a/src/mono/mono/mini/interp/mintops.def b/src/mono/mono/mini/interp/mintops.def index f3cbbb5f91167..fd8691ba36b13 100644 --- a/src/mono/mono/mini/interp/mintops.def +++ b/src/mono/mono/mini/interp/mintops.def @@ -700,17 +700,15 @@ OPDEF(MINT_ARRAY_ELEMENT_SIZE, "array_element_size", 1, Pop1, Push1, MintOpNoArg OPDEF(MINT_ARRAY_IS_PRIMITIVE, "array_is_primitive", 1, Pop1, Push1, MintOpNoArgs) /* Calls */ -OPDEF(MINT_CALL, "call", 3, VarPop, Push1, MintOpMethodToken) -OPDEF(MINT_VCALL, "vcall", 3, VarPop, Push0, MintOpMethodToken) -OPDEF(MINT_CALLVIRT, "callvirt", 3, VarPop, Push1, MintOpMethodToken) -OPDEF(MINT_VCALLVIRT, "vcallvirt", 3, VarPop, Push0, MintOpMethodToken) -OPDEF(MINT_CALLVIRT_FAST, "callvirt.fast", 3, VarPop, Push1, MintOpMethodToken) -OPDEF(MINT_VCALLVIRT_FAST, "vcallvirt.fast", 3, VarPop, Push0, MintOpMethodToken) -OPDEF(MINT_CALL_DELEGATE, "call.delegate", 2, VarPop, VarPush, MintOpMethodToken) -OPDEF(MINT_CALLI, "calli", 2, VarPop, VarPush, MintOpMethodToken) -OPDEF(MINT_CALLI_NAT, "calli.nat", 3, VarPop, VarPush, MintOpMethodToken) +OPDEF(MINT_CALL, "call", 4, VarPop, Push1, MintOpMethodToken) +OPDEF(MINT_CALLVIRT, "callvirt", 4, VarPop, Push1, MintOpMethodToken) +OPDEF(MINT_CALLVIRT_FAST, "callvirt.fast", 4, VarPop, Push1, MintOpMethodToken) +OPDEF(MINT_CALL_DELEGATE, "call.delegate", 3, VarPop, VarPush, MintOpMethodToken) +OPDEF(MINT_CALLI, "calli", 3, VarPop, VarPush, MintOpMethodToken) +OPDEF(MINT_CALLI_NAT, "calli.nat", 5, VarPop, VarPush, MintOpMethodToken) +OPDEF(MINT_CALLI_NAT_DYNAMIC, "calli.nat.dynamic", 3, VarPop, VarPush, MintOpMethodToken) OPDEF(MINT_CALLI_NAT_FAST, "calli.nat.fast", 4, VarPop, VarPush, MintOpMethodToken) -OPDEF(MINT_CALL_VARARG, "call.vararg", 3, VarPop, VarPush, MintOpMethodToken) +OPDEF(MINT_CALL_VARARG, "call.vararg", 4, VarPop, VarPush, MintOpMethodToken) OPDEF(MINT_CALLRUN, "callrun", 3, VarPop, VarPush, MintOpNoArgs) OPDEF(MINT_ICALL_V_V, "mono_icall_v_v", 2, Pop0, Push0, MintOpClassToken) /* not really */ @@ -728,7 +726,7 @@ OPDEF(MINT_ICALL_PPPPP_P, "mono_icall_ppppp_p", 2, Pop5, Push1, MintOpClassToken OPDEF(MINT_ICALL_PPPPPP_V, "mono_icall_pppppp_v", 2, Pop6, Push0, MintOpClassToken) OPDEF(MINT_ICALL_PPPPPP_P, "mono_icall_pppppp_p", 2, Pop6, Push1, MintOpClassToken) // FIXME: MintOp -OPDEF(MINT_JIT_CALL, "mono_jit_call", 2, VarPop, VarPush, MintOpNoArgs) +OPDEF(MINT_JIT_CALL, "mono_jit_call", 3, VarPop, VarPush, MintOpNoArgs) OPDEF(MINT_JIT_CALL2, "mono_jit_call2", 5, VarPop, VarPush, MintOpNoArgs) OPDEF(MINT_MONO_LDPTR, "mono_ldptr", 2, Pop0, Push1, MintOpClassToken) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 70d866ed11108..4bca4e3752c66 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -2169,7 +2169,6 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target guint32 vt_res_size = 0; int op = -1; int native = 0; - int is_void = 0; int need_null_check = is_virtual; gboolean is_delegate_invoke = FALSE; @@ -2368,10 +2367,12 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target vararg_stack = ALIGN_TO (vararg_stack, align); vararg_stack += arg_size; } - /* allocate space for the pointer to varargs space start */ - vararg_stack += sizeof (gpointer); - vt_stack_used += ALIGN_TO (vararg_stack, MINT_VT_ALIGNMENT); + /* + * MINT_CALL_VARARG needs this space on the vt stack. Make sure the + * vtstack space is sufficient. + */ PUSH_VT (td, vararg_stack); + POP_VT (td, vararg_stack); } if (need_null_check) { @@ -2418,6 +2419,8 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target vt_stack_used += size; } } + /* Pop the vt stack used by the arguments */ + td->vt_sp -= vt_stack_used; /* need to handle typedbyref ... */ if (csignature->ret->type != MONO_TYPE_VOID) { @@ -2435,8 +2438,7 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target PUSH_VT(td, vt_res_size); } PUSH_TYPE(td, stack_type[mt], klass); - } else - is_void = TRUE; + } if (op >= 0) { interp_add_ins (td, op); @@ -2459,47 +2461,62 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target interp_add_ins (td, MINT_JIT_CALL); td->last_ins->data [0] = get_data_item_index (td, (void *)mono_interp_get_imethod (domain, target_method, error)); mono_error_assert_ok (error); + td->last_ins->data [1] = vt_stack_used; } else { -#ifndef MONO_ARCH_HAS_NO_PROPER_MONOCTX - /* Try using fast icall path for simple signatures */ - if (native && !method->dynamic) - op = interp_icall_op_for_sig (csignature); -#endif - if (csignature->call_convention == MONO_CALL_VARARG) - interp_add_ins (td, MINT_CALL_VARARG); - else if (is_delegate_invoke) - interp_add_ins (td, MINT_CALL_DELEGATE); - else if (calli) - interp_add_ins (td, native ? ((op != -1) ? MINT_CALLI_NAT_FAST : MINT_CALLI_NAT) : MINT_CALLI); - else if (is_virtual && !mono_class_is_marshalbyref (target_method->klass)) - interp_add_ins (td, is_void ? MINT_VCALLVIRT_FAST : MINT_CALLVIRT_FAST); - else if (is_virtual) - interp_add_ins (td, is_void ? MINT_VCALLVIRT : MINT_CALLVIRT); - else - interp_add_ins (td, is_void ? MINT_VCALL : MINT_CALL); - if (is_delegate_invoke) { + interp_add_ins (td, MINT_CALL_DELEGATE); td->last_ins->data [0] = get_data_item_index (td, (void *)csignature); + td->last_ins->data [1] = vt_stack_used; } else if (calli) { - td->last_ins->data [0] = get_data_item_index (td, (void *)csignature); -#ifdef TARGET_X86 - /* Windows not tested/supported yet */ - if (td->last_ins->opcode == MINT_CALLI_NAT) - g_assertf (csignature->call_convention == MONO_CALL_DEFAULT || csignature->call_convention == MONO_CALL_C, "Interpreter supports only cdecl pinvoke on x86"); +#ifndef MONO_ARCH_HAS_NO_PROPER_MONOCTX + /* Try using fast icall path for simple signatures */ + if (native && !method->dynamic) + op = interp_icall_op_for_sig (csignature); #endif - if (op != -1) { - g_assert (td->last_ins->opcode == MINT_CALLI_NAT_FAST); + interp_add_ins (td, MINT_CALLI_NAT_FAST); td->last_ins->data [1] = op; td->last_ins->data [2] = save_last_error; + } else if (native && method->dynamic && csignature->pinvoke) { + interp_add_ins (td, MINT_CALLI_NAT_DYNAMIC); + td->last_ins->data [1] = vt_stack_used; } else if (native) { - g_assert (td->last_ins->opcode == MINT_CALLI_NAT); - td->last_ins->data [1] = save_last_error; + interp_add_ins (td, MINT_CALLI_NAT); +#ifdef TARGET_X86 + /* Windows not tested/supported yet */ + g_assertf (csignature->call_convention == MONO_CALL_DEFAULT || csignature->call_convention == MONO_CALL_C, "Interpreter supports only cdecl pinvoke on x86"); +#endif + td->last_ins->data [1] = vt_stack_used; + td->last_ins->data [2] = vt_res_size; + td->last_ins->data [3] = save_last_error; + } else { + interp_add_ins (td, MINT_CALLI); + td->last_ins->data [1] = vt_stack_used; } + td->last_ins->data [0] = get_data_item_index (td, (void *)csignature); } else { InterpMethod *imethod = mono_interp_get_imethod (domain, target_method, error); + return_val_if_nok (error, FALSE); + + if (csignature->call_convention == MONO_CALL_VARARG) { + interp_add_ins (td, MINT_CALL_VARARG); + td->last_ins->data [1] = get_data_item_index (td, (void *)csignature); + } else if (is_virtual && !mono_class_is_marshalbyref (target_method->klass)) { + interp_add_ins (td, MINT_CALLVIRT_FAST); + if (mono_class_is_interface (target_method->klass)) + td->last_ins->data [1] = -2 * MONO_IMT_SIZE + mono_method_get_imt_slot (target_method); + else + td->last_ins->data [1] = mono_method_get_vtable_slot (target_method); + } else if (is_virtual) { + interp_add_ins (td, MINT_CALLVIRT); + td->last_ins->data [1] = imethod->param_count + imethod->hasthis; + } else { + interp_add_ins (td, MINT_CALL); + td->last_ins->data [1] = imethod->param_count + imethod->hasthis; + } td->last_ins->data [0] = get_data_item_index (td, (void *)imethod); - td->last_ins->data [1] = imethod->param_count + imethod->hasthis; + td->last_ins->data [2] = vt_stack_used; + #ifdef ENABLE_EXPERIMENT_TIERED if (MINT_IS_PATCHABLE_CALL (td->last_ins->opcode)) { g_assert (!calli && !is_virtual); @@ -2507,25 +2524,9 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target g_hash_table_insert (td->patchsite_hash, td->last_ins, target_method); } #endif - return_val_if_nok (error, FALSE); - if (csignature->call_convention == MONO_CALL_VARARG) - td->last_ins->data [1] = get_data_item_index (td, (void *)csignature); - else if (is_virtual && !mono_class_is_marshalbyref (target_method->klass)) { - /* FIXME Use fastpath also for MBRO. Asserts in mono_method_get_vtable_slot */ - if (mono_class_is_interface (target_method->klass)) - td->last_ins->data [1] = -2 * MONO_IMT_SIZE + mono_method_get_imt_slot (target_method); - else - td->last_ins->data [1] = mono_method_get_vtable_slot (target_method); - } } } td->ip += 5; - if (vt_stack_used != 0 || vt_res_size != 0) { - interp_add_ins (td, MINT_VTRESULT); - td->last_ins->data [0] = vt_res_size; - WRITE32_INS (td->last_ins, 1, &vt_stack_used); - td->vt_sp -= vt_stack_used; - } return TRUE; } @@ -6437,16 +6438,10 @@ get_inst_stack_usage (TransformData *td, InterpInst *ins, int *pop, int *push) case MINT_JIT_CALL: case MINT_CALL: case MINT_CALLVIRT: - case MINT_CALLVIRT_FAST: - case MINT_VCALL: - case MINT_VCALLVIRT: - case MINT_VCALLVIRT_FAST: { + case MINT_CALLVIRT_FAST: { InterpMethod *imethod = (InterpMethod*) td->data_items [ins->data [0]]; *pop = imethod->param_count + imethod->hasthis; - if (opcode == MINT_JIT_CALL) - *push = imethod->rtype->type != MONO_TYPE_VOID; - else - *push = opcode == MINT_CALL || opcode == MINT_CALLVIRT || opcode == MINT_CALLVIRT_FAST; + *push = imethod->rtype->type != MONO_TYPE_VOID; break; } #ifndef ENABLE_NETCORE @@ -6465,6 +6460,7 @@ get_inst_stack_usage (TransformData *td, InterpInst *ins, int *pop, int *push) } case MINT_CALLI: case MINT_CALLI_NAT: + case MINT_CALLI_NAT_DYNAMIC: case MINT_CALLI_NAT_FAST: { MonoMethodSignature *csignature = (MonoMethodSignature*) td->data_items [ins->data [0]]; *pop = csignature->param_count + csignature->hasthis + 1; From 32fdcaf5eeb890c00f2a5310cc36b24cc1025884 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Wed, 27 May 2020 11:12:39 +0200 Subject: [PATCH 410/420] [browser][wasm] InteropServices.JavaScript backing code. (#37044) --- src/mono/wasm/runtime/binding_support.js | 7 +++-- src/mono/wasm/runtime/corebindings.c | 34 ++++++++++++------------ 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/mono/wasm/runtime/binding_support.js b/src/mono/wasm/runtime/binding_support.js index 46b9383373e83..c97e327373e60 100644 --- a/src/mono/wasm/runtime/binding_support.js +++ b/src/mono/wasm/runtime/binding_support.js @@ -5,7 +5,7 @@ var BindingSupportLib = { $BINDING__postset: 'BINDING.export_functions (Module);', $BINDING: { - BINDING_ASM: "[WebAssembly.Bindings]WebAssembly.Runtime", + BINDING_ASM: "[System.Runtime.InteropServices.JavaScript]System.Runtime.InteropServices.JavaScript.Runtime", mono_wasm_object_registry: [], mono_wasm_ref_counter: 0, mono_wasm_free_list: [], @@ -57,7 +57,7 @@ var BindingSupportLib = { if (binding_fqn_class !== null && typeof binding_fqn_class !== "undefined") { - var namespace = "WebAssembly"; + var namespace = "System.Runtime.InteropServices.JavaScript"; var classname = binding_fqn_class.length > 0 ? binding_fqn_class : "Runtime"; if (binding_fqn_class.indexOf(".") != -1) { var idx = binding_fqn_class.lastIndexOf("."); @@ -83,7 +83,7 @@ var BindingSupportLib = { this.unbind_js_obj_and_free = get_method ("UnBindJSObjectAndFree"); this.unbind_raw_obj_and_free = get_method ("UnBindRawJSObjectAndFree"); this.get_js_id = get_method ("GetJSObjectId"); - this.get_raw_mono_obj = get_method ("GetMonoObject"); + this.get_raw_mono_obj = get_method ("GetDotNetObject"); this.box_js_int = get_method ("BoxInt"); this.box_js_double = get_method ("BoxDouble"); @@ -103,7 +103,6 @@ var BindingSupportLib = { this.create_date_time = get_method ("CreateDateTime"); this.create_uri = get_method ("CreateUri"); - this.object_to_enum = get_method ("ObjectToEnum"); this.init = true; }, diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index f4700369585f9..4b78715bc0b21 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -71,23 +71,23 @@ mono_wasm_compile_function (MonoString *str, int *is_exception) void core_initialize_internals () { - mono_add_internal_call ("WebAssembly.Runtime::InvokeJSWithArgs", mono_wasm_invoke_js_with_args); - mono_add_internal_call ("WebAssembly.Runtime::GetObjectProperty", mono_wasm_get_object_property); - mono_add_internal_call ("WebAssembly.Runtime::GetByIndex", mono_wasm_get_by_index); - mono_add_internal_call ("WebAssembly.Runtime::SetObjectProperty", mono_wasm_set_object_property); - mono_add_internal_call ("WebAssembly.Runtime::SetByIndex", mono_wasm_set_by_index); - mono_add_internal_call ("WebAssembly.Runtime::GetGlobalObject", mono_wasm_get_global_object); - mono_add_internal_call ("WebAssembly.Runtime::ReleaseHandle", mono_wasm_release_handle); - mono_add_internal_call ("WebAssembly.Runtime::ReleaseObject", mono_wasm_release_object); - mono_add_internal_call ("WebAssembly.Runtime::NewObjectJS", mono_wasm_new_object); - mono_add_internal_call ("WebAssembly.Runtime::BindCoreObject", mono_wasm_bind_core_object); - mono_add_internal_call ("WebAssembly.Runtime::BindHostObject", mono_wasm_bind_host_object); - mono_add_internal_call ("WebAssembly.Runtime::New", mono_wasm_new); - mono_add_internal_call ("WebAssembly.Runtime::TypedArrayToArray", mono_wasm_typed_array_to_array); - mono_add_internal_call ("WebAssembly.Runtime::TypedArrayCopyTo", mono_wasm_typed_array_copy_to); - mono_add_internal_call ("WebAssembly.Runtime::TypedArrayFrom", mono_wasm_typed_array_from); - mono_add_internal_call ("WebAssembly.Runtime::TypedArrayCopyFrom", mono_wasm_typed_array_copy_from); - mono_add_internal_call ("WebAssembly.Runtime::CompileFunction", mono_wasm_compile_function); + mono_add_internal_call ("Interop/Runtime::InvokeJSWithArgs", mono_wasm_invoke_js_with_args); + mono_add_internal_call ("Interop/Runtime::GetObjectProperty", mono_wasm_get_object_property); + mono_add_internal_call ("Interop/Runtime::GetByIndex", mono_wasm_get_by_index); + mono_add_internal_call ("Interop/Runtime::SetObjectProperty", mono_wasm_set_object_property); + mono_add_internal_call ("Interop/Runtime::SetByIndex", mono_wasm_set_by_index); + mono_add_internal_call ("Interop/Runtime::GetGlobalObject", mono_wasm_get_global_object); + mono_add_internal_call ("Interop/Runtime::ReleaseHandle", mono_wasm_release_handle); + mono_add_internal_call ("Interop/Runtime::ReleaseObject", mono_wasm_release_object); + mono_add_internal_call ("Interop/Runtime::NewObjectJS", mono_wasm_new_object); + mono_add_internal_call ("Interop/Runtime::BindCoreObject", mono_wasm_bind_core_object); + mono_add_internal_call ("Interop/Runtime::BindHostObject", mono_wasm_bind_host_object); + mono_add_internal_call ("Interop/Runtime::New", mono_wasm_new); + mono_add_internal_call ("Interop/Runtime::TypedArrayToArray", mono_wasm_typed_array_to_array); + mono_add_internal_call ("Interop/Runtime::TypedArrayCopyTo", mono_wasm_typed_array_copy_to); + mono_add_internal_call ("Interop/Runtime::TypedArrayFrom", mono_wasm_typed_array_from); + mono_add_internal_call ("Interop/Runtime::TypedArrayCopyFrom", mono_wasm_typed_array_copy_from); + mono_add_internal_call ("Interop/Runtime::CompileFunction", mono_wasm_compile_function); } From 8b92b46602bafafb9b345a6c4c897e9ace02297d Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Wed, 27 May 2020 16:56:10 +0300 Subject: [PATCH 411/420] Make ApkBuilder less verbose (#37050) The output is still pretty useful and x4 times less verbose. --- .../tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs | 2 +- tools-local/tasks/mobile.tasks/AndroidAppBuilder/Utils.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs index 1833c950c17f6..e7fcebdd08eb1 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs @@ -123,7 +123,7 @@ public class ApkBuilder string cmake = "cmake"; string zip = "zip"; - Utils.RunProcess(zip, workingDir: Path.Combine(OutputDir, "assets-tozip"), args: "-r ../assets/assets.zip ."); + Utils.RunProcess(zip, workingDir: Path.Combine(OutputDir, "assets-tozip"), args: "-q -r ../assets/assets.zip ."); Directory.Delete(Path.Combine(OutputDir, "assets-tozip"), true); if (!File.Exists(androidJar)) diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Utils.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Utils.cs index a5e182465c741..bc23f927ae26f 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Utils.cs +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/Utils.cs @@ -26,7 +26,7 @@ public static string GetEmbeddedResource(string file) IDictionary? envVars = null, string? workingDir = null, bool ignoreErrors = false, - bool silent = false) + bool silent = true) { LogInfo($"Running: {path} {args}"); var outputBuilder = new StringBuilder(); @@ -52,7 +52,7 @@ public static string GetEmbeddedResource(string file) Process? process = Process.Start(processStartInfo); if (process == null) - throw new ArgumentException("Process.Start({path} {args}) returned null process"); + throw new ArgumentException($"Process.Start({path} {args}) returned null process"); process.ErrorDataReceived += (sender, e) => { @@ -60,8 +60,8 @@ public static string GetEmbeddedResource(string file) { LogError(e.Data); outputBuilder.AppendLine(e.Data); - errorBuilder.AppendLine(e.Data); } + errorBuilder.AppendLine(e.Data); }; process.OutputDataReceived += (sender, e) => { From d422b0fba578003fc4b801b2b71adac70d1d8013 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Wed, 27 May 2020 16:57:20 +0300 Subject: [PATCH 412/420] Reduce app size for iOS (#36902) We did the same mistake for Android - `libmonosgen-2.0.dylib` shouldn't be copied to bundle (we already have a mono runtime there) --- .config/dotnet-tools.json | 2 +- .../AppleAppBuilder/AppleAppBuilder.cs | 2 +- .../mobile.tasks/AppleAppBuilder/Xcode.cs | 18 ++++++++++++++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index fcd09033203e0..51d9b2432e848 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "1.0.0-prerelease.20265.8", + "version": "1.0.0-prerelease.20271.3", "commands": [ "xharness" ] diff --git a/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs b/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs index 4722c7f0a5f07..39ba74d890f45 100644 --- a/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/AppleAppBuilder/AppleAppBuilder.cs @@ -163,7 +163,7 @@ public override bool Execute() if (GenerateXcodeProject) { XcodeProjectPath = Xcode.GenerateXCode(ProjectName, MainLibraryFileName, assemblerFiles, - AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, UseAotForSimulator, NativeMainSource); + AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, UseAotForSimulator, Optimized, NativeMainSource); if (BuildAppBundle) { diff --git a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs index 821f2671500e5..76ec75c0d3225 100644 --- a/tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs +++ b/tools-local/tasks/mobile.tasks/AppleAppBuilder/Xcode.cs @@ -22,10 +22,15 @@ internal class Xcode bool preferDylibs, bool useConsoleUiTemplate, bool useAotForSimulator, + bool stripDebugSymbols, string? nativeMainSource = null) { // bundle everything as resources excluding native files - string[] excludes = {".dll.o", ".dll.s", ".dwarf", ".m", ".h", ".a", ".bc"}; + var excludes = new List { ".dll.o", ".dll.s", ".dwarf", ".m", ".h", ".a", ".bc", "libmonosgen-2.0.dylib" }; + if (stripDebugSymbols) + { + excludes.Add(".pdb"); + } string[] resources = Directory.GetFiles(workspace) .Where(f => !excludes.Any(e => f.EndsWith(e, StringComparison.InvariantCultureIgnoreCase))) @@ -150,7 +155,16 @@ internal class Xcode args.Append(" -configuration ").Append(config); Utils.RunProcess("xcodebuild", args.ToString(), workingDir: Path.GetDirectoryName(xcodePrjPath)); - return Path.Combine(Path.GetDirectoryName(xcodePrjPath)!, config + "-" + sdk, + + string appPath = Path.Combine(Path.GetDirectoryName(xcodePrjPath)!, config + "-" + sdk, Path.GetFileNameWithoutExtension(xcodePrjPath) + ".app"); + + long appSize = new DirectoryInfo(appPath) + .EnumerateFiles("*", SearchOption.AllDirectories) + .Sum(file => file.Length); + + Utils.LogInfo($"\nAPP size: {(appSize / 1000_000.0):0.#} Mb.\n"); + + return appPath; } } From 511cadad236df4733813e7b477aade532a5fc693 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Wed, 27 May 2020 15:59:38 +0200 Subject: [PATCH 413/420] Update the -vs switch and add docs for it (#37026) * Remove testhost DOTNET_ROOT from vs switch We don't need to point to the testhost folder anymore for libraries for supporting VS Test Explorer. * Update docs * Fix verbosity alias --- .../requirements/windows-requirements.md | 8 ++++ eng/build.ps1 | 42 +++++++++---------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/docs/workflow/requirements/windows-requirements.md b/docs/workflow/requirements/windows-requirements.md index d623f0bcaa07e..5753ccf266a93 100644 --- a/docs/workflow/requirements/windows-requirements.md +++ b/docs/workflow/requirements/windows-requirements.md @@ -71,6 +71,14 @@ While not strictly needed to build or test this repository, having the .NET SDK We use this in the [Using Your Build](../testing/using-your-build.md) instructions. The minimum required version of the SDK is specified in the [global.json file](https://github.com/dotnet/runtime/blob/master/global.json#L3). [You can find the installers and binaries for nightly builds of .NET SDK here](https://github.com/dotnet/installer#installers-and-binaries). +Alternatively, to avoid modifying your machine state, you can use the repository's locally acquired SDK by passing in the solution to load via the `-vs` switch: + +``` +build.cmd -vs System.Text.RegularExpressions +``` + +This will set the `DOTNET_ROOT` and `PATH` environment variables to point to the locally acquired SDK under `runtime\.dotnet\` and will launch the Visual Studio instance which is registered for the `sln` extension. + ## Adding to the default PATH variable The commands above need to be on your command lookup path. Some installers will automatically add them to the path as part of the installation, but if not here is how you can do it. diff --git a/eng/build.ps1 b/eng/build.ps1 index d03d2262e063f..f8f1164bcafc8 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -5,6 +5,7 @@ Param( [ValidateSet("Debug","Release","Checked")][string[]][Alias('c')]$configuration = @("Debug"), [string][Alias('f')]$framework, [string]$vs, + [string][Alias('v')]$verbosity = "minimal", [ValidateSet("Windows_NT","Linux","OSX","Browser")][string]$os, [switch]$allconfigurations, [switch]$coverage, @@ -20,7 +21,7 @@ Param( function Get-Help() { Write-Host "Common settings:" Write-Host " -subset Build a subset, print available subsets with -subset help (short: -s)" - Write-Host " -vs Open the solution with VS for Test Explorer support. Path or solution name (ie -vs Microsoft.CSharp)" + Write-Host " -vs Open the solution with VS using the locally acquired SDK. Path or solution name (ie -vs Microsoft.CSharp)" Write-Host " -os Build operating system: Windows_NT, Linux, OSX, or Browser" Write-Host " -arch Build platform: x86, x64, arm, arm64, or wasm (short: -a). Pass a comma-separated list to build for multiple architectures." Write-Host " -configuration Build configuration: Debug, Release or [CoreCLR]Checked (short: -c). Pass a comma-separated list to build for multiple configurations" @@ -59,38 +60,32 @@ if ($help -or (($null -ne $properties) -and ($properties.Contains('/help') -or $ exit 0 } -# VS Test Explorer support for libraries if ($vs) { - Write-Host "VS Test Explorer now works without needing to call build.cmd. The -vs switch will be removed eventually." . $PSScriptRoot\common\tools.ps1 - # Microsoft.DotNet.CoreSetup.sln is special - hosting tests are currently meant to run on the - # bootstrapped .NET Core, not on the live-built runtime. - if (([System.IO.Path]::GetFileName($vs) -ieq "Microsoft.DotNet.CoreSetup.sln") -or ($vs -ieq "Microsoft.DotNet.CoreSetup")) { + if (-Not (Test-Path $vs)) { + $solution = $vs + # Search for the solution in libraries + $vs = Split-Path $PSScriptRoot -Parent | Join-Path -ChildPath "src\libraries" | Join-Path -ChildPath $vs | Join-Path -ChildPath "$vs.sln" if (-Not (Test-Path $vs)) { - if (-Not ( $vs.endswith(".sln"))) { - $vs = "$vs.sln" + $vs = $solution + # Search for the solution in installer + if (-Not ($vs.endswith(".sln"))) { + $vs = "$vs.sln" + } + $vs = Split-Path $PSScriptRoot -Parent | Join-Path -ChildPath "src\installer" | Join-Path -ChildPath $vs + if (-Not (Test-Path $vs)) { + Write-Error "Passed in solution cannot be resolved." + exit 1 } - $vs = Join-Path "$PSScriptRoot\..\src\installer" $vs } - - # This tells .NET Core to use the bootstrapped runtime to run the tests - $env:DOTNET_ROOT=InitializeDotNetCli -install:$false } - else { - if (-Not (Test-Path $vs)) { - $vs = Join-Path "$PSScriptRoot\..\src\libraries" $vs | Join-Path -ChildPath "$vs.sln" - } - - $archTestHost = if ($arch) { $arch } else { "x64" } - # This tells .NET Core to use the same dotnet.exe that build scripts use - $env:DOTNET_ROOT="$PSScriptRoot\..\artifacts\bin\testhost\net5.0-Windows_NT-$configuration-$archTestHost"; - $env:DEVPATH="$PSScriptRoot\..\artifacts\bin\testhost\net472-Windows_NT-$configuration-$archTestHost"; - } + # This tells .NET Core to use the bootstrapped runtime + $env:DOTNET_ROOT=InitializeDotNetCli -install:$false # This tells MSBuild to load the SDK from the directory of the bootstrapped SDK - $env:DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR=InitializeDotNetCli -install:$false + $env:DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR=$env:DOTNET_ROOT # This tells .NET Core not to go looking for .NET Core in other places $env:DOTNET_MULTILEVEL_LOOKUP=0; @@ -131,6 +126,7 @@ foreach ($argument in $PSBoundParameters.Keys) "os" { $arguments += " /p:TargetOS=$($PSBoundParameters[$argument])" } "allconfigurations" { $arguments += " /p:BuildAllConfigurations=true" } "properties" { $arguments += " " + $properties } + "verbosity" { $arguments += " -$argument " + $($PSBoundParameters[$argument]) } # configuration and arch can be specified multiple times, so they should be no-ops here "configuration" {} "arch" {} From d9ba700187449056433d7f836a98918c1c6cff1d Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Wed, 27 May 2020 10:37:31 -0400 Subject: [PATCH 414/420] Add a BundleTestWasmApp target to build wasm test apps for libraries. (#36739) Beginning of a BundleTestWasmApp target to build wasm test apps for libraries. --- Directory.Build.props | 2 ++ eng/testing/WasmRunnerTemplate.sh | 12 ++++++++ eng/testing/tests.mobile.targets | 20 ++++++++++++- eng/testing/tests.props | 1 + eng/testing/tests.targets | 1 + .../tests/WasmTestRunner/WasmTestRunner.cs | 29 +++++++++++++++++++ .../WasmTestRunner/WasmTestRunner.csproj | 11 +++++++ src/libraries/pretest.proj | 1 + src/mono/netcore/sample/wasm/Makefile | 8 +++-- .../netcore/sample/wasm/WasmSample.csproj | 2 +- .../wasm/runtime.js => wasm/runtime-test.js} | 0 .../WasmAppBuilder/WasmAppBuilder.cs | 2 +- 12 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 eng/testing/WasmRunnerTemplate.sh create mode 100644 src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.cs create mode 100644 src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.csproj rename src/mono/{netcore/sample/wasm/runtime.js => wasm/runtime-test.js} (100%) diff --git a/Directory.Build.props b/Directory.Build.props index 0415a94c76350..70d6c03f17741 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -50,10 +50,12 @@ $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleAppBuilder', 'Debug', '$(NetCoreAppCurrent)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', 'Debug', '$(NetCoreAppCurrent)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'WasmAppBuilder', 'Debug', '$(NetCoreAppCurrent)', 'publish')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'MonoAOTCompiler', 'Debug', '$(NetCoreAppCurrent)')) $([MSBuild]::NormalizePath('$(AppleAppBuilderDir)', 'AppleAppBuilder.dll')) $([MSBuild]::NormalizePath('$(AndroidAppBuilderDir)', 'AndroidAppBuilder.dll')) + $([MSBuild]::NormalizePath('$(WasmAppBuilderDir)', 'WasmAppBuilder.dll')) $([MSBuild]::NormalizePath('$(MonoAOTCompilerDir)', 'MonoAOTCompiler.dll')) diff --git a/eng/testing/WasmRunnerTemplate.sh b/eng/testing/WasmRunnerTemplate.sh new file mode 100644 index 0000000000000..2d4b8f95d4f49 --- /dev/null +++ b/eng/testing/WasmRunnerTemplate.sh @@ -0,0 +1,12 @@ +set -ev + +EXECUTION_DIR=$(dirname $0) +TEST_NAME=$1 +TARGET_ARCH=$2 + +echo "Test: $1 Arch: $2" + +cd $EXECUTION_DIR +v8 --expose_wasm runtime.js -- --enable-gc --run WasmTestRunner.dll $TEST_NAME + +exit 0 diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 4728c595d981f..3fd1594b73bd5 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -106,11 +106,29 @@ + + + + + + + + + + <_runnerFilesToPublish Include="$(AndroidTestRunnerDir)*" Condition="'$(TargetOS)' == 'Android'" /> <_runnerFilesToPublish Include="$(AppleTestRunnerDir)*" Condition="'$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'tvOS'" /> + <_runnerFilesToPublish Include="$(WasmTestRunnerDir)*" Condition="'$(TargetOS)' == 'Browser'" /> @@ -132,5 +150,5 @@ + DependsOnTargets="UpdateRuntimePack;Publish;BundleTestAppleApp;BundleTestAndroidApp;BundleTestWasmApp" /> diff --git a/eng/testing/tests.props b/eng/testing/tests.props index 9b7bc1d270ee7..cccce13b1c454 100644 --- a/eng/testing/tests.props +++ b/eng/testing/tests.props @@ -25,6 +25,7 @@ $(NetCoreAppCurrent)-$(Configuration) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AppleTestRunner', '$(MobileRunnersDirSuffix)')) $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidTestRunner', '$(MobileRunnersDirSuffix)')) + $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'WasmTestRunner', '$(MobileRunnersDirSuffix)')) $(PackageRID) true diff --git a/eng/testing/tests.targets b/eng/testing/tests.targets index 8abd2532274d0..c84fec867d31c 100644 --- a/eng/testing/tests.targets +++ b/eng/testing/tests.targets @@ -4,6 +4,7 @@ RunnerTemplate.sh AppleRunnerTemplate.sh AndroidRunnerTemplate.sh + WasmRunnerTemplate.sh $(MSBuildThisFileDirectory)$(RunScriptInputName) diff --git a/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.cs b/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.cs new file mode 100644 index 0000000000000..0ee51166fbf29 --- /dev/null +++ b/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.cs @@ -0,0 +1,29 @@ +// 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. + +using System; +using System.Linq; +using System.Text; +using System.IO; +using System.Collections.Generic; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; + +public class WasmTestRunner +{ + public static int Main(string[] args) + { + Console.Write("Args: "); + foreach (string arg in args) + { + Console.Write(arg); + } + Console.WriteLine("."); + + return 0; + } +} diff --git a/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.csproj b/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.csproj new file mode 100644 index 0000000000000..7d68c49a196a3 --- /dev/null +++ b/src/libraries/Common/tests/WasmTestRunner/WasmTestRunner.csproj @@ -0,0 +1,11 @@ + + + Exe + enable + $(NetCoreAppCurrent) + + + + + + diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj index 94141031b8b85..7b8e5f9f9f38b 100644 --- a/src/libraries/pretest.proj +++ b/src/libraries/pretest.proj @@ -18,6 +18,7 @@ + diff --git a/src/mono/netcore/sample/wasm/runtime.js b/src/mono/wasm/runtime-test.js similarity index 100% rename from src/mono/netcore/sample/wasm/runtime.js rename to src/mono/wasm/runtime-test.js diff --git a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs index 5261f4c08b276..ce6839f4f6275 100644 --- a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -69,7 +69,7 @@ public class WasmAppBuilder : Task File.Copy (assembly.Location, Path.Join (AppDir, "managed", Path.GetFileName (assembly.Location)), true); foreach (var f in new string [] { "dotnet.wasm", "dotnet.js" }) File.Copy (Path.Join (RuntimePackDir, "native", "wasm", "runtimes", "release", f), Path.Join (AppDir, f), true); - File.Copy (MainJS!, Path.Join (AppDir, Path.GetFileName (MainJS!)), true); + File.Copy (MainJS!, Path.Join (AppDir, "runtime.js"), true); using (var sw = File.CreateText (Path.Join (AppDir, "mono-config.js"))) { sw.WriteLine ("config = {"); From 80affe5452124d8101784ad4ff3f175e9fb7cf53 Mon Sep 17 00:00:00 2001 From: Fan Yang <52458914+fanyang-mono@users.noreply.github.com> Date: Wed, 27 May 2020 11:21:49 -0400 Subject: [PATCH 415/420] Enable jumps4 tests, since the issue has been fixed via mono/mono PR #19809 (#37015) --- src/coreclr/tests/issues.targets | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index a4717f3035c12..27080bf7a7262 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -1373,12 +1373,6 @@ https://github.com/dotnet/runtime/issues/34068 - - https://github.com/dotnet/runtime/issues/34379 - - - needs triage - needs triage From a890e65a738797d20ed38dab74f844db42dcf38f Mon Sep 17 00:00:00 2001 From: Kirill Frolov Date: Wed, 27 May 2020 18:30:20 +0300 Subject: [PATCH 416/420] Fix build with FEATURE_GDBJIT enabled (#37054) This commit fixes broken build in case when following arguments added to build.sh script: --cmakeargs -DFEATURE_GDBJIT=true --- src/coreclr/src/vm/gdbjit.cpp | 10 ---------- src/coreclr/src/vm/gdbjit.h | 11 ++++++++++- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/coreclr/src/vm/gdbjit.cpp b/src/coreclr/src/vm/gdbjit.cpp index 1642c9fbf7d56..8d8e34e6362f4 100644 --- a/src/coreclr/src/vm/gdbjit.cpp +++ b/src/coreclr/src/vm/gdbjit.cpp @@ -1792,16 +1792,6 @@ void VarDebugInfo::DumpDebugInfo(char* ptr, int& offset) offset += len; } -/* static data for symbol strings */ -struct Elf_Symbol { - const char* m_name; - int m_off; - TADDR m_value; - int m_section, m_size; - NewArrayHolder m_symbol_name; - Elf_Symbol() : m_name(nullptr), m_off(0), m_value(0), m_section(0), m_size(0) {} -}; - template static int countFuncs(T &arr, int n) { diff --git a/src/coreclr/src/vm/gdbjit.h b/src/coreclr/src/vm/gdbjit.h index 8d9359c16ca5e..fa5a4883cb742 100644 --- a/src/coreclr/src/vm/gdbjit.h +++ b/src/coreclr/src/vm/gdbjit.h @@ -334,7 +334,16 @@ class VarDebugInfo: public DwarfDumpable uintptr_t m_high_pc; }; -struct Elf_Symbol; +/* static data for symbol strings */ +struct Elf_Symbol { + const char* m_name; + int m_off; + TADDR m_value; + int m_section, m_size; + NewArrayHolder m_symbol_name; + Elf_Symbol() : m_name(nullptr), m_off(0), m_value(0), m_section(0), m_size(0) {} +}; + class Elf_Builder; class DebugStringsCU; From b42753b432be057c05742d07ee733ac2d13390f3 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Wed, 27 May 2020 09:35:05 -0700 Subject: [PATCH 417/420] Improve test ALPN detection (#36928) * Improve test ALPN detection * feedback from review * add tvos * update casing --- .../TestUtilities/System/PlatformDetection.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index df828e0f7eeff..a17d3eebce28d 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -24,6 +24,8 @@ public static partial class PlatformDetection public static bool IsMonoInterpreter => GetIsRunningOnMonoInterpreter(); public static bool IsFreeBSD => RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")); public static bool IsNetBSD => RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")); + public static bool IsiOS => RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS")); + public static bool IstvOS => RuntimeInformation.IsOSPlatform(OSPlatform.Create("TVOS")); public static bool IsArmProcess => RuntimeInformation.ProcessArchitecture == Architecture.Arm; public static bool IsNotArmProcess => !IsArmProcess; @@ -109,11 +111,13 @@ public static bool IsNonZeroLowerBoundArraySupported // Windows - Schannel supports alpn from win8.1/2012 R2 and higher. // Linux - OpenSsl supports alpn from openssl 1.0.2 and higher. // OSX - SecureTransport doesn't expose alpn APIs. TODO https://github.com/dotnet/runtime/issues/27727 + public static bool IsOpenSslSupported => IsLinux || IsFreeBSD; + public static bool SupportsAlpn => (IsWindows && !IsWindows7) || - ((!IsOSX && !IsWindows) && + (IsOpenSslSupported && (OpenSslVersion.Major >= 1 && (OpenSslVersion.Minor >= 1 || OpenSslVersion.Build >= 2))); - public static bool SupportsClientAlpn => SupportsAlpn || (IsOSX && Environment.OSVersion.Version > new Version(10, 12)); + public static bool SupportsClientAlpn => SupportsAlpn || IsOSX || IsiOS || IstvOS; // OpenSSL 1.1.1 and above. public static bool SupportsTls13 => GetTls13Support(); @@ -261,16 +265,18 @@ private static bool GetTls13Support() // assume no if key is missing or on error. return false; } - else if (IsOSX) + else if (IsOSX || IsiOS || IstvOS) { // [ActiveIssue("https://github.com/dotnet/runtime/issues/1979")] return false; } - else + else if (IsOpenSslSupported) { // Covers Linux and FreeBSD return OpenSslVersion >= new Version(1,1,1); } + + return false; } private static bool GetIsRunningOnMonoInterpreter() From 5f4d5dae6eca5557d0850fd2d7daffa58738ca41 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Wed, 27 May 2020 09:46:41 -0700 Subject: [PATCH 418/420] uddate Ubuntu and Alpine RID (#37031) Co-authored-by: Tomas Weinfurt --- .../runtime.compatibility.json | 301 ++++++++++++++++++ .../Microsoft.NETCore.Platforms/runtime.json | 127 ++++++++ .../runtimeGroups.props | 4 +- 3 files changed, 430 insertions(+), 2 deletions(-) diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json index 8612ca4647164..ca8d8b4493f6a 100644 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json +++ b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json @@ -92,6 +92,47 @@ "any", "base" ], + "alpine.3.12": [ + "alpine.3.12", + "alpine.3.11", + "alpine.3.10", + "alpine.3.9", + "alpine.3.8", + "alpine.3.7", + "alpine.3.6", + "alpine", + "linux-musl", + "linux", + "unix", + "any", + "base" + ], + "alpine.3.12-x64": [ + "alpine.3.12-x64", + "alpine.3.12", + "alpine.3.11-x64", + "alpine.3.11", + "alpine.3.10-x64", + "alpine.3.10", + "alpine.3.9-x64", + "alpine.3.9", + "alpine.3.8-x64", + "alpine.3.8", + "alpine.3.7-x64", + "alpine.3.7", + "alpine.3.6-x64", + "alpine.3.6", + "alpine-x64", + "alpine", + "linux-musl-x64", + "linux-musl", + "linux-x64", + "linux", + "unix-x64", + "unix", + "any", + "base" + ], "alpine.3.6": [ "alpine.3.6", "alpine", @@ -5334,6 +5375,266 @@ "any", "base" ], + "ubuntu.20.04": [ + "ubuntu.20.04", + "ubuntu", + "debian", + "linux", + "unix", + "any", + "base" + ], + "ubuntu.20.04-arm": [ + "ubuntu.20.04-arm", + "ubuntu.20.04", + "ubuntu-arm", + "ubuntu", + "debian-arm", + "debian", + "linux-arm", + "linux", + "unix-arm", + "unix", + "any", + "base" + ], + "ubuntu.20.04-arm64": [ + "ubuntu.20.04-arm64", + "ubuntu.20.04", + "ubuntu-arm64", + "ubuntu", + "debian-arm64", + "debian", + "linux-arm64", + "linux", + "unix-arm64", + "unix", + "any", + "base" + ], + "ubuntu.20.04-x64": [ + "ubuntu.20.04-x64", + "ubuntu.20.04", + "ubuntu-x64", + "ubuntu", + "debian-x64", + "debian", + "linux-x64", + "linux", + "unix-x64", + "unix", + "any", + "base" + ], + "ubuntu.20.04-x86": [ + "ubuntu.20.04-x86", + "ubuntu.20.04", + "ubuntu-x86", + "ubuntu", + "debian-x86", + "debian", + "linux-x86", + "linux", + "unix-x86", + "unix", + "any", + "base" + ], + "ubuntu.20.10": [ + "ubuntu.20.10", + "ubuntu", + "debian", + "linux", + "unix", + "any", + "base" + ], + "ubuntu.20.10-arm": [ + "ubuntu.20.10-arm", + "ubuntu.20.10", + "ubuntu-arm", + "ubuntu", + "debian-arm", + "debian", + "linux-arm", + "linux", + "unix-arm", + "unix", + "any", + "base" + ], + "ubuntu.20.10-arm64": [ + "ubuntu.20.10-arm64", + "ubuntu.20.10", + "ubuntu-arm64", + "ubuntu", + "debian-arm64", + "debian", + "linux-arm64", + "linux", + "unix-arm64", + "unix", + "any", + "base" + ], + "ubuntu.20.10-x64": [ + "ubuntu.20.10-x64", + "ubuntu.20.10", + "ubuntu-x64", + "ubuntu", + "debian-x64", + "debian", + "linux-x64", + "linux", + "unix-x64", + "unix", + "any", + "base" + ], + "ubuntu.20.10-x86": [ + "ubuntu.20.10-x86", + "ubuntu.20.10", + "ubuntu-x86", + "ubuntu", + "debian-x86", + "debian", + "linux-x86", + "linux", + "unix-x86", + "unix", + "any", + "base" + ], + "ubuntu.21.04": [ + "ubuntu.21.04", + "ubuntu", + "debian", + "linux", + "unix", + "any", + "base" + ], + "ubuntu.21.04-arm": [ + "ubuntu.21.04-arm", + "ubuntu.21.04", + "ubuntu-arm", + "ubuntu", + "debian-arm", + "debian", + "linux-arm", + "linux", + "unix-arm", + "unix", + "any", + "base" + ], + "ubuntu.21.04-arm64": [ + "ubuntu.21.04-arm64", + "ubuntu.21.04", + "ubuntu-arm64", + "ubuntu", + "debian-arm64", + "debian", + "linux-arm64", + "linux", + "unix-arm64", + "unix", + "any", + "base" + ], + "ubuntu.21.04-x64": [ + "ubuntu.21.04-x64", + "ubuntu.21.04", + "ubuntu-x64", + "ubuntu", + "debian-x64", + "debian", + "linux-x64", + "linux", + "unix-x64", + "unix", + "any", + "base" + ], + "ubuntu.21.04-x86": [ + "ubuntu.21.04-x86", + "ubuntu.21.04", + "ubuntu-x86", + "ubuntu", + "debian-x86", + "debian", + "linux-x86", + "linux", + "unix-x86", + "unix", + "any", + "base" + ], + "ubuntu.21.10": [ + "ubuntu.21.10", + "ubuntu", + "debian", + "linux", + "unix", + "any", + "base" + ], + "ubuntu.21.10-arm": [ + "ubuntu.21.10-arm", + "ubuntu.21.10", + "ubuntu-arm", + "ubuntu", + "debian-arm", + "debian", + "linux-arm", + "linux", + "unix-arm", + "unix", + "any", + "base" + ], + "ubuntu.21.10-arm64": [ + "ubuntu.21.10-arm64", + "ubuntu.21.10", + "ubuntu-arm64", + "ubuntu", + "debian-arm64", + "debian", + "linux-arm64", + "linux", + "unix-arm64", + "unix", + "any", + "base" + ], + "ubuntu.21.10-x64": [ + "ubuntu.21.10-x64", + "ubuntu.21.10", + "ubuntu-x64", + "ubuntu", + "debian-x64", + "debian", + "linux-x64", + "linux", + "unix-x64", + "unix", + "any", + "base" + ], + "ubuntu.21.10-x86": [ + "ubuntu.21.10-x86", + "ubuntu.21.10", + "ubuntu-x86", + "ubuntu", + "debian-x86", + "debian", + "linux-x86", + "linux", + "unix-x86", + "unix", + "any", + "base" + ], "unix": [ "unix", "any", diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json index ff9a224f0c471..aa9f28ca15d33 100644 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json +++ b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json @@ -33,6 +33,17 @@ "alpine.3.10-x64" ] }, + "alpine.3.12": { + "#import": [ + "alpine.3.11" + ] + }, + "alpine.3.12-x64": { + "#import": [ + "alpine.3.12", + "alpine.3.11-x64" + ] + }, "alpine.3.6": { "#import": [ "alpine" @@ -2335,6 +2346,122 @@ "ubuntu-x86" ] }, + "ubuntu.20.04": { + "#import": [ + "ubuntu" + ] + }, + "ubuntu.20.04-arm": { + "#import": [ + "ubuntu.20.04", + "ubuntu-arm" + ] + }, + "ubuntu.20.04-arm64": { + "#import": [ + "ubuntu.20.04", + "ubuntu-arm64" + ] + }, + "ubuntu.20.04-x64": { + "#import": [ + "ubuntu.20.04", + "ubuntu-x64" + ] + }, + "ubuntu.20.04-x86": { + "#import": [ + "ubuntu.20.04", + "ubuntu-x86" + ] + }, + "ubuntu.20.10": { + "#import": [ + "ubuntu" + ] + }, + "ubuntu.20.10-arm": { + "#import": [ + "ubuntu.20.10", + "ubuntu-arm" + ] + }, + "ubuntu.20.10-arm64": { + "#import": [ + "ubuntu.20.10", + "ubuntu-arm64" + ] + }, + "ubuntu.20.10-x64": { + "#import": [ + "ubuntu.20.10", + "ubuntu-x64" + ] + }, + "ubuntu.20.10-x86": { + "#import": [ + "ubuntu.20.10", + "ubuntu-x86" + ] + }, + "ubuntu.21.04": { + "#import": [ + "ubuntu" + ] + }, + "ubuntu.21.04-arm": { + "#import": [ + "ubuntu.21.04", + "ubuntu-arm" + ] + }, + "ubuntu.21.04-arm64": { + "#import": [ + "ubuntu.21.04", + "ubuntu-arm64" + ] + }, + "ubuntu.21.04-x64": { + "#import": [ + "ubuntu.21.04", + "ubuntu-x64" + ] + }, + "ubuntu.21.04-x86": { + "#import": [ + "ubuntu.21.04", + "ubuntu-x86" + ] + }, + "ubuntu.21.10": { + "#import": [ + "ubuntu" + ] + }, + "ubuntu.21.10-arm": { + "#import": [ + "ubuntu.21.10", + "ubuntu-arm" + ] + }, + "ubuntu.21.10-arm64": { + "#import": [ + "ubuntu.21.10", + "ubuntu-arm64" + ] + }, + "ubuntu.21.10-x64": { + "#import": [ + "ubuntu.21.10", + "ubuntu-x64" + ] + }, + "ubuntu.21.10-x86": { + "#import": [ + "ubuntu.21.10", + "ubuntu-x86" + ] + }, "unix": { "#import": [ "any" diff --git a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props index 5ee96996906b8..1cb561273e87a 100644 --- a/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props +++ b/src/libraries/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props @@ -16,7 +16,7 @@ linux-musl x64 - 3.6;3.7;3.8;3.9;3.10;3.11 + 3.6;3.7;3.8;3.9;3.10;3.11;3.12 @@ -180,7 +180,7 @@ debian x64;x86;arm;arm64 - 16.04;16.10;17.04;17.10;18.04;18.10;19.04;19.10 + 16.04;16.10;17.04;17.10;18.04;18.10;19.04;19.10;20.04;20.10;21.04;21.10 false From 0c043d58ccce29e1d22acd4f77b0e0b352579ac5 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 27 May 2020 17:11:49 +0000 Subject: [PATCH 419/420] [master] Update dependencies from mono/linker dotnet/xharness (#37051) * Update dependencies from https://github.com/mono/linker build 20200526.2 Microsoft.NET.ILLink.Tasks From Version 5.0.0-preview.3.20271.1 -> To Version 5.0.0-preview.3.20276.2 * Update dependencies from https://github.com/dotnet/xharness build 20200527.1 Microsoft.DotNet.XHarness.Tests.Runners From Version 1.0.0-prerelease.20275.1 -> To Version 1.0.0-prerelease.20277.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0901fe72ef2f4..0e5212ef380e4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -170,13 +170,13 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - 5780105febb3018552f797fee40f7d60edcd594b + 3481158940a2b7f1114950cc7ba5bd56e0bfc761 - + https://github.com/dotnet/xharness - 1a11b8022ecc81242dafc48dbbc3e94f924c8ba2 + 8f6cc04f53cb6759758ffc97c9c8ca3ab4802f7f diff --git a/eng/Versions.props b/eng/Versions.props index 2b3d55fa56220..586f105dc5466 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -107,7 +107,7 @@ 4.8.0 16.7.0-preview-20200521-01 - 1.0.0-prerelease.20275.1 + 1.0.0-prerelease.20277.1 2.4.1 1.2.1 2.0.5 @@ -116,7 +116,7 @@ 3.1.0-preview-20200129.1 - 5.0.0-preview.3.20271.1 + 5.0.0-preview.3.20276.2 9.0.1-alpha.1.20268.2 9.0.1-alpha.1.20268.2 From e7b0f33a494cf0e70c0720e8b052e67121048bb5 Mon Sep 17 00:00:00 2001 From: jashook Date: Fri, 29 May 2020 09:17:19 -0700 Subject: [PATCH 420/420] Fix pri0 test build. --- .../COM/ComWrappers/WeakReference/WeakReferenceTest.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj b/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj index edcc33106ebde..97dd973ac5472 100644 --- a/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj +++ b/src/coreclr/tests/src/Interop/COM/ComWrappers/WeakReference/WeakReferenceTest.csproj @@ -8,7 +8,6 @@ true true -